Merge "Modify operation enum."
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 495ae45..42ac921 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -240,6 +240,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.input.classifier</name>
+        <version>1.0</version>
+        <interface>
+            <name>IInputClassifier</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
@@ -440,7 +448,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.vibrator</name>
-        <version>1.0-2</version>
+        <version>1.0-3</version>
         <interface>
             <name>IVibrator</name>
             <instance>default</instance>
diff --git a/current.txt b/current.txt
index 3f124ae..c063f3e 100644
--- a/current.txt
+++ b/current.txt
@@ -401,5 +401,6 @@
 271187e261b30c01a33011aea257c07a2d2f05b72943ebee89e973e997849973 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
 e78cf871f9fd1c072874e481e06e18e2681763cf2aa38c1fd777d53bab4eb69b android.hardware.sensors@1.0::types
+3d01e29e8129186f7567c4f9c8bee7480a0768e587b1be9b28adb0a6cbec6bf2 android.hardware.tv.cec@1.0::types
 1722ad002317b1fae1400de709e90f442d94ef22864e05f7a12af48c32e8edc8 android.hardware.usb@1.1::types
 29c8da7a13c40d488f569c812441d5754ee45bdcdb8ce6564f524b708d10a057 android.hardware.vibrator@1.1::types
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 200671e..9b6b076 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -13,6 +13,7 @@
         "IAGnssRil.hal",
         "IGnss.hal",
         "IGnssCallback.hal",
+        "IGnssConfiguration.hal",
         "IGnssMeasurement.hal",
         "IGnssMeasurementCallback.hal",
     ],
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index fb8b040..e1acd6d 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -20,13 +20,14 @@
 import @1.1::IGnss;
 
 import IGnssCallback;
+import IGnssConfiguration;
 import IGnssMeasurement;
 import IAGnss;
 import IAGnssRil;
 
 /** Represents the standard GNSS (Global Navigation Satellite System) interface. */
 interface IGnss extends @1.1::IGnss {
-     /**
+    /**
      * Opens the interface and provides the callback routines to the implementation of this
      * interface.
      *
@@ -37,6 +38,13 @@
     setCallback_2_0(IGnssCallback callback) generates (bool success);
 
     /**
+     * This method returns the IGnssConfiguration interface.
+     *
+     * @return gnssConfigurationIface Handle to the IGnssConfiguration interface.
+     */
+    getExtensionGnssConfiguration_2_0() generates (IGnssConfiguration gnssConfigurationIface);
+
+    /**
      * This method returns the IAGnss Interface.
      *
      * The getExtensionAGnss() must return nullptr as the @1.0::IAGnss interface is
diff --git a/gnss/2.0/IGnssConfiguration.hal b/gnss/2.0/IGnssConfiguration.hal
new file mode 100644
index 0000000..90c376e
--- /dev/null
+++ b/gnss/2.0/IGnssConfiguration.hal
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.gnss@2.0;
+
+import @1.1::IGnssConfiguration;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ *
+ * Due to the introduction of new GNSS HAL package android.hardware.gnss.visibility_control@1.0
+ * the following methods in @1.0::IGnssConfiguration are deprecated in this version and not
+ * called by the framework.
+ *
+ * setGpsLock(bitfield<GpsLock> lock) generates (bool success);
+ * setSuplEs(bool enabled) generates (bool success);
+ */
+interface IGnssConfiguration extends @1.1::IGnssConfiguration {
+    /**
+     * This method sets the emergency session extension duration. The GNSS HAL
+     * implementation must serve emergency SUPL and Control Plane network initiated
+     * location requests for this extra duration after the user initiated emergency
+     * session ends.
+     *
+     * @param emergencyExtensionSeconds Number of seconds to extend the emergency
+     * session duration post emergency call.
+     *
+     * @return success True if the GNSS HAL implementation accepts and supports the
+     * extended duration for emergency SUPL and Control Plane location requests.
+     */
+    setEsExtensionSec(uint32_t emergencyExtensionSeconds) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 9119ee4..92d5c1f 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -21,6 +21,7 @@
     vendor: true,
     vintf_fragments: ["android.hardware.gnss@2.0-service.xml"],
     srcs: [
+        "GnssConfiguration.cpp",
         "AGnss.cpp",
         "AGnssRil.cpp",
         "Gnss.cpp",
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index bde904f..5c752d5 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -20,6 +20,7 @@
 #include <log/log.h>
 #include "AGnss.h"
 #include "AGnssRil.h"
+#include "GnssConfiguration.h"
 #include "GnssMeasurement.h"
 
 using ::android::hardware::Status;
@@ -181,6 +182,10 @@
 }
 
 // Methods from V2_0::IGnss follow.
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+    return new GnssConfiguration{};
+}
+
 Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
     return new AGnss{};
 }
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index 47792cf..e86158f 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -72,6 +72,7 @@
     Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
 
     // Methods from V2_0::IGnss follow.
+    Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
     Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
     Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
     Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
diff --git a/gnss/2.0/default/GnssConfiguration.cpp b/gnss/2.0/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..4389dd2
--- /dev/null
+++ b/gnss/2.0/default/GnssConfiguration.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "GnssConfiguration"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enable) {
+    ALOGD("setSuplEs enable: %d", enable);
+    // Method deprecated in 2.0 and not expected to be called by the framework.
+    return false;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
+    // TODO implement
+    return bool{};
+}
+
+Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
+    // TODO implement
+    return bool{};
+}
+
+Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock> gpsLock) {
+    ALOGD("setGpsLock gpsLock: %hhu", static_cast<GpsLock>(gpsLock));
+    // Method deprecated in 2.0 and not expected to be called by the framework.
+    return false;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
+    // TODO implement
+    return bool{};
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
+    // TODO implement
+    return bool{};
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
+    // TODO implement
+    return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+    const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>&) {
+    // TODO (b/122463906): Reuse 1.1 implementation.
+    return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+    ALOGD("setEsExtensionSec emergencyExtensionSeconds: %d", emergencyExtensionSeconds);
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/gnss/2.0/default/GnssConfiguration.h b/gnss/2.0/default/GnssConfiguration.h
new file mode 100644
index 0000000..0c02ccd
--- /dev/null
+++ b/gnss/2.0/default/GnssConfiguration.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.0/IGnssConfiguration.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct GnssConfiguration : public IGnssConfiguration {
+    // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+    Return<bool> setSuplEs(bool enabled) override;
+    Return<bool> setSuplVersion(uint32_t version) override;
+    Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
+    Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
+    Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
+    Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
+    Return<bool> setEmergencySuplPdn(bool enable) override;
+
+    // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+    Return<bool> setBlacklist(
+        const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+    // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+    Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
index ae36c50..a8e40ba 100644
--- a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
+++ b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
@@ -23,6 +23,7 @@
     ::testing::AddGlobalTestEnvironment(GnssHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
     GnssHidlEnvironment::Instance()->init(&argc, argv);
+    // TODO (b/122463165): Expand coverage to include 1.1 and 1.0 VTS tests.
     int status = RUN_ALL_TESTS();
     ALOGI("Test result = %d", status);
     return status;
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index ef232c9..cef06a2 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -21,6 +21,7 @@
 
 using android::hardware::hidl_vec;
 
+using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
 using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
 using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
 using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
@@ -60,6 +61,56 @@
 }
 
 /*
+ * TestGnssConfigurationExtension:
+ * Gets the GnssConfigurationExtension and verifies that it returns an actual extension by
+ * calling a method.
+ *
+ * The GNSS HAL 2.0 implementation must support @2.0::IGnssConfiguration interface due to
+ * the deprecation of some methods in @1.0::IGnssConfiguration interface.
+ */
+TEST_F(GnssHalTest, TestGnssConfigurationExtension) {
+    auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+    ASSERT_TRUE(gnssConfiguration.isOk());
+    sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+    ASSERT_NE(iGnssConfiguration, nullptr);
+
+    auto result = iGnssConfiguration->setEsExtensionSec(180);
+    ASSERT_TRUE(result.isOk());
+    // Expected result can be true or false depending on whether HAL implementation supports
+    // detecting emergency sessions without involving the framework.
+}
+
+/*
+ * TestGnssConfiguration_setSuplEs_Deprecation:
+ * Calls setSuplEs and verifies that it returns false.
+ */
+TEST_F(GnssHalTest, TestGnssConfiguration_setSuplEs_Deprecation) {
+    auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+    ASSERT_TRUE(gnssConfiguration.isOk());
+    sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+    ASSERT_NE(iGnssConfiguration, nullptr);
+
+    auto result = iGnssConfiguration->setSuplEs(false);
+    ASSERT_TRUE(result.isOk());
+    EXPECT_FALSE(result);
+}
+
+/*
+ * TestGnssConfiguration_setGpsLock_Deprecation:
+ * Calls setGpsLock and verifies that it returns false.
+ */
+TEST_F(GnssHalTest, TestGnssConfiguration_setGpsLock_Deprecation) {
+    auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+    ASSERT_TRUE(gnssConfiguration.isOk());
+    sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+    ASSERT_NE(iGnssConfiguration, nullptr);
+
+    auto result = iGnssConfiguration->setGpsLock(0);
+    ASSERT_TRUE(result.isOk());
+    EXPECT_FALSE(result);
+}
+
+/*
  * TestAGnssRilExtension:
  * Gets the AGnssRilExtension and verifies that it returns an actual extension.
  *
@@ -76,11 +127,11 @@
 }
 
 /*
- * TestAGnssRilUpdateNetworkState_2_0:
+ * TestAGnssRil_UpdateNetworkState_2_0:
  * 1. Updates GNSS HAL that a network has connected.
  * 2. Updates GNSS HAL that network has disconnected.
  */
-TEST_F(GnssHalTest, TestAGnssRilUpdateNetworkState_2_0) {
+TEST_F(GnssHalTest, TestAGnssRil_UpdateNetworkState_2_0) {
     auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
     ASSERT_TRUE(agnssRil.isOk());
     sp<IAGnssRil_2_0> iAGnssRil = agnssRil;
diff --git a/input/classifier/1.0/Android.bp b/input/classifier/1.0/Android.bp
new file mode 100644
index 0000000..c3c6fc6
--- /dev/null
+++ b/input/classifier/1.0/Android.bp
@@ -0,0 +1,35 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.input.classifier@1.0",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "IInputClassifier.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    types: [
+        "Action",
+        "Axis",
+        "Button",
+        "Classification",
+        "EdgeFlag",
+        "Flag",
+        "Meta",
+        "MotionEvent",
+        "PointerCoords",
+        "PointerProperties",
+        "PolicyFlag",
+        "Source",
+        "SourceClass",
+        "ToolType",
+        "VideoFrame",
+    ],
+    gen_java: true,
+}
+
diff --git a/input/classifier/1.0/IInputClassifier.hal b/input/classifier/1.0/IInputClassifier.hal
new file mode 100644
index 0000000..edc1138
--- /dev/null
+++ b/input/classifier/1.0/IInputClassifier.hal
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+package android.hardware.input.classifier@1.0;
+
+interface IInputClassifier {
+
+  /**
+   * Returns the classification for the current sequence of input events.
+   */
+  classify(MotionEvent event) generates (Classification classification);
+
+};
diff --git a/input/classifier/1.0/default/Android.bp b/input/classifier/1.0/default/Android.bp
new file mode 100644
index 0000000..ddd883c
--- /dev/null
+++ b/input/classifier/1.0/default/Android.bp
@@ -0,0 +1,23 @@
+cc_binary {
+    name: "android.hardware.input.classifier@1.0-service-example",
+    init_rc: ["android.hardware.input.classifier@1.0-service-example.rc"],
+    relative_install_path: "hw",
+    vendor: true,
+    vintf_fragments: ["manifest_input.classifier.xml"],
+    srcs: [
+        "InputClassifier.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.input.classifier@1.0",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
diff --git a/input/classifier/1.0/default/InputClassifier.cpp b/input/classifier/1.0/default/InputClassifier.cpp
new file mode 100644
index 0000000..c463361
--- /dev/null
+++ b/input/classifier/1.0/default/InputClassifier.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "InputClassifierHAL"
+
+#include "InputClassifier.h"
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/Timers.h>
+
+using namespace android::hardware::input::classifier::V1_0;
+
+namespace android {
+namespace hardware {
+namespace input {
+namespace classifier {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::input::classifier::V1_0::IInputClassifier follow.
+Return<Classification> InputClassifier::classify(const MotionEvent& event) {
+    /**
+     * In this example implementation, we will see how many "pixels" inside the video frame
+     * exceed the value of 250. If more than 6 such pixels are present, then treat the event
+     * as a "DEEP_PRESS".
+     */
+    if (event.frames.size() == 0) {
+        return Classification::NONE;
+    }
+    ALOGI("Frame(O) timestamp = %" PRIu64 ", received %zu frame(s)", event.frames[0].timestamp,
+          event.frames.size());
+    for (const VideoFrame& frame : event.frames) {
+        size_t count = 0;
+        for (size_t i = 0; i < frame.data.size(); i++) {
+            if (frame.data[i] > 250) {
+                count++;
+            }
+        }
+        if (count > 6) {
+            return Classification::DEEP_PRESS;
+        }
+    }
+
+    return Classification::NONE;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace classifier
+}  // namespace input
+}  // namespace hardware
+}  // namespace android
diff --git a/input/classifier/1.0/default/InputClassifier.h b/input/classifier/1.0/default/InputClassifier.h
new file mode 100644
index 0000000..0858ecb
--- /dev/null
+++ b/input/classifier/1.0/default/InputClassifier.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef ANDROID_HARDWARE_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
+#define ANDROID_HARDWARE_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
+
+#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace input {
+namespace classifier {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+
+struct InputClassifier : public IInputClassifier {
+    // Methods from ::android::hardware::input::classifier::V1_0::IInputClassifier follow.
+    Return<Classification> classify(
+        const ::android::hardware::input::classifier::V1_0::MotionEvent& event) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace classifier
+}  // namespace input
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
diff --git a/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc b/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc
new file mode 100644
index 0000000..f799bf4
--- /dev/null
+++ b/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc
@@ -0,0 +1,9 @@
+service vendor.input.classifier-1-0 /vendor/bin/hw/android.hardware.input.classifier@1.0-service-example
+    # Must be specified if "disabled" is set. This HAL will only start if requested via getService
+    interface android.hardware.input.classifier@1.0::IInputClassifier default
+    class hal
+    user nobody
+    # will not be restarted if it exits until it is requested to be restarted
+    oneshot
+    # will only be started when requested
+    disabled
diff --git a/input/classifier/1.0/default/manifest_input.classifier.xml b/input/classifier/1.0/default/manifest_input.classifier.xml
new file mode 100644
index 0000000..8634169
--- /dev/null
+++ b/input/classifier/1.0/default/manifest_input.classifier.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.input.classifier</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IInputClassifier</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/input/classifier/1.0/default/service.cpp b/input/classifier/1.0/default/service.cpp
new file mode 100644
index 0000000..6ef2118
--- /dev/null
+++ b/input/classifier/1.0/default/service.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "android.hardware.input.classifier@1.0"
+
+#include <inttypes.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+#include "InputClassifier.h"
+#include "android/hardware/input/classifier/1.0/IInputClassifier.h"
+
+using android::sp;
+using android::status_t;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::input::classifier::V1_0::IInputClassifier;
+using android::hardware::input::classifier::V1_0::implementation::InputClassifier;
+
+int main() {
+    sp<IInputClassifier> classifier = new InputClassifier();
+
+    configureRpcThreadpool(1, true);
+    const status_t status = classifier->registerAsService();
+
+    if (status != android::OK) {
+        ALOGE("Could not register InputClassifier HAL!");
+        return EXIT_FAILURE;  // or handle error
+    }
+
+    joinRpcThreadpool();
+    LOG_ALWAYS_FATAL("Under normal operation, joinRpcThreadpool should never return");
+    return EXIT_FAILURE;
+}
diff --git a/input/classifier/1.0/types.hal b/input/classifier/1.0/types.hal
new file mode 100644
index 0000000..244ecd9
--- /dev/null
+++ b/input/classifier/1.0/types.hal
@@ -0,0 +1,829 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+package android.hardware.input.classifier@1.0;
+
+
+/**
+ * Constants that identify each individual axis of a motion event.
+ */
+enum Axis : uint64_t {
+    /**
+     * Axis constant: X axis of a motion event.
+     *
+     * - For a touch screen, reports the absolute X screen position of the center of
+     * the touch contact area.  The units are display pixels.
+     * - For a touch pad, reports the absolute X surface position of the center of the touch
+     * contact area. The units are device-dependent.
+     * - For a mouse, reports the absolute X screen position of the mouse pointer.
+     * The units are display pixels.
+     * - For a trackball, reports the relative horizontal displacement of the trackball.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     * - For a joystick, reports the absolute X position of the joystick.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     */
+    X = 0,
+    /**
+     * Axis constant: Y axis of a motion event.
+     *
+     * - For a touch screen, reports the absolute Y screen position of the center of
+     * the touch contact area.  The units are display pixels.
+     * - For a touch pad, reports the absolute Y surface position of the center of the touch
+     * contact area. The units are device-dependent.
+     * - For a mouse, reports the absolute Y screen position of the mouse pointer.
+     * The units are display pixels.
+     * - For a trackball, reports the relative vertical displacement of the trackball.
+     * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+     * - For a joystick, reports the absolute Y position of the joystick.
+     * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).
+     */
+    Y = 1,
+    /**
+     * Axis constant: Pressure axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the approximate pressure applied to the surface
+     * by a finger or other tool.  The value is normalized to a range from
+     * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1
+     * may be generated depending on the calibration of the input device.
+     * - For a trackball, the value is set to 1 if the trackball button is pressed
+     * or 0 otherwise.
+     * - For a mouse, the value is set to 1 if the primary mouse button is pressed
+     * or 0 otherwise.
+     */
+    PRESSURE = 2,
+    /**
+     * Axis constant: Size axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the approximate size of the contact area in
+     * relation to the maximum detectable size for the device.  The value is normalized
+     * to a range from 0 (smallest detectable size) to 1 (largest detectable size),
+     * although it is not a linear scale. This value is of limited use.
+     * To obtain calibrated size information, see
+     * {@link TOUCH_MAJOR} or {@link TOOL_MAJOR}.
+     */
+    SIZE = 3,
+    /**
+     * Axis constant: TouchMajor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the major axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are display pixels.
+     * - For a touch pad, reports the length of the major axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are device-dependent.
+     */
+    TOUCH_MAJOR = 4,
+    /**
+     * Axis constant: TouchMinor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the minor axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are display pixels.
+     * - For a touch pad, reports the length of the minor axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     */
+    TOUCH_MINOR = 5,
+    /**
+     * Axis constant: ToolMajor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the major axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * - For a touch pad, reports the length of the major axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     *
+     * The tool size may be larger than the touch size since the tool may not be fully
+     * in contact with the touch sensor.
+     */
+    TOOL_MAJOR = 6,
+    /**
+     * Axis constant: ToolMinor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the minor axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * - For a touch pad, reports the length of the minor axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     *
+     * The tool size may be larger than the touch size since the tool may not be fully
+     * in contact with the touch sensor.
+     */
+    TOOL_MINOR = 7,
+    /**
+     * Axis constant: Orientation axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the orientation of the finger
+     * or tool in radians relative to the vertical plane of the device.
+     * An angle of 0 radians indicates that the major axis of contact is oriented
+     * upwards, is perfectly circular or is of unknown orientation.  A positive angle
+     * indicates that the major axis of contact is oriented to the right.  A negative angle
+     * indicates that the major axis of contact is oriented to the left.
+     * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+     * (finger pointing fully right).
+     * - For a stylus, the orientation indicates the direction in which the stylus
+     * is pointing in relation to the vertical axis of the current orientation of the screen.
+     * The range is from -PI radians to PI radians, where 0 is pointing up,
+     * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians
+     * is pointing right.  See also {@link TILT}.
+     */
+    ORIENTATION = 8,
+    /**
+     * Axis constant: Vertical Scroll axis of a motion event.
+     *
+     * - For a mouse, reports the relative movement of the vertical scroll wheel.
+     * The value is normalized to a range from -1.0 (down) to 1.0 (up).
+     *
+     * The framework may use this axis to scroll views vertically.
+     */
+    VSCROLL = 9,
+    /**
+     * Axis constant: Horizontal Scroll axis of a motion event.
+     *
+     * - For a mouse, reports the relative movement of the horizontal scroll wheel.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     *
+     * The framework may use this axis to scroll views horizontally.
+     */
+    HSCROLL = 10,
+    /**
+     * Axis constant: Z axis of a motion event.
+     *
+     * - For a joystick, reports the absolute Z position of the joystick.
+     * The value is normalized to a range from -1.0 (high) to 1.0 (low).
+     * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+     * to report the absolute X position of the second joystick instead.</em>
+     */
+    Z = 11,
+    /**
+     * Axis constant: X Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the X axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     */
+    RX = 12,
+    /**
+     * Axis constant: Y Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the Y axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     */
+    RY = 13,
+    /**
+     * Axis constant: Z Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the Z axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     * On game pads with two analog joysticks, this axis is often reinterpreted
+     * to report the absolute Y position of the second joystick instead.
+     */
+    RZ = 14,
+    /**
+     * Axis constant: Hat X axis of a motion event.
+     *
+     * - For a joystick, reports the absolute X position of the directional hat control.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     */
+    HAT_X = 15,
+    /**
+     * Axis constant: Hat Y axis of a motion event.
+     *
+     * - For a joystick, reports the absolute Y position of the directional hat control.
+     * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+     */
+    HAT_Y = 16,
+    /**
+     * Axis constant: Left Trigger axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the left trigger control.
+     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+     */
+    LTRIGGER = 17,
+    /**
+     * Axis constant: Right Trigger axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the right trigger control.
+     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+     */
+    RTRIGGER = 18,
+    /**
+     * Axis constant: Throttle axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the throttle control.
+     * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).
+     */
+    THROTTLE = 19,
+    /**
+     * Axis constant: Rudder axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the rudder control.
+     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+     */
+    RUDDER = 20,
+    /**
+     * Axis constant: Wheel axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the steering wheel control.
+     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+     */
+    WHEEL = 21,
+    /**
+     * Axis constant: Gas axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the gas (accelerator) control.
+     * The value is normalized to a range from 0.0 (no acceleration)
+     * to 1.0 (maximum acceleration).
+     */
+    GAS = 22,
+    /**
+     * Axis constant: Brake axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the brake control.
+     * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).
+     */
+    BRAKE = 23,
+    /**
+     * Axis constant: Distance axis of a motion event.
+     *
+     * - For a stylus, reports the distance of the stylus from the screen.
+     * A value of 0.0 indicates direct contact and larger values indicate increasing
+     * distance from the surface.
+     */
+    DISTANCE = 24,
+    /**
+     * Axis constant: Tilt axis of a motion event.
+     *
+     * - For a stylus, reports the tilt angle of the stylus in radians where
+     * 0 radians indicates that the stylus is being held perpendicular to the
+     * surface, and PI/2 radians indicates that the stylus is being held flat
+     * against the surface.
+     */
+    TILT = 25,
+    /**
+     * Axis constant:  Generic scroll axis of a motion event.
+     *
+     * - This is used for scroll axis motion events that can't be classified as strictly
+     *   vertical or horizontal. The movement of a rotating scroller is an example of this.
+     */
+    SCROLL = 26,
+    /**
+     * Axis constant: The movement of x position of a motion event.
+     *
+     * - For a mouse, reports a difference of x position between the previous position.
+     * This is useful when pointer is captured, in that case the mouse pointer doesn't
+     * change the location but this axis reports the difference which allows the app
+     * to see how the mouse is moved.
+     */
+    RELATIVE_X = 27,
+    /**
+     * Axis constant: The movement of y position of a motion event.
+     *
+     * Same as {@link RELATIVE_X}, but for y position.
+     */
+    RELATIVE_Y = 28,
+    /**
+     * Axis constant: Generic 1 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_1 = 32,
+    /**
+     * Axis constant: Generic 2 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_2 = 33,
+    /**
+     * Axis constant: Generic 3 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_3 = 34,
+    /**
+     * Axis constant: Generic 4 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_4 = 35,
+    /**
+     * Axis constant: Generic 5 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_5 = 36,
+    /**
+     * Axis constant: Generic 6 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_6 = 37,
+    /**
+     * Axis constant: Generic 7 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_7 = 38,
+    /**
+     * Axis constant: Generic 8 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_8 = 39,
+    /**
+     * Axis constant: Generic 9 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_9 = 40,
+    /**
+     * Axis constant: Generic 10 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_10 = 41,
+    /**
+     * Axis constant: Generic 11 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_11 = 42,
+    /**
+     * Axis constant: Generic 12 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_12 = 43,
+    /**
+     * Axis constant: Generic 13 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_13 = 44,
+    /**
+     * Axis constant: Generic 14 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_14 = 45,
+    /**
+     * Axis constant: Generic 15 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_15 = 46,
+    /**
+     * Axis constant: Generic 16 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_16 = 47,
+};
+
+/**
+ * Tool type of a pointer
+ */
+enum ToolType: uint8_t {
+    UNKNOWN = 0,
+    FINGER = 1,
+    STYLUS = 2,
+    MOUSE = 3,
+    ERASER = 4,
+};
+
+/**
+ * Properties of a particular pointer. Analogous to Android's PointerProperties.
+ */
+struct PointerProperties {
+    /**
+     * A number identifying a specific pointer. When a pointer is lifted,
+     * this value may be reused by another new pointer, even during the
+     * same gesture. For example, if there are two pointers touching the screen
+     * at the same time, they might have pointer ID's of 0 and 1. If the
+     * pointer with id = 0 is lifted, while the pointer with id = 1 remains, and
+     * a new pointer is placed on the screen, then the new pointer may receive
+     * an id of 0. While a pointer is active, it is guaranteed to keep the same
+     * id.
+     */
+    int32_t id;
+    /**
+     * Type of tool used to make contact, such as a finger or stylus, if known.
+     */
+    ToolType toolType;
+};
+
+/**
+ * Pointer coordinate data. Analogous to Android's PointerCoords.
+ */
+struct PointerCoords {
+    /**
+     * Bitfield of axes that are present in this structure.
+     */
+    bitfield<Axis> bits;
+    /**
+     * The values corresponding to each non-zero axis. This vector only
+     * contains non-zero entries. If an axis that is not currently specified
+     * in "bits" is requested, a zero value is returned.
+     * There are only as many values stored here
+     * as there are non-zero bits in the "bits" field.
+     * The values are position-packed. So the first non-zero axis will be
+     * at position 0, the next non-zero axis will be at position 1, and so on.
+     */
+    vec<float> values;
+};
+
+enum SourceClass: uint8_t {
+    NONE = 1 << 0,
+    BUTTON = 1 << 1,
+    POINTER = 1 << 2,
+    NAVIGATION = 1 << 3,
+    POSITION = 1 << 4,
+    JOYSTICK = 1 << 5,
+};
+
+/**
+ * Input sources
+ */
+enum Source: uint32_t {
+    UNKNOWN = 0,
+    KEYBOARD = (1 << 8) | SourceClass:BUTTON,
+    DPAD = (1 << 9) | SourceClass:BUTTON,
+    GAMEPAD = (1 << 10) | SourceClass:BUTTON,
+    TOUCHSCREEN = (1 << 12) | SourceClass:POINTER,
+    MOUSE = (1 << 13) | SourceClass:POINTER,
+    STYLUS = (1 << 14) | SourceClass:POINTER,
+    BLUETOOTH_STYLUS = (1 << 15) | STYLUS,
+    TRACKBALL = (1 << 16) | SourceClass:NAVIGATION,
+    MOUSE_RELATIVE = (1 << 17) | SourceClass:NAVIGATION,
+    TOUCHPAD = (1 << 20) | SourceClass:POSITION,
+    TOUCH_NAVIGATION = (1 << 21) | SourceClass:NONE,
+    ROTARY_ENCODER = (1 << 22) | SourceClass:NONE,
+    JOYSTICK = (1 << 24) | SourceClass:JOYSTICK,
+    ANY = 0xFFFFFF00,
+};
+
+/** Motion event actions */
+enum Action: int32_t {
+    /** A pressed gesture has started, the motion contains the initial starting location. */
+    DOWN = 0,
+    /**
+     * A pressed gesture has finished, the motion contains the final release location
+     * as well as any intermediate points since the last down or move event.
+     */
+    UP = 1,
+    /**
+     * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
+     * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point.
+     */
+    MOVE = 2,
+    /**
+     * The current gesture has been aborted.
+     * You will not receive any more points in it. You must treat this as
+     * an up event, but not perform any action that you normally would.
+     */
+    CANCEL = 3,
+    /**
+     * A movement has happened outside of the normal bounds of the UI element.
+     * This does not provide a full gesture, but only the initial location of the movement/touch.
+     */
+    OUTSIDE = 4,
+    /**
+     * A non-primary pointer has gone down.
+     */
+    POINTER_DOWN = 5,
+    /**
+     * A non-primary pointer has gone up.
+     */
+    POINTER_UP = 6,
+    /**
+     * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
+     * The motion contains the most recent point, as well as any intermediate points since
+     * the last hover move event.
+     */
+    HOVER_MOVE = 7,
+    /**
+     * The motion event contains relative vertical and/or horizontal scroll offsets.
+     * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
+     * and AMOTION_EVENT_AXIS_HSCROLL.
+     * The pointer may or may not be down when this event is dispatched.
+     * The framework will always deliver this action to the window under the pointer, which
+     * may not be the window currently touched.
+     */
+    SCROLL = 8,
+    /**
+     * The pointer is not down but has entered the boundaries of a window or view.
+     */
+    HOVER_ENTER = 9,
+    /**
+     * The pointer is not down but has exited the boundaries of a window or view.
+     */
+    HOVER_EXIT = 10,
+    /**
+     * One or more buttons have been pressed.
+     */
+    BUTTON_PRESS = 11,
+    /**
+     * One or more buttons have been released.
+     */
+    BUTTON_RELEASE = 12,
+};
+
+/** Edge flags */
+enum EdgeFlag : int32_t {
+    /** No edges are intersected */
+    NONE = 0,
+    /** Motion intersected top edge of the screen */
+    TOP = 1 << 0,
+    /** Motion intersected bottom edge of the screen */
+    BOTTOM = 1 << 1,
+    /** Motion intersected left edge of the screen */
+    LEFT = 1 << 2,
+    /** Motion intersected right edge of the screen */
+    RIGHT = 1 << 3,
+};
+
+/** Policy flags */
+enum PolicyFlag : uint32_t {
+    // The following flags originate in RawEvents
+
+    /** Event should wake the device */
+    WAKE = 1 << 0,
+    /** Key is virtual, and should generate haptic feedback */
+    VIRTUAL = 1 << 1,
+    /** Key is the special function modifier */
+    FUNCTION = 1 << 2,
+    /**
+     * Key represents a special gesture that has been detected
+     * by the touch firmware or driver.
+     */
+    GESTURE = 1 << 3,
+
+    // The following flags may be generated here in the InputClassifier HAL
+    // or in later InputListener stages
+
+    /** Event was injected */
+    INJECTED = 1 << 24,
+    /**
+     * Event comes from a trusted source, such as a directly attached input
+     * device or an application with system-wide event injection permission.
+     */
+    TRUSTED = 1 << 25,
+    /** Event has passed through an input filter. */
+    FILTERED = 1 << 26,
+    /** Disable automatic key repeating behaviour. */
+    DISABLE_KEY_REPEAT = 1 << 27,
+
+    // The following flags are set by the input reader policy as it intercepts each event
+
+    /** Device was in an interactive state when the event was intercepted */
+    INTERACTIVE = 1 << 29,
+    /** Event should be dispatched to applications */
+    PASS_TO_USER = 1 << 30,
+};
+
+/**
+ * Buttons that are associated with motion events.
+ */
+enum Button : int32_t {
+    NONE = 0,
+    PRIMARY = 1 << 0,
+    SECONDARY = 1 << 1,
+    TERTIARY = 1 << 2,
+    BACK = 1 << 3,
+    FORWARD = 1 << 4,
+    STYLUS_PRIMARY = 1 << 5,
+    STYLUS_SECONDARY = 1 << 6,
+};
+
+/**
+ * Meta key / modifier state
+ */
+enum Meta : int32_t {
+    NONE = 0,
+
+    /** One of the ALT meta keys is pressed. */
+    ALT_ON = 1 << 1, // 0x02
+
+    /** The left ALT meta key is pressed. */
+    ALT_LEFT_ON = 1 << 4, // 0x10
+
+    /** The right ALT meta key is pressed. */
+    ALT_RIGHT_ON = 1 << 5, // 0x20
+
+    /** One of the SHIFT meta keys is pressed. */
+    SHIFT_ON = 1 << 0, // 0x01
+
+    /** The left SHIFT meta key is pressed. */
+    SHIFT_LEFT_ON = 1 << 6, // 0x40
+
+    /** The right SHIFT meta key is pressed. */
+    SHIFT_RIGHT_ON = 1 << 7, // 0x80
+
+    /** The SYM meta key is pressed. */
+    SYM_ON = 1 << 2, // 0x04
+
+    /** The FUNCTION meta key is pressed. */
+    FUNCTION_ON = 1 << 3, // 0x08
+
+    /** One of the CTRL meta keys is pressed. */
+    CTRL_ON = 1 << 12, // 0x1000
+
+    /** The left CTRL meta key is pressed. */
+    CTRL_LEFT_ON = 1 << 13, // 0x2000
+
+    /** The right CTRL meta key is pressed. */
+    CTRL_RIGHT_ON = 1 << 14, // 0x4000
+
+    /** One of the META meta keys is pressed. */
+    META_ON = 1 << 16, // 0x10000
+
+    /** The left META meta key is pressed. */
+    META_LEFT_ON = 1 << 17, // 0x20000
+
+    /** The right META meta key is pressed. */
+    META_RIGHT_ON = 1 << 18, //0x40000
+
+    /** The CAPS LOCK meta key is on. */
+    CAPS_LOCK_ON = 1 << 20, // 0x100000
+
+    /** The NUM LOCK meta key is on. */
+    NUM_LOCK_ON = 1 << 21, // 0x200000
+
+    /** The SCROLL LOCK meta key is on. */
+    SCROLL_LOCK_ON = 1 << 22, // 0x400000
+};
+
+/**
+ * Motion event flags
+ */
+enum Flag : int32_t {
+    /**
+     * Indicates that the window that received this motion event is partly
+     * or wholly obscured by another visible window above it. This flag is set to true
+     * even if the event did not directly pass through the obscured area.
+     * A security sensitive application can check this flag to identify situations in which
+     * a malicious application may have covered up part of its content for the purpose
+     * of misleading the user or hijacking touches. An appropriate response might be
+     * to drop the suspect touches or to take additional precautions to confirm the user's
+     * actual intent.
+     */
+    WINDOW_IS_OBSCURED = 1 << 0,
+    /**
+     * This flag indicates that the event has been generated by a gesture generator. It
+     * could be used, for example, to determine whether touch slop should be applied.
+     */
+    IS_GENERATED_GESTURE = 1 << 3, // 0x8
+    /**
+     * Motion event is inconsistent with previously sent motion events.
+     */
+    TAINTED = 1 << 31, // 0x80000000
+};
+
+/**
+ * Touch heatmap.
+ *
+ * The array is a 2-D row-major matrix with dimensions (height, width).
+ * The heatmap data does not rotate when device orientation changes.
+ *
+ * Example:
+ *
+ * If the data in the array is:
+ * data[i] = i for i in 0 .. 59,
+ * then it can be represented as follows:
+ *
+ *  <--    width   -- >
+ *   0  1  2  3  4  5   ^
+ *   6  7  8  9 10 11   |
+ *  12 12 14 15 16 17   |
+ *  18    ...      23   | height
+ *  24    ...      29   |
+ *  30    ...      35   |
+ *  36    ...      41   |
+ *  42    ...      47   |
+ *  48    ...      53   |
+ *  54    ...      59   v
+ *
+ * Looking at the device in standard portrait orientation,
+ * the element "0" is the top left of the screen,
+ * "5" is at the top right, and "59" is the bottom right.
+ * Here width=6, and height=10.
+ */
+struct VideoFrame {
+    /**
+     * Video frame data.
+     * Size of the data is width * height.
+     */
+    vec<int16_t> data;
+    uint32_t width;
+    uint32_t height;
+    /**
+     * Time at which the frame was collected, in nanoseconds.
+     * Measured with the same clock that is used to populate MotionEvent times.
+     */
+    uint64_t timestamp;
+};
+
+/**
+ * Analogous to Android's native MotionEvent / NotifyMotionArgs.
+ * Stores the basic information about pointer movements.
+ */
+struct MotionEvent {
+    // InputEvent fields
+    /**
+     * The id of the device which produced this event.
+     */
+    int32_t deviceId;
+    /**
+     * The source type of this event.
+     */
+    Source source;
+    /**
+     * The display id associated with this event.
+     */
+    int32_t displayId;
+
+    // NotifyMotionArgs fields
+    /**
+     * Time when the initial touch down occurred, in nanoseconds.
+     */
+    int64_t downTime;
+    /**
+     * Time when this event occurred, in nanoseconds.
+     */
+    int64_t eventTime;
+    /**
+     * The kind of action being performed.
+     */
+    Action action;
+    /**
+     * For ACTION_POINTER_DOWN or ACTION_POINTER_UP, this contains the associated pointer index.
+     * The index may be used to get information about the pointer that has gone down or up.
+     */
+    uint8_t actionIndex;
+    /**
+     * The button that has been modified during a press or release action.
+     */
+    Button actionButton;
+    /**
+     * The motion event flags.
+     */
+    bitfield<Flag> flags;
+    /**
+     * The motion event policy flags.
+     */
+    bitfield<PolicyFlag> policyFlags;
+    /**
+     * The edges, if any, that were touched by this motion event.
+     */
+    bitfield<EdgeFlag> edgeFlags;
+    /**
+     * The state of any meta / modifier keys that were in effect when the event was generated.
+     */
+    bitfield<Meta> metaState;
+    /**
+     * The state of buttons that are pressed.
+     */
+    bitfield<Button> buttonState;
+    /**
+     * The precision of the X coordinate being reported.
+     */
+    float xPrecision;
+    /**
+     * The precision of the Y coordinate being reported.
+     */
+    float yPrecision;
+    /**
+     * The properties of each pointer present in this motion event.
+     */
+    vec<PointerProperties> pointerProperties;
+    /**
+     * The coordinates of each pointer.
+     */
+    vec<PointerCoords> pointerCoords;
+
+    // Additional fields from NotifyMotionArgs
+    /**
+     * Device time at which the event occurred, in microseconds.
+     * Will wrap after a little over an hour.
+     */
+    uint32_t deviceTimestamp;
+    /**
+     * The video frames, if any, associated with the current or previous motion events.
+     */
+    vec<VideoFrame> frames;
+};
+
+
+enum Classification : uint8_t {
+    NONE = 0,
+    /**
+     * Too early to classify the gesture, need more events.
+     */
+    AMBIGUOUS_GESTURE = 1,
+    /**
+     * User is force-pressing the screen.
+     */
+    DEEP_PRESS = 2,
+};
diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp
index ad114f3..32f9712 100644
--- a/radio/1.4/Android.bp
+++ b/radio/1.4/Android.bp
@@ -30,6 +30,7 @@
         "DataConnActiveStatus",
         "DataProfileInfo",
         "DataRegStateResult",
+        "EmergencyCallRouting",
         "EmergencyNumber",
         "EmergencyNumberSource",
         "EmergencyServiceCategory",
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 8438777..b0810a4 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -18,9 +18,11 @@
 
 import @1.0::Dial;
 import @1.2::DataRequestReason;
+import @1.2::NetworkScanRequest;
 import @1.3::IRadio;
 import @1.4::AccessNetwork;
 import @1.4::DataProfileInfo;
+import @1.4::EmergencyCallRouting;
 import @1.4::EmergencyServiceCategory;
 import @1.4::RadioAccessFamily;
 
@@ -101,21 +103,26 @@
     oneway setDataProfile_1_4(int32_t serial, vec<DataProfileInfo> profiles);
 
     /**
-     * Initiate emergency voice call, with zero or more emergency service category(s).
+     * Initiate emergency voice call, with zero or more emergency service category(s) and routing
+     * information for handling the call. Android uses this request to make its emergency call
+     * instead of using @1.0::IRadio.dial if the 'address' in the 'dialInfo' field is identified
+     * as an emergency number by Android.
      *
-     * Note this API is the same as IRadio.dial except using the
-     * @1.4::EmergencyServiceCategory as the input param.
+     * In multi-sim senario, this radio request is sent through the IRadio service that serves
+     * the subscription the emergency number belongs to, no matter of the PUK/PIN state of the
+     * subscription and the service state.
      *
-     * If the number in the 'dialInfo' field is identified as an emergency number in Android,
-     * Android use this request for its emergency call instead of @1.0::IRadio.dial. The
-     * implementation decides how to handle the call (e.g. emergency routing or normal
-     * routing).
+     * Some countries or carriers require some emergency numbers that must be handled with normal
+     * call routing or emergency routing. If the 'routing' field is specified as
+     * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to
+     * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the
+     * implementation must use emergency routing to handle the call; if it is
+     * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call.
      *
      * If the dialed emergency number does not have a specified emergency service category, the
-     * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; iff either the
-     * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED or the underlying
+     * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the underlying
      * technology used to request emergency services does not support the emergency service
-     * category, the interpretation of the categories is defined by implementation.
+     * category, the categories may be ignored.
      *
      * Reference: 3gpp TS 22.101, Section 10 - Emergency Calls
      *
@@ -123,11 +130,23 @@
      * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
      * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s)
      *     of the call.
+     * @param routing @1.4::EmergencyCallRouting the emergency call routing information.
      *
      * Response function is IRadioResponse.emergencyDialResponse()
      */
     oneway emergencyDial(int32_t serial, Dial dialInfo,
-            bitfield<EmergencyServiceCategory> categories);
+            bitfield<EmergencyServiceCategory> categories, EmergencyCallRouting routing);
+
+    /**
+     * Starts a network scan
+     *
+     * @param serial Serial number of request.
+     * @param request Defines the radio networks/bands/channels which need to be scanned.
+     *
+     * Same API as @1.2::IRadio.startNetworkScan_1_2, except using the
+     * @1.4::IRadioResponse.startNetworkScanResponse_1_4 as the response.
+     */
+    oneway startNetworkScan_1_4(int32_t serial, NetworkScanRequest request);
 
     /**
      * Query the preferred network type bitmap.
diff --git a/radio/1.4/IRadioIndication.hal b/radio/1.4/IRadioIndication.hal
index 626b494..a58d19c 100644
--- a/radio/1.4/IRadioIndication.hal
+++ b/radio/1.4/IRadioIndication.hal
@@ -27,17 +27,17 @@
      * Report the current list of emergency numbers
      *
      * Each emergency number (@1.4::EmergencyNumber) in the emergency number list contains a
-     * dialing number, zero or more service category(s), mobile country code, and source(s) that
-     * indicate where it comes from.
+     * dialing number, zero or more service category(s), mobile country code, mobile network code,
+     * and source(s) that indicate where it comes from.
      *
-     * Radio must report all the valid emergency numbers with known mobile country code and
-     * emergency service categories from all available sources including network signaling, sim,
-     * modem/oem configuration, and default configuration (112 and 911 must be always available;
-     * additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not present).
-     * Radio shall not report emergency numbers that are invalid in the current locale. The
-     * reported emergency number list must not have duplicate @1.4::EmergencyNumber entries. Please
-     * refer the documentation of @1.4::EmergencyNumber to construct each emergency number to
-     * report.
+     * Radio must report all the valid emergency numbers with known mobile country code, mobile
+     * network code and emergency service categories from all available sources including network
+     * signaling, sim, modem/oem configuration, and default configuration (112 and 911 must be
+     * always available; additionally, 000, 08, 110, 999, 118 and 119 must be available when sim
+     * is not present). Radio shall not report emergency numbers that are invalid in the current
+     * locale. The reported emergency number list must not have duplicate @1.4::EmergencyNumber
+     * entries. Please refer the documentation of @1.4::EmergencyNumber to construct each
+     * emergency number to report.
      *
      * Radio must report the complete list of emergency numbers whenever the emergency numbers in
      * the list are changed or whenever the client and the radio server are connected.
diff --git a/radio/1.4/IRadioResponse.hal b/radio/1.4/IRadioResponse.hal
index df40969..a58a5c1 100644
--- a/radio/1.4/IRadioResponse.hal
+++ b/radio/1.4/IRadioResponse.hal
@@ -50,6 +50,23 @@
 
     /**
      * @param info Response info struct containing response type, serial no. and error
+     *
+     * Same API as @1.1::IRadioResponse.startNetworkScanResponse, except disallowing error codes
+     * OPERATION_NOT_ALLOWED and REQUEST_NOT_SUPPORTED.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:DEVICE_IN_USE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:MODEM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    oneway startNetworkScanResponse_1_4(RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
      * @param cellInfo List of current cell information known to radio
      *
      * Valid errors returned:
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index d0eb0ac..74613af 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -53,7 +53,7 @@
 
 /**
  * Emergency number contains information of number, one or more service category(s), mobile country
- * code (mcc), and source(s) that indicate where it comes from.
+ * code (mcc), mobile network country (mnc) and source(s) that indicate where it comes from.
  *
  * If the source of the emergency number is associated with country, field ‘mcc’ must be provided;
  * otherwise the field ‘mcc’ must be an empty string.
@@ -155,6 +155,25 @@
     DEFAULT = 1 << 3,
 };
 
+/**
+ * Indicates how the implementation should handle the emergency call if it is required by Android.
+ */
+enum EmergencyCallRouting : int32_t {
+    /**
+     * Indicates Android does not require how to handle the corresponding emergency call; it is
+     * decided by implementation.
+     */
+    UNKNOWN = 0,
+    /**
+     * Indicates the implementation must handle the call through emergency routing.
+     */
+    EMERGENCY = 1,
+    /**
+     * Indicates the implementation must handle the call through normal call routing.
+     */
+    NORMAL = 2,
+};
+
 enum RadioTechnology : @1.0::RadioTechnology {
     /** 5G NR. */
     NR = 20,
diff --git a/tv/cec/1.0/types.hal b/tv/cec/1.0/types.hal
index c734c4d..ebe65ae 100644
--- a/tv/cec/1.0/types.hal
+++ b/tv/cec/1.0/types.hal
@@ -114,6 +114,8 @@
     VENDOR_COMMAND_WITH_ID = 0xA0,
     CLEAR_EXTERNAL_TIMER = 0xA1,
     SET_EXTERNAL_TIMER = 0xA2,
+    REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
+    REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
     INITIATE_ARC = 0xC0,
     REPORT_ARC_INITIATED = 0xC1,
     REPORT_ARC_TERMINATED = 0xC2,
diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp
new file mode 100644
index 0000000..28370d6
--- /dev/null
+++ b/vibrator/1.3/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.vibrator@1.3",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "IVibrator.hal",
+    ],
+    interfaces: [
+        "android.hardware.vibrator@1.0",
+        "android.hardware.vibrator@1.1",
+        "android.hardware.vibrator@1.2",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
+
diff --git a/vibrator/1.3/IVibrator.hal b/vibrator/1.3/IVibrator.hal
new file mode 100644
index 0000000..01c2801
--- /dev/null
+++ b/vibrator/1.3/IVibrator.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.vibrator@1.3;
+
+import @1.0::Status;
+import @1.2::IVibrator;
+
+interface IVibrator extends @1.2::IVibrator {
+  /**
+   * Returns whether the vibrator supports control through an alternate interface.
+   */
+  supportsExternalControl() generates (bool supports);
+
+  /**
+   * Enables/disables control override of vibrator to audio.
+   *
+   * When this API is set, the vibrator control should be ceded to audio system
+   * for haptic audio. While this is enabled, issuing of other commands to control
+   * the vibrator is unsupported and the resulting behavior is undefined. Amplitude
+   * control may or may not be supported and is reflected in the return value of
+   * supportsAmplitudeControl() while this is enabled. When this is disabled, the
+   * vibrator should resume to an off state.
+   *
+   * @param enabled Whether external control should be enabled or disabled.
+   * @return status Whether the command was successful or not. Must return
+   *                Status::UNSUPPORTED_OPERATION if external control is
+   *                not supported by the device.
+   */
+  setExternalControl(bool enabled) generates (Status status);
+};
diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..5b4c893
--- /dev/null
+++ b/vibrator/1.3/vts/functional/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2018 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.
+//
+
+cc_test {
+    name: "VtsHalVibratorV1_3TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["VtsHalVibratorV1_3TargetTest.cpp"],
+    static_libs: [
+        "android.hardware.vibrator@1.0",
+        "android.hardware.vibrator@1.1",
+        "android.hardware.vibrator@1.2",
+        "android.hardware.vibrator@1.3",
+    ],
+    test_suites: ["general-tests"],
+}
+
diff --git a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
new file mode 100644
index 0000000..a67d1dc
--- /dev/null
+++ b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "vibrator_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/vibrator/1.0/types.h>
+#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <unistd.h>
+
+using ::android::sp;
+using ::android::hardware::vibrator::V1_0::Status;
+using ::android::hardware::vibrator::V1_3::IVibrator;
+
+// Test environment for Vibrator HIDL HAL.
+class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static VibratorHidlEnvironment* Instance() {
+        static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IVibrator>(); }
+
+   private:
+    VibratorHidlEnvironment() {}
+};
+
+// The main test class for VIBRATOR HIDL HAL 1.3.
+class VibratorHidlTest_1_3 : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
+            VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+        ASSERT_NE(vibrator, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IVibrator> vibrator;
+};
+
+TEST_F(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
+    if (vibrator->supportsExternalControl()) {
+        EXPECT_EQ(Status::OK, vibrator->setExternalControl(true));
+        sleep(1);
+        EXPECT_EQ(Status::OK, vibrator->setExternalControl(false));
+        sleep(1);
+    }
+}
+
+TEST_F(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
+    if (!vibrator->supportsExternalControl()) {
+        EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setExternalControl(true));
+    }
+}
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    VibratorHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}