Merge "Improve visibility of IMemory security risks"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 3f2469c..fb476db 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -3505,7 +3505,7 @@
 
     struct sockaddr addr;
     socklen_t alen = sizeof(addr);
-    int fd = accept(s, &addr, &alen);
+    int fd = accept4(s, &addr, &alen, SOCK_CLOEXEC);
 
     // Close socket just after accept(), to make sure that connect() by client will get error
     // when the socket is used by the other services.
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index ad7e4c4..a7ccf64 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -163,11 +163,11 @@
 VintfInfo getVintfInfo(const std::shared_ptr<const ObjectType>& object,
                        const FqInstance& fqInstance, vintf::TransportArch ta, VintfInfo value) {
     bool found = false;
-    (void)object->forEachInstanceOfVersion(fqInstance.getPackage(), fqInstance.getVersion(),
-                                           [&](const auto& instance) {
-                                               found = match(instance, fqInstance, ta);
-                                               return !found; // continue if not found
-                                           });
+    (void)object->forEachHidlInstanceOfVersion(fqInstance.getPackage(), fqInstance.getVersion(),
+                                               [&](const auto& instance) {
+                                                   found = match(instance, fqInstance, ta);
+                                                   return !found; // continue if not found
+                                               });
     return found ? value : VINTF_INFO_EMPTY;
 }
 
@@ -453,7 +453,7 @@
     }
 
     bool found = false;
-    (void)manifest->forEachInstanceOfVersion(package, version, [&found](const auto&) {
+    (void)manifest->forEachHidlInstanceOfVersion(package, version, [&found](const auto&) {
         found = true;
         return false; // break
     });
@@ -797,9 +797,9 @@
 
         std::map<std::string, TableEntry> entries;
 
-        manifest->forEachInstance([&] (const vintf::ManifestInstance& manifestInstance) {
+        manifest->forEachHidlInstance([&] (const vintf::ManifestInstance& manifestInstance) {
             TableEntry entry{
-                .interfaceName = manifestInstance.getFqInstance().string(),
+                .interfaceName = manifestInstance.description(),
                 .transport = manifestInstance.transport(),
                 .arch = manifestInstance.arch(),
                 // TODO(b/71555570): Device manifest does not distinguish HALs from vendor or ODM.
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index bc457ce..f25e954 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -70,6 +70,7 @@
         "libutils",
     ],
     test_suites: ["device-tests"],
+    require_root: true,
 }
 
 cc_test {
@@ -136,6 +137,7 @@
         "libutils",
     ],
     test_suites: ["device-tests"],
+    require_root: true,
 }
 
 aidl_interface {
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 386f731..2ab34da 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -435,6 +435,9 @@
     surface->expectTap(1, 1);
 }
 
+/**
+ * TODO(b/139494112) fix tests once we define expected behavior
+ *
 // Ensure we send the input to the right surface when the surface visibility changes due to the
 // first buffer being submitted. ref: b/120839715
 TEST_F(InputSurfacesTest, input_respects_buffer_layer_buffer) {
@@ -486,6 +489,7 @@
     injectTap(11, 11);
     bgSurface->expectTap(1, 1);
 }
+*/
 
 TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index 5a9360c..582fed3 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -18,6 +18,8 @@
 #include <private/dvr/trusted_uids.h>
 #include <private/dvr/types.h>
 
+#include "DisplayHardware/DisplayIdentification.h"
+
 using android::dvr::display::DisplayProtocol;
 using android::pdx::Channel;
 using android::pdx::ErrorStatus;
@@ -44,19 +46,6 @@
            Endpoint::Create(display::DisplayProtocol::kClientPath)) {
     hardware_composer_.Initialize(
         hidl, primary_display_id, request_display_callback);
-
-    uint8_t port;
-    const auto error = hidl->getDisplayIdentificationData(
-        primary_display_id, &display_identification_port_,
-        &display_identification_data_);
-    if (error != android::hardware::graphics::composer::V2_1::Error::NONE) {
-      if (error !=
-          android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED) {
-        ALOGI("DisplayService: identification data error\n");
-      } else {
-        ALOGI("DisplayService: identification data unsupported\n");
-      }
-    }
 }
 
 bool DisplayService::IsInitialized() const {
@@ -212,6 +201,7 @@
 pdx::Status<std::string> DisplayService::OnGetConfigurationData(
     pdx::Message& /*message*/, display::ConfigFileType config_type) {
   std::string property_name;
+  DisplayIdentificationData display_identification_data;
   switch (config_type) {
     case display::ConfigFileType::kLensMetrics:
       property_name = kDvrLensMetricsProperty;
@@ -223,11 +213,13 @@
       property_name = kDvrDeviceConfigProperty;
       break;
     case display::ConfigFileType::kDeviceEdid:
-      if (display_identification_data_.size() == 0) {
+      display_identification_data =
+          hardware_composer_.GetCurrentDisplayIdentificationData();
+      if (display_identification_data.size() == 0) {
         return ErrorStatus(ENOENT);
       }
-      return std::string(display_identification_data_.begin(),
-                         display_identification_data_.end());
+      return std::string(display_identification_data.begin(),
+                         display_identification_data.end());
     default:
       return ErrorStatus(EINVAL);
   }
@@ -246,7 +238,7 @@
 
 pdx::Status<uint8_t> DisplayService::OnGetDisplayIdentificationPort(
     pdx::Message& /*message*/) {
-  return display_identification_port_;
+  return hardware_composer_.GetCurrentDisplayPort();
 }
 
 // Creates a new DisplaySurface and associates it with this channel. This may
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index 06ba566..89f1eae 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -18,8 +18,6 @@
 #include "epoll_event_dispatcher.h"
 #include "hardware_composer.h"
 
-#include "DisplayHardware/DisplayIdentification.h"
-
 namespace android {
 namespace dvr {
 
@@ -120,9 +118,6 @@
 
   DisplayService(const DisplayService&) = delete;
   void operator=(const DisplayService&) = delete;
-
-  DisplayIdentificationData display_identification_data_;
-  uint8_t display_identification_port_;
 };
 
 }  // namespace dvr
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 9072d89..67607af 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -137,6 +137,20 @@
   composer_callback_->SetVsyncService(nullptr);
 }
 
+void HardwareComposer::UpdateEdidData(Hwc2::Composer* composer,
+                                      hwc2_display_t hw_id) {
+  const auto error = composer->getDisplayIdentificationData(
+      hw_id, &display_port_, &display_identification_data_);
+  if (error != android::hardware::graphics::composer::V2_1::Error::NONE) {
+    if (error !=
+        android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED) {
+      ALOGI("hardware_composer: identification data error\n");
+    } else {
+      ALOGI("hardware_composer: identification data unsupported\n");
+    }
+  }
+}
+
 bool HardwareComposer::Initialize(
     Hwc2::Composer* composer, hwc2_display_t primary_display_id,
     RequestDisplayCallback request_display_callback) {
@@ -164,6 +178,8 @@
       "HardwareComposer: Failed to create interrupt event fd : %s",
       strerror(errno));
 
+  UpdateEdidData(composer, primary_display_id);
+
   post_thread_ = std::thread(&HardwareComposer::PostThread, this);
 
   initialized_ = true;
@@ -988,6 +1004,9 @@
       EnableDisplay(*external_display_, false);
     }
 
+    // Update the cached edid data for the current display.
+    UpdateEdidData(composer_.get(), target_display_->id);
+
     // Turn the new target display on.
     EnableDisplay(*target_display_, true);
 
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index db0d6a7..989ce35 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -25,6 +25,7 @@
 #include <private/dvr/shared_buffer_helpers.h>
 #include <private/dvr/vsync_service.h>
 
+#include "DisplayHardware/DisplayIdentification.h"
 #include "acquired_buffer.h"
 #include "display_surface.h"
 
@@ -334,6 +335,14 @@
   int OnNewGlobalBuffer(DvrGlobalBufferKey key, IonBuffer& ion_buffer);
   void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);
 
+  // Gets the edid data for the current active display (internal or external)
+  DisplayIdentificationData GetCurrentDisplayIdentificationData() {
+    return display_identification_data_;
+  }
+
+  // Gets the edid port for the current active display (internal or external)
+  uint8_t GetCurrentDisplayPort() { return display_port_; }
+
  private:
   DisplayParams GetDisplayParams(Hwc2::Composer* composer,
       hwc2_display_t display, bool is_primary);
@@ -544,6 +553,11 @@
   bool vsync_trace_parity_ = false;
   sp<VsyncService> vsync_service_;
 
+  // Edid section.
+  void UpdateEdidData(Hwc2::Composer* composer, hwc2_display_t hw_id);
+  DisplayIdentificationData display_identification_data_;
+  uint8_t display_port_;
+
   static constexpr int kPostThreadInterrupted = 1;
 
   HardwareComposer(const HardwareComposer&) = delete;
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 1eb979e..c516ab7 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -262,12 +262,32 @@
  * if the entry is not found.
  * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
  */
-template <typename T, typename U>
-static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
+template <typename K, typename V>
+static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
     auto it = map.find(key);
-    return it != map.end() ? it->second : T{};
+    return it != map.end() ? it->second : V{};
 }
 
+/**
+ * Find the entry in std::unordered_map by value, and remove it.
+ * If more than one entry has the same value, then all matching
+ * key-value pairs will be removed.
+ *
+ * Return true if at least one value has been removed.
+ */
+template <typename K, typename V>
+static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
+    bool removed = false;
+    for (auto it = map.begin(); it != map.end();) {
+        if (it->second == value) {
+            it = map.erase(it);
+            removed = true;
+        } else {
+            it++;
+        }
+    }
+    return removed;
+}
 
 // --- InputDispatcher ---
 
@@ -300,8 +320,9 @@
         drainInboundQueueLocked();
     }
 
-    while (mConnectionsByFd.size() != 0) {
-        unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
+    while (!mConnectionsByFd.empty()) {
+        sp<Connection> connection = mConnectionsByFd.begin()->second;
+        unregisterInputChannel(connection->inputChannel);
     }
 }
 
@@ -1072,9 +1093,8 @@
     pokeUserActivityLocked(eventEntry);
 
     for (const InputTarget& inputTarget : inputTargets) {
-        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
-        if (connectionIndex >= 0) {
-            sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+        sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel);
+        if (connection != nullptr) {
             prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
         } else {
 #if DEBUG_FOCUS
@@ -1172,21 +1192,18 @@
         mInputTargetWaitTimeoutExpired = true;
 
         // Input state will not be realistic.  Mark it out of sync.
-        if (inputChannel.get()) {
-            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-            if (connectionIndex >= 0) {
-                sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-                sp<IBinder> token = connection->inputChannel->getToken();
+        sp<Connection> connection = getConnectionLocked(inputChannel);
+        if (connection != nullptr) {
+            sp<IBinder> token = connection->inputChannel->getToken();
 
-                if (token != nullptr) {
-                    removeWindowByTokenLocked(token);
-                }
+            if (token != nullptr) {
+                removeWindowByTokenLocked(token);
+            }
 
-                if (connection->status == Connection::STATUS_NORMAL) {
-                    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
-                            "application not responding");
-                    synthesizeCancelationEventsForConnectionLocked(connection, options);
-                }
+            if (connection->status == Connection::STATUS_NORMAL) {
+                CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
+                                           "application not responding");
+                synthesizeCancelationEventsForConnectionLocked(connection, options);
             }
         }
     }
@@ -1857,16 +1874,15 @@
     }
 
     // If the window's connection is not registered then keep waiting.
-    ssize_t connectionIndex = getConnectionIndexLocked(
-            getInputChannelLocked(windowHandle->getToken()));
-    if (connectionIndex < 0) {
+    sp<Connection> connection =
+            getConnectionLocked(getInputChannelLocked(windowHandle->getToken()));
+    if (connection == nullptr) {
         return StringPrintf("Waiting because the %s window's input channel is not "
                 "registered with the input dispatcher.  The window may be in the process "
                 "of being removed.", targetType);
     }
 
     // If the connection is dead then keep waiting.
-    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
     if (connection->status != Connection::STATUS_NORMAL) {
         return StringPrintf("Waiting because the %s window's input connection is %s."
                 "The window may be in the process of being removed.", targetType,
@@ -2410,15 +2426,14 @@
     { // acquire lock
         std::scoped_lock _l(d->mLock);
 
-        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
-        if (connectionIndex < 0) {
+        if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
             ALOGE("Received spurious receive callback for unknown input channel.  "
                     "fd=%d, events=0x%x", fd, events);
             return 0; // remove the callback
         }
 
         bool notify;
-        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
+        sp<Connection> connection = d->mConnectionsByFd[fd];
         if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
             if (!(events & ALOOPER_EVENT_INPUT)) {
                 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
@@ -2470,9 +2485,8 @@
 
 void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
         const CancelationOptions& options) {
-    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByFd.valueAt(i), options);
+    for (const auto& pair : mConnectionsByFd) {
+        synthesizeCancelationEventsForConnectionLocked(pair.second, options);
     }
 }
 
@@ -2495,11 +2509,12 @@
 
 void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
         const sp<InputChannel>& channel, const CancelationOptions& options) {
-    ssize_t index = getConnectionIndexLocked(channel);
-    if (index >= 0) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByFd.valueAt(index), options);
+    sp<Connection> connection = getConnectionLocked(channel);
+    if (connection == nullptr) {
+        return;
     }
+
+    synthesizeCancelationEventsForConnectionLocked(connection, options);
 }
 
 void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
@@ -3586,15 +3601,11 @@
             return false;
         }
 
-
         sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
         sp<InputChannel> toChannel = getInputChannelLocked(toToken);
-        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
-        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
-        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
-            sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
-            sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
-
+        sp<Connection> fromConnection = getConnectionLocked(fromChannel);
+        sp<Connection> toConnection = getConnectionLocked(toChannel);
+        if (fromConnection != nullptr && toConnection != nullptr) {
             fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
             CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                     "transferring touch focus from this window to another window");
@@ -3815,16 +3826,16 @@
         dump += INDENT "ReplacedKeys: <empty>\n";
     }
 
-    if (!mConnectionsByFd.isEmpty()) {
+    if (!mConnectionsByFd.empty()) {
         dump += INDENT "Connections:\n";
-        for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
-            const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
-            dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
-                    "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
-                    i, connection->getInputChannelName().c_str(),
-                    connection->getWindowName().c_str(),
-                    connection->getStatusLabel(), toString(connection->monitor),
-                    toString(connection->inputPublisherBlocked));
+        for (const auto& pair : mConnectionsByFd) {
+            const sp<Connection>& connection = pair.second;
+            dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
+                                         "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
+                                 pair.first, connection->getInputChannelName().c_str(),
+                                 connection->getWindowName().c_str(), connection->getStatusLabel(),
+                                 toString(connection->monitor),
+                                 toString(connection->inputPublisherBlocked));
 
             if (!connection->outboundQueue.empty()) {
                 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
@@ -3893,8 +3904,8 @@
 
     { // acquire lock
         std::scoped_lock _l(mLock);
-
-        if (getConnectionIndexLocked(inputChannel) >= 0) {
+        sp<Connection> existingConnection = getConnectionLocked(inputChannel);
+        if (existingConnection != nullptr) {
             ALOGW("Attempted to register already registered input channel '%s'",
                     inputChannel->getName().c_str());
             return BAD_VALUE;
@@ -3903,7 +3914,7 @@
         sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
 
         int fd = inputChannel->getFd();
-        mConnectionsByFd.add(fd, connection);
+        mConnectionsByFd[fd] = connection;
         mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
 
         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
@@ -3932,7 +3943,7 @@
         sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
 
         const int fd = inputChannel->getFd();
-        mConnectionsByFd.add(fd, connection);
+        mConnectionsByFd[fd] = connection;
         mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
 
         auto& monitorsByDisplay = isGestureMonitor
@@ -3970,16 +3981,15 @@
 
 status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
         bool notify) {
-    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-    if (connectionIndex < 0) {
+    sp<Connection> connection = getConnectionLocked(inputChannel);
+    if (connection == nullptr) {
         ALOGW("Attempted to unregister already unregistered input channel '%s'",
                 inputChannel->getName().c_str());
         return BAD_VALUE;
     }
 
-    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-    mConnectionsByFd.removeItemsAt(connectionIndex);
-
+    const bool removed = removeByValue(mConnectionsByFd, connection);
+    ALOG_ASSERT(removed);
     mInputChannelsByToken.erase(inputChannel->getToken());
 
     if (connection->monitor) {
@@ -4079,19 +4089,20 @@
     return std::nullopt;
 }
 
-ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
+sp<InputDispatcher::Connection> InputDispatcher::getConnectionLocked(
+        const sp<InputChannel>& inputChannel) {
     if (inputChannel == nullptr) {
-        return -1;
+        return nullptr;
     }
 
-    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
-        sp<Connection> connection = mConnectionsByFd.valueAt(i);
+    for (const auto& pair : mConnectionsByFd) {
+        sp<Connection> connection = pair.second;
         if (connection->inputChannel->getToken() == inputChannel->getToken()) {
-            return i;
+            return connection;
         }
     }
 
-    return -1;
+    return nullptr;
 }
 
 void InputDispatcher::onDispatchCycleFinishedLocked(
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 92e1e5f..e35ba27 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -887,7 +887,7 @@
             bool addOutsideTargets = false, bool addPortalWindows = false) REQUIRES(mLock);
 
     // All registered connections mapped by channel file descriptor.
-    KeyedVector<int, sp<Connection> > mConnectionsByFd GUARDED_BY(mLock);
+    std::unordered_map<int, sp<Connection>> mConnectionsByFd GUARDED_BY(mLock);
 
     struct IBinderHash {
         std::size_t operator()(const sp<IBinder>& b) const {
@@ -901,7 +901,7 @@
     std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token)
             REQUIRES(mLock);
 
-    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
+    sp<Connection> getConnectionLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
 
     // Input channels that will receive a copy of all input events sent to the provided display.
     std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 5f79750..f2e861d 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -196,8 +196,9 @@
     bool sidebandStreamChanged = true;
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
+        mSidebandStream = mConsumer->getSidebandStream();
         auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
-        layerCompositionState.sidebandStream = mConsumer->getSidebandStream();
+        layerCompositionState.sidebandStream = mSidebandStream;
         if (layerCompositionState.sidebandStream != nullptr) {
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index d40a38c..4a11303 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -30,8 +30,4 @@
     return false;
 }
 
-bool ContainerLayer::canReceiveInput() const {
-    return !isHiddenByPolicy();
-}
-
 } // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index f0fbb61..c3624f6 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,8 +31,6 @@
     const char* getType() const override { return "ContainerLayer"; }
     bool isVisible() const override;
 
-    bool canReceiveInput() const override;
-
     bool isCreatedFromMainThread() const override { return true; }
 };
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8f6672c..bed33a7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1994,7 +1994,7 @@
 }
 
 bool Layer::canReceiveInput() const {
-    return isVisible();
+    return !isHiddenByPolicy();
 }
 
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(