Merge "Add new lazy service target to default camera HAL"
diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd
index 311b9c1..b0927b2 100644
--- a/audio/5.0/config/audio_policy_configuration.xsd
+++ b/audio/5.0/config/audio_policy_configuration.xsd
@@ -281,6 +281,19 @@
             <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="vendorExtension">
+        <!-- Vendor extension names must be prefixed by "VX_" to distinguish them from AOSP values.
+             Vendor are encouraged to namespace their module names to avoid conflicts.
+             Example for an hypothetical Google virtual reality device:
+                <devicePort tagName="VR" type="VX_GOOGLE_VR" role="sink">
+        -->
+        <xs:restriction base="xs:string">
+            <xs:pattern value="VX_[_a-zA-Z0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="extendableAudioDevice">
+        <xs:union memberTypes="audioDevice vendorExtension"/>
+    </xs:simpleType>
     <!-- Enum values of audio_format_t in audio.h
          TODO: generate from hidl to avoid manual sync. -->
     <xs:simpleType name="audioFormat">
@@ -353,6 +366,9 @@
             <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="extendableAudioFormat">
+        <xs:union memberTypes="audioFormat vendorExtension"/>
+    </xs:simpleType>
     <!-- Enum values of audio::common::4_0::AudioUsage
          TODO: generate from HIDL to avoid manual sync. -->
     <xs:simpleType name="audioUsage">
@@ -395,7 +411,7 @@
     </xs:simpleType>
     <xs:complexType name="profile">
         <xs:attribute name="name" type="xs:token" use="optional"/>
-        <xs:attribute name="format" type="audioFormat" use="optional"/>
+        <xs:attribute name="format" type="extendableAudioFormat" use="optional"/>
         <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
         <xs:attribute name="channelMasks" type="channelMask" use="optional"/>
     </xs:complexType>
@@ -432,7 +448,7 @@
                         <xs:element name="gains" type="gains" minOccurs="0"/>
                     </xs:sequence>
                     <xs:attribute name="tagName" type="xs:token" use="required"/>
-                    <xs:attribute name="type" type="audioDevice" use="required"/>
+                    <xs:attribute name="type" type="extendableAudioDevice" use="required"/>
                     <xs:attribute name="role" type="role" use="required"/>
                     <xs:attribute name="address" type="xs:string" use="optional" default=""/>
                     <!-- Note that XSD 1.0 can not check that a type only has one default. -->
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 45476ee..7824d23 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -40,7 +40,7 @@
      * scale is a 32 bit floating point with value greater then zero.
      */
     TENSOR_QUANT16_SYMM = 7,
-    /** A tensor of 16 bit floating point values. */
+    /** A tensor of IEEE 754 16 bit floating point values. */
     TENSOR_FLOAT16 = 8,
     /**
      * A tensor of 8 bit boolean values.
@@ -49,6 +49,8 @@
      * represents false; any other value represents true.
      */
     TENSOR_BOOL8 = 9,
+    /** An IEEE 754 16 bit floating point scalar value. */
+    FLOAT16 = 10,
     /* ADDING A NEW FUNDAMENTAL TYPE REQUIRES UPDATING THE VALUE OF
      * OperandTypeRange::OPERAND_FUNDAMENTAL_MAX.
      */
@@ -62,7 +64,7 @@
  */
 enum OperandTypeRange : uint32_t {
     OPERAND_FUNDAMENTAL_MIN = 0,
-    OPERAND_FUNDAMENTAL_MAX = 9,
+    OPERAND_FUNDAMENTAL_MAX = 10,
     OPERAND_OEM_MIN     = 10000,
     OPERAND_OEM_MAX     = 10001,
 };
@@ -109,7 +111,7 @@
     QUANTIZE = 70,
     QUANTIZED_16BIT_LSTM = 71,
     RANDOM_MULTINOMIAL = 72,
-    REDUCE = 73,
+    REDUCE_PROD = 73,
     ROI_ALIGN = 74,
     RSQRT = 75,
     SELECT = 76,
@@ -128,6 +130,11 @@
     ROI_POOLING = 89,
     EQUAL = 90,
     NOT_EQUAL = 91,
+    REDUCE_SUM = 92,
+    REDUCE_MAX = 93,
+    REDUCE_MIN = 94,
+    REDUCE_ANY = 95,
+    REDUCE_ALL = 96,
     /* ADDING A NEW FUNDAMENTAL OPERATION REQUIRES UPDATING THE VALUE OF
      * OperationTypeRange::OPERATION_FUNDAMENTAL_MAX.
      */
@@ -141,7 +148,7 @@
  */
 enum OperationTypeRange : uint32_t {
     OPERATION_FUNDAMENTAL_MIN = 0,
-    OPERATION_FUNDAMENTAL_MAX = 91,
+    OPERATION_FUNDAMENTAL_MAX = 96,
     OPERATION_OEM_MIN = 10000,
     OPERATION_OEM_MAX = 10000,
 };
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index 562ac33..ac23f41 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -152,6 +152,7 @@
 
 static uint32_t getInvalidRank(OperandType type) {
     switch (type) {
+        case OperandType::FLOAT16:
         case OperandType::FLOAT32:
         case OperandType::INT32:
         case OperandType::UINT32:
@@ -183,6 +184,7 @@
 
 static float getInvalidScale(OperandType type) {
     switch (type) {
+        case OperandType::FLOAT16:
         case OperandType::FLOAT32:
         case OperandType::INT32:
         case OperandType::UINT32:
@@ -215,6 +217,7 @@
 
 static std::vector<int32_t> getInvalidZeroPoints(OperandType type) {
     switch (type) {
+        case OperandType::FLOAT16:
         case OperandType::FLOAT32:
         case OperandType::INT32:
         case OperandType::UINT32:
@@ -258,6 +261,7 @@
     Operand newOperand = *operand;
     newOperand.type = type;
     switch (type) {
+        case OperandType::FLOAT16:
         case OperandType::FLOAT32:
         case OperandType::INT32:
         case OperandType::UINT32:
diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp
index 163a870..45e2e88 100644
--- a/wifi/1.3/Android.bp
+++ b/wifi/1.3/Android.bp
@@ -21,6 +21,7 @@
     types: [
       "StaLinkLayerRadioStats",
       "StaLinkLayerStats",
+      "WifiChannelStats",
     ],
     gen_java: true,
 }
diff --git a/wifi/1.3/default/hidl_struct_util.cpp b/wifi/1.3/default/hidl_struct_util.cpp
index b3d612f..a24d048 100644
--- a/wifi/1.3/default/hidl_struct_util.cpp
+++ b/wifi/1.3/default/hidl_struct_util.cpp
@@ -797,6 +797,55 @@
     return true;
 }
 
+bool convertLegacyLinkLayerRadioStatsToHidl(
+    const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
+    V1_3::StaLinkLayerRadioStats* hidl_radio_stat) {
+    if (!hidl_radio_stat) {
+        return false;
+    }
+    *hidl_radio_stat = {};
+
+    hidl_radio_stat->V1_0.onTimeInMs = legacy_radio_stat.stats.on_time;
+    hidl_radio_stat->V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time;
+    hidl_radio_stat->V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time;
+    hidl_radio_stat->V1_0.onTimeInMsForScan =
+        legacy_radio_stat.stats.on_time_scan;
+    hidl_radio_stat->V1_0.txTimeInMsPerLevel =
+        legacy_radio_stat.tx_time_per_levels;
+    hidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
+    hidl_radio_stat->onTimeInMsForBgScan =
+        legacy_radio_stat.stats.on_time_gscan;
+    hidl_radio_stat->onTimeInMsForRoamScan =
+        legacy_radio_stat.stats.on_time_roam_scan;
+    hidl_radio_stat->onTimeInMsForPnoScan =
+        legacy_radio_stat.stats.on_time_pno_scan;
+    hidl_radio_stat->onTimeInMsForHs20Scan =
+        legacy_radio_stat.stats.on_time_hs20;
+
+    std::vector<V1_3::WifiChannelStats> hidl_channel_stats;
+
+    for (const auto& channel_stat : legacy_radio_stat.channel_stats) {
+        V1_3::WifiChannelStats hidl_channel_stat;
+        hidl_channel_stat.onTimeInMs = channel_stat.on_time;
+        hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time;
+        /*
+         * TODO once b/119142899 is fixed,
+         * replace below code with convertLegacyWifiChannelInfoToHidl()
+         */
+        hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
+        hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
+        hidl_channel_stat.channel.centerFreq0 =
+            channel_stat.channel.center_freq0;
+        hidl_channel_stat.channel.centerFreq1 =
+            channel_stat.channel.center_freq1;
+        hidl_channel_stats.push_back(hidl_channel_stat);
+    }
+
+    hidl_radio_stat->channelStats = hidl_channel_stats;
+
+    return true;
+}
+
 bool convertLegacyLinkLayerStatsToHidl(
     const legacy_hal::LinkLayerStats& legacy_stats,
     V1_3::StaLinkLayerStats* hidl_stats) {
@@ -843,23 +892,10 @@
     std::vector<V1_3::StaLinkLayerRadioStats> hidl_radios_stats;
     for (const auto& legacy_radio_stats : legacy_stats.radios) {
         V1_3::StaLinkLayerRadioStats hidl_radio_stats;
-        hidl_radio_stats.V1_0.onTimeInMs = legacy_radio_stats.stats.on_time;
-        hidl_radio_stats.V1_0.txTimeInMs = legacy_radio_stats.stats.tx_time;
-        hidl_radio_stats.V1_0.rxTimeInMs = legacy_radio_stats.stats.rx_time;
-        hidl_radio_stats.V1_0.onTimeInMsForScan =
-            legacy_radio_stats.stats.on_time_scan;
-        hidl_radio_stats.V1_0.txTimeInMsPerLevel =
-            legacy_radio_stats.tx_time_per_levels;
-        hidl_radio_stats.onTimeInMsForNanScan =
-            legacy_radio_stats.stats.on_time_nbd;
-        hidl_radio_stats.onTimeInMsForBgScan =
-            legacy_radio_stats.stats.on_time_gscan;
-        hidl_radio_stats.onTimeInMsForRoamScan =
-            legacy_radio_stats.stats.on_time_roam_scan;
-        hidl_radio_stats.onTimeInMsForPnoScan =
-            legacy_radio_stats.stats.on_time_pno_scan;
-        hidl_radio_stats.onTimeInMsForHs20Scan =
-            legacy_radio_stats.stats.on_time_hs20;
+        if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats,
+                                                    &hidl_radio_stats)) {
+            return false;
+        }
         hidl_radios_stats.push_back(hidl_radio_stats);
     }
     hidl_stats->radios = hidl_radios_stats;
diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
index 7056759..790b7fa 100644
--- a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
@@ -37,6 +37,7 @@
 namespace V1_3 {
 namespace implementation {
 using namespace android::hardware::wifi::V1_0;
+using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz;
 
 class HidlStructUtilTest : public Test {};
 
@@ -166,6 +167,17 @@
         for (int i = 0; i < 4; i++) {
             radio.tx_time_per_levels.push_back(rand());
         }
+
+        legacy_hal::wifi_channel_stat channel_stat1 = {
+            .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+            .cca_busy_time = 0x55,
+            .on_time = 0x1111};
+        legacy_hal::wifi_channel_stat channel_stat2 = {
+            .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+            .cca_busy_time = 0x66,
+            .on_time = 0x2222};
+        radio.channel_stats.push_back(channel_stat1);
+        radio.channel_stats.push_back(channel_stat2);
     }
 
     V1_3::StaLinkLayerStats converted{};
@@ -236,6 +248,25 @@
                   converted.radios[i].onTimeInMsForPnoScan);
         EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
                   converted.radios[i].onTimeInMsForHs20Scan);
+        EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
+                  converted.radios[i].channelStats.size());
+        for (int k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
+            EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+                      converted.radios[i].channelStats[k].channel.width);
+            EXPECT_EQ(
+                legacy_stats.radios[i].channel_stats[k].channel.center_freq,
+                converted.radios[i].channelStats[k].channel.centerFreq);
+            EXPECT_EQ(
+                legacy_stats.radios[i].channel_stats[k].channel.center_freq0,
+                converted.radios[i].channelStats[k].channel.centerFreq0);
+            EXPECT_EQ(
+                legacy_stats.radios[i].channel_stats[k].channel.center_freq1,
+                converted.radios[i].channelStats[k].channel.centerFreq1);
+            EXPECT_EQ(legacy_stats.radios[i].channel_stats[k].cca_busy_time,
+                      converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+            EXPECT_EQ(legacy_stats.radios[i].channel_stats[k].on_time,
+                      converted.radios[i].channelStats[k].onTimeInMs);
+        }
     }
 }
 
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp
index 2cd7c2a..84a2c03 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/wifi_legacy_hal.cpp
@@ -652,6 +652,8 @@
         [&link_stats_ptr](wifi_request_id /* id */,
                           wifi_iface_stat* iface_stats_ptr, int num_radios,
                           wifi_radio_stat* radio_stats_ptr) {
+            wifi_radio_stat* l_radio_stats_ptr;
+
             if (iface_stats_ptr != nullptr) {
                 link_stats_ptr->iface = *iface_stats_ptr;
                 link_stats_ptr->iface.num_peers = 0;
@@ -662,20 +664,35 @@
                 LOG(ERROR) << "Invalid radio stats in link layer stats";
                 return;
             }
+            l_radio_stats_ptr = radio_stats_ptr;
             for (int i = 0; i < num_radios; i++) {
                 LinkLayerRadioStats radio;
-                radio.stats = radio_stats_ptr[i];
+
+                radio.stats = *l_radio_stats_ptr;
                 // Copy over the tx level array to the separate vector.
-                if (radio_stats_ptr[i].num_tx_levels > 0 &&
-                    radio_stats_ptr[i].tx_time_per_levels != nullptr) {
+                if (l_radio_stats_ptr->num_tx_levels > 0 &&
+                    l_radio_stats_ptr->tx_time_per_levels != nullptr) {
                     radio.tx_time_per_levels.assign(
-                        radio_stats_ptr[i].tx_time_per_levels,
-                        radio_stats_ptr[i].tx_time_per_levels +
-                            radio_stats_ptr[i].num_tx_levels);
+                        l_radio_stats_ptr->tx_time_per_levels,
+                        l_radio_stats_ptr->tx_time_per_levels +
+                            l_radio_stats_ptr->num_tx_levels);
                 }
                 radio.stats.num_tx_levels = 0;
                 radio.stats.tx_time_per_levels = nullptr;
+                /* Copy over the channel stat to separate vector */
+                if (l_radio_stats_ptr->num_channels > 0) {
+                    /* Copy the channel stats */
+                    radio.channel_stats.assign(
+                        l_radio_stats_ptr->channels,
+                        l_radio_stats_ptr->channels +
+                            l_radio_stats_ptr->num_channels);
+                }
                 link_stats_ptr->radios.push_back(radio);
+                l_radio_stats_ptr =
+                    (wifi_radio_stat*)((u8*)l_radio_stats_ptr +
+                                       sizeof(wifi_radio_stat) +
+                                       (sizeof(wifi_channel_stat) *
+                                        l_radio_stats_ptr->num_channels));
             }
         };
 
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h
index 2f513c4..d6f05ae 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.3/default/wifi_legacy_hal.h
@@ -61,6 +61,7 @@
 struct LinkLayerRadioStats {
     wifi_radio_stat stats;
     std::vector<uint32_t> tx_time_per_levels;
+    std::vector<wifi_channel_stat> channel_stats;
 };
 
 struct LinkLayerStats {
diff --git a/wifi/1.3/types.hal b/wifi/1.3/types.hal
index 4585ff3..3b292b0 100644
--- a/wifi/1.3/types.hal
+++ b/wifi/1.3/types.hal
@@ -19,6 +19,22 @@
 import @1.0::StaLinkLayerRadioStats;
 import @1.0::StaLinkLayerIfaceStats;
 import @1.0::TimeStampInMs;
+import @1.0::WifiChannelInfo;
+
+struct WifiChannelStats {
+    /**
+    * Channel information.
+    */
+    WifiChannelInfo channel;
+    /**
+     * Total time for which the radio is awake on this channel.
+     */
+    uint32_t onTimeInMs;
+    /**
+     * Total time for which CCA is held busy on this channel.
+     */
+    uint32_t ccaBusyTimeInMs;
+};
 
 struct StaLinkLayerRadioStats {
     /**
@@ -51,6 +67,11 @@
      * or crash.
      */
     uint32_t onTimeInMsForHs20Scan;
+
+    /**
+     * List of channel stats associated with this radio
+     */
+    vec<WifiChannelStats> channelStats;
 };
 
 /**