Merge "Require IRadio 1.4 for Devices Launching Q"
diff --git a/graphics/allocator/2.0/default/OWNERS b/graphics/allocator/2.0/default/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/allocator/2.0/default/OWNERS
+++ b/graphics/allocator/2.0/default/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/allocator/2.0/utils/OWNERS
+++ b/graphics/allocator/2.0/utils/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS
index 4714be2..db8fb80 100644
--- a/graphics/composer/2.1/default/OWNERS
+++ b/graphics/composer/2.1/default/OWNERS
@@ -1,5 +1,6 @@
 # Graphics team
 courtneygo@google.com
 jessehall@google.com
-olv@google.com
+lpy@google.com
 stoza@google.com
+vhau@google.com
diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS
index d515a23..5acc631 100644
--- a/graphics/composer/2.1/utils/OWNERS
+++ b/graphics/composer/2.1/utils/OWNERS
@@ -1,4 +1,5 @@
 courtneygo@google.com
 jessehall@google.com
-olv@google.com
+lpy@google.com
 stoza@google.com
+vhau@google.com
diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS
index ef69d7c..0b42d2e 100644
--- a/graphics/composer/2.1/vts/OWNERS
+++ b/graphics/composer/2.1/vts/OWNERS
@@ -1,6 +1,7 @@
 # Graphics team
-olv@google.com
+lpy@google.com
+vhau@google.com
 
 # VTS team
 yim@google.com
-zhuoyao@google.com
\ No newline at end of file
+zhuoyao@google.com
diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS
index 4714be2..db8fb80 100644
--- a/graphics/composer/2.2/default/OWNERS
+++ b/graphics/composer/2.2/default/OWNERS
@@ -1,5 +1,6 @@
 # Graphics team
 courtneygo@google.com
 jessehall@google.com
-olv@google.com
+lpy@google.com
 stoza@google.com
+vhau@google.com
diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS
index 1beb074..a17a50c 100644
--- a/graphics/composer/2.2/utils/OWNERS
+++ b/graphics/composer/2.2/utils/OWNERS
@@ -1,7 +1,8 @@
 # Graphics team
 courtneygo@google.com
-olv@google.com
+lpy@google.com
 stoza@google.com
+vhau@google.com
 
 # VTS team
 yim@google.com
diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS
index 1beb074..a17a50c 100644
--- a/graphics/composer/2.2/vts/functional/OWNERS
+++ b/graphics/composer/2.2/vts/functional/OWNERS
@@ -1,7 +1,8 @@
 # Graphics team
 courtneygo@google.com
-olv@google.com
+lpy@google.com
 stoza@google.com
+vhau@google.com
 
 # VTS team
 yim@google.com
diff --git a/graphics/mapper/2.0/default/OWNERS b/graphics/mapper/2.0/default/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/mapper/2.0/default/OWNERS
+++ b/graphics/mapper/2.0/default/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/mapper/2.0/utils/OWNERS
+++ b/graphics/mapper/2.0/utils/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/mapper/2.0/vts/OWNERS b/graphics/mapper/2.0/vts/OWNERS
index ef69d7c..8e86f64 100644
--- a/graphics/mapper/2.0/vts/OWNERS
+++ b/graphics/mapper/2.0/vts/OWNERS
@@ -1,6 +1,6 @@
 # Graphics team
-olv@google.com
+marissaw@google.com
 
 # VTS team
 yim@google.com
-zhuoyao@google.com
\ No newline at end of file
+zhuoyao@google.com
diff --git a/graphics/mapper/2.1/default/OWNERS b/graphics/mapper/2.1/default/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/mapper/2.1/default/OWNERS
+++ b/graphics/mapper/2.1/default/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/mapper/2.1/utils/OWNERS b/graphics/mapper/2.1/utils/OWNERS
index 3aa5fa1..273cb4c 100644
--- a/graphics/mapper/2.1/utils/OWNERS
+++ b/graphics/mapper/2.1/utils/OWNERS
@@ -1,4 +1,4 @@
 # Graphics team
 jessehall@google.com
-olv@google.com
+marissaw@google.com
 stoza@google.com
diff --git a/graphics/mapper/2.1/vts/OWNERS b/graphics/mapper/2.1/vts/OWNERS
index ef69d7c..8e86f64 100644
--- a/graphics/mapper/2.1/vts/OWNERS
+++ b/graphics/mapper/2.1/vts/OWNERS
@@ -1,6 +1,6 @@
 # Graphics team
-olv@google.com
+marissaw@google.com
 
 # VTS team
 yim@google.com
-zhuoyao@google.com
\ No newline at end of file
+zhuoyao@google.com
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 7c5b0bc..3b4eb21 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -72,7 +72,8 @@
     copy_back_<int16_t>(dst, ra, src);
     copy_back_<_Float16>(dst, ra, src);
     copy_back_<bool8>(dst, ra, src);
-    static_assert(6 == std::tuple_size<MixedTyped>::value,
+    copy_back_<int8_t>(dst, ra, src);
+    static_assert(7 == std::tuple_size<MixedTyped>::value,
                   "Number of types in MixedTyped changed, but copy_back function wasn't updated");
 }
 
diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp
index 528a2c7..7d13104 100644
--- a/neuralnetworks/1.2/Android.bp
+++ b/neuralnetworks/1.2/Android.bp
@@ -17,6 +17,7 @@
         "android.hardware.neuralnetworks@1.0",
         "android.hardware.neuralnetworks@1.1",
         "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
     ],
     types: [
         "Model",
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 7824d23..40c07e7 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -22,6 +22,8 @@
 import @1.0::PerformanceInfo;
 import @1.1::OperationType;
 
+import android.hidl.safe_union@1.0::Monostate;
+
 enum OperandType : @1.0::OperandType {
     /**
      * An 8 bit boolean scalar value.
@@ -51,6 +53,29 @@
     TENSOR_BOOL8 = 9,
     /** An IEEE 754 16 bit floating point scalar value. */
     FLOAT16 = 10,
+    /**
+     * A tensor of 8 bit signed integers that represent real numbers.
+     *
+     * This tensor is associated with additional fields that are
+     * used to convert the 8 bit signed integer to the real value and vice versa.
+     * These fields are:
+     * - channelDim: a 32 bit unsigned integer indicating channel dimension.
+     * - scales: an array of positive 32 bit floating point values.
+     * The size of the scales array must be equal to dimensions[channelDim].
+     * These fields are located inside Operand's extraParams union, inside the
+     * SymmPerChannelQuantParams struct.
+     *
+     * An Operand of this type must use 'channelQuant' field of its extraParams
+     * union.
+     *
+     * The channel dimension of this tensor must not be unknown (dimensions[channelDim] != 0).
+     *
+     * The formula for real values:
+     * realValue[..., C, ...] =
+     *     integerValue[..., C, ...] * scales[C]
+     * where C is an index in the Channel dimension.
+     */
+    TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
     /* ADDING A NEW FUNDAMENTAL TYPE REQUIRES UPDATING THE VALUE OF
      * OperandTypeRange::OPERAND_FUNDAMENTAL_MAX.
      */
@@ -64,7 +89,7 @@
  */
 enum OperandTypeRange : uint32_t {
     OPERAND_FUNDAMENTAL_MIN = 0,
-    OPERAND_FUNDAMENTAL_MAX = 10,
+    OPERAND_FUNDAMENTAL_MAX = 11,
     OPERAND_OEM_MIN     = 10000,
     OPERAND_OEM_MAX     = 10001,
 };
@@ -135,6 +160,7 @@
     REDUCE_MIN = 94,
     REDUCE_ANY = 95,
     REDUCE_ALL = 96,
+    INSTANCE_NORMALIZATION = 97,
     /* ADDING A NEW FUNDAMENTAL OPERATION REQUIRES UPDATING THE VALUE OF
      * OperationTypeRange::OPERATION_FUNDAMENTAL_MAX.
      */
@@ -148,7 +174,7 @@
  */
 enum OperationTypeRange : uint32_t {
     OPERATION_FUNDAMENTAL_MIN = 0,
-    OPERATION_FUNDAMENTAL_MAX = 96,
+    OPERATION_FUNDAMENTAL_MAX = 97,
     OPERATION_OEM_MIN = 10000,
     OPERATION_OEM_MAX = 10000,
 };
@@ -176,6 +202,25 @@
 };
 
 /**
+ * Parameters for TENSOR_QUANT8_SYMM_PER_CHANNEL operand.
+ */
+struct SymmPerChannelQuantParams {
+    /** Array of scaling values for each channel. Each value must be greater than zero. */
+    vec<float> scales;
+    /** Index of the channel dimension */
+    uint32_t channelDim;
+};
+
+// TODO(slavash): Operand Extension support
+// /**
+//  * Parameters for an unknown (as of 1.2) operand extension. This is
+//  * a vendor-specific extension or a platform extension (backport of
+//  * functionality from newer NNAPI interface).
+//  */
+// struct OperandParamsUnknown {
+// };
+
+/**
  * Describes one operand of the model's graph.
  */
 struct Operand {
@@ -268,6 +313,28 @@
      * - location.length is set.
      */
     DataLocation location;
+
+    /**
+     * Union of extra parameters, used by some types of Operands that need additional
+     * information for the complete definition of an Operand.
+     */
+    safe_union ExtraParams {
+       /**
+        * Placeholder for operand with no extra parameters.
+        */
+       Monostate none;
+
+       /**
+        * Used with TENSOR_QUANT8_SYMM_PER_CHANNEL operand type.
+        */
+       SymmPerChannelQuantParams channelQuant;
+
+       // TODO(slavash): Operand Extension support
+       // /**
+       //  * Used with Extension operand type.
+       //  */
+       // OperandParamsUnknown unknown;
+    } extraParams;
 };
 
 /**
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index 8f6d54f..9621009 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -162,6 +162,7 @@
         case OperandType::TENSOR_INT32:
         case OperandType::TENSOR_QUANT8_ASYMM:
         case OperandType::TENSOR_QUANT16_SYMM:
+        case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
             return 0;
         default:
             return 0;
@@ -190,6 +191,7 @@
         case OperandType::BOOL:
         case OperandType::TENSOR_FLOAT16:
         case OperandType::TENSOR_FLOAT32:
+        case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
             return 1.0f;
         case OperandType::TENSOR_INT32:
             return -1.0f;
@@ -224,6 +226,7 @@
         case OperandType::TENSOR_FLOAT16:
         case OperandType::TENSOR_FLOAT32:
         case OperandType::TENSOR_INT32:
+        case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
             return {1};
         case OperandType::TENSOR_QUANT8_ASYMM:
             return {-1, 256};
@@ -287,6 +290,21 @@
                 operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
             newOperand.scale = operand->scale != 0.0f ? operand->scale : 1.0f;
             break;
+        case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: {
+            newOperand.dimensions =
+                operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
+            newOperand.scale = 0.0f;
+            newOperand.zeroPoint = 0;
+
+            SymmPerChannelQuantParams channelQuant;
+            channelQuant.channelDim = 0;
+            channelQuant.scales = hidl_vec<float>(
+                operand->dimensions.size() > 0 ? static_cast<size_t>(operand->dimensions[0]) : 0);
+            for (size_t i = 0; i < channelQuant.scales.size(); ++i) {
+                channelQuant.scales[i] = 1.0f;
+            }
+            newOperand.extraParams.channelQuant(std::move(channelQuant));
+        } break;
         case OperandType::OEM:
         case OperandType::TENSOR_OEM_BYTE:
         default:
@@ -307,6 +325,8 @@
         // - ARGMIN and ARGMAX's first argument can be any of
         // TENSOR_(FLOAT16|FLOAT32|INT32|QUANT8_ASYMM).
         // - CAST's argument can be any of TENSOR_(FLOAT16|FLOAT32|INT32|QUANT8_ASYMM).
+        // - RANDOM_MULTINOMIAL's argument can be either TENSOR_FLOAT16 or TENSOR_FLOAT32.
+        // - CONV_2D filter type (arg 1) can be QUANT8_ASYMM or QUANT8_SYMM_PER_CHANNEL
         switch (operation.type) {
             case OperationType::LSH_PROJECTION: {
                 if (operand == operation.inputs[1]) {
@@ -321,6 +341,17 @@
                     return true;
                 }
             } break;
+            case OperationType::RANDOM_MULTINOMIAL: {
+                if (type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32) {
+                    return true;
+                }
+            } break;
+            case OperationType::CONV_2D: {
+                if (operand == 1 && (type == OperandType::TENSOR_QUANT8_ASYMM ||
+                                     type == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL)) {
+                    return true;
+                }
+            } break;
             default:
                 break;
         }