Merge "Add blindScan condition to blindScan test"
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 6490d99..c011f73 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -32,11 +32,27 @@
     srcs: [
         "VtsHalGraphicsComposer3_TargetTest.cpp",
         "composer-vts/GraphicsComposerCallback.cpp",
+        "composer-vts/TestCommandReader.cpp",
     ],
 
     shared_libs: [
         "libbinder_ndk",
         "libbinder",
+        "libfmq",
+        "libbase",
+        "libsync",
+        "libui",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
+        "libvndksupport",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
@@ -44,9 +60,19 @@
         "android.hardware.graphics.common@1.2",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
+        "android.hardware.graphics.allocator@4.0",
         "android.hardware.graphics.composer@3-vts",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@2.1-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+        "libaidlcommonsupport",
     ],
-
+    cflags: [
+        "-Wconversion",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index fab7fbc..9ea837e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1,13 +1,23 @@
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/command-buffer.h>
 #include <binder/ProcessState.h>
-#include <composer-vts/include/GraphicsComposerCallback.h>
 #include <gtest/gtest.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
 #include <algorithm>
 #include <numeric>
 #include <regex>
@@ -16,8 +26,12 @@
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
+#include "composer-vts/include/GraphicsComposerCallback.h"
+#include "composer-vts/include/TestCommandReader.h"
 
-#pragma push_macro("LOG_TAG")
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 #undef LOG_TAG
 #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
 
@@ -33,6 +47,12 @@
 
     int64_t get() const { return mDisplayId; }
 
+    FRect getCrop() const {
+        return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
+    }
+
+    Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+
     void setDimensions(int32_t displayWidth, int32_t displayHeight) {
         mDisplayWidth = displayWidth;
         mDisplayHeight = displayHeight;
@@ -60,10 +80,30 @@
 
         // assume the first displays are built-in and are never removed
         mDisplays = waitForDisplays();
+
+        // explicitly disable vsync
+        for (const auto& display : mDisplays) {
+            EXPECT_TRUE(mComposerClient->setVsyncEnabled(display.get(), false).isOk());
+        }
+        mComposerCallback->setVsyncAllowed(false);
+
+        mWriter = std::make_unique<CommandWriterBase>(1024);
+        mReader = std::make_unique<TestCommandReader>();
     }
 
-    // use the slot count usually set by SF
-    static constexpr uint32_t kBufferSlotCount = 64;
+    void TearDown() override {
+        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncPeriodChangeCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidSeamlessPossibleCount());
+        }
+    }
 
     // returns an invalid display id (one that has not been registered to a
     // display.  Currently assuming that a device will never have close to
@@ -168,6 +208,282 @@
         }
     }
 
+    void execute() {
+        TestCommandReader* reader = mReader.get();
+        CommandWriterBase* writer = mWriter.get();
+        bool queueChanged = false;
+        int32_t commandLength = 0;
+        std::vector<NativeHandle> commandHandles;
+        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+        if (queueChanged) {
+            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
+            ASSERT_TRUE(ret.isOk());
+        }
+
+        ExecuteCommandsStatus commandStatus;
+        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
+                            .isOk());
+
+        if (commandStatus.queueChanged) {
+            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
+            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
+            reader->setMQDescriptor(outputCommandQueue);
+        }
+        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
+        reader->parse();
+        reader->reset();
+        writer->reset();
+    }
+
+    ::android::sp<::android::GraphicBuffer> allocate(uint32_t width, uint32_t height) {
+        ::android::sp<::android::GraphicBuffer> buffer =
+                ::android::sp<::android::GraphicBuffer>::make(
+                        width, height, ::android::PIXEL_FORMAT_RGBA_8888,
+                        /*layerCount*/ 1,
+                        static_cast<uint64_t>(
+                                static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                                static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
+                        "VtsHalGraphicsComposer3_TargetTest");
+
+        return buffer;
+    }
+
+    struct TestParameters {
+        nsecs_t delayForChange;
+        bool refreshMiss;
+    };
+
+    static inline auto toTimePoint(nsecs_t time) {
+        return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
+    }
+
+    int64_t createLayer(const VtsDisplay& display) {
+        int64_t layer;
+        EXPECT_TRUE(mComposerClient->createLayer(display.get(), kBufferSlotCount, &layer).isOk());
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        if (resourceIt == mDisplayResources.end()) {
+            resourceIt = mDisplayResources.insert({display.get(), DisplayResource(false)}).first;
+        }
+
+        EXPECT_TRUE(resourceIt->second.layers.insert(layer).second)
+                << "duplicated layer id " << layer;
+
+        return layer;
+    }
+
+    void destroyLayer(const VtsDisplay& display, int64_t layer) {
+        auto const error = mComposerClient->destroyLayer(display.get(), layer);
+        ASSERT_TRUE(error.isOk()) << "failed to destroy layer " << layer;
+
+        auto resourceIt = mDisplayResources.find(display.get());
+        ASSERT_NE(mDisplayResources.end(), resourceIt);
+        resourceIt->second.layers.erase(layer);
+    }
+
+    void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
+        std::vector<int32_t> displayConfigs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display, &displayConfigs).isOk());
+        for (const int32_t config1 : displayConfigs) {
+            for (const int32_t config2 : displayConfigs) {
+                if (config1 != config2) {
+                    func(config1, config2);
+                }
+            }
+        }
+    }
+
+    void setActiveConfig(VtsDisplay& display, int32_t config) {
+        EXPECT_TRUE(mComposerClient->setActiveConfig(display.get(), config).isOk());
+        int32_t displayWidth;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH,
+                                                  &displayWidth)
+                            .isOk());
+        int32_t displayHeight;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT,
+                                                  &displayHeight)
+                            .isOk());
+        display.setDimensions(displayWidth, displayHeight);
+    }
+
+    void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
+        if (timeline != nullptr) {
+            // Refresh time should be before newVsyncAppliedTimeNanos
+            EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
+
+            std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
+        }
+
+        mWriter->selectDisplay(display.get());
+        setPowerMode(display.get(), PowerMode::ON);
+        EXPECT_TRUE(
+                mComposerClient
+                        ->setColorMode(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC)
+                        .isOk());
+
+        FRect displayCrop = display.getCrop();
+        auto displayWidth = static_cast<uint32_t>(std::ceilf(displayCrop.right - displayCrop.left));
+        auto displayHeight =
+                static_cast<uint32_t>(std::ceilf(displayCrop.bottom - displayCrop.top));
+        int64_t layer = 0;
+        ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
+        {
+            auto buffer = allocate(displayWidth, displayHeight);
+            ASSERT_NE(nullptr, buffer);
+            ASSERT_EQ(::android::OK, buffer->initCheck());
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter->selectLayer(layer);
+            mWriter->setLayerCompositionType(Composition::DEVICE);
+            mWriter->setLayerDisplayFrame(display.getFrameRect());
+            mWriter->setLayerPlaneAlpha(1);
+            mWriter->setLayerSourceCrop(display.getCrop());
+            mWriter->setLayerTransform(static_cast<Transform>(0));
+            mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
+            mWriter->setLayerZOrder(10);
+            mWriter->setLayerBlendMode(BlendMode::NONE);
+            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
+            mWriter->setLayerBuffer(0, buffer->handle, -1);
+            mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+
+            mWriter->validateDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+            mReader->mCompositionChanges.clear();
+
+            mWriter->presentDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+        }
+
+        {
+            auto buffer = allocate(displayWidth, displayHeight);
+            ASSERT_NE(nullptr, buffer->handle);
+
+            mWriter->selectLayer(layer);
+            mWriter->setLayerBuffer(0, buffer->handle, -1);
+            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
+            mWriter->validateDisplay();
+            execute();
+            ASSERT_EQ(0, mReader->mErrors.size());
+            mReader->mCompositionChanges.clear();
+
+            mWriter->presentDisplay();
+            execute();
+        }
+
+        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
+    }
+
+    void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
+                                  int64_t desiredTimeNanos, int64_t oldPeriodNanos,
+                                  int64_t newPeriodNanos) {
+        const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
+        while (std::chrono::steady_clock::now() <= kChangeDeadline) {
+            int32_t vsyncPeriodNanos;
+            EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos).isOk());
+            if (systemTime() <= desiredTimeNanos) {
+                EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
+            } else if (vsyncPeriodNanos == newPeriodNanos) {
+                break;
+            }
+            std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
+        }
+    }
+
+    void Test_setActiveConfigWithConstraints(const TestParameters& params) {
+        for (VtsDisplay& display : mDisplays) {
+            forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+
+                int32_t vsyncPeriod1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod1)
+                                    .isOk());
+                int32_t configGroup1;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config1,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup1)
+                                    .isOk());
+                int32_t vsyncPeriod2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::VSYNC_PERIOD,
+                                                          &vsyncPeriod2)
+                                    .isOk());
+                int32_t configGroup2;
+                EXPECT_TRUE(mComposerClient
+                                    ->getDisplayAttribute(display.get(), config2,
+                                                          DisplayAttribute::CONFIG_GROUP,
+                                                          &configGroup2)
+                                    .isOk());
+
+                if (vsyncPeriod1 == vsyncPeriod2) {
+                    return;  // continue
+                }
+
+                // We don't allow delayed change when changing config groups
+                if (params.delayForChange > 0 && configGroup1 != configGroup2) {
+                    return;  // continue
+                }
+
+                VsyncPeriodChangeTimeline timeline;
+                VsyncPeriodChangeConstraints constraints = {
+                        .desiredTimeNanos = systemTime() + params.delayForChange,
+                        .seamlessRequired = false};
+                EXPECT_TRUE(setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                    .isOk());
+
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+                // Refresh rate should change within a reasonable time
+                constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s;  // 1 second
+                EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+                            kReasonableTimeForChange.count());
+
+                if (timeline.refreshRequired) {
+                    if (params.refreshMiss) {
+                        // Miss the refresh frame on purpose to make sure the implementation sends a
+                        // callback
+                        std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
+                                                      100ms);
+                    }
+                    sendRefreshFrame(display, &timeline);
+                }
+                waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
+                                         vsyncPeriod1, vsyncPeriod2);
+
+                // At this point the refresh rate should have changed already, however in rare
+                // cases the implementation might have missed the deadline. In this case a new
+                // timeline should have been provided.
+                auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+                if (timeline.refreshRequired && params.refreshMiss) {
+                    EXPECT_TRUE(newTimeline.has_value());
+                }
+
+                if (newTimeline.has_value()) {
+                    if (newTimeline->refreshRequired) {
+                        sendRefreshFrame(display, &newTimeline.value());
+                    }
+                    waitForVsyncPeriodChange(display.get(), newTimeline.value(),
+                                             constraints.desiredTimeNanos, vsyncPeriod1,
+                                             vsyncPeriod2);
+                }
+
+                int32_t vsyncPeriodNanos;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
+            });
+        }
+    }
+
     void setPowerMode(int64_t display, PowerMode powerMode) {
         ::ndk::ScopedAStatus error = mComposerClient->setPowerMode(display, powerMode);
         ASSERT_TRUE(error.isOk() ||
@@ -181,7 +497,7 @@
         DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
 
         bool isVirtual;
-        std::unordered_set<int32_t> layers;
+        std::unordered_set<int64_t> layers;
     };
 
     std::shared_ptr<IComposer> mComposer;
@@ -190,6 +506,10 @@
     int64_t mPrimaryDisplay;
     std::vector<VtsDisplay> mDisplays;
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+    std::unique_ptr<CommandWriterBase> mWriter;
+    std::unique_ptr<TestCommandReader> mReader;
+    // use the slot count usually set by SF
+    static constexpr uint32_t kBufferSlotCount = 64;
     std::unordered_map<int64_t, DisplayResource> mDisplayResources;
 };
 
@@ -209,6 +529,94 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod) {
+    for (VtsDisplay& display : mDisplays) {
+        std::vector<int32_t> configs;
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+        for (int32_t config : configs) {
+            int32_t expectedVsyncPeriodNanos = -1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config,
+                                                      DisplayAttribute::VSYNC_PERIOD,
+                                                      &expectedVsyncPeriodNanos)
+                                .isOk());
+
+            VsyncPeriodChangeTimeline timeline;
+            VsyncPeriodChangeConstraints constraints;
+
+            constraints.desiredTimeNanos = systemTime();
+            constraints.seamlessRequired = false;
+            EXPECT_TRUE(mComposerClient
+                                ->setActiveConfigWithConstraints(display.get(), config, constraints,
+                                                                 &timeline)
+                                .isOk());
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(display, &timeline);
+            }
+            waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
+                                     expectedVsyncPeriodNanos);
+
+            int32_t vsyncPeriodNanos;
+            int retryCount = 100;
+            do {
+                std::this_thread::sleep_for(10ms);
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                --retryCount;
+            } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
+
+            EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+            // Make sure that the vsync period stays the same if the active config is not
+            // changed.
+            auto timeout = 1ms;
+            for (int i = 0; i < 10; i++) {
+                std::this_thread::sleep_for(timeout);
+                timeout *= 2;
+                vsyncPeriodNanos = 0;
+                EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+                                    .isOk());
+                EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+    VsyncPeriodChangeTimeline timeline;
+    VsyncPeriodChangeConstraints constraints;
+
+    constraints.seamlessRequired = true;
+    constraints.desiredTimeNanos = systemTime();
+
+    for (VtsDisplay& display : mDisplays) {
+        forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+            int32_t configGroup1;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config1,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup1)
+                                .isOk());
+            int32_t configGroup2;
+            EXPECT_TRUE(mComposerClient
+                                ->getDisplayAttribute(display.get(), config2,
+                                                      DisplayAttribute::CONFIG_GROUP, &configGroup2)
+                                .isOk());
+            if (configGroup1 != configGroup2) {
+                setActiveConfig(display, config1);
+                sendRefreshFrame(display, nullptr);
+                EXPECT_EQ(IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
+                          setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+                                  .getServiceSpecificError());
+            }
+        });
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints) {
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
+}
 TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
     DisplayIdentification displayIdentification0;
 
@@ -423,9 +831,9 @@
                                                                 &displayContentSamplingAttributes)
                         .isOk());
 
-    uint64_t maxFrames = 10;
-    uint64_t timestamp = 0;
-    uint64_t frameCount = 0;
+    int64_t maxFrames = 10;
+    int64_t timestamp = 0;
+    int64_t frameCount = 0;
     DisplayContentSample displayContentSample;
     auto error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
                                                             &displayContentSample);
@@ -440,12 +848,10 @@
             displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
             displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
 
-    for (auto i = 0; i < histogram.size(); i++) {
-        if (static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i)) {
-            EXPECT_NE(histogram[i].size(), 0);
-        } else {
-            EXPECT_EQ(histogram[i].size(), 0);
-        }
+    for (size_t i = 0; i < histogram.size(); i++) {
+        const bool shouldHaveHistogram =
+                static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
+        EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
     }
 }
 
@@ -510,7 +916,7 @@
 TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) {
     for (const auto& display : mDisplays) {
         std::vector<int32_t> configs;
-        mComposerClient->getDisplayConfigs(display.get(), &configs);
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
         for (const auto& config : configs) {
             const std::array<DisplayAttribute, 4> requiredAttributes = {{
                     DisplayAttribute::WIDTH,
@@ -546,7 +952,7 @@
 TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) {
     for (const auto& display : mDisplays) {
         std::vector<int32_t> configs;
-        mComposerClient->getDisplayConfigs(display.get(), &configs);
+        EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
 
         EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
             return config == IComposerClient::INVALID_CONFIGURATION;
@@ -748,7 +1154,7 @@
     std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
     std::unordered_set<std::string> uniqueNames;
     for (const auto& key : keys) {
-        std::string name(key.name.c_str());
+        std::string name(key.name);
 
         // Keys must not start with 'android' or 'com.android'
         EXPECT_FALSE(name.find("android") == 0);
@@ -862,7 +1268,7 @@
 
 TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
     bool isDozeSupported = false;
-    mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported);
+    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
     if (!isDozeSupported) {
         auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
         EXPECT_FALSE(error.isOk());
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index bb5f3f1..00ea4f3 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,17 +28,38 @@
     defaults: ["hidl_defaults"],
     srcs: [
         "GraphicsComposerCallback.cpp",
+        "TestCommandReader.cpp",
+    ],
+    header_libs: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "libgtest",
         "libbase",
+        "libfmq",
+        "libsync",
+        "libaidlcommonsupport",
+        "android.hardware.graphics.mapper@2.0-vts",
+        "android.hardware.graphics.mapper@3.0-vts",
+        "android.hardware.graphics.mapper@4.0-vts",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libhidlbase",
+        "android.hardware.graphics.composer3-V1-ndk",
     ],
     cflags: [
         "-O0",
         "-g",
         "-DLOG_TAG=\"ComposerVts\"",
+        "-Wconversion",
+    ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer3-command-buffer",
     ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
new file mode 100644
index 0000000..0346686
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 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.
+ */
+
+#include "include/TestCommandReader.h"
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+void TestCommandReader::parse() {
+    mErrors.clear();
+    mCompositionChanges.clear();
+    while (!isEmpty()) {
+        int32_t command;
+        uint16_t length;
+        ASSERT_TRUE(beginCommand(&command, &length));
+
+        parseSingleCommand(command, length);
+
+        endCommand();
+    }
+}
+
+void TestCommandReader::parseSingleCommand(int32_t commandRaw, uint16_t length) {
+    auto command = static_cast<Command>(commandRaw);
+
+    switch (command) {
+        case Command::SET_CLIENT_TARGET_PROPERTY:
+            ASSERT_EQ(2, length);
+            read();
+            close(readFence());
+            break;
+        case Command::SELECT_DISPLAY:
+            ASSERT_EQ(2, length);
+            read64();  // display
+            break;
+        case Command::SET_ERROR: {
+            ASSERT_EQ(2, length);
+            auto loc = read();
+            auto err = readSigned();
+            std::pair<uint32_t, uint32_t> error(loc, err);
+            mErrors.push_back(error);
+        } break;
+        case Command::SET_CHANGED_COMPOSITION_TYPES:
+            ASSERT_EQ(0, length % 3);
+            for (uint16_t count = 0; count < length / 3; ++count) {
+                uint64_t layerId = read64();
+                uint32_t composition = read();
+
+                std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
+                mCompositionChanges.push_back(compositionChange);
+            }
+            break;
+        case Command::SET_DISPLAY_REQUESTS:
+            ASSERT_EQ(1, length % 3);
+            read();  // displayRequests, ignored for now
+            for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
+                read64();  // layer
+                // silently eat requests to clear the client target, since we won't be testing
+                // client composition anyway
+                ASSERT_EQ(1u, read());
+            }
+            break;
+        case Command::SET_PRESENT_FENCE:
+            ASSERT_EQ(1, length);
+            close(readFence());
+            break;
+        case Command::SET_RELEASE_FENCES:
+            ASSERT_EQ(0, length % 3);
+            for (uint16_t count = 0; count < length / 3; ++count) {
+                read64();
+                close(readFence());
+            }
+            break;
+        default:
+            GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
+            break;
+    }
+}
+}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
index 9afc72f..02e5151 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
@@ -15,12 +15,18 @@
  */
 #pragma once
 
-#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
 
+#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
 #include <android-base/thread_annotations.h>
 #include <mutex>
 #include <unordered_set>
 
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
 namespace aidl::android::hardware::graphics::composer3::vts {
 
 // IComposerCallback to be installed with IComposerClient::registerCallback.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
new file mode 100644
index 0000000..852a56e
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 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.
+ */
+#pragma once
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <android/hardware/graphics/composer3/command-buffer.h>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop  // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+class TestCommandReader : public CommandReaderBase {
+  public:
+    virtual ~TestCommandReader() = default;
+
+    std::vector<std::pair<uint32_t, uint32_t>> mErrors;
+    std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
+
+    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
+    // unexpected errors or commands.
+    void parse();
+    virtual void parseSingleCommand(int32_t commandRaw, uint16_t length);
+};
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 812e64a..e1d1982 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -60,6 +60,8 @@
     battery_monitor_.init(healthd_config_.get());
 }
 
+Health::~Health() {}
+
 //
 // Getters.
 //
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index e49f44c..6bd4946 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -43,6 +43,7 @@
     // A subclass may modify |config| before passing it to the parent constructor.
     // See implementation of Health for code samples.
     Health(std::string_view instance_name, std::unique_ptr<struct healthd_config>&& config);
+    virtual ~Health();
 
     ndk::ScopedAStatus registerCallback(
             const std::shared_ptr<IHealthInfoCallback>& callback) override;
diff --git a/neuralnetworks/1.0/utils/OWNERS b/neuralnetworks/1.0/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.0/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.0/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.0/vts/functional/OWNERS b/neuralnetworks/1.0/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.1/utils/OWNERS b/neuralnetworks/1.1/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.1/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.1/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.1/vts/functional/OWNERS b/neuralnetworks/1.1/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.2/utils/OWNERS b/neuralnetworks/1.2/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.2/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.2/vts/OWNERS b/neuralnetworks/1.2/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.2/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.2/vts/functional/OWNERS b/neuralnetworks/1.2/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/1.3/utils/OWNERS b/neuralnetworks/1.3/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/1.3/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/1.3/vts/OWNERS b/neuralnetworks/1.3/vts/OWNERS
deleted file mode 100644
index b5a8e1f..0000000
--- a/neuralnetworks/1.3/vts/OWNERS
+++ /dev/null
@@ -1,16 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-mikie@google.com
-mks@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
-
-# VTS team
-yim@google.com
-yuexima@google.com
diff --git a/neuralnetworks/1.3/vts/functional/OWNERS b/neuralnetworks/1.3/vts/functional/OWNERS
deleted file mode 100644
index a48301d..0000000
--- a/neuralnetworks/1.3/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 195575
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
diff --git a/neuralnetworks/aidl/vts/OWNERS b/neuralnetworks/OWNERS
similarity index 78%
rename from neuralnetworks/aidl/vts/OWNERS
rename to neuralnetworks/OWNERS
index f1a757a..def3ea9 100644
--- a/neuralnetworks/aidl/vts/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,9 +1,10 @@
+# Bug component: 195575
 # Neuralnetworks team
 butlermichael@google.com
 dgross@google.com
+galarragas@google.com
+ianhua@google.com
 jeanluc@google.com
 miaowang@google.com
-mikie@google.com
 pszczepaniak@google.com
 xusongw@google.com
-ianhua@google.com
diff --git a/neuralnetworks/README b/neuralnetworks/README
index d8c8f5d..b0c605d 100644
--- a/neuralnetworks/README
+++ b/neuralnetworks/README
@@ -1,2 +1,2 @@
 NeuralNetworks sample driver implementation is located at
-frameworks/ml/nn/driver/sample.
+packages/modules/NeuralNetworks/driver/sample*.
diff --git a/neuralnetworks/aidl/utils/OWNERS b/neuralnetworks/aidl/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/aidl/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/neuralnetworks/utils/OWNERS b/neuralnetworks/utils/OWNERS
deleted file mode 100644
index e4feee3..0000000
--- a/neuralnetworks/utils/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-jeanluc@google.com
-levp@google.com
-miaowang@google.com
-pszczepaniak@google.com
-slavash@google.com
-vddang@google.com
-xusongw@google.com
diff --git a/sensors/common/utils/convertV2_1.h b/sensors/common/utils/convertV2_1.h
index 9231011..00359043 100644
--- a/sensors/common/utils/convertV2_1.h
+++ b/sensors/common/utils/convertV2_1.h
@@ -77,6 +77,25 @@
     return reinterpret_cast<const hidl_vec<V1_0::SensorInfo>&>(infos);
 }
 
+inline void convertToSensor(const V2_1::SensorInfo& src, sensor_t* dst) {
+    dst->name = strdup(src.name.c_str());
+    dst->vendor = strdup(src.vendor.c_str());
+    dst->version = src.version;
+    dst->handle = src.sensorHandle;
+    dst->type = (int)src.type;
+    dst->maxRange = src.maxRange;
+    dst->resolution = src.resolution;
+    dst->power = src.power;
+    dst->minDelay = src.minDelay;
+    dst->fifoReservedEventCount = src.fifoReservedEventCount;
+    dst->fifoMaxEventCount = src.fifoMaxEventCount;
+    dst->stringType = strdup(src.typeAsString.c_str());
+    dst->requiredPermission = strdup(src.requiredPermission.c_str());
+    dst->maxDelay = src.maxDelay;
+    dst->flags = src.flags;
+    dst->reserved[0] = dst->reserved[1] = 0;
+}
+
 inline void convertFromSensorEvent(const sensors_event_t& src, V2_1::Event* dst) {
     switch ((SensorType)src.type) {
         case SensorType::HINGE_ANGLE:
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
index 5d5b943..2b1b379 100644
--- a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     task_profiles ProcessCapacityHigh
+    onrestart restart media.tuner
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
index 3718a93..62ee520 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
@@ -3,4 +3,5 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
index fa09456..d0248c2 100644
--- a/tv/tuner/aidl/default/tuner-default.rc
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -4,3 +4,4 @@
     group mediadrm drmrpc
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks
+    onrestart restart media.tuner