Merge "SF: Enable HWC composition strategy prediction" into tm-dev
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 700940a..b1e17b7 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -57,6 +57,7 @@
 using android::base::testing::HasValue;
 using android::base::testing::Ok;
 using testing::ExplainMatchResult;
+using testing::Matcher;
 using testing::Not;
 using testing::WithParamInterface;
 
@@ -1258,12 +1259,23 @@
 
 class BinderLibRpcTest : public BinderLibRpcTestBase {};
 
+// e.g. EXPECT_THAT(expr, Debuggable(StatusEq(...))
+// If device is debuggable AND not on user builds, expects matcher.
+// Otherwise expects INVALID_OPERATION.
+// Debuggable + non user builds is necessary but not sufficient for setRpcClientDebug to work.
+static Matcher<status_t> Debuggable(const Matcher<status_t> &matcher) {
+    bool isDebuggable = android::base::GetBoolProperty("ro.debuggable", false) &&
+            android::base::GetProperty("ro.build.type", "") != "user";
+    return isDebuggable ? matcher : StatusEq(INVALID_OPERATION);
+}
+
 TEST_F(BinderLibRpcTest, SetRpcClientDebug) {
     auto binder = addServer();
     ASSERT_TRUE(binder != nullptr);
     auto [socket, port] = CreateSocket();
     ASSERT_TRUE(socket.ok());
-    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()), StatusEq(OK));
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()),
+                Debuggable(StatusEq(OK)));
 }
 
 // Tests for multiple RpcServer's on the same binder object.
@@ -1274,12 +1286,14 @@
     auto [socket1, port1] = CreateSocket();
     ASSERT_TRUE(socket1.ok());
     auto keepAliveBinder1 = sp<BBinder>::make();
-    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1), StatusEq(OK));
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1),
+                Debuggable(StatusEq(OK)));
 
     auto [socket2, port2] = CreateSocket();
     ASSERT_TRUE(socket2.ok());
     auto keepAliveBinder2 = sp<BBinder>::make();
-    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2), StatusEq(OK));
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2),
+                Debuggable(StatusEq(OK)));
 }
 
 // Negative tests for RPC APIs on IBinder. Call should fail in the same way on both remote and
@@ -1298,7 +1312,7 @@
     auto binder = GetService();
     ASSERT_TRUE(binder != nullptr);
     EXPECT_THAT(binder->setRpcClientDebug(android::base::unique_fd(), sp<BBinder>::make()),
-                StatusEq(BAD_VALUE));
+                Debuggable(StatusEq(BAD_VALUE)));
 }
 
 TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoKeepAliveBinder) {
@@ -1306,7 +1320,8 @@
     ASSERT_TRUE(binder != nullptr);
     auto [socket, port] = CreateSocket();
     ASSERT_TRUE(socket.ok());
-    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr), StatusEq(UNEXPECTED_NULL));
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr),
+                Debuggable(StatusEq(UNEXPECTED_NULL)));
 }
 INSTANTIATE_TEST_CASE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
                         BinderLibRpcTestP::ParamToString);
diff --git a/libs/ui/Transform.cpp b/libs/ui/Transform.cpp
index b34d906..42dd85e 100644
--- a/libs/ui/Transform.cpp
+++ b/libs/ui/Transform.cpp
@@ -134,6 +134,10 @@
     return mMatrix[1][1];
 }
 
+float Transform::det() const {
+    return mMatrix[0][0] * mMatrix[1][1] - mMatrix[0][1] * mMatrix[1][0];
+}
+
 float Transform::getScaleX() const {
     return sqrt((dsdx() * dsdx()) + (dtdx() * dtdx()));
 }
@@ -390,7 +394,7 @@
         const float x = M[2][0];
         const float y = M[2][1];
 
-        const float idet = 1.0f / (a*d - b*c);
+        const float idet = 1.0f / det();
         result.mMatrix[0][0] =  d*idet;
         result.mMatrix[0][1] = -c*idet;
         result.mMatrix[1][0] = -b*idet;
diff --git a/libs/ui/include/ui/Transform.h b/libs/ui/include/ui/Transform.h
index 33fbe05..f1178ca 100644
--- a/libs/ui/include/ui/Transform.h
+++ b/libs/ui/include/ui/Transform.h
@@ -77,6 +77,7 @@
     float dtdx() const;
     float dtdy() const;
     float dsdy() const;
+    float det() const;
 
     float getScaleX() const;
     float getScaleY() const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 533acfd..4de8dc2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -338,6 +338,12 @@
     // Calculate effective layer transform
     mEffectiveTransform = parentTransform * getActiveTransform(s);
 
+    if (CC_UNLIKELY(!isTransformValid())) {
+        ALOGW("Stop computing bounds for %s because it has invalid transformation.",
+              getDebugName());
+        return;
+    }
+
     // Transform parent bounds to layer space
     parentBounds = getActiveTransform(s).inverse().transform(parentBounds);
 
@@ -1326,6 +1332,10 @@
             }
         }
     }
+    if (CC_UNLIKELY(!isTransformValid())) {
+        ALOGW("Hide layer %s because it has invalid transformation.", getDebugName());
+        return true;
+    }
     return s.flags & layer_state_t::eLayerHidden;
 }
 
@@ -1858,6 +1868,11 @@
     return mEffectiveTransform;
 }
 
+bool Layer::isTransformValid() const {
+    float transformDet = getTransform().det();
+    return transformDet != 0 && !isinf(transformDet) && !isnan(transformDet);
+}
+
 half Layer::getAlpha() const {
     const auto& p = mDrawingParent.promote();
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 21dd5f4..2b5e337 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -752,6 +752,7 @@
                                   FrameEventHistoryDelta* outDelta);
 
     ui::Transform getTransform() const;
+    bool isTransformValid() const;
 
     // Returns the Alpha of the Surface, accounting for the Alpha
     // of parent Surfaces in the hierarchy (alpha's will be multiplied
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c581a90..e8034de 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2603,6 +2603,13 @@
     // Find the largest width and height among all the displays.
     int32_t maxDisplayWidth = 0;
     int32_t maxDisplayHeight = 0;
+
+    // If there are no displays, set a valid display bounds so we can still compute a valid layer
+    // bounds.
+    if (ON_MAIN_THREAD(mDisplays.size()) == 0) {
+        maxDisplayWidth = maxDisplayHeight = 5000;
+    }
+
     for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
         const auto& displayDevice = pair.second;
         int32_t width = displayDevice->getWidth();
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 947fdce..cf44eff 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -204,8 +204,7 @@
     mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
     mFlinger.mutableMaxRenderTargetSize() = 16384;
 
-    flinger->setLayerTracingFlags(LayerTracing::TRACE_BUFFERS | LayerTracing::TRACE_INPUT |
-                                  LayerTracing::TRACE_BUFFERS);
+    flinger->setLayerTracingFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
     flinger->startLayerTracing(traceFile.entry(0).elapsed_realtime_nanos());
     std::unique_ptr<TraceGenFlingerDataMapper> mapper =
             std::make_unique<TraceGenFlingerDataMapper>();