Merge "Rename colorimetry to color mode"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ed29e07..dca0695 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1554,8 +1554,12 @@
         if (ds.update_progress_) {
             if (do_broadcast) {
                 // clang-format off
+
+                // NOTE: flag must be kept in sync when the value of
+                // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
                 std::vector<std::string> am_args = {
                      "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
+                     "-f", "0x01000000",
                      "--es", "android.intent.extra.NAME", ds.name_,
                      "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
                      "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
@@ -1794,8 +1798,12 @@
         if (!ds.path_.empty()) {
             MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
             // clang-format off
+
+            // NOTE: flag must be kept in sync when the value of
+            // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
             std::vector<std::string> am_args = {
                  "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
+                 "-f", "0x01000000",
                  "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
                  "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
                  "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index 909318a..ce7804b 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -108,6 +108,9 @@
         PLAYER_EVENT                          = IBinder::FIRST_CALL_TRANSACTION + 69,
         RELEASE_PLAYER                        = IBinder::FIRST_CALL_TRANSACTION + 70,
 
+        /*
+        DISABLE_RINGTONE_SYNC                 = IBinder::FIRST_CALL_TRANSACTION + 71,
+        */
     };
 
     DECLARE_META_INTERFACE(AudioManager)
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index 493ecde..f8ded74 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -146,6 +146,10 @@
     // documented by the source.
     int64_t getTimestamp();
 
+    // getDataSpace retrieves the DataSpace associated with the texture image
+    // set by the most recent call to updateTexImage.
+    android_dataspace getCurrentDataSpace();
+
     // getFrameNumber retrieves the frame number associated with the texture
     // image set by the most recent call to updateTexImage.
     //
@@ -414,6 +418,10 @@
     // gets set each time updateTexImage is called.
     int64_t mCurrentTimestamp;
 
+    // mCurrentDataSpace is the dataspace for the current texture. It
+    // gets set each time updateTexImage is called.
+    android_dataspace mCurrentDataSpace;
+
     // mCurrentFrameNumber is the frame counter for the current texture.
     // It gets set each time updateTexImage is called.
     uint64_t mCurrentFrameNumber;
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 304a0c0..258cd2f 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -385,6 +385,7 @@
         uint32_t numPendingBuffers{0};
         uint64_t nextFrameNumber{0};
         FrameEventHistoryDelta frameTimestamps;
+        bool bufferReplaced{false};
     };
 
     virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 0b6a8f7..4be11b4 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -151,6 +151,9 @@
             nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime,
             nsecs_t* outDequeueReadyTime, nsecs_t* outReleaseTime);
 
+    status_t getDisplayRefreshCyclePeriod(nsecs_t* outMinRefreshDuration,
+            nsecs_t* outMaxRefreshDuration);
+
     status_t getUniqueId(uint64_t* outId) const;
 
 protected:
@@ -207,6 +210,7 @@
     int dispatchSetAutoRefresh(va_list args);
     int dispatchEnableFrameTimestamps(va_list args);
     int dispatchGetFrameTimestamps(va_list args);
+    int dispatchGetDisplayRefreshCyclePeriod(va_list args);
 
 protected:
     virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index b86c72c..183b42d 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -143,6 +143,7 @@
     status_t    setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask);
     status_t    setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent);
     status_t    setLayer(const sp<IBinder>& id, uint32_t layer);
+    status_t    setLayerInfo(const sp<IBinder>& id, uint32_t type, uint32_t appid);
     status_t    setAlpha(const sp<IBinder>& id, float alpha=1.0f);
     status_t    setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy);
     status_t    setPosition(const sp<IBinder>& id, float x, float y);
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 5e731c3..456bde4 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -62,6 +62,7 @@
 
     status_t    setLayerStack(uint32_t layerStack);
     status_t    setLayer(uint32_t layer);
+    status_t    setLayerInfo(uint32_t type, uint32_t appid);
     status_t    setPosition(float x, float y);
     status_t    setSize(uint32_t w, uint32_t h);
     status_t    hide();
diff --git a/include/media/hardware/VideoAPI.h b/include/media/hardware/VideoAPI.h
index 3667c4b..a090876 100644
--- a/include/media/hardware/VideoAPI.h
+++ b/include/media/hardware/VideoAPI.h
@@ -110,7 +110,7 @@
 // though could verify that nSize is at least the size of the structure at the
 // time of implementation. All new fields will be added at the end of the structure
 // ensuring backward compatibility.
-struct __attribute__ ((__packed__)) ColorAspects {
+struct __attribute__ ((__packed__, aligned(alignof(uint32_t)))) ColorAspects {
     // this is in sync with the range values in graphics.h
     enum Range : uint32_t {
         RangeUnspecified,
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 292dd3b..b648751 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -56,6 +56,7 @@
         eFinalCropChanged           = 0x00000400,
         eOverrideScalingModeChanged = 0x00000800,
         eGeometryAppliesWithResize  = 0x00001000,
+        eLayerInfoChanged           = 0x00002000,
     };
 
     layer_state_t()
@@ -64,7 +65,7 @@
             alpha(0), flags(0), mask(0),
             reserved(0), crop(Rect::INVALID_RECT),
             finalCrop(Rect::INVALID_RECT), frameNumber(0),
-            overrideScalingMode(-1)
+            overrideScalingMode(-1), type(0), appid(0)
     {
         matrix.dsdx = matrix.dtdy = 1.0f;
         matrix.dsdy = matrix.dtdx = 0.0f;
@@ -97,6 +98,8 @@
             sp<IBinder>     handle;
             uint64_t        frameNumber;
             int32_t         overrideScalingMode;
+            uint32_t        type;
+            uint32_t        appid;
             // non POD must be last. see write/read
             Region          transparentRegion;
 };
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 39b9a0b..3f69b1f 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -879,6 +879,7 @@
             mCore->mSharedBufferCache.dataspace = dataSpace;
         }
 
+        output->bufferReplaced = false;
         if (mCore->mQueue.empty()) {
             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
             // and simply queue this buffer
@@ -905,6 +906,7 @@
                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
                         mCore->mActiveBuffers.erase(last.mSlot);
                         mCore->mFreeBuffers.push_back(last.mSlot);
+                        output->bufferReplaced = true;
                     }
                 }
 
@@ -1158,6 +1160,7 @@
             output->numPendingBuffers =
                     static_cast<uint32_t>(mCore->mQueue.size());
             output->nextFrameNumber = mCore->mFrameCounter + 1;
+            output->bufferReplaced = false;
 
             if (listener != NULL) {
                 // Set up a death notification so that we can disconnect
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index fea9df7..b11a3e5 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -157,6 +157,7 @@
     mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     mCurrentFence(Fence::NO_FENCE),
     mCurrentTimestamp(0),
+    mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
     mCurrentFrameNumber(0),
     mDefaultWidth(1),
     mDefaultHeight(1),
@@ -185,6 +186,7 @@
     mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     mCurrentFence(Fence::NO_FENCE),
     mCurrentTimestamp(0),
+    mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
     mCurrentFrameNumber(0),
     mDefaultWidth(1),
     mDefaultHeight(1),
@@ -321,6 +323,7 @@
         mCurrentCrop.makeInvalid();
         mCurrentTransform = 0;
         mCurrentTimestamp = 0;
+        mCurrentDataSpace = HAL_DATASPACE_UNKNOWN;
         mCurrentFence = Fence::NO_FENCE;
         mCurrentFenceTime = FenceTime::NO_FENCE;
 
@@ -488,6 +491,7 @@
     mCurrentTransform = item.mTransform;
     mCurrentScalingMode = item.mScalingMode;
     mCurrentTimestamp = item.mTimestamp;
+    mCurrentDataSpace = item.mDataSpace;
     mCurrentFence = item.mFence;
     mCurrentFenceTime = item.mFenceTime;
     mCurrentFrameNumber = item.mFrameNumber;
@@ -914,6 +918,12 @@
     return mCurrentTimestamp;
 }
 
+android_dataspace GLConsumer::getCurrentDataSpace() {
+    GLC_LOGV("getCurrentDataSpace");
+    Mutex::Autolock lock(mMutex);
+    return mCurrentDataSpace;
+}
+
 uint64_t GLConsumer::getFrameNumber() {
     GLC_LOGV("getFrameNumber");
     Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 18a80e8..abdf649 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -831,7 +831,8 @@
             sizeof(height) +
             sizeof(transformHint) +
             sizeof(numPendingBuffers) +
-            sizeof(nextFrameNumber);
+            sizeof(nextFrameNumber) +
+            sizeof(bufferReplaced);
 }
 
 size_t IGraphicBufferProducer::QueueBufferOutput::getFlattenedSize() const {
@@ -854,6 +855,7 @@
     FlattenableUtils::write(buffer, size, transformHint);
     FlattenableUtils::write(buffer, size, numPendingBuffers);
     FlattenableUtils::write(buffer, size, nextFrameNumber);
+    FlattenableUtils::write(buffer, size, bufferReplaced);
 
     return frameTimestamps.flatten(buffer, size, fds, count);
 }
@@ -870,6 +872,7 @@
     FlattenableUtils::read(buffer, size, transformHint);
     FlattenableUtils::read(buffer, size, numPendingBuffers);
     FlattenableUtils::read(buffer, size, nextFrameNumber);
+    FlattenableUtils::read(buffer, size, bufferReplaced);
 
     return frameTimestamps.unflatten(buffer, size, fds, count);
 }
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index d1c576e..3949186 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -42,6 +42,8 @@
     output.writeStrongBinder(handle);
     output.writeUint64(frameNumber);
     output.writeInt32(overrideScalingMode);
+    output.writeUint32(type);
+    output.writeUint32(appid);
     output.write(transparentRegion);
     return NO_ERROR;
 }
@@ -70,6 +72,8 @@
     handle = input.readStrongBinder();
     frameNumber = input.readUint64();
     overrideScalingMode = input.readInt32();
+    type = input.readUint32();
+    appid = input.readUint32();
     input.read(transparentRegion);
     return NO_ERROR;
 }
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c859828..851a495 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -28,6 +28,7 @@
 
 #include <ui/Fence.h>
 #include <ui/Region.h>
+#include <ui/DisplayStatInfo.h>
 
 #include <gui/IProducerListener.h>
 #include <gui/ISurfaceComposer.h>
@@ -261,6 +262,18 @@
 
     return NO_ERROR;
 }
+status_t Surface::getDisplayRefreshCyclePeriod(nsecs_t* outMinRefreshDuration,
+            nsecs_t* outMaxRefreshDuration) {
+    ATRACE_CALL();
+
+    DisplayStatInfo stats;
+    status_t err = composerService()->getDisplayStats(NULL, &stats);
+
+    *outMinRefreshDuration = stats.vsyncPeriod;
+    *outMaxRefreshDuration = stats.vsyncPeriod;
+
+    return NO_ERROR;
+}
 
 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
     Surface* c = getSelf(window);
@@ -828,6 +841,9 @@
     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
         res = dispatchGetFrameTimestamps(args);
         break;
+    case NATIVE_WINDOW_GET_REFRESH_CYCLE_PERIOD:
+        res = dispatchGetDisplayRefreshCyclePeriod(args);
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -973,6 +989,13 @@
             outDisplayRetireTime, outDequeueReadyTime, outReleaseTime);
 }
 
+int Surface::dispatchGetDisplayRefreshCyclePeriod(va_list args) {
+    nsecs_t* outMinRefreshDuration = va_arg(args, int64_t*);
+    nsecs_t* outMaxRefreshDuration = va_arg(args, int64_t*);
+    return getDisplayRefreshCyclePeriod(outMinRefreshDuration,
+            outMaxRefreshDuration);
+}
+
 int Surface::connect(int api) {
     static sp<IProducerListener> listener = new DummyProducerListener();
     return connect(api, listener);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 58b2a87..3346a83 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -149,6 +149,8 @@
             uint32_t w, uint32_t h);
     status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
             uint32_t z);
+    status_t setLayerInfo(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+            uint32_t type, uint32_t appid);
     status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
             uint32_t flags, uint32_t mask);
     status_t setTransparentRegionHint(
@@ -335,6 +337,18 @@
     return NO_ERROR;
 }
 
+status_t Composer::setLayerInfo(const sp<SurfaceComposerClient>& client,
+        const sp<IBinder>& id, uint32_t type, uint32_t appid) {
+    Mutex::Autolock _l(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s)
+        return BAD_INDEX;
+    s->what |= layer_state_t::eLayerInfoChanged;
+    s->type = type;
+    s->appid = appid;
+    return NO_ERROR;
+}
+
 status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id, uint32_t flags,
         uint32_t mask) {
@@ -704,6 +718,10 @@
     return getComposer().setLayer(this, id, z);
 }
 
+status_t SurfaceComposerClient::setLayerInfo(const sp<IBinder>& id, uint32_t type, uint32_t appid) {
+    return getComposer().setLayerInfo(this, id, type, appid);
+}
+
 status_t SurfaceComposerClient::hide(const sp<IBinder>& id) {
     return getComposer().setFlags(this, id,
             layer_state_t::eLayerHidden,
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 33c1d90..b47e434 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -107,6 +107,11 @@
     if (err < 0) return err;
     return mClient->setLayer(mHandle, layer);
 }
+status_t SurfaceControl::setLayerInfo(uint32_t type, uint32_t appid) {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->setLayerInfo(mHandle, type, appid);
+}
 status_t SurfaceControl::setPosition(float x, float y) {
     status_t err = validate();
     if (err < 0) return err;
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 98c0449..91ce531 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -1076,4 +1076,45 @@
     }
 }
 
+TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
+    createBufferQueue();
+    sp<DummyConsumer> dc(new DummyConsumer);
+    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
+    IGraphicBufferProducer::QueueBufferOutput output;
+    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
+            NATIVE_WINDOW_API_CPU, true, &output));
+    ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
+
+    int slot = BufferQueue::INVALID_BUFFER_SLOT;
+    sp<Fence> fence = Fence::NO_FENCE;
+    sp<GraphicBuffer> buffer = nullptr;
+    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
+        HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
+        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
+    BufferItem item{};
+
+    // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
+    // BUFFER_NEEDS_REALLOCATION below
+    int slots[2] = {};
+    ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
+    for (size_t i = 0; i < 2; ++i) {
+        status_t result = mProducer->dequeueBuffer(&slots[i], &fence,
+                0, 0, 0, 0, nullptr);
+        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+        ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
+    }
+    for (size_t i = 0; i < 2; ++i) {
+        ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
+    }
+
+    // Fill 2 buffers without consumer consuming them. Verify that all
+    // queued buffer returns proper bufferReplaced flag
+    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
+    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
+    ASSERT_EQ(false, output.bufferReplaced);
+    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
+    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
+    ASSERT_EQ(true, output.bufferReplaced);
+}
+
 } // namespace android
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 41ad918..de0321d 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -491,6 +491,11 @@
 }
 
 int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
+
+    if (!isDirectReportSupported()) {
+        return INVALID_OPERATION;
+    }
+
     Mutex::Autolock _l(mLock);
 
     int32_t channelHandle = mSensorDevice->register_direct_channel(
@@ -506,6 +511,11 @@
 
 int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle,
         const struct sensors_direct_cfg_t *config) {
+
+    if (!isDirectReportSupported()) {
+        return INVALID_OPERATION;
+    }
+
     Mutex::Autolock _l(mLock);
 
     int32_t ret = mSensorDevice->config_direct_report(
@@ -513,6 +523,12 @@
     ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret);
     return ret;
 }
+
+bool SensorDevice::isDirectReportSupported() const {
+    bool ret = mSensorDevice->register_direct_channel != nullptr
+            && mSensorDevice->config_direct_report != nullptr;
+    return ret;
+}
 // ---------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index b6886a2..7dd256a 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -59,6 +59,7 @@
     status_t flush(void* ident, int handle);
     status_t setMode(uint32_t mode);
 
+    bool isDirectReportSupported() const;
     int32_t registerDirectChannel(const sensors_direct_mem_t *memory);
     void unregisterDirectChannel(int32_t channelHandle);
     int32_t configureDirectChannel(int32_t sensorHandle,
@@ -147,6 +148,8 @@
             const hardware::hidl_vec<Event> &src,
             const hardware::hidl_vec<SensorInfo> &dynamicSensorsAdded,
             sensors_event_t *dst);
+
+    bool mIsDirectReportSupported;
 #endif  // ENABLE_TREBLE
 };
 
diff --git a/services/sensorservice/SensorDeviceTreble.cpp b/services/sensorservice/SensorDeviceTreble.cpp
index 0a75400..3edd50b 100644
--- a/services/sensorservice/SensorDeviceTreble.cpp
+++ b/services/sensorservice/SensorDeviceTreble.cpp
@@ -77,6 +77,9 @@
                     mSensors->activate(list[i].sensorHandle, 0 /* enabled */);
                 }
             });
+
+    mIsDirectReportSupported =
+           (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION);
 }
 
 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
@@ -581,6 +584,10 @@
     return ret;
 }
 
+bool SensorDevice::isDirectReportSupported() const {
+    return mIsDirectReportSupported;
+}
+
 void SensorDevice::convertToSensorEvent(
         const Event &src, sensors_event_t *dst) {
     ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 72f6a7e..b388448 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -139,6 +139,7 @@
     mCurrentState.flags = layerFlags;
     mCurrentState.sequence = 0;
     mCurrentState.requested = mCurrentState.active;
+    mCurrentState.dataSpace = HAL_DATASPACE_UNKNOWN;
 
     // drawing state & current state are identical
     mDrawingState = mCurrentState;
@@ -751,6 +752,14 @@
         setCompositionType(hwcId, HWC2::Composition::Device);
     }
 
+    ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
+    error = hwcLayer->setDataspace(mCurrentState.dataSpace);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(),
+              mCurrentState.dataSpace, to_string(error).c_str(),
+              static_cast<int32_t>(error));
+    }
+
     auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
     error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
     if (error != HWC2::Error::None) {
@@ -1680,6 +1689,16 @@
     return true;
 }
 
+bool Layer::setDataSpace(android_dataspace dataSpace) {
+    if (mCurrentState.dataSpace == dataSpace)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.dataSpace = dataSpace;
+    mCurrentState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+
 void Layer::deferTransactionUntil(const sp<IBinder>& handle,
         uint64_t frameNumber) {
     mCurrentState.handle = handle;
@@ -1993,6 +2012,8 @@
         recomputeVisibleRegions = true;
      }
 
+    setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace());
+
     Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
     const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
     const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 92d2292..1654a51 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -139,6 +139,7 @@
         // dependent.
         Region activeTransparentRegion;
         Region requestedTransparentRegion;
+        android_dataspace dataSpace;
     };
 
     // -----------------------------------------------------------------------
@@ -166,6 +167,7 @@
     bool setCrop(const Rect& crop, bool immediate);
     bool setFinalCrop(const Rect& crop);
     bool setLayerStack(uint32_t layerStack);
+    bool setDataSpace(android_dataspace dataSpace);
     void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
     bool setOverrideScalingMode(int32_t overrideScalingMode);
 
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 243ea69..08eee37 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -196,11 +196,22 @@
           num_images(num_images_),
           frame_timestamps_enabled(false) {
         timing.clear();
+        ANativeWindow* window = surface.window.get();
+        int64_t min_rdur;
+        int64_t max_rdur;
+        native_window_get_refresh_cycle_period(
+            window,
+            &min_rdur,
+            &max_rdur);
+        min_refresh_duration = static_cast<uint64_t>(min_rdur);
+        max_refresh_duration = static_cast<uint64_t>(max_rdur);
     }
 
     Surface& surface;
     uint32_t num_images;
     bool frame_timestamps_enabled;
+    uint64_t min_refresh_duration;
+    uint64_t max_refresh_duration;
 
     struct Image {
         Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {}
@@ -345,9 +356,7 @@
                                 // timestamps to calculate the info that should
                                 // be reported to the user:
                                 //
-                                // FIXME: GET ACTUAL VALUE RATHER THAN HARD-CODE
-                                // IT:
-                                ti->calculate(16666666);
+                                ti->calculate(swapchain.min_refresh_duration);
                                 num_ready++;
                             }
                             break;
@@ -1274,13 +1283,13 @@
 VKAPI_ATTR
 VkResult GetRefreshCycleDurationGOOGLE(
     VkDevice,
-    VkSwapchainKHR,
+    VkSwapchainKHR swapchain_handle,
     VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
+    Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
     VkResult result = VK_SUCCESS;
 
-    // TODO(ianelliott): FULLY IMPLEMENT THIS FUNCTION!!!
-    pDisplayTimingProperties->minRefreshDuration = 16666666;
-    pDisplayTimingProperties->maxRefreshDuration = 16666666;
+    pDisplayTimingProperties->minRefreshDuration = swapchain.min_refresh_duration;
+    pDisplayTimingProperties->maxRefreshDuration = swapchain.max_refresh_duration;
 
     return result;
 }