HWC2: Check SidebandStream capability on load

Checks whether the HWC2 device has the SidebandStream capability
before attempting to load the corresponding function pointer

Bug: 28161394
Change-Id: I6407d61a1b23138781e57213bcb868be46609018
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 5c78c68..f7678e4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -30,6 +30,7 @@
 
 #include <android/configuration.h>
 
+#include <algorithm>
 #include <inttypes.h>
 
 extern "C" {
@@ -303,6 +304,12 @@
     mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
 }
 
+bool Device::hasCapability(HWC2::Capability capability) const
+{
+    return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
+            capability) != mCapabilities.cend();
+}
+
 void Device::loadFunctionPointers()
 {
     // For all of these early returns, we log an error message inside
@@ -378,8 +385,10 @@
             mSetLayerDisplayFrame)) return;
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
             mSetLayerPlaneAlpha)) return;
-    if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
-            mSetLayerSidebandStream)) return;
+    if (hasCapability(Capability::SidebandStream)) {
+        if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
+                mSetLayerSidebandStream)) return;
+    }
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
             mSetLayerSourceCrop)) return;
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
@@ -973,6 +982,11 @@
 
 Error Layer::setSidebandStream(const native_handle_t* stream)
 {
+    if (!mDevice.hasCapability(Capability::SidebandStream)) {
+        ALOGE("Attempted to call setSidebandStream without checking that the "
+                "device supports sideband streams");
+        return Error::Unsupported;
+    }
     int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
             mDisplayId, mId, stream);
     return static_cast<Error>(intError);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 7d33a0a..967add0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -89,6 +89,8 @@
     // as connected
     std::shared_ptr<Display> getDisplayById(hwc2_display_t id);
 
+    bool hasCapability(HWC2::Capability capability) const;
+
 private:
     // Initialization methods