Merge "audio: Add support for dumping info from effect HAL modules"
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index ffe4506..8f8a888 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -643,8 +643,10 @@
             int32_t device;
         } alsa;             // used for USB_*
     } address;
-    string busAddress;      // used for BUS
-    string rSubmixAddress;  // used for REMOTE_SUBMIX
+    /** Arbitrary BUS device unique address. Should not be interpreted by the framework. */
+    string busAddress;
+    /** Arbitrary REMOTE_SUBMIX device unique address. Should not be interpreted by the HAL. */
+    string rSubmixAddress;
 };
 
 /**
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index a22cc1c..7f8b6a0 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -142,14 +142,13 @@
     android::DeviceVector availableOutputDevices;
     android::DeviceVector availableInputDevices;
     sp<android::DeviceDescriptor> defaultOutputDevice;
-    android::VolumeCurvesCollection volumes;
 };
 
 class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
    public:
     PolicyConfig()
         : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
-                            defaultOutputDevice, &volumes) {
+                            defaultOutputDevice) {
         for (const char* location : kConfigLocations) {
             std::string path = std::string(location) + '/' + kConfigFileName;
             if (access(path.c_str(), F_OK) == 0) {
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
new file mode 100644
index 0000000..fec2a3a
--- /dev/null
+++ b/automotive/evs/OWNERS
@@ -0,0 +1,3 @@
+changyeon@google.com
+haoxiangl@google.com
+swan@google.com
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index e874146..3efaaec 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -282,7 +282,6 @@
         | VehiclePropertyType:INT32
         | VehicleArea:SEAT),
 
-
     /**
      * Current odometer value of the vehicle
      *
@@ -1112,6 +1111,91 @@
         | VehiclePropertyType:INT32
         | VehicleArea:SEAT),
 
+   /**
+     * Distance units for display
+     *
+     * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
+     * Kilometer.
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported distance display units.
+     * For example: configArray[0] = 0x21 // METER
+     *              configArray[1] = 0x23 // KILOMETER
+     *              configArray[2] = 0x24 // MILE
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    DISTANCE_DISPLAY_UNITS = (
+        0x0600
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
+
+    /**
+     * Fuel volume units for display
+     *
+     * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
+     * Gallon.
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
+     * Volume units are defined in VehicleUnit.
+     * For example: configArray[0] = 0x41 // LITER
+     *              configArray[1] = 0x42 // GALLON
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    FUEL_VOLUME_DISPLAY_UNITS = (
+        0x0601
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
+
+    /**
+     * Tire pressure units for display
+     *
+     * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
+     * Kilopascal.
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
+     * Pressure units are defined in VehicleUnit.
+     * For example: configArray[0] = 0x70 // KILOPASCAL
+     *              configArray[1] = 0x71 // PSI
+     *              configArray[2] = 0x72 // BAR
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    TIRE_PRESSURE_DISPLAY_UNITS = (
+        0x0602
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
+
+    /**
+     * EV battery units for display
+     *
+     * Indicates which units the car is using to display EV battery information to the user. Eg.
+     * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
+     * Electrical energy units are defined in VehicleUnit.
+     * For example: configArray[0] = 0x60 // watt-hours
+     *              configArray[1] = 0x64 // ampere-hours
+     *              configArray[2] = 0x65 // kilowatt-hours
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    EV_BATTERY_DISPLAY_UNITS = (
+        0x0603
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
 
     /**
      * Outside temperature
@@ -1779,6 +1863,22 @@
         | VehicleArea:SEAT),
 
     /**
+     * Seat Occupancy
+     *
+     * Indicates whether a particular seat is occupied or not, to the best of the car's ability
+     * to determine. Valid values are from the VehicleSeatOccupancyState enum.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleSeatOccupancyState
+     */
+    SEAT_OCCUPANCY = (
+        0x0BB0
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:SEAT),
+
+    /**
      * Window Position
      *
      * Min = window up / closed
@@ -2113,6 +2213,83 @@
         | VehiclePropertyGroup:SYSTEM
         | VehiclePropertyType:INT32
         | VehicleArea:GLOBAL),
+
+    /**
+     * Cabin lights
+     *
+     * Return current status of cabin lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    CABIN_LIGHTS_STATE = (
+        0x0F01
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
+
+    /**
+     * Cabin lights switch
+     *
+     * The position of the physical switch which controls the cabin lights.
+     * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    CABIN_LIGHTS_SWITCH = (
+        0x0F02
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:GLOBAL),
+
+    /**
+     * Reading lights
+     *
+     * Return current status of reading lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    READING_LIGHTS_STATE = (
+        0x0F03
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:SEAT),
+
+    /**
+     * Reading lights switch
+     *
+     * The position of the physical switch which controls the reading lights.
+     * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    READING_LIGHTS_SWITCH = (
+        0x0F04
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:INT32
+        | VehicleArea:SEAT),
+
+};
+
+/**
+ * Used by seat occupancy to enumerate the current occupancy state of the seat.
+ */
+enum  VehicleSeatOccupancyState : int32_t {
+
+    UNKNOWN = 0,
+    VACANT = 1,
+    OCCUPIED = 2
 };
 
 /**
@@ -2404,10 +2581,13 @@
     MILLIMETER     = 0x20,
     METER          = 0x21,
     KILOMETER      = 0x23,
+    MILE           = 0x24,
     CELSIUS        = 0x30,
     FAHRENHEIT     = 0x31,
     KELVIN         = 0x32,
     MILLILITER     = 0x40,
+    LITER          = 0x41,
+    GALLON         = 0x42,
     NANO_SECS      = 0x50,
     SECS           = 0x53,
     YEAR           = 0x59,
@@ -2417,8 +2597,12 @@
     MILLIAMPERE    = 0x61,
     MILLIVOLT      = 0x62,
     MILLIWATTS     = 0x63,
+    AMPERE_HOURS   = 0x64,
+    KILOWATT_HOUR  = 0x65,
 
     KILOPASCAL     = 0x70,
+    PSI            = 0x71,
+    BAR            = 0x72,
     DEGREES        = 0x80,
 };
 
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 2f9fb6e..244d7a0 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -121,7 +121,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.cas</name>
-        <version>1.0-1</version>
+        <version>1.1</version>
         <interface>
             <name>IMediaCasService</name>
             <instance>default</instance>
diff --git a/current.txt b/current.txt
index be71351..ce8e05f 100644
--- a/current.txt
+++ b/current.txt
@@ -418,7 +418,7 @@
 9471b12b1c255bb530695720bc4174bd74987b75b1f820854af8944bc8c215c9 android.hardware.audio@5.0::IStreamOut
 1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
 83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
-edda213e520f387a3e367834b0772978b308a0f59b54479990aa9411aee9bcc4 android.hardware.audio.common@5.0::types
+894af04bebfe7da5b6791eefeb6eb3627da63d5efea735f16876d11d8ca4f61d android.hardware.audio.common@5.0::types
 f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
 fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
 e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
@@ -464,12 +464,12 @@
 7f460e795f5d1ed5e378935f98c6db4d39497de988aef1b4c2a4a07a6c400392 android.hardware.gnss@2.0::IAGnss
 2e5ad983734069e84a760004b32da0d09e4170c05380abe27e6eb80e4aa70d5a android.hardware.gnss@2.0::IAGnssCallback
 1f4ac068a88a72360280d94a7f6fd7c63813c1eea4891a0eb01394d3e7e775f2 android.hardware.gnss@2.0::IAGnssRil
-52e56490d35b4214d68c44f013e22bdf681fd6f8e5947c643dbb8453f9a03dcd android.hardware.gnss@2.0::IGnss
-0676e99eda39ff32f6891bcb56ea27df17007c439b9f900aa9a3919776920c23 android.hardware.gnss@2.0::IGnssCallback
+6e2f9a44375a0ae0b49ca7d711cb88945189d398535078408269e1e85889061d android.hardware.gnss@2.0::IGnss
+54d253b10c7da2a4a708d11acda3118b283df1540bc10323a5a3773c94cc8e71 android.hardware.gnss@2.0::IGnssCallback
 ecc966c68bddbd95c8dae782b84204cf01c75734675e8769963f3b5106ec128b android.hardware.gnss@2.0::IGnssConfiguration
 c67759f5d6387d273b66729180d03690e827f0b6b8d4e13ce2ff42d31b224065 android.hardware.gnss@2.0::IGnssMeasurement
-08615296d42451856f82c4953b45c4257d0a7b935fd98557c2ee2812c79fe0c3 android.hardware.gnss@2.0::IGnssMeasurementCallback
-141269652bcf30a7557edc4cd4311aa3e2ac67a252a7e8d3959b956d35793344 android.hardware.gnss@2.0::types
+089338944c45f66f25ba4ee958c161c42fefeb73ec60e4451f3535a1b3fd10c7 android.hardware.gnss@2.0::IGnssMeasurementCallback
+9e66234e65bcde75733d75d8b5d5cc094c2a5e14b074a25cd3f9ad141dc56f60 android.hardware.gnss@2.0::types
 50623a69a88b1c8a05738e4af7d5f78e905f415ccb0e84c99d0a71ea182e9393 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
 6ef12cd95df73f8f80c25eb035d98ca4594f9cee571fdabea838a0b6016dd908 android.hardware.gnss.measurement_corrections@1.0::types
 0d278956d7fc6fdf9ca9c42962ff2d73967bbb1c9f0b3e0b58d71b7095c286bc android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl
@@ -487,7 +487,7 @@
 dd1ec219f5d2e2b33c6c0bcb92e63bbedb36f7c716413462848f6b6ae74fc864 android.hardware.health.storage@1.0::IStorage
 2b4a14661e6a38617b7dd0c6ebb66a56a90e564674ac7697a14cb8a0cab92b2f android.hardware.health.storage@1.0::types
 30006fde4cb1f255f2530208728bff692100411b20af5b66fa31a9196d51f00b android.hardware.input.classifier@1.0::IInputClassifier
-97d8757bb05eb23d6a218bda374e095dfbb064c47714e2f859963c11f433e822 android.hardware.input.common@1.0::types
+0300c7667030da36c3de585f176ce18ff4b0d2615446d4930f331097378c06ef android.hardware.input.common@1.0::types
 24ae089981d58bc4cc74d75a6055bf357338ae6744ce1b467c5b4a9c470aba6d android.hardware.media.bufferpool@2.0::IAccessor
 897f45ee7db24ef227dea83ca3e4de72d53ff6bb7adc7983c90a650a1a6ff576 android.hardware.media.bufferpool@2.0::IClientManager
 aee53b2865b4f7939fb3df6fae758d9750c14f93dd454b479fc74aa7978fda4f android.hardware.media.bufferpool@2.0::IConnection
@@ -512,12 +512,12 @@
 cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
 abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
 4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
-69c394e7fe3236beb6231a709865e8a882aac7a612c8dddf64f5a66028fa2c68 android.hardware.power.stats@1.0::types
+2043037d5baaff604805757d06979aa861013a1e87430db745265339a8681f79 android.hardware.power.stats@1.0::types
 11620ce020b6ef8f5b63eb2a39390de4a2fbbccc0a5e558b5b1a0e22e33f63cf android.hardware.radio@1.3::IRadio
 e9d0f11a52715f5a29d89e2d8e2e21db1e16a43174af6b9d51a62d705cda1455 android.hardware.radio@1.3::IRadioIndication
 d233f0da44f55fdef0a95db5229231412787bb67695cd1ea197ce89a3c2908b9 android.hardware.radio@1.3::IRadioResponse
 750a363c8cec70baa1aac19e275c15233c5898e93c6bb5155fa2ca7f365490dc android.hardware.radio@1.3::types
-21e6ce53f1759f6a213ca05bac3c0325ed911f74764d1c1f6fa5ed8068ade65b android.hardware.radio@1.4::IRadio
+4ac73ec1e4cfa535209e5e22547f08beb20ef812b4a29d0824780f52cbe2324d android.hardware.radio@1.4::IRadio
 33d9e6895cca98aa56296bb01720d18b8acd0e4de4960beb712e63ad147438a5 android.hardware.radio@1.4::IRadioIndication
 0cc0dd87c634aad36d7df22b2832839ef7ded71909dbcde11cfdd69dc0dc52b8 android.hardware.radio@1.4::IRadioResponse
 29d34232cc3974626b08759e039fe788bded7695cdeb098458e3e11e4c7d3603 android.hardware.radio@1.4::types
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 9b04be0..230dd90 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -25,6 +25,9 @@
         "android.hidl.base@1.0",
     ],
     types: [
+        "ElapsedRealtime",
+        "ElapsedRealtimeFlags",
+        "GnssLocation",
     ],
     gen_java: true,
     gen_java_constants: true,
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index 1f1858e..2c149b7 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -20,6 +20,7 @@
 import android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl;
 import @1.1::IGnss;
 
+import GnssLocation;
 import IGnssCallback;
 import IGnssConfiguration;
 import IGnssMeasurement;
@@ -94,4 +95,16 @@
      * @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
      */
     getExtensionVisibilityControl() generates (IGnssVisibilityControl visibilityControlIface);
+
+    /**
+     * Injects current location from the best available location provider.
+     *
+     * Unlike injectLocation, this method may inject a recent GNSS location from the HAL
+     * implementation, if that is the best available location known to the framework.
+     *
+     * @param location Location information from the best available location provider.
+     *
+     * @return success Returns true if successful.
+     */
+    injectBestLocation_2_0(GnssLocation location) generates (bool success);
 };
\ No newline at end of file
diff --git a/gnss/2.0/IGnssCallback.hal b/gnss/2.0/IGnssCallback.hal
index 6baff91..e2ac02a 100644
--- a/gnss/2.0/IGnssCallback.hal
+++ b/gnss/2.0/IGnssCallback.hal
@@ -18,6 +18,7 @@
 
 import @1.0::IGnssCallback;
 import @1.1::IGnssCallback;
+import GnssLocation;
 
 /**
  * The interface is required for the HAL to communicate certain information
@@ -44,4 +45,11 @@
      */
     gnssSetCapabilitiesCb_2_0(bitfield<Capabilities> capabilities);
 
+   /**
+     * Called when a GNSS location is available.
+     *
+     * @param location Location information from HAL.
+     */
+    gnssLocationCb_2_0(GnssLocation location);
+
 };
\ No newline at end of file
diff --git a/gnss/2.0/IGnssMeasurementCallback.hal b/gnss/2.0/IGnssMeasurementCallback.hal
index fc44465..d5dc038 100644
--- a/gnss/2.0/IGnssMeasurementCallback.hal
+++ b/gnss/2.0/IGnssMeasurementCallback.hal
@@ -18,6 +18,7 @@
 
 import @1.0::IGnssMeasurementCallback;
 import @1.1::IGnssMeasurementCallback;
+import ElapsedRealtime;
 
 /** The callback interface to report measurements from the HAL. */
 interface IGnssMeasurementCallback extends @1.1::IGnssMeasurementCallback {
@@ -492,6 +493,12 @@
 
         /** The GNSS clock time reading. */
         GnssClock clock;
+
+        /**
+         * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos()
+         * clock.
+         */
+        ElapsedRealtime elapsedRealtime;
     };
 
     /**
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 1efc9f5..599681b 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -17,7 +17,10 @@
 #define LOG_TAG "Gnss"
 
 #include "Gnss.h"
+
 #include <log/log.h>
+#include <utils/SystemClock.h>
+
 #include "AGnss.h"
 #include "AGnssRil.h"
 #include "GnssConfiguration.h"
@@ -40,6 +43,24 @@
 sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
 sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
 
+namespace {
+
+V2_0::GnssLocation getMockLocationV2_0() {
+    const ElapsedRealtime timestamp = {
+            .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+                     ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1000000};
+
+    V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
+    return location;
+}
+
+}  // namespace
+
 Gnss::Gnss() : mMinIntervalMs(1000) {}
 
 Gnss::~Gnss() {
@@ -48,7 +69,7 @@
 
 // Methods from V1_0::IGnss follow.
 Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return bool{};
 }
 
@@ -61,7 +82,7 @@
     mIsActive = true;
     mThread = std::thread([this]() {
         while (mIsActive == true) {
-            const auto location = Utils::getMockLocation();
+            const auto location = getMockLocationV2_0();
             this->reportLocation(location);
 
             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
@@ -79,44 +100,44 @@
 }
 
 Return<void> Gnss::cleanup() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return Void();
 }
 
 Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return bool{};
 }
 
 Return<bool> Gnss::injectLocation(double, double, float) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return bool{};
 }
 
 Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return Void();
 }
 
 Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
                                    V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
                                    uint32_t) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return bool{};
 }
 
 Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IAGnssRil>{};
 }
 
 Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssGeofencing>{};
 }
 
 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IAGnss>{};
 }
 
@@ -131,27 +152,27 @@
 }
 
 Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssNavigationMessage>{};
 }
 
 Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssXtra>{};
 }
 
 Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssConfiguration>{};
 }
 
 Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssDebug>{};
 }
 
 Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_0::IGnssBatching>{};
 }
 
@@ -194,7 +215,7 @@
 }
 
 Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<V1_1::IGnssConfiguration>{};
 }
 
@@ -204,7 +225,7 @@
 }
 
 Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return bool{};
 }
 
@@ -228,7 +249,7 @@
 
 Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
 Gnss::getExtensionMeasurementCorrections() {
-    // TODO implement
+    // TODO(b/124012850): Implement function.
     return sp<measurement_corrections::V1_0::IMeasurementCorrections>{};
 }
 
@@ -268,16 +289,21 @@
     return true;
 }
 
-Return<void> Gnss::reportLocation(const GnssLocation& location) const {
+Return<void> Gnss::reportLocation(const V2_0::GnssLocation& location) const {
     std::unique_lock<std::mutex> lock(mMutex);
-    if (sGnssCallback_1_1 == nullptr) {
-        ALOGE("%s: sGnssCallback is null.", __func__);
+    if (sGnssCallback_2_0 == nullptr) {
+        ALOGE("%s: sGnssCallback 2.0 is null.", __func__);
         return Void();
     }
-    sGnssCallback_1_1->gnssLocationCb(location);
+    sGnssCallback_2_0->gnssLocationCb_2_0(location);
     return Void();
 }
 
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
+    // TODO(b/124012850): Implement function.
+    return bool{};
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace gnss
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index 7d9e783..f02ab0a 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -91,15 +91,16 @@
     getExtensionMeasurementCorrections() override;
     Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
             override;
+    Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
 
-   private:
-     Return<void> reportLocation(const GnssLocation&) const;
-     static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
-     static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
-     std::atomic<long> mMinIntervalMs;
-     std::atomic<bool> mIsActive;
-     std::thread mThread;
-     mutable std::mutex mMutex;
+  private:
+    Return<void> reportLocation(const V2_0::GnssLocation&) const;
+    static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
+    static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
+    std::atomic<long> mMinIntervalMs;
+    std::atomic<bool> mIsActive;
+    std::thread mThread;
+    mutable std::mutex mMutex;
 };
 
 }  // namespace implementation
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 0f707b4..702c9e2 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -16,7 +16,9 @@
 #define LOG_TAG "GnssMeasurement"
 
 #include "GnssMeasurement.h"
+
 #include <log/log.h>
+#include <utils/SystemClock.h>
 
 namespace android {
 namespace hardware {
@@ -129,7 +131,18 @@
                                                        .driftNsps = -51.757811607455452,
                                                        .driftUncertaintyNsps = 310.64968328491528,
                                                        .hwClockDiscontinuityCount = 1};
-    GnssData gnssData = {.measurements = measurements, .clock = clock};
+
+    ElapsedRealtime timestamp = {
+            .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+                     ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1000000};
+
+    GnssData gnssData = {
+            .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
     return gnssData;
 }
 
diff --git a/gnss/2.0/types.hal b/gnss/2.0/types.hal
index 97c178f..4abb604 100644
--- a/gnss/2.0/types.hal
+++ b/gnss/2.0/types.hal
@@ -16,5 +16,60 @@
 
 package android.hardware.gnss@2.0;
 
+import @1.0::GnssLocation;
+
 /** Network handle type. */
 typedef uint64_t net_handle_t;
+
+/**
+ * Flags indicating the validity of the fields in ElapsedRealtime.
+ */
+@export(name="", value_prefix="ELAPSED_REALTIME_")
+enum ElapsedRealtimeFlags : uint16_t {
+    /** A valid timestampNs is stored in the data structure. */
+    HAS_TIMESTAMP_NS        = 1 << 0,
+    /** A valid timeUncertaintyNs is stored in the data structure. */
+    HAS_TIME_UNCERTAINTY_NS = 1 << 1,
+};
+
+/**
+ * Represents an estimate of elapsed time since boot of Android for a given event.
+ *
+ * This timestamp MUST represent the time the event happened and MUST be synchronized
+ * with the SystemClock.elapsedRealtimeNanos() clock.
+ */
+struct ElapsedRealtime {
+    /**
+     * A set of flags indicating the validity of each field in this data structure.
+     *
+     * Fields may have invalid information in them, if not marked as valid by the
+     * corresponding bit in flags.
+     */
+    bitfield<ElapsedRealtimeFlags> flags;
+
+    /**
+     * Estimate of the elapsed time since boot value for the corresponding event in nanoseconds.
+     */
+    uint64_t timestampNs;
+
+    /**
+     * Estimate of the relative precision of the alignment of this SystemClock
+     * timestamp, with the reported measurements in nanoseconds (68% confidence).
+     */
+    uint64_t timeUncertaintyNs;
+};
+
+/** Represents a location. */
+struct GnssLocation {
+    @1.0::GnssLocation v1_0;
+
+    /**
+     * Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
+     * clock.
+     *
+     * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
+     * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
+     * needs to be estimatedd by syncing the notion of time via PTP or some other mechanism. 
+     */
+    ElapsedRealtime elapsedRealtime;
+};
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index 1580c28..c564f41 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -130,10 +130,10 @@
     return false;
 }
 
-void GnssHalTest::CheckLocation(const GnssLocation& location, bool check_speed) {
+void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) {
     const bool check_more_accuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
 
-    Utils::checkLocation(location, check_speed, check_more_accuracies);
+    Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies);
 }
 
 void GnssHalTest::StartAndCheckLocations(int count) {
@@ -193,6 +193,14 @@
     return Void();
 }
 
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
+    ALOGI("Capabilities (v2.0) received %d", capabilities);
+    parent_.capabilities_called_count_++;
+    parent_.last_capabilities_ = capabilities;
+    parent_.notify();
+    return Void();
+}
+
 Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
     ALOGI("Name received: %s", name.c_str());
     parent_.name_called_count_++;
@@ -201,8 +209,19 @@
     return Void();
 }
 
-Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation& location) {
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) {
     ALOGI("Location received");
+    GnssLocation_2_0 location_v2_0;
+    location_v2_0.v1_0 = location;
+    return gnssLocationCbImpl(location_v2_0);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) {
+    ALOGI("Location (v2.0) received");
+    return gnssLocationCbImpl(location);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) {
     parent_.location_called_count_++;
     parent_.last_location_ = location;
     parent_.notify();
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 2c16651..7793eb7 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -18,7 +18,6 @@
 #define GNSS_HAL_TEST_H_
 
 #include <android/hardware/gnss/2.0/IGnss.h>
-
 #include <VtsHalHidlTargetTestBase.h>
 #include <VtsHalHidlTargetTestEnvBase.h>
 
@@ -29,11 +28,13 @@
 using android::hardware::Return;
 using android::hardware::Void;
 
-using android::hardware::gnss::V1_0::GnssLocation;
-
 using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V1_1::IGnssCallback;
 using android::hardware::gnss::V2_0::IGnss;
+using android::hardware::gnss::V2_0::IGnssCallback;
+
+using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
 using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
 using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
 using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
@@ -97,10 +98,15 @@
         Return<void> gnssRequestTimeCb() override { return Void(); }
         // Actual (test) callback handlers
         Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
-        Return<void> gnssLocationCb(const GnssLocation& location) override;
+        Return<void> gnssLocationCb(const GnssLocation_1_0& location) override;
+        Return<void> gnssLocationCb_2_0(const GnssLocation_2_0& location) override;
         Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+        Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
         Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
         Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
+
+      private:
+        Return<void> gnssLocationCbImpl(const GnssLocation_2_0& location);
     };
 
     /* Callback class for GnssMeasurement. */
@@ -147,7 +153,7 @@
      *
      *   check_speed: true if speed related fields are also verified.
      */
-    void CheckLocation(const GnssLocation& location, const bool check_speed);
+    void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
 
     /*
      * StartAndCheckLocations:
@@ -186,7 +192,7 @@
 
     IGnssCallback::GnssSystemInfo last_info_;
     uint32_t last_capabilities_;
-    GnssLocation last_location_;
+    GnssLocation_2_0 last_location_;
     IGnssMeasurementCallback_2_0::GnssData last_measurement_;
     android::hardware::hidl_string last_name_;
 
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 48f2be8..b135dba 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -31,7 +31,9 @@
 using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
 using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
 using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
+
 using android::hardware::gnss::V1_0::IGnssNi;
+using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
 
 /*
@@ -269,3 +271,64 @@
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
 }
+
+/*
+ * TestGnssDataElapsedRealtimeFlags:
+ * Sets a GnssMeasurementCallback, waits for a GnssData object, and verifies the flags in member
+ * elapsedRealitme are valid.
+ */
+TEST_F(GnssHalTest, TestGnssDataElapsedRealtimeFlags) {
+    const int kFirstGnssMeasurementTimeoutSeconds = 10;
+
+    auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0();
+    if (!gnssMeasurement.isOk()) {
+        return;
+    }
+
+    sp<IGnssMeasurement_2_0> iGnssMeasurement = gnssMeasurement;
+    if (iGnssMeasurement == nullptr) {
+        return;
+    }
+
+    sp<IGnssMeasurementCallback_2_0> callback = new GnssMeasurementCallback(*this);
+
+    auto result = iGnssMeasurement->setCallback_2_0(callback, /* enableFullTracking= */ true);
+    ASSERT_TRUE(result.isOk());
+    EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
+
+    wait(kFirstGnssMeasurementTimeoutSeconds);
+    EXPECT_EQ(measurement_called_count_, 1);
+
+    ASSERT_TRUE((int)last_measurement_.elapsedRealtime.flags >= 0 &&
+                (int)last_measurement_.elapsedRealtime.flags <=
+                        (int)ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS);
+
+    // We expect a non-zero timestamp when set.
+    if (last_measurement_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        ASSERT_TRUE(last_measurement_.elapsedRealtime.timestampNs != 0);
+    }
+
+    iGnssMeasurement->close();
+}
+
+TEST_F(GnssHalTest, TestGnssLocationElapsedRealtime) {
+    StartAndCheckFirstLocation();
+
+    ASSERT_TRUE((int)last_location_.elapsedRealtime.flags >= 0 &&
+                (int)last_location_.elapsedRealtime.flags <=
+                        (int)ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS);
+
+    // We expect a non-zero timestamp when set.
+    if (last_location_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        ASSERT_TRUE(last_location_.elapsedRealtime.timestampNs != 0);
+    }
+
+    StopAndClearLocations();
+}
+
+// This test only verify that injectBestLocation_2_0 does not crash.
+TEST_F(GnssHalTest, TestInjectBestLocation_2_0) {
+    StartAndCheckFirstLocation();
+    gnss_hal_->injectBestLocation_2_0(last_location_);
+    StopAndClearLocations();
+}
diff --git a/input/common/1.0/types.hal b/input/common/1.0/types.hal
index 1a07f3b..9ad368b 100644
--- a/input/common/1.0/types.hal
+++ b/input/common/1.0/types.hal
@@ -685,20 +685,20 @@
  * 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.
+ * The heatmap data is rotated 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:
+ * then it can be represented as a 10 x 6 matrix:
  *
- *  <--    width   -- >
+ *  <--   width   -->
  *   0  1  2  3  4  5   ^
  *   6  7  8  9 10 11   |
- *  12 12 14 15 16 17   |
- *  18    ...      23   | height
- *  24    ...      29   |
+ *  12 13 14 15 16 17   |
+ *  18    ...      23   |
+ *  24    ...      29   | height
  *  30    ...      35   |
  *  36    ...      41   |
  *  42    ...      47   |
@@ -708,16 +708,33 @@
  * 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.
+ * Here height=10 and width=6.
+ *
+ * If the screen orientation changes to landscape (a 90 degree orientation
+ * change), the frame's dimensions will become 6 x 10
+ * and the data will look as follows:
+ * 54 48 42 36 30 24 18 12  6  0     ^
+ * ...                  13  7  1     |
+ * ...                  14  8  2     | height
+ * ...                  15  9  3     |
+ * ...                  16 10  4     |
+ * 59 53 47 41 35 29 23 17 11  5     v
+ * <--        width          -->
+ *
+ * Here the element "0" is at the physical top left of the unrotated screen.
+ *
+ * Since the coordinates of a MotionEvent are also adjusted based on the
+ * orientation, the rotation of the video frame data ensures that
+ * the axes for MotionEvent and VideoFrame data are consistent.
  */
 struct VideoFrame {
     /**
      * Video frame data.
-     * Size of the data is width * height.
+     * Size of the data is height * width.
      */
     vec<int16_t> data;
-    uint32_t width;
     uint32_t height;
+    uint32_t width;
     /**
      * Time at which the frame was collected, in nanoseconds.
      * Measured with the same clock that is used to populate MotionEvent times.
diff --git a/power/stats/1.0/types.hal b/power/stats/1.0/types.hal
index 644224b..6051e3f 100644
--- a/power/stats/1.0/types.hal
+++ b/power/stats/1.0/types.hal
@@ -26,9 +26,9 @@
 struct RailInfo {
     /** Index corresponding to the rail */
     uint32_t index;
-    /** Name of the rail */
+    /** Name of the rail (opaque to the framework) */
     string railName;
-    /** Name of the subsystem to which this rail belongs */
+    /** Name of the subsystem to which this rail belongs (opaque to the framework) */
     string subsysName;
     /** Hardware sampling rate */
     uint32_t samplingRate;
@@ -71,7 +71,7 @@
 struct PowerEntityInfo {
     /** Unique ID corresponding to the PowerEntity */
     uint32_t powerEntityId;
-    /** Name of the PowerEntity */
+    /** Name of the PowerEntity (opaque to the framework) */
     string powerEntityName;
     /** Type of the PowerEntity */
     PowerEntityType type;
@@ -82,7 +82,7 @@
      * ID corresponding to the state. Unique for a given PowerEntityStateSpace
      */
     uint32_t powerEntityStateId;
-    /** Name of the state */
+    /** Name of the state (opaque to the framework) */
     string powerEntityStateName;
 };
 
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index f7ae39f..046f074 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -115,11 +115,13 @@
      * PUK/PIN state of the subscription and the service state of the radio.
      *
      * 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.
+     * call routing if possible or emergency routing. 1) if the 'routing' field is specified as
+     * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to
+     * use normal call routing to handle the call; if service cannot support normal routing, the
+     * implementation must use emergency routing to handle the call. 2) if 'routing' is specified
+     * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to
+     * handle the call. 3) if 'routing' is specified as @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; if the dialed
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 f9404d2..c395df6 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -96,6 +96,370 @@
 }
 
 /*
+ * Test IRadio.startNetworkScan() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT, .interval = 60, .specifiers = {specifier}};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
+
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::SIM_ABSENT}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do not support the
+        // required manual GSM search functionality. This is tracked in b/112206766.
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid specifier.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
+    serial = GetRandomSerialNumber();
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
+                                                                    .interval = 60};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 4,
+            .specifiers = {specifier},
+            .maxSearchTime = 60,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 1};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 301,
+            .specifiers = {specifier},
+            .maxSearchTime = 60,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 1};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            .maxSearchTime = 59,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 1};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            .maxSearchTime = 3601,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 1};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            .maxSearchTime = 600,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 0};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            .maxSearchTime = 600,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 11};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            // Some vendor may not support max search time of 360s.
+            // This issue is tracked in b/112205669.
+            .maxSearchTime = 300,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 10};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity and plmns
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
+    serial = GetRandomSerialNumber();
+
+    RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+                                      .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+                                      .channels = {1, 2}};
+
+    ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+            .type = ScanType::ONE_SHOT,
+            .interval = 60,
+            .specifiers = {specifier},
+            // Some vendor may not support max search time of 360s.
+            // This issue is tracked in b/112205669.
+            .maxSearchTime = 300,
+            .incrementalResults = false,
+            .incrementalResultsPeriodicity = 10,
+            .mccMncs = {"310410"}};
+
+    Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+}
+
+/*
+ * Test IRadio.getSignalStrength_1_4() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, getSignalStrength_1_4) {
+    serial = GetRandomSerialNumber();
+
+    radio_v1_4->getSignalStrength_1_4(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+    }
+}
+
+/*
  * Test IRadio.setupDataCall_1_4() for the response returned.
  */
 TEST_F(RadioHidlTest_v1_4, setupDataCall_1_4) {