Add DataSpace API to convert between ADataSpace and ColorSpace

Also implement getDataSpace functions in SurfaceTexture and Image field
to help with upstream HDR work.

Bug: 201539996
Bug: 201535454
Test: android.hardware.camera2.cts.ImageWriterTest, android.hardware.cts.DataSpaceTest pass
Change-Id: I17fa43c1ba60e6f59da1910cebcef0dab993ce3b
diff --git a/core/api/current.txt b/core/api/current.txt
index 066746d..fe6167e6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -16308,6 +16308,7 @@
     ctor public SurfaceTexture(boolean);
     method public void attachToGLContext(int);
     method public void detachFromGLContext();
+    method public long getDataSpace();
     method public long getTimestamp();
     method public void getTransformMatrix(float[]);
     method public boolean isReleased();
@@ -17519,6 +17520,52 @@
     method public int getMinFrequency();
   }
 
+  public final class DataSpace {
+    method public static long getRange(long);
+    method public static long getStandard(long);
+    method public static long getTransfer(long);
+    method public static long pack(long, long, long);
+    field public static final long DATASPACE_ADOBE_RGB = 151715840L; // 0x90b0000L
+    field public static final long DATASPACE_BT2020 = 147193856L; // 0x8c60000L
+    field public static final long DATASPACE_BT2020_PQ = 163971072L; // 0x9c60000L
+    field public static final long DATASPACE_BT601_525 = 281280512L; // 0x10c40000L
+    field public static final long DATASPACE_BT601_625 = 281149440L; // 0x10c20000L
+    field public static final long DATASPACE_BT709 = 281083904L; // 0x10c10000L
+    field public static final long DATASPACE_DCI_P3 = 155844608L; // 0x94a0000L
+    field public static final long DATASPACE_DISPLAY_P3 = 143261696L; // 0x88a0000L
+    field public static final long DATASPACE_JFIF = 146931712L; // 0x8c20000L
+    field public static final long DATASPACE_SCRGB = 411107328L; // 0x18810000L
+    field public static final long DATASPACE_SCRGB_LINEAR = 406913024L; // 0x18410000L
+    field public static final long DATASPACE_SRGB = 142671872L; // 0x8810000L
+    field public static final long DATASPACE_SRGB_LINEAR = 138477568L; // 0x8410000L
+    field public static final long DATASPACE_UNKNOWN = 0L; // 0x0L
+    field public static final long RANGE_EXTENDED = 402653184L; // 0x18000000L
+    field public static final long RANGE_FULL = 134217728L; // 0x8000000L
+    field public static final long RANGE_LIMITED = 268435456L; // 0x10000000L
+    field public static final long RANGE_UNSPECIFIED = 0L; // 0x0L
+    field public static final long STANDARD_ADOBE_RGB = 720896L; // 0xb0000L
+    field public static final long STANDARD_BT2020 = 393216L; // 0x60000L
+    field public static final long STANDARD_BT2020_CONSTANT_LUMINANCE = 458752L; // 0x70000L
+    field public static final long STANDARD_BT470M = 524288L; // 0x80000L
+    field public static final long STANDARD_BT601_525 = 262144L; // 0x40000L
+    field public static final long STANDARD_BT601_525_UNADJUSTED = 327680L; // 0x50000L
+    field public static final long STANDARD_BT601_625 = 131072L; // 0x20000L
+    field public static final long STANDARD_BT601_625_UNADJUSTED = 196608L; // 0x30000L
+    field public static final long STANDARD_BT709 = 65536L; // 0x10000L
+    field public static final long STANDARD_DCI_P3 = 655360L; // 0xa0000L
+    field public static final long STANDARD_FILM = 589824L; // 0x90000L
+    field public static final long STANDARD_UNSPECIFIED = 0L; // 0x0L
+    field public static final long TRANSFER_GAMMA2_2 = 16777216L; // 0x1000000L
+    field public static final long TRANSFER_GAMMA2_6 = 20971520L; // 0x1400000L
+    field public static final long TRANSFER_GAMMA2_8 = 25165824L; // 0x1800000L
+    field public static final long TRANSFER_HLG = 33554432L; // 0x2000000L
+    field public static final long TRANSFER_LINEAR = 4194304L; // 0x400000L
+    field public static final long TRANSFER_SMPTE_170M = 12582912L; // 0xc00000L
+    field public static final long TRANSFER_SRGB = 8388608L; // 0x800000L
+    field public static final long TRANSFER_ST2084 = 29360128L; // 0x1c00000L
+    field public static final long TRANSFER_UNSPECIFIED = 0L; // 0x0L
+  }
+
   public class GeomagneticField {
     ctor public GeomagneticField(float, float, float, long);
     method public float getDeclination();
@@ -21452,6 +21499,7 @@
   public abstract class Image implements java.lang.AutoCloseable {
     method public abstract void close();
     method public android.graphics.Rect getCropRect();
+    method public long getDataSpace();
     method public abstract int getFormat();
     method @Nullable public android.hardware.HardwareBuffer getHardwareBuffer();
     method public abstract int getHeight();
@@ -21459,6 +21507,7 @@
     method public abstract long getTimestamp();
     method public abstract int getWidth();
     method public void setCropRect(android.graphics.Rect);
+    method public void setDataSpace(long);
     method public void setTimestamp(long);
   }
 
diff --git a/core/java/android/hardware/DataSpace.java b/core/java/android/hardware/DataSpace.java
new file mode 100644
index 0000000..65383c5
--- /dev/null
+++ b/core/java/android/hardware/DataSpace.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright 2021 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;
+
+import android.annotation.LongDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * DataSpace identifies three components of colors - standard (primaries), transfer and range.
+ *
+ * <p>A DataSpace describes how buffer data, such as from an {@link android.media.Image Image}
+ * or a {@link android.hardware.HardwareBuffer HardwareBuffer}
+ * should be interpreted by both applications and typical hardware.</p>
+ *
+ * <p>As buffer information is not guaranteed to be representative of color information,
+ * while DataSpace is typically used to describe three aspects of interpreting colors,
+ * some DataSpaces may describe other typical interpretations of buffer data
+ * such as depth information.</p>
+ *
+ * <p>Note that while {@link android.graphics.ColorSpace ColorSpace} and {@code DataSpace}
+ * are similar concepts, they are not equivalent. Not all ColorSpaces,
+ * such as {@link android.graphics.ColorSpace.Named#ACES ColorSpace.Named.ACES},
+ * are able to be understood by typical hardware blocks so they cannot be DataSpaces.</p>
+ *
+ * <h3>Standard aspect</h3>
+ *
+ * <p>Defines the chromaticity coordinates of the source primaries in terms of
+ * the CIE 1931 definition of x and y specified in ISO 11664-1.</p>
+ *
+ * <h3>Transfer aspect</h3>
+ *
+ * <p>Transfer characteristics are the opto-electronic transfer characteristic
+ * at the source as a function of linear optical intensity (luminance).</p>
+ *
+ * <p>For digital signals, E corresponds to the recorded value. Normally, the
+ * transfer function is applied in RGB space to each of the R, G and B
+ * components independently. This may result in color shift that can be
+ * minized by applying the transfer function in Lab space only for the L
+ * component. Implementation may apply the transfer function in RGB space
+ * for all pixel formats if desired.</p>
+ *
+ * <h3>Range aspect</h3>
+ *
+ * <p>Defines the range of values corresponding to the unit range of {@code 0-1}.</p>
+ */
+
+public final class DataSpace {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @LongDef(flag = true, value = {
+        STANDARD_UNSPECIFIED,
+        STANDARD_BT709,
+        STANDARD_BT601_625,
+        STANDARD_BT601_625_UNADJUSTED,
+        STANDARD_BT601_525,
+        STANDARD_BT601_525_UNADJUSTED,
+        STANDARD_BT2020,
+        STANDARD_BT2020_CONSTANT_LUMINANCE,
+        STANDARD_BT470M,
+        STANDARD_FILM,
+        STANDARD_DCI_P3,
+        STANDARD_ADOBE_RGB
+    })
+    public @interface DataSpaceStandard {};
+
+    private static final long STANDARD_MASK = 63 << 16;
+
+    /**
+     * Chromacity coordinates are unknown or are determined by the application.
+     */
+    public static final long STANDARD_UNSPECIFIED  = 0 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.2126}, {@code KB = 0.0722} luminance interpretation
+     * for RGB conversion.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.300   0.600
+     *  blue            0.150   0.060
+     *  red             0.640   0.330
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT709 = 1 << 16;
+    /**
+     * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation
+     * for RGB conversion from the one purely determined by the primaries
+     * to minimize the color shift into RGB space that uses BT.709
+     * primaries.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.290   0.600
+     *  blue            0.150   0.060
+     *  red             0.640   0.330
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT601_625 = 2 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.222}, {@code KB = 0.071} luminance interpretation
+     * for RGB conversion.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.290   0.600
+     *  blue            0.150   0.060
+     *  red             0.640   0.330
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT601_625_UNADJUSTED = 3 << 16;
+    /**
+     * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation
+     * for RGB conversion from the one purely determined by the primaries
+     * to minimize the color shift into RGB space that uses BT.709
+     * primaries.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.310   0.595
+     *  blue            0.155   0.070
+     *  red             0.630   0.340
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT601_525 = 4 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.212}, {@code KB = 0.087} luminance interpretation
+     * for RGB conversion (as in SMPTE 240M).
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.310   0.595
+     *  blue            0.155   0.070
+     *  red             0.630   0.340
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT601_525_UNADJUSTED = 5 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation
+     * for RGB conversion.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.170   0.797
+     *  blue            0.131   0.046
+     *  red             0.708   0.292
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT2020 = 6 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation
+     * for RGB conversion using the linear domain.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.170   0.797
+     *  blue            0.131   0.046
+     *  red             0.708   0.292
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.30}, {@code KB = 0.11} luminance interpretation
+     * for RGB conversion.
+     *
+     * <pre>
+     * Primaries:       x      y
+     *  green           0.21   0.71
+     *  blue            0.14   0.08
+     *  red             0.67   0.33
+     *  white (C)       0.310  0.316 </pre>
+     */
+    public static final long STANDARD_BT470M = 8 << 16;
+    /**
+     * Use the unadjusted {@code KR = 0.254}, {@code KB = 0.068} luminance interpretation
+     * for RGB conversion.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.243   0.692
+     *  blue            0.145   0.049
+     *  red             0.681   0.319
+     *  white (C)       0.310   0.316 </pre>
+     */
+    public static final long STANDARD_FILM = 9 << 16;
+    /**
+     * SMPTE EG 432-1 and SMPTE RP 431-2.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.265   0.690
+     *  blue            0.150   0.060
+     *  red             0.680   0.320
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_DCI_P3 = 10 << 16;
+    /**
+     * Adobe RGB primaries.
+     *
+     * <pre>
+     * Primaries:       x       y
+     *  green           0.210   0.710
+     *  blue            0.150   0.060
+     *  red             0.640   0.330
+     *  white (D65)     0.3127  0.3290 </pre>
+     */
+    public static final long STANDARD_ADOBE_RGB = 11 << 16;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @LongDef(flag = true, value = {
+        TRANSFER_UNSPECIFIED,
+        TRANSFER_LINEAR,
+        TRANSFER_SRGB,
+        TRANSFER_SMPTE_170M,
+        TRANSFER_GAMMA2_2,
+        TRANSFER_GAMMA2_6,
+        TRANSFER_GAMMA2_8,
+        TRANSFER_ST2084,
+        TRANSFER_HLG
+    })
+    public @interface DataSpaceTransfer {};
+
+    private static final long TRANSFER_MASK = 31 << 22;
+
+    /**
+     * Transfer characteristics are unknown or are determined by the
+     * application.
+     */
+    public static final long TRANSFER_UNSPECIFIED = 0 << 22;
+    /**
+     * Linear transfer.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     *  E = L
+     *      L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *      E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_LINEAR = 1 << 22;
+    /**
+     * sRGB transfer.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = 1.055 * L^(1/2.4) - 0.055  for 0.0031308 <= L <= 1
+     *   = 12.92 * L                  for 0 <= L < 0.0031308
+     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *     E - corresponding electrical signal}</pre>
+     *
+     * Use for RGB formats.
+     */
+    public static final long TRANSFER_SRGB = 2 << 22;
+    /**
+     * SMPTE 170M transfer.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = 1.099 * L ^ 0.45 - 0.099  for 0.018 <= L <= 1
+     *   = 4.500 * L                 for 0 <= L < 0.018
+     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *     E - corresponding electrical signal}</pre>
+     *
+     * Use for YCbCr formats.
+     */
+    public static final long TRANSFER_SMPTE_170M = 3 << 22;
+    /**
+     * Display gamma 2.2.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = L ^ (1/2.2)
+     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *     E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_GAMMA2_2 = 4 << 22;
+    /**
+     *  Display gamma 2.6.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = L ^ (1/2.6)
+     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *     E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_GAMMA2_6 = 5 << 22;
+    /**
+     *  Display gamma 2.8.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = L ^ (1/2.8)
+     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry
+     *     E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_GAMMA2_8 = 6 << 22;
+    /**
+     * SMPTE ST 2084 (Dolby Perceptual Quantizer).
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m
+     * c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375
+     * c2 = 32 * 2413 / 4096 = 18.8515625
+     * c3 = 32 * 2392 / 4096 = 18.6875
+     * m = 128 * 2523 / 4096 = 78.84375
+     * n = 0.25 * 2610 / 4096 = 0.1593017578125
+     *     L - luminance of image 0 <= L <= 1 for HDR colorimetry.
+     *         L = 1 corresponds to 10000 cd/m2
+     *     E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_ST2084 = 7 << 22;
+    /**
+     * ARIB STD-B67 Hybrid Log Gamma.
+     *
+     * <pre>{@code
+     * Transfer characteristic curve:
+     * E = r * L^0.5                 for 0 <= L <= 1
+     *   = a * ln(L - b) + c         for 1 < L
+     * a = 0.17883277
+     * b = 0.28466892
+     * c = 0.55991073
+     * r = 0.5
+     *     L - luminance of image 0 <= L for HDR colorimetry. L = 1 corresponds
+     *         to reference white level of 100 cd/m2
+     *     E - corresponding electrical signal}</pre>
+     */
+    public static final long TRANSFER_HLG = 8 << 22;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @LongDef(flag = true, value = {
+        RANGE_UNSPECIFIED,
+        RANGE_FULL,
+        RANGE_LIMITED,
+        RANGE_EXTENDED
+    })
+    public @interface DataSpaceRange {};
+
+    private static final long RANGE_MASK = 7 << 27;
+
+    /**
+     * Range characteristics are unknown or are determined by the application.
+     */
+    public static final long RANGE_UNSPECIFIED = 0 << 27;
+    /**
+     * Full range uses all values for Y, Cb and Cr from
+     * {@code 0} to {@code 2^b-1}, where b is the bit depth of the color format.
+     */
+    public static final long RANGE_FULL = 1 << 27;
+    /**
+     * Limited range uses values {@code 16/256*2^b} to {@code 235/256*2^b} for Y, and
+     * {@code 1/16*2^b} to {@code 15/16*2^b} for Cb, Cr, R, G and B, where b is the bit depth of
+     * the color format.
+     *
+     * <p>E.g. For 8-bit-depth formats:
+     * Luma (Y) samples should range from 16 to 235, inclusive
+     * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive
+     *
+     * For 10-bit-depth formats:
+     * Luma (Y) samples should range from 64 to 940, inclusive
+     * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive. </p>
+     */
+    public static final long RANGE_LIMITED = 2 << 27;
+    /**
+     * Extended range is used for scRGB only.
+     *
+     * <p>Intended for use with floating point pixel formats. [0.0 - 1.0] is the standard
+     * sRGB space. Values outside the range [0.0 - 1.0] can encode
+     * color outside the sRGB gamut. [-0.5, 7.5] is the scRGB range.
+     * Used to blend/merge multiple dataspaces on a single display.</p>
+     */
+    public static final long RANGE_EXTENDED = 3 << 27;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @LongDef(flag = true, value = {
+        DATASPACE_UNKNOWN,
+        DATASPACE_SCRGB_LINEAR,
+        DATASPACE_SRGB,
+        DATASPACE_SCRGB,
+        DATASPACE_DISPLAY_P3,
+        DATASPACE_BT2020_PQ,
+        DATASPACE_ADOBE_RGB,
+        DATASPACE_JFIF,
+        DATASPACE_BT601_625,
+        DATASPACE_BT601_525,
+        DATASPACE_BT2020,
+        DATASPACE_BT709,
+        DATASPACE_DCI_P3,
+        DATASPACE_SRGB_LINEAR
+    })
+    public @interface NamedDataSpace {};
+
+    /**
+     * Default-assumption data space, when not explicitly specified.
+     *
+     * <p>It is safest to assume a buffer is an image with sRGB primaries and
+     * encoding ranges, but the consumer and/or the producer of the data may
+     * simply be using defaults. No automatic gamma transform should be
+     * expected, except for a possible display gamma transform when drawn to a
+     * screen.</p>
+     */
+    public static final long DATASPACE_UNKNOWN = 0;
+    /**
+     * scRGB linear encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT709
+     *   Transfer: TRANSFER_LINEAR
+     *   Range: RANGE_EXTENDED</pre>
+     *
+     * The values are floating point.
+     * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
+     * Values beyond the range [0.0 - 1.0] would correspond to other colors
+     * spaces and/or HDR content.
+     */
+    public static final long DATASPACE_SCRGB_LINEAR = 406913024;
+    /**
+     * sRGB gamma encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT709
+     *   Transfer: TRANSFER_SRGB
+     *   Range: RANGE_FULL</pre>
+     *
+     * When written, the inverse transformation is performed.
+     *
+     * The alpha component, if present, is always stored in linear space and
+     * is left unmodified when read or written.
+     */
+    public static final long DATASPACE_SRGB = 142671872;
+    /**
+     * scRGB gamma encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT709
+     *   Transfer: TRANSFER_SRGB
+     *   Range: RANGE_EXTENDED</pre>
+     *
+     * The values are floating point.
+     *
+     * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
+     * Values beyond the range [0.0 - 1.0] would correspond to other colors
+     * spaces and/or HDR content.
+     */
+    public static final long DATASPACE_SCRGB = 411107328;
+    /**
+     * Display P3 encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_DCI_P3
+     *   Transfer: TRANSFER_SRGB
+     *   Range: RANGE_FULL</pre>
+     */
+    public static final long DATASPACE_DISPLAY_P3 = 143261696;
+    /**
+     * ITU-R Recommendation 2020 (BT.2020)
+     *
+     * Ultra High-definition television.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT2020
+     *   Transfer: TRANSFER_ST2084
+     *   Range: RANGE_FULL</pre>
+     */
+    public static final long DATASPACE_BT2020_PQ = 163971072;
+    /**
+     * Adobe RGB encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_ADOBE_RGB
+     *   Transfer: TRANSFER_GAMMA2_2
+     *   Range: RANGE_FULL</pre>
+     *
+     * Note: Application is responsible for gamma encoding the data.
+     */
+    public static final long DATASPACE_ADOBE_RGB = 151715840;
+    /**
+     * JPEG File Interchange Format (JFIF).
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT601_625
+     *   Transfer: TRANSFER_SMPTE_170M
+     *   Range: RANGE_FULL</pre>
+     *
+     * Same model as BT.601-625, but all values (Y, Cb, Cr) range from {@code 0} to {@code 255}
+     */
+    public static final long DATASPACE_JFIF = 146931712;
+    /**
+     * ITU-R Recommendation 601 (BT.601) - 525-line
+     *
+     * Standard-definition television, 525 Lines (NTSC).
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT601_625
+     *   Transfer: TRANSFER_SMPTE_170M
+     *   Range: RANGE_LIMITED</pre>
+     */
+    public static final long DATASPACE_BT601_625 = 281149440;
+    /**
+     * ITU-R Recommendation 709 (BT.709)
+     *
+     * High-definition television.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT601_525
+     *   Transfer: TRANSFER_SMPTE_170M
+     *   Range: RANGE_LIMITED</pre>
+     */
+    public static final long DATASPACE_BT601_525 = 281280512;
+    /**
+     * ITU-R Recommendation 2020 (BT.2020)
+     *
+     * Ultra High-definition television.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT2020
+     *   Transfer: TRANSFER_SMPTE_170M
+     *   Range: RANGE_FULL</pre>
+     */
+    public static final long DATASPACE_BT2020 = 147193856;
+    /**
+     * ITU-R Recommendation 709 (BT.709)
+     *
+     * High-definition television.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT709
+     *   Transfer: TRANSFER_SMPTE_170M
+     *   Range: RANGE_LIMITED</pre>
+     */
+    public static final long DATASPACE_BT709 = 281083904;
+    /**
+     * SMPTE EG 432-1 and SMPTE RP 431-2
+     *
+     * Digital Cinema DCI-P3.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_DCI_P3
+     *   Transfer: TRANSFER_GAMMA2_6
+     *   Range: RANGE_FULL</pre>
+     *
+     * Note: Application is responsible for gamma encoding the data as
+     * a 2.6 gamma encoding is not supported in HW.
+     */
+    public static final long DATASPACE_DCI_P3 = 155844608;
+    /**
+     * sRGB linear encoding.
+     *
+     * <p>Composed of the following -</p>
+     * <pre>
+     *   Primaries: STANDARD_BT709
+     *   Transfer: TRANSFER_LINEAR
+     *   Range: RANGE_FULL</pre>
+     *
+     * The values are encoded using the full range ([0,255] for 8-bit) for all
+     * components.
+     */
+    public static final long DATASPACE_SRGB_LINEAR = 138477568;
+
+    private DataSpace() {}
+
+    /**
+     * Pack the dataSpace value using standard, transfer and range field value.
+     * Field values should be in the correct bits place.
+     *
+     * @param standard Chromaticity coordinates of source primaries
+     * @param transfer Opto-electronic transfer characteristic at the source
+     * @param range The range of values
+     *
+     * @return The long dataspace packed by standard, transfer and range value
+     */
+    public static @NamedDataSpace long pack(@DataSpaceStandard long standard,
+                                        @DataSpaceTransfer long transfer,
+                                        @DataSpaceRange long range) {
+        if ((standard & STANDARD_MASK) != standard) {
+            throw new IllegalArgumentException("Invalid standard " + standard);
+        }
+        if ((transfer & TRANSFER_MASK) != transfer) {
+            throw new IllegalArgumentException("Invalid transfer " + transfer);
+        }
+        if ((range & RANGE_MASK) != range) {
+            throw new IllegalArgumentException("Invalid range " + range);
+        }
+        return standard | transfer | range;
+    }
+
+    /**
+     * Unpack the standard field value from the packed dataSpace value.
+     *
+     * @param dataSpace The packed dataspace value
+     *
+     * @return The standard aspect
+     */
+    public static @DataSpaceStandard long getStandard(@NamedDataSpace long dataSpace) {
+        @DataSpaceStandard long standard = dataSpace & STANDARD_MASK;
+        return standard;
+    }
+
+    /**
+     * Unpack the transfer field value from the packed dataSpace value
+     *
+     * @param dataSpace The packed dataspace value
+     *
+     * @return The transfer aspect
+     */
+    public static @DataSpaceTransfer long getTransfer(@NamedDataSpace long dataSpace) {
+        @DataSpaceTransfer long transfer = dataSpace & TRANSFER_MASK;
+        return transfer;
+    }
+
+    /**
+     * Unpack the range field value from the packed dataSpace value
+     *
+     * @param dataSpace The packed dataspace value
+     *
+     * @return The range aspect
+     */
+    public static @DataSpaceRange long getRange(@NamedDataSpace long dataSpace) {
+        @DataSpaceRange long range = dataSpace & RANGE_MASK;
+        return range;
+    }
+}
diff --git a/core/jni/android_graphics_SurfaceTexture.cpp b/core/jni/android_graphics_SurfaceTexture.cpp
index 2f12289..0f647ea 100644
--- a/core/jni/android_graphics_SurfaceTexture.cpp
+++ b/core/jni/android_graphics_SurfaceTexture.cpp
@@ -346,6 +346,11 @@
     return surfaceTexture->getTimestamp();
 }
 
+static jlong SurfaceTexture_getDataSpace(JNIEnv* env, jobject thiz) {
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+    return surfaceTexture->getCurrentDataSpace();
+}
+
 static void SurfaceTexture_release(JNIEnv* env, jobject thiz)
 {
     sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
@@ -361,17 +366,18 @@
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gSurfaceTextureMethods[] = {
-    {"nativeInit",                 "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
-    {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
-    {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
-    {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
-    {"nativeReleaseTexImage",      "()V",   (void*)SurfaceTexture_releaseTexImage },
-    {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
-    {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
-    {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
-    {"nativeGetTimestamp",         "()J",   (void*)SurfaceTexture_getTimestamp },
-    {"nativeRelease",              "()V",   (void*)SurfaceTexture_release },
-    {"nativeIsReleased",           "()Z",   (void*)SurfaceTexture_isReleased },
+        {"nativeInit", "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init},
+        {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize},
+        {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize},
+        {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage},
+        {"nativeReleaseTexImage", "()V", (void*)SurfaceTexture_releaseTexImage},
+        {"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext},
+        {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext},
+        {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix},
+        {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp},
+        {"nativeGetDataSpace", "()J", (void*)SurfaceTexture_getDataSpace},
+        {"nativeRelease", "()V", (void*)SurfaceTexture_release},
+        {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased},
 };
 
 int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 9b2effc..d84a24d 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -17,7 +17,9 @@
 package android.graphics;
 
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.hardware.DataSpace.NamedDataSpace;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -348,6 +350,14 @@
     }
 
     /**
+     * Retrieve the dataspace associated with the texture image.
+     */
+    @SuppressLint("MethodNameUnits")
+    public @NamedDataSpace long getDataSpace() {
+        return nativeGetDataSpace();
+    }
+
+    /**
      * {@code release()} frees all the buffers and puts the SurfaceTexture into the
      * 'abandoned' state. Once put in this state the SurfaceTexture can never
      * leave it. When in the 'abandoned' state, all methods of the
@@ -416,6 +426,7 @@
     private native void nativeFinalize();
     private native void nativeGetTransformMatrix(float[] mtx);
     private native long nativeGetTimestamp();
+    private native long nativeGetDataSpace();
     private native void nativeSetDefaultBufferSize(int width, int height);
     private native void nativeUpdateTexImage();
     private native void nativeReleaseTexImage();
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index bac44ad..f7bd614 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -17,9 +17,12 @@
 package android.media;
 
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Rect;
+import android.hardware.DataSpace;
+import android.hardware.DataSpace.NamedDataSpace;
 import android.hardware.HardwareBuffer;
 
 import java.nio.ByteBuffer;
@@ -272,6 +275,31 @@
         return;
     }
 
+    private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN;
+
+    /**
+     * Get the dataspace associated with this frame.
+     */
+    @SuppressLint("MethodNameUnits")
+    public @NamedDataSpace long getDataSpace() {
+        throwISEIfImageIsInvalid();
+        return mDataSpace;
+    }
+
+    /**
+     * Set the dataspace associated with this frame.
+     * <p>
+     * If dataspace for an image is not set, dataspace value depends on {@link android.view.Surface}
+     * that is provided in the {@link ImageWriter} constructor.
+     * </p>
+     *
+     * @param dataSpace The Dataspace to be set for this image
+     */
+    public void setDataSpace(@NamedDataSpace long dataSpace) {
+        throwISEIfImageIsInvalid();
+        mDataSpace = dataSpace;
+    }
+
     private Rect mCropRect;
 
     /**
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 5656dff..bd0f32e 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.annotation.CallbackExecutor;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.graphics.GraphicBuffer;
@@ -28,7 +27,6 @@
 import android.hardware.camera2.MultiResolutionImageReader;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Message;
 import android.view.Surface;
 
 import dalvik.system.VMRuntime;
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 1b74367..1fc2cf9 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -23,9 +23,9 @@
 import android.graphics.ImageFormat.Format;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.SurfaceUtils;
-import android.hardware.HardwareBuffer;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -454,8 +454,9 @@
         }
 
         Rect crop = image.getCropRect();
-        nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), crop.left, crop.top,
-                crop.right, crop.bottom, image.getTransform(), image.getScalingMode());
+        nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
+                crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
+                image.getScalingMode());
 
         /**
          * Only remove and cleanup the Images that are owned by this
@@ -642,13 +643,13 @@
         Rect crop = image.getCropRect();
         if (image.getNativeContext() != 0) {
             nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(), image.getFormat(),
-                    image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom,
-                    image.getTransform(), image.getScalingMode());
+                    image.getTimestamp(), image.getDataSpace(), crop.left, crop.top, crop.right,
+                    crop.bottom, image.getTransform(), image.getScalingMode());
         } else {
             GraphicBuffer gb = GraphicBuffer.createFromHardwareBuffer(image.getHardwareBuffer());
             nativeAttachAndQueueGraphicBuffer(mNativeContext, gb, image.getFormat(),
-                    image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom,
-                    image.getTransform(), image.getScalingMode());
+                    image.getTimestamp(), image.getDataSpace(), crop.left, crop.top, crop.right,
+                    crop.bottom, image.getTransform(), image.getScalingMode());
             gb.destroy();
             image.close();
         }
@@ -976,15 +977,15 @@
     private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi);
 
     private synchronized native void nativeQueueInputImage(long nativeCtx, Image image,
-            long timestampNs, int left, int top, int right, int bottom, int transform,
-            int scalingMode);
+            long timestampNs, long dataSpace, int left, int top, int right, int bottom,
+            int transform, int scalingMode);
 
     private synchronized native int nativeAttachAndQueueImage(long nativeCtx,
-            long imageNativeBuffer, int imageFormat, long timestampNs, int left,
-            int top, int right, int bottom, int transform, int scalingMode);
+            long imageNativeBuffer, int imageFormat, long timestampNs, long dataSpace,
+            int left, int top, int right, int bottom, int transform, int scalingMode);
     private synchronized native int nativeAttachAndQueueGraphicBuffer(long nativeCtx,
-            GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, int left,
-            int top, int right, int bottom, int transform, int scalingMode);
+            GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, long dataSpace,
+            int left, int top, int right, int bottom, int transform, int scalingMode);
 
     private synchronized native void cancelImage(long nativeCtx, Image image);
 
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 5174c0c..021507c 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -48,6 +48,7 @@
 #define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID       "mNativeContext"
 #define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID   "mNativeBuffer"
 #define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID       "mTimestamp"
+#define ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID       "mDataSpace"
 #define ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID       "mTransform"
 #define ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID       "mScalingMode"
 
@@ -71,6 +72,7 @@
 static struct {
     jfieldID mNativeBuffer;
     jfieldID mTimestamp;
+    jfieldID mDataSpace;
     jfieldID mTransform;
     jfieldID mScalingMode;
     jfieldID mPlanes;
@@ -319,6 +321,12 @@
                         "can't find android/graphics/ImageReader.%s",
                         ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID);
 
+    gSurfaceImageClassInfo.mDataSpace = env->GetFieldID(
+            imageClazz, ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID, "J");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mDataSpace == NULL,
+                        "can't find android/graphics/ImageReader.%s",
+                        ANDROID_MEDIA_SURFACEIMAGE_DS_JNI_ID);
+
     gSurfaceImageClassInfo.mTransform = env->GetFieldID(
             imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID, "I");
     LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTransform == NULL,
@@ -619,6 +627,8 @@
     Image_setBufferItem(env, image, buffer);
     env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
             static_cast<jlong>(buffer->mTimestamp));
+    env->SetLongField(image, gSurfaceImageClassInfo.mDataSpace,
+            static_cast<jlong>(buffer->mDataSpace));
     auto transform = buffer->mTransform;
     if (buffer->mTransformToDisplayInverse) {
         transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index b291ac95b..0a5490d 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -53,6 +53,7 @@
 } gImageWriterClassInfo;
 
 static struct {
+    jfieldID mDataSpace;
     jfieldID mNativeBuffer;
     jfieldID mNativeFenceFd;
     jfieldID mPlanes;
@@ -87,6 +88,9 @@
     void setBufferHeight(int height) { mHeight = height; }
     int getBufferHeight() { return mHeight; }
 
+    void setBufferDataSpace(android_dataspace dataSpace) { mDataSpace = dataSpace; }
+    android_dataspace getBufferDataSpace() { return mDataSpace; }
+
     void queueAttachedFlag(bool isAttached) {
         Mutex::Autolock l(mAttachedFlagQueueLock);
         mAttachedFlagQueue.push_back(isAttached);
@@ -105,6 +109,7 @@
     int mFormat;
     int mWidth;
     int mHeight;
+    android_dataspace mDataSpace;
 
     // Class for a shared thread used to detach buffers from buffer queues
     // to discard buffers after consumers are done using them.
@@ -316,7 +321,7 @@
 // -------------------------------Private method declarations--------------
 
 static void Image_setNativeContext(JNIEnv* env, jobject thiz,
-        sp<GraphicBuffer> buffer, int fenceFd);
+        sp<GraphicBuffer> buffer, int fenceFd, long dataSpace);
 static void Image_getNativeContext(JNIEnv* env, jobject thiz,
         GraphicBuffer** buffer, int* fenceFd);
 static void Image_unlockIfLocked(JNIEnv* env, jobject thiz);
@@ -328,6 +333,12 @@
     jclass imageClazz = env->FindClass("android/media/ImageWriter$WriterSurfaceImage");
     LOG_ALWAYS_FATAL_IF(imageClazz == NULL,
             "can't find android/media/ImageWriter$WriterSurfaceImage");
+
+    gSurfaceImageClassInfo.mDataSpace = env->GetFieldID(
+            imageClazz, "mDataSpace", "J");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mDataSpace == NULL,
+            "can't find android/media/ImageWriter$WriterSurfaceImage.mDataSpace");
+
     gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID(
             imageClazz, IMAGE_BUFFER_JNI_ID, "J");
     LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL,
@@ -465,6 +476,7 @@
             jniThrowRuntimeException(env, "Failed to set Surface dataspace");
             return 0;
         }
+        ctx->setBufferDataSpace(nativeDataspace);
         surfaceFormat = userFormat;
     }
 
@@ -544,7 +556,7 @@
     // 3. need use lockAsync here, as it will handle the dequeued fence for us automatically.
 
     // Finally, set the native info into image object.
-    Image_setNativeContext(env, image, buffer, fenceFd);
+    Image_setNativeContext(env, image, buffer, fenceFd, ctx->getBufferDataSpace());
 }
 
 static void ImageWriter_close(JNIEnv* env, jobject thiz, jlong nativeCtx) {
@@ -605,12 +617,12 @@
 
     anw->cancelBuffer(anw.get(), buffer, fenceFd);
 
-    Image_setNativeContext(env, image, NULL, -1);
+    Image_setNativeContext(env, image, NULL, -1, HAL_DATASPACE_UNKNOWN);
 }
 
 static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image,
-        jlong timestampNs, jint left, jint top, jint right, jint bottom, jint transform,
-        jint scalingMode) {
+        jlong timestampNs, jlong dataSpace, jint left, jint top, jint right,
+        jint bottom, jint transform, jint scalingMode) {
     ALOGV("%s", __FUNCTION__);
     JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
     if (ctx == NULL || thiz == NULL) {
@@ -642,6 +654,15 @@
         return;
     }
 
+    // Set dataSpace
+    ALOGV("dataSpace to be queued: %" PRId64, dataSpace);
+    res = native_window_set_buffers_data_space(
+        anw.get(), static_cast<android_dataspace>(dataSpace));
+    if (res != OK) {
+        jniThrowRuntimeException(env, "Set dataspace failed");
+        return;
+    }
+
     // Set crop
     android_native_rect_t cropRect;
     cropRect.left = left;
@@ -689,12 +710,12 @@
     }
 
     // Clear the image native context: end of this image's lifecycle in public API.
-    Image_setNativeContext(env, image, NULL, -1);
+    Image_setNativeContext(env, image, NULL, -1, HAL_DATASPACE_UNKNOWN);
 }
 
 static status_t attachAndQeueuGraphicBuffer(JNIEnv* env, JNIImageWriterContext *ctx,
-        sp<Surface> surface, sp<GraphicBuffer> gb, jlong timestampNs, jint left, jint top,
-        jint right, jint bottom, jint transform, jint scalingMode) {
+        sp<Surface> surface, sp<GraphicBuffer> gb, jlong timestampNs, jlong dataSpace,
+        jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) {
     status_t res = OK;
     // Step 1. Attach Image
     res = surface->attachBuffer(gb.get());
@@ -713,8 +734,8 @@
     }
     sp < ANativeWindow > anw = surface;
 
-    // Step 2. Set timestamp, crop, transform and scaling mode. Note that we do not need unlock the
-    // image because it was not locked.
+    // Step 2. Set timestamp, dataspace, crop, transform and scaling mode.
+    // Note that we do not need unlock the image because it was not locked.
     ALOGV("timestamp to be queued: %" PRId64, timestampNs);
     res = native_window_set_buffers_timestamp(anw.get(), timestampNs);
     if (res != OK) {
@@ -722,6 +743,14 @@
         return res;
     }
 
+    ALOGV("dataSpace to be queued: %" PRId64, dataSpace);
+    res = native_window_set_buffers_data_space(
+        anw.get(), static_cast<android_dataspace>(dataSpace));
+    if (res != OK) {
+        jniThrowRuntimeException(env, "Set dataSpace failed");
+        return res;
+    }
+
     android_native_rect_t cropRect;
     cropRect.left = left;
     cropRect.top = top;
@@ -775,8 +804,8 @@
 }
 
 static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx,
-        jlong nativeBuffer, jint imageFormat, jlong timestampNs, jint left, jint top,
-        jint right, jint bottom, jint transform, jint scalingMode) {
+        jlong nativeBuffer, jint imageFormat, jlong timestampNs, jlong dataSpace,
+        jint left, jint top, jint right, jint bottom, jint transform, jint scalingMode) {
     ALOGV("%s", __FUNCTION__);
     JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
     if (ctx == NULL || thiz == NULL) {
@@ -801,12 +830,12 @@
         return -1;
     }
 
-    return attachAndQeueuGraphicBuffer(env, ctx, surface, buffer->mGraphicBuffer, timestampNs, left,
-            top, right, bottom, transform, scalingMode);
+    return attachAndQeueuGraphicBuffer(env, ctx, surface, buffer->mGraphicBuffer, timestampNs,
+            dataSpace, left, top, right, bottom, transform, scalingMode);
 }
 
 static jint ImageWriter_attachAndQueueGraphicBuffer(JNIEnv* env, jobject thiz, jlong nativeCtx,
-        jobject buffer, jint format, jlong timestampNs, jint left, jint top,
+        jobject buffer, jint format, jlong timestampNs, jlong dataSpace, jint left, jint top,
         jint right, jint bottom, jint transform, jint scalingMode) {
     ALOGV("%s", __FUNCTION__);
     JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
@@ -830,9 +859,8 @@
                 "Trying to attach an invalid graphic buffer");
         return -1;
     }
-
-    return attachAndQeueuGraphicBuffer(env, ctx, surface, graphicBuffer, timestampNs, left,
-            top, right, bottom, transform, scalingMode);
+    return attachAndQeueuGraphicBuffer(env, ctx, surface, graphicBuffer, timestampNs,
+            dataSpace, left, top, right, bottom, transform, scalingMode);
 }
 
 // --------------------------Image methods---------------------------------------
@@ -853,7 +881,7 @@
 }
 
 static void Image_setNativeContext(JNIEnv* env, jobject thiz,
-        sp<GraphicBuffer> buffer, int fenceFd) {
+        sp<GraphicBuffer> buffer, int fenceFd, long dataSpace) {
     ALOGV("%s:", __FUNCTION__);
     GraphicBuffer* p = NULL;
     Image_getNativeContext(env, thiz, &p, /*fenceFd*/NULL);
@@ -867,6 +895,8 @@
             reinterpret_cast<jlong>(buffer.get()));
 
     env->SetIntField(thiz, gSurfaceImageClassInfo.mNativeFenceFd, reinterpret_cast<jint>(fenceFd));
+
+    env->SetLongField(thiz, gSurfaceImageClassInfo.mDataSpace, dataSpace);
 }
 
 static void Image_unlockIfLocked(JNIEnv* env, jobject thiz) {
@@ -1066,12 +1096,15 @@
     {"nativeInit",              "(Ljava/lang/Object;Landroid/view/Surface;IIII)J",
                                                               (void*)ImageWriter_init },
     {"nativeClose",              "(J)V",                      (void*)ImageWriter_close },
-    {"nativeAttachAndQueueImage", "(JJIJIIIIII)I",          (void*)ImageWriter_attachAndQueueImage },
+    {"nativeAttachAndQueueImage",
+        "(JJIJJIIIIII)I",
+        (void*)ImageWriter_attachAndQueueImage },
     {"nativeAttachAndQueueGraphicBuffer",
-        "(JLandroid/graphics/GraphicBuffer;IJIIIIII)I",
+        "(JLandroid/graphics/GraphicBuffer;IJJIIIIII)I",
         (void*)ImageWriter_attachAndQueueGraphicBuffer },
     {"nativeDequeueInputImage", "(JLandroid/media/Image;)V",  (void*)ImageWriter_dequeueImage },
-    {"nativeQueueInputImage",   "(JLandroid/media/Image;JIIIIII)V",  (void*)ImageWriter_queueImage },
+    {"nativeQueueInputImage",   "(JLandroid/media/Image;JJIIIIII)V",
+                                                               (void*)ImageWriter_queueImage },
     {"cancelImage",             "(JLandroid/media/Image;)V",   (void*)ImageWriter_cancelImage },
 };