Merge "Associate touch video devices with input devices"
diff --git a/cmds/lshal/OWNERS b/cmds/lshal/OWNERS
new file mode 100644
index 0000000..60038da
--- /dev/null
+++ b/cmds/lshal/OWNERS
@@ -0,0 +1,2 @@
+elsk@google.com
+smoreland@google.com
diff --git a/include/input/Input.h b/include/input/Input.h
index ee22bc6..037270c 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -681,7 +681,7 @@
  */
 class PooledInputEventFactory : public InputEventFactoryInterface {
 public:
-    PooledInputEventFactory(size_t maxPoolSize = 20);
+    explicit PooledInputEventFactory(size_t maxPoolSize = 20);
     virtual ~PooledInputEventFactory();
 
     virtual KeyEvent* createKeyEvent();
diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
index 9f4559f..a1a32a6 100644
--- a/include/input/KeyCharacterMap.h
+++ b/include/input/KeyCharacterMap.h
@@ -195,7 +195,7 @@
         };
 
         struct Property {
-            inline Property(int32_t property = 0, int32_t metaState = 0) :
+            inline explicit Property(int32_t property = 0, int32_t metaState = 0) :
                     property(property), metaState(metaState) { }
 
             int32_t property;
diff --git a/libs/input/tests/TestHelpers.h b/libs/input/tests/TestHelpers.h
index fe87bb9..343d81f 100644
--- a/libs/input/tests/TestHelpers.h
+++ b/libs/input/tests/TestHelpers.h
@@ -62,7 +62,7 @@
     int mDelayMillis;
 
 public:
-    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
+    explicit DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
 
 protected:
     virtual ~DelayedTask() { }
diff --git a/libs/renderengine/gl/ProgramCache.cpp b/libs/renderengine/gl/ProgramCache.cpp
index bf2354d..49bdd2a 100644
--- a/libs/renderengine/gl/ProgramCache.cpp
+++ b/libs/renderengine/gl/ProgramCache.cpp
@@ -151,7 +151,8 @@
     needs.set(Key::Y410_BT2020_MASK,
               description.isY410BT2020 ? Key::Y410_BT2020_ON : Key::Y410_BT2020_OFF);
 
-    if (needs.hasTransformMatrix() || (needs.getInputTF() != needs.getOutputTF())) {
+    if (needs.hasTransformMatrix() ||
+        (description.inputTransferFunction != description.outputTransferFunction)) {
         switch (description.inputTransferFunction) {
             case Description::TransferFunction::LINEAR:
             default:
diff --git a/opengl/OWNERS b/opengl/OWNERS
new file mode 100644
index 0000000..881f1b8
--- /dev/null
+++ b/opengl/OWNERS
@@ -0,0 +1,16 @@
+# alanward@google.com
+chiur@google.com
+chrisforbes@google.com
+cnorthrop@google.com
+courtneygo@google.com
+hliatis@google.com
+ianelliott@google.com
+jessehall@google.com
+lpy@google.com
+marissaw@google.com
+nduca@google.com
+pmuetschard@google.com
+timvp@google.com
+tobine@google.com
+vhau@google.com
+zzyiwei@google.com
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 8091b94..0e46928 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -26,6 +26,8 @@
 #include <private/gui/SyncFeatures.h>
 #include <renderengine/Image.h>
 
+#include <limits>
+
 namespace android {
 
 // clang-format off
@@ -347,6 +349,22 @@
 
     if (s.crop.isEmpty() && s.buffer) {
         return s.buffer->getBounds();
+    } else if (s.buffer) {
+        Rect crop = s.crop;
+        crop.left = std::max(crop.left, 0);
+        crop.top = std::max(crop.top, 0);
+        uint32_t bufferWidth = s.buffer->getWidth();
+        uint32_t bufferHeight = s.buffer->getHeight();
+        if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
+            bufferWidth <= std::numeric_limits<int32_t>::max()) {
+            crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
+            crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
+        }
+        if (!crop.isValid()) {
+            // Crop rect is out of bounds, return whole buffer
+            return s.buffer->getBounds();
+        }
+        return crop;
     }
     return s.crop;
 }
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 1f08f4e..1683982 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -43,6 +43,40 @@
 
 // ---------------------------------------------------------------------------
 
+EventThreadConnection::EventThreadConnection(EventThread* eventThread)
+      : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
+
+EventThreadConnection::~EventThreadConnection() {
+    // do nothing here -- clean-up will happen automatically
+    // when the main thread wakes up
+}
+
+void EventThreadConnection::onFirstRef() {
+    // NOTE: mEventThread doesn't hold a strong reference on us
+    mEventThread->registerDisplayEventConnection(this);
+}
+
+status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
+    outChannel->setReceiveFd(mChannel.moveReceiveFd());
+    return NO_ERROR;
+}
+
+status_t EventThreadConnection::setVsyncRate(uint32_t count) {
+    mEventThread->setVsyncRate(count, this);
+    return NO_ERROR;
+}
+
+void EventThreadConnection::requestNextVsync() {
+    mEventThread->requestNextVsync(this);
+}
+
+status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
+    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
+    return size < 0 ? status_t(size) : status_t(NO_ERROR);
+}
+
+// ---------------------------------------------------------------------------
+
 EventThread::~EventThread() = default;
 
 namespace impl {
@@ -110,12 +144,11 @@
     mVSyncSource->setPhaseOffset(phaseOffset);
 }
 
-sp<BnDisplayEventConnection> EventThread::createEventConnection() const {
-    return new Connection(const_cast<EventThread*>(this));
+sp<EventThreadConnection> EventThread::createEventConnection() const {
+    return new EventThreadConnection(const_cast<EventThread*>(this));
 }
 
-status_t EventThread::registerDisplayEventConnection(
-        const sp<EventThread::Connection>& connection) {
+status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
     std::lock_guard<std::mutex> lock(mMutex);
 
     // this should never happen
@@ -132,8 +165,7 @@
     return NO_ERROR;
 }
 
-void EventThread::removeDisplayEventConnectionLocked(
-        const wp<EventThread::Connection>& connection) {
+void EventThread::removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) {
     auto it = std::find(mDisplayEventConnections.cbegin(),
             mDisplayEventConnections.cend(), connection);
     if (it != mDisplayEventConnections.cend()) {
@@ -141,7 +173,7 @@
     }
 }
 
-void EventThread::setVsyncRate(uint32_t count, const sp<EventThread::Connection>& connection) {
+void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) {
     if (int32_t(count) >= 0) { // server must protect against bad params
         std::lock_guard<std::mutex> lock(mMutex);
         const int32_t new_count = (count == 0) ? -1 : count;
@@ -152,7 +184,7 @@
     }
 }
 
-void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
+void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
     std::lock_guard<std::mutex> lock(mMutex);
     if (mResetIdleTimer) {
         mResetIdleTimer();
@@ -212,11 +244,11 @@
     std::unique_lock<std::mutex> lock(mMutex);
     while (mKeepRunning) {
         DisplayEventReceiver::Event event;
-        std::vector<sp<EventThread::Connection>> signalConnections;
+        std::vector<sp<EventThreadConnection>> signalConnections;
         signalConnections = waitForEventLocked(&lock, &event);
 
         // dispatch events to listeners...
-        for (const sp<Connection>& conn : signalConnections) {
+        for (const sp<EventThreadConnection>& conn : signalConnections) {
             // now see if we still need to report this event
             status_t err = conn->postEvent(event);
             if (err == -EAGAIN || err == -EWOULDBLOCK) {
@@ -239,9 +271,9 @@
 
 // This will return when (1) a vsync event has been received, and (2) there was
 // at least one connection interested in receiving it when we started waiting.
-std::vector<sp<EventThread::Connection>> EventThread::waitForEventLocked(
+std::vector<sp<EventThreadConnection>> EventThread::waitForEventLocked(
         std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* outEvent) {
-    std::vector<sp<EventThread::Connection>> signalConnections;
+    std::vector<sp<EventThreadConnection>> signalConnections;
 
     while (signalConnections.empty() && mKeepRunning) {
         bool eventPending = false;
@@ -276,7 +308,7 @@
         // find out connections waiting for events
         auto it = mDisplayEventConnections.begin();
         while (it != mDisplayEventConnections.end()) {
-            sp<Connection> connection(it->promote());
+            sp<EventThreadConnection> connection(it->promote());
             if (connection != nullptr) {
                 bool added = false;
                 if (connection->count >= 0) {
@@ -399,49 +431,13 @@
     StringAppendF(&result, "  soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
     StringAppendF(&result, "  numListeners=%zu,\n  events-delivered: %u\n",
                   mDisplayEventConnections.size(), mVSyncEvent[0].vsync.count);
-    for (const wp<Connection>& weak : mDisplayEventConnections) {
-        sp<Connection> connection = weak.promote();
+    for (const wp<EventThreadConnection>& weak : mDisplayEventConnections) {
+        sp<EventThreadConnection> connection = weak.promote();
         StringAppendF(&result, "    %p: count=%d\n", connection.get(),
                       connection != nullptr ? connection->count : 0);
     }
     StringAppendF(&result, "  other-events-pending: %zu\n", mPendingEvents.size());
 }
 
-// ---------------------------------------------------------------------------
-
-EventThread::Connection::Connection(EventThread* eventThread)
-      : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
-
-EventThread::Connection::~Connection() {
-    // do nothing here -- clean-up will happen automatically
-    // when the main thread wakes up
-}
-
-void EventThread::Connection::onFirstRef() {
-    // NOTE: mEventThread doesn't hold a strong reference on us
-    mEventThread->registerDisplayEventConnection(this);
-}
-
-status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
-    outChannel->setReceiveFd(mChannel.moveReceiveFd());
-    return NO_ERROR;
-}
-
-status_t EventThread::Connection::setVsyncRate(uint32_t count) {
-    mEventThread->setVsyncRate(count, this);
-    return NO_ERROR;
-}
-
-void EventThread::Connection::requestNextVsync() {
-    mEventThread->requestNextVsync(this);
-}
-
-status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) {
-    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
-    return size < 0 ? status_t(size) : status_t(NO_ERROR);
-}
-
-// ---------------------------------------------------------------------------
-
 } // namespace impl
 } // namespace android
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 0773c05..66f54bd 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -38,6 +38,7 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
+class EventThread;
 class EventThreadTest;
 class SurfaceFlinger;
 
@@ -57,6 +58,28 @@
     virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
 };
 
+class EventThreadConnection : public BnDisplayEventConnection {
+public:
+    explicit EventThreadConnection(EventThread* eventThread);
+    virtual ~EventThreadConnection();
+
+    virtual status_t postEvent(const DisplayEventReceiver::Event& event);
+
+    status_t stealReceiveChannel(gui::BitTube* outChannel) override;
+    status_t setVsyncRate(uint32_t count) override;
+    void requestNextVsync() override; // asynchronous
+
+    // count >= 1 : continuous event. count is the vsync rate
+    // count == 0 : one-shot event that has not fired
+    // count ==-1 : one-shot event that fired this round / disabled
+    int32_t count;
+
+private:
+    virtual void onFirstRef();
+    EventThread* const mEventThread;
+    gui::BitTube mChannel;
+};
+
 class EventThread {
 public:
     // TODO: Remove once stable display IDs are plumbed through SF/WM interface.
@@ -64,7 +87,7 @@
 
     virtual ~EventThread();
 
-    virtual sp<BnDisplayEventConnection> createEventConnection() const = 0;
+    virtual sp<EventThreadConnection> createEventConnection() const = 0;
 
     // called before the screen is turned off from main thread
     virtual void onScreenReleased() = 0;
@@ -78,32 +101,16 @@
     virtual void dump(std::string& result) const = 0;
 
     virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
+
+    virtual status_t registerDisplayEventConnection(
+            const sp<EventThreadConnection>& connection) = 0;
+    virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0;
+    virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
 };
 
 namespace impl {
 
 class EventThread : public android::EventThread, private VSyncSource::Callback {
-    class Connection : public BnDisplayEventConnection {
-    public:
-        explicit Connection(EventThread* eventThread);
-        virtual ~Connection();
-
-        virtual status_t postEvent(const DisplayEventReceiver::Event& event);
-
-        // count >= 1 : continuous event. count is the vsync rate
-        // count == 0 : one-shot event that has not fired
-        // count ==-1 : one-shot event that fired this round / disabled
-        int32_t count;
-
-    private:
-        virtual void onFirstRef();
-        status_t stealReceiveChannel(gui::BitTube* outChannel) override;
-        status_t setVsyncRate(uint32_t count) override;
-        void requestNextVsync() override; // asynchronous
-        EventThread* const mEventThread;
-        gui::BitTube mChannel;
-    };
-
 public:
     using ResyncWithRateLimitCallback = std::function<void()>;
     using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
@@ -118,10 +125,11 @@
                 const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
     ~EventThread();
 
-    sp<BnDisplayEventConnection> createEventConnection() const override;
+    sp<EventThreadConnection> createEventConnection() const override;
 
-    void setVsyncRate(uint32_t count, const sp<Connection>& connection);
-    void requestNextVsync(const sp<Connection>& connection);
+    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
+    void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
+    void requestNextVsync(const sp<EventThreadConnection>& connection) override;
 
     // called before the screen is turned off from main thread
     void onScreenReleased() override;
@@ -144,14 +152,14 @@
                 ResyncWithRateLimitCallback resyncWithRateLimitCallback,
                 InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
 
-    status_t registerDisplayEventConnection(const sp<Connection>& connection);
 
     void threadMain();
-    std::vector<sp<EventThread::Connection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
-                                                                DisplayEventReceiver::Event* event)
+    std::vector<sp<EventThreadConnection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
+                                                              DisplayEventReceiver::Event* event)
             REQUIRES(mMutex);
 
-    void removeDisplayEventConnectionLocked(const wp<Connection>& connection) REQUIRES(mMutex);
+    void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
+            REQUIRES(mMutex);
     void enableVSyncLocked() REQUIRES(mMutex);
     void disableVSyncLocked() REQUIRES(mMutex);
 
@@ -170,7 +178,7 @@
     mutable std::condition_variable mCondition;
 
     // protected by mLock
-    std::vector<wp<Connection>> mDisplayEventConnections GUARDED_BY(mMutex);
+    std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
     std::queue<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
     std::array<DisplayEventReceiver::Event, 2> mVSyncEvent GUARDED_BY(mMutex);
     bool mUseSoftwareVSync GUARDED_BY(mMutex) = false;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 58355ae..36403cc 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -101,7 +101,7 @@
                    this);
 }
 
-void MessageQueue::setEventConnection(const sp<BnDisplayEventConnection>& connection) {
+void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
     if (mEventTube.getFd() >= 0) {
         mLooper->removeFd(mEventTube.getFd());
     }
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 2ec697e..24a3834 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -87,7 +87,7 @@
     virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
     // TODO(akrulec): Remove this function once everything is migrated to Scheduler.
     virtual void setEventThread(EventThread* events) = 0;
-    virtual void setEventConnection(const sp<BnDisplayEventConnection>& connection) = 0;
+    virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
     virtual void waitMessage() = 0;
     virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
     virtual void invalidate() = 0;
@@ -116,7 +116,7 @@
     sp<SurfaceFlinger> mFlinger;
     sp<Looper> mLooper;
     android::EventThread* mEventThread;
-    sp<IDisplayEventConnection> mEvents;
+    sp<EventThreadConnection> mEvents;
     gui::BitTube mEventTube;
     sp<Handler> mHandler;
 
@@ -127,7 +127,7 @@
     ~MessageQueue() override = default;
     void init(const sp<SurfaceFlinger>& flinger) override;
     void setEventThread(android::EventThread* events) override;
-    void setEventConnection(const sp<BnDisplayEventConnection>& connection) override;
+    void setEventConnection(const sp<EventThreadConnection>& connection) override;
 
     void waitMessage() override;
     status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) override;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index fad56e6..c363ba5 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -126,7 +126,7 @@
     return mConnections[handle->id]->thread.get();
 }
 
-sp<BnDisplayEventConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
+sp<EventThreadConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
     RETURN_VALUE_IF_INVALID(nullptr);
     return mConnections[handle->id]->eventConnection;
 }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 8d4514b..9d7dd4d 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -53,14 +53,14 @@
 
     class Connection {
     public:
-        Connection(sp<ConnectionHandle> handle, sp<BnDisplayEventConnection> eventConnection,
+        Connection(sp<ConnectionHandle> handle, sp<EventThreadConnection> eventConnection,
                    std::unique_ptr<EventThread> eventThread)
               : handle(handle), eventConnection(eventConnection), thread(std::move(eventThread)) {}
 
         ~Connection() = default;
 
         sp<ConnectionHandle> handle;
-        sp<BnDisplayEventConnection> eventConnection;
+        sp<EventThreadConnection> eventConnection;
         const std::unique_ptr<EventThread> thread;
     };
 
@@ -79,7 +79,7 @@
     // Getter methods.
     EventThread* getEventThread(const sp<ConnectionHandle>& handle);
 
-    sp<BnDisplayEventConnection> getEventConnection(const sp<ConnectionHandle>& handle);
+    sp<EventThreadConnection> getEventConnection(const sp<ConnectionHandle>& handle);
 
     // Should be called when receiving a hotplug event.
     void hotplugReceived(const sp<ConnectionHandle>& handle, EventThread::DisplayType displayType,
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index e62fc6e..037d32f 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1710,22 +1710,52 @@
     shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
 }
 
-// TODO (marissaw): change Layer to make crop to be in bounds instead of passing a bad crop to hwc
-// TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) {
-//    sp<SurfaceControl> layer;
-//    ASSERT_NO_FATAL_FAILURE(
-//            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
-//    ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
-//
-//    Transaction()
-//            .setCrop(layer, Rect(-128, -64, 128, 64))
-//            .setFrame(layer, Rect(0, 0, 32, 32))
-//            .apply();
-//    auto shot = screenshot();
-//    shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
-//    shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
-//}
-//
+TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", mDisplayWidth, mDisplayHeight / 2,
+                                                ISurfaceComposerClient::eFXSurfaceBufferState));
+    sp<GraphicBuffer> buffer =
+            new GraphicBuffer(mDisplayWidth, mDisplayHeight / 2, PIXEL_FORMAT_RGBA_8888, 1,
+                              BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                      BufferUsage::COMPOSER_OVERLAY,
+                              "test");
+    fillGraphicBufferColor(buffer, Rect(0, 0, mDisplayWidth, mDisplayHeight / 4), Color::BLUE);
+    fillGraphicBufferColor(buffer, Rect(0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2),
+                           Color::RED);
+
+    Transaction().setBuffer(layer, buffer).apply();
+
+    // Partially out of bounds in the negative (upper left) direction
+    Transaction().setCrop(layer, Rect(-128, -128, mDisplayWidth, mDisplayHeight / 4)).apply();
+    {
+        SCOPED_TRACE("out of bounds, negative (upper left) direction");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLUE);
+        shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLACK);
+    }
+
+    // Partially out of bounds in the positive (lower right) direction
+    Transaction()
+            .setCrop(layer, Rect(0, mDisplayHeight / 4, mDisplayWidth + 1, mDisplayHeight))
+            .apply();
+    {
+        SCOPED_TRACE("out of bounds, positive (lower right) direction");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::RED);
+        shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight / 2), Color::BLACK);
+    }
+
+    // Fully out of buffer space bounds
+    Transaction().setCrop(layer, Rect(-128, -128, -1, -1)).apply();
+    {
+        SCOPED_TRACE("Fully out of bounds");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight / 4), Color::BLUE);
+        shot->expectColor(Rect(0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2),
+                          Color::RED);
+    }
+}
+
 TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferQueue) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index fb3b7a2..acbed51 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -47,10 +47,10 @@
 
 class EventThreadTest : public testing::Test {
 protected:
-    class MockEventThreadConnection : public android::impl::EventThread::Connection {
+    class MockEventThreadConnection : public android::EventThreadConnection {
     public:
         explicit MockEventThreadConnection(android::impl::EventThread* eventThread)
-              : android::impl::EventThread::Connection(eventThread) {}
+              : android::EventThreadConnection(eventThread) {}
         MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
     };
 
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 35f30d7..4253ad8 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -23,9 +23,10 @@
 
 class SchedulerTest : public testing::Test {
 protected:
-    class MockEventThreadConnection : public BnDisplayEventConnection {
+    class MockEventThreadConnection : public android::EventThreadConnection {
     public:
-        MockEventThreadConnection() = default;
+        explicit MockEventThreadConnection(EventThread* eventThread)
+              : EventThreadConnection(eventThread) {}
         ~MockEventThreadConnection() = default;
 
         MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
@@ -77,7 +78,9 @@
     std::unique_ptr<mock::EventThread> eventThread = std::make_unique<mock::EventThread>();
     mEventThread = eventThread.get();
     mScheduler = std::make_unique<MockScheduler>(std::move(eventThread));
-    mEventThreadConnection = new MockEventThreadConnection();
+    EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
+
+    mEventThreadConnection = new MockEventThreadConnection(mEventThread);
 
     // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
     // sure that call gets executed and returns an EventThread::Connection object.
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 0a1c827..bb6e183 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -28,12 +28,16 @@
     EventThread();
     ~EventThread() override;
 
-    MOCK_CONST_METHOD0(createEventConnection, sp<BnDisplayEventConnection>());
+    MOCK_CONST_METHOD0(createEventConnection, sp<EventThreadConnection>());
     MOCK_METHOD0(onScreenReleased, void());
     MOCK_METHOD0(onScreenAcquired, void());
     MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool));
     MOCK_CONST_METHOD1(dump, void(std::string&));
     MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset));
+    MOCK_METHOD1(registerDisplayEventConnection,
+                 status_t(const sp<android::EventThreadConnection> &));
+    MOCK_METHOD2(setVsyncRate, void(uint32_t, const sp<android::EventThreadConnection> &));
+    MOCK_METHOD1(requestNextVsync, void(const sp<android::EventThreadConnection> &));
 };
 
 } // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
index f2f3675..dc8d606 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
@@ -18,6 +18,7 @@
 
 #include <gmock/gmock.h>
 
+#include "Scheduler/EventThread.h"
 #include "Scheduler/MessageQueue.h"
 
 namespace android {
@@ -30,7 +31,7 @@
 
     MOCK_METHOD1(init, void(const sp<SurfaceFlinger>&));
     MOCK_METHOD1(setEventThread, void(android::EventThread*));
-    MOCK_METHOD1(setEventConnection, void(const sp<BnDisplayEventConnection>& connection));
+    MOCK_METHOD1(setEventConnection, void(const sp<android::EventThreadConnection>& connection));
     MOCK_METHOD0(waitMessage, void());
     MOCK_METHOD2(postMessage, status_t(const sp<MessageBase>&, nsecs_t));
     MOCK_METHOD0(invalidate, void());
diff --git a/vulkan/OWNERS b/vulkan/OWNERS
new file mode 100644
index 0000000..f4c7af9
--- /dev/null
+++ b/vulkan/OWNERS
@@ -0,0 +1 @@
+include ../opengl/OWNERS
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 7f6b9aa..7604c95 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
 // API version (major.minor.patch)
 define VERSION_MAJOR 1
 define VERSION_MINOR 1
-define VERSION_PATCH 95
+define VERSION_PATCH 96
 
 // API limits
 define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -620,7 +620,7 @@
 @extension("VK_KHR_vulkan_memory_model") define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model"
 
 // 213
-@extension("VK_EXT_pci_bus_info") define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 1
+@extension("VK_EXT_pci_bus_info") define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2
 @extension("VK_EXT_pci_bus_info") define VK_EXT_PCI_BUS_INFO_EXENSION_NAME "VK_EXT_pci_bus_info"
 
 // 215
@@ -636,11 +636,11 @@
 @extension("VK_EXT_scalar_block_layout") define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
 
 // 224
-@extension("VK_GOOGLE_hlsl_functionality1") define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 0
+@extension("VK_GOOGLE_hlsl_functionality1") define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1
 @extension("VK_GOOGLE_hlsl_functionality1") define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
 
 // 225
-@extension("VK_GOOGLE_decorate_string") define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 0
+@extension("VK_GOOGLE_decorate_string") define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1
 @extension("VK_GOOGLE_decorate_string") define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string"
 
 // 247
@@ -7740,10 +7740,10 @@
 class VkPhysicalDevicePCIBusInfoPropertiesEXT {
     VkStructureType                                 sType
     void*                                           pNext
-    u16                                             pciDomain
-    u8                                              pciBus
-    u8                                              pciDevice
-    u8                                              pciFunction
+    u32                                             pciDomain
+    u32                                             pciBus
+    u32                                             pciDevice
+    u32                                             pciFunction
 }
 
 @extension("VK_FUCHSIA_imagepipe_surface") // 215
diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h
index 5006410..72542c7 100644
--- a/vulkan/include/vulkan/vulkan_core.h
+++ b/vulkan/include/vulkan/vulkan_core.h
@@ -43,7 +43,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 95
+#define VK_HEADER_VERSION 96
 
 
 #define VK_NULL_HANDLE 0
@@ -8862,16 +8862,16 @@
 #endif
 
 #define VK_EXT_pci_bus_info 1
-#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION  1
+#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION  2
 #define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info"
 
 typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT {
     VkStructureType    sType;
     void*              pNext;
-    uint16_t           pciDomain;
-    uint8_t            pciBus;
-    uint8_t            pciDevice;
-    uint8_t            pciFunction;
+    uint32_t           pciDomain;
+    uint32_t           pciBus;
+    uint32_t           pciDevice;
+    uint32_t           pciFunction;
 } VkPhysicalDevicePCIBusInfoPropertiesEXT;
 
 
@@ -8917,12 +8917,12 @@
 
 
 #define VK_GOOGLE_hlsl_functionality1 1
-#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 0
+#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1
 #define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
 
 
 #define VK_GOOGLE_decorate_string 1
-#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 0
+#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1
 #define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string"