Merge "SF: Remove BufferQueueLayer tests"
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 08a1428..f2395ba 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -216,6 +216,7 @@
         "abseil-*",
         "android-*",
         "bugprone-*",
+        "-bugprone-branch-clone", // b/155034972
         "cert-*",
         "clang-analyzer-*",
         "google-*",
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 79c8c8f..32e018d 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -113,6 +113,7 @@
         "abseil-*",
         "android-*",
         "bugprone-*",
+        "-bugprone-branch-clone", // b/155034972
         "cert-*",
         "clang-analyzer-*",
         "-clang-analyzer-core.CallAndMessage",
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 262987f..c6cdeb7 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -566,6 +566,55 @@
     bgSurface->expectTap(12, 24);
 }
 
+TEST_F(InputSurfacesTest, touchable_region) {
+    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
+
+    surface->mInputInfo.touchableRegion.set(Rect{19, 29, 21, 31});
+
+    surface->showAt(11, 22);
+
+    // A tap within the surface but outside the touchable region should not be sent to the surface.
+    injectTap(20, 30);
+    EXPECT_EQ(surface->consumeEvent(200 /*timeoutMs*/), nullptr);
+
+    injectTap(31, 52);
+    surface->expectTap(20, 30);
+}
+
+TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) {
+    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
+    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
+    bgSurface->showAt(100, 100);
+
+    // Set the touchable region to the values at the limit of its corresponding type.
+    // Since the surface is offset from the origin, the touchable region will be transformed into
+    // display space, which would trigger an overflow or an underflow. Ensure that we are protected
+    // against such a situation.
+    fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
+
+    fgSurface->showAt(100, 100);
+
+    // Expect no crash for overflow. The overflowed touchable region is ignored, so the background
+    // surface receives touch.
+    injectTap(112, 124);
+    bgSurface->expectTap(12, 24);
+}
+
+TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) {
+    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
+    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
+    bgSurface->showAt(0, 0);
+
+    fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
+    fgSurface->showAt(0, 0);
+
+    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
+
+    // Expect no crash for overflow.
+    injectTap(12, 24);
+    fgSurface->expectTap(6, 12);
+}
+
 // Ensure we ignore transparent region when getting screen bounds when positioning input frame.
 TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index f57ff33..3ee60a9 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -512,6 +512,15 @@
     return out;
 }
 
+class AndroidPalmRejectionModel : public ::ui::OneDeviceTrainNeuralStylusPalmDetectionFilterModel {
+public:
+    AndroidPalmRejectionModel()
+          : ::ui::OneDeviceTrainNeuralStylusPalmDetectionFilterModel(/*default version*/ "",
+                                                                     std::vector<float>()) {
+        config_.resample_touch = true;
+    }
+};
+
 PalmRejector::PalmRejector(const AndroidPalmFilterDeviceInfo& info,
                            std::unique_ptr<::ui::PalmDetectionFilter> filter)
       : mSharedPalmState(std::make_unique<::ui::SharedPalmDetectionFilterState>()),
@@ -523,8 +532,7 @@
         return;
     }
     std::unique_ptr<::ui::NeuralStylusPalmDetectionFilterModel> model =
-            std::make_unique<::ui::OneDeviceTrainNeuralStylusPalmDetectionFilterModel>(
-                    std::vector<float>());
+            std::make_unique<AndroidPalmRejectionModel>();
     mPalmDetectionFilter =
             std::make_unique<::ui::NeuralStylusPalmDetectionFilter>(mDeviceInfo, std::move(model),
                                                                     mSharedPalmState.get());
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 0062f42..7f14b94 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -47,6 +47,10 @@
 constexpr int UP = AMOTION_EVENT_ACTION_UP;
 constexpr int CANCEL = AMOTION_EVENT_ACTION_CANCEL;
 
+static nsecs_t toNs(std::chrono::nanoseconds duration) {
+    return duration.count();
+}
+
 struct PointerData {
     float x;
     float y;
@@ -630,41 +634,41 @@
  */
 TEST_F(PalmRejectorTest, TwoPointersAreCanceled) {
     std::vector<NotifyMotionArgs> argsList;
-    constexpr nsecs_t downTime = 255955749837000;
+    const nsecs_t downTime = toNs(0ms);
 
     mPalmRejector->processMotion(
             generateMotionArgs(downTime, downTime, DOWN, {{1342.0, 613.0, 79.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955759313000, MOVE, {{1406.0, 650.0, 52.0}}));
+            generateMotionArgs(downTime, toNs(8ms), MOVE, {{1406.0, 650.0, 52.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955766361000, MOVE, {{1429.0, 672.0, 46.0}}));
+            generateMotionArgs(downTime, toNs(16ms), MOVE, {{1429.0, 672.0, 46.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955775989000, MOVE, {{1417.0, 685.0, 41.0}}));
+            generateMotionArgs(downTime, toNs(24ms), MOVE, {{1417.0, 685.0, 41.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955775989000, POINTER_1_DOWN,
+            generateMotionArgs(downTime, toNs(32ms), POINTER_1_DOWN,
                                {{1417.0, 685.0, 41.0}, {1062.0, 697.0, 10.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955783039000, MOVE,
+            generateMotionArgs(downTime, toNs(40ms), MOVE,
                                {{1414.0, 702.0, 41.0}, {1059.0, 731.0, 12.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955792536000, MOVE,
+            generateMotionArgs(downTime, toNs(48ms), MOVE,
                                {{1415.0, 719.0, 44.0}, {1060.0, 760.0, 11.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955799474000, MOVE,
+            generateMotionArgs(downTime, toNs(56ms), MOVE,
                                {{1421.0, 733.0, 42.0}, {1065.0, 769.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955809177000, MOVE,
+            generateMotionArgs(downTime, toNs(64ms), MOVE,
                                {{1426.0, 742.0, 43.0}, {1068.0, 771.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955816131000, MOVE,
+            generateMotionArgs(downTime, toNs(72ms), MOVE,
                                {{1430.0, 748.0, 45.0}, {1069.0, 772.0, 13.0}}));
     argsList = mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955825907000, MOVE,
+            generateMotionArgs(downTime, toNs(80ms), MOVE,
                                {{1432.0, 750.0, 44.0}, {1069.0, 772.0, 13.0}}));
     ASSERT_EQ(1u, argsList.size());
     ASSERT_EQ(0 /* No FLAG_CANCELED */, argsList[0].flags);
     argsList = mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955832736000, MOVE,
+            generateMotionArgs(downTime, toNs(88ms), MOVE,
                                {{1433.0, 751.0, 44.0}, {1070.0, 771.0, 13.0}}));
     ASSERT_EQ(2u, argsList.size());
     ASSERT_EQ(POINTER_0_UP, argsList[0].action);
@@ -674,94 +678,94 @@
     ASSERT_EQ(0, argsList[1].flags);
 
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955842432000, MOVE,
+            generateMotionArgs(downTime, toNs(96ms), MOVE,
                                {{1433.0, 751.0, 42.0}, {1071.0, 770.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955849380000, MOVE,
+            generateMotionArgs(downTime, toNs(104ms), MOVE,
                                {{1433.0, 751.0, 45.0}, {1072.0, 769.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955859046000, MOVE,
+            generateMotionArgs(downTime, toNs(112ms), MOVE,
                                {{1433.0, 751.0, 43.0}, {1072.0, 768.0, 13.0}}));
     argsList = mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955869823000, MOVE,
+            generateMotionArgs(downTime, toNs(120ms), MOVE,
                                {{1433.0, 751.0, 45.0}, {1072.0, 767.0, 13.0}}));
     ASSERT_EQ(1u, argsList.size());
     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, argsList[0].action);
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955875641000, MOVE,
+            generateMotionArgs(downTime, toNs(128ms), MOVE,
                                {{1433.0, 751.0, 43.0}, {1072.0, 766.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955882693000, MOVE,
+            generateMotionArgs(downTime, toNs(136ms), MOVE,
                                {{1433.0, 750.0, 44.0}, {1072.0, 765.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955892324000, MOVE,
+            generateMotionArgs(downTime, toNs(144ms), MOVE,
                                {{1433.0, 750.0, 42.0}, {1072.0, 763.0, 14.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955899425000, MOVE,
+            generateMotionArgs(downTime, toNs(152ms), MOVE,
                                {{1434.0, 750.0, 44.0}, {1073.0, 761.0, 14.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955909400000, MOVE,
+            generateMotionArgs(downTime, toNs(160ms), MOVE,
                                {{1435.0, 750.0, 43.0}, {1073.0, 759.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955915885000, MOVE,
+            generateMotionArgs(downTime, toNs(168ms), MOVE,
                                {{1436.0, 750.0, 45.0}, {1074.0, 757.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955925607000, MOVE,
+            generateMotionArgs(downTime, toNs(176ms), MOVE,
                                {{1436.0, 750.0, 44.0}, {1074.0, 755.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955932580000, MOVE,
+            generateMotionArgs(downTime, toNs(184ms), MOVE,
                                {{1436.0, 750.0, 45.0}, {1074.0, 753.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955942231000, MOVE,
+            generateMotionArgs(downTime, toNs(192ms), MOVE,
                                {{1436.0, 749.0, 44.0}, {1074.0, 751.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955949204000, MOVE,
+            generateMotionArgs(downTime, toNs(200ms), MOVE,
                                {{1435.0, 748.0, 45.0}, {1074.0, 749.0, 15.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955959103000, MOVE,
+            generateMotionArgs(downTime, toNs(208ms), MOVE,
                                {{1434.0, 746.0, 44.0}, {1074.0, 747.0, 14.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955965884000, MOVE,
+            generateMotionArgs(downTime, toNs(216ms), MOVE,
                                {{1433.0, 744.0, 44.0}, {1075.0, 745.0, 14.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955975649000, MOVE,
+            generateMotionArgs(downTime, toNs(224ms), MOVE,
                                {{1431.0, 741.0, 43.0}, {1075.0, 742.0, 13.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955982537000, MOVE,
+            generateMotionArgs(downTime, toNs(232ms), MOVE,
                                {{1428.0, 738.0, 43.0}, {1076.0, 739.0, 12.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955992284000, MOVE,
+            generateMotionArgs(downTime, toNs(240ms), MOVE,
                                {{1400.0, 726.0, 54.0}, {1076.0, 739.0, 13.0}}));
     argsList = mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955999348000, POINTER_1_UP,
+            generateMotionArgs(downTime, toNs(248ms), POINTER_1_UP,
                                {{1362.0, 716.0, 55.0}, {1076.0, 739.0, 13.0}}));
     ASSERT_TRUE(argsList.empty());
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255955999348000, MOVE, {{1362.0, 716.0, 55.0}}));
+            generateMotionArgs(downTime, toNs(256ms), MOVE, {{1362.0, 716.0, 55.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956008885000, MOVE, {{1347.0, 707.0, 54.0}}));
+            generateMotionArgs(downTime, toNs(264ms), MOVE, {{1347.0, 707.0, 54.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956015791000, MOVE, {{1340.0, 698.0, 54.0}}));
+            generateMotionArgs(downTime, toNs(272ms), MOVE, {{1340.0, 698.0, 54.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956025804000, MOVE, {{1338.0, 694.0, 55.0}}));
+            generateMotionArgs(downTime, toNs(280ms), MOVE, {{1338.0, 694.0, 55.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956032314000, MOVE, {{1336.0, 690.0, 53.0}}));
+            generateMotionArgs(downTime, toNs(288ms), MOVE, {{1336.0, 690.0, 53.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956042329000, MOVE, {{1334.0, 685.0, 47.0}}));
+            generateMotionArgs(downTime, toNs(296ms), MOVE, {{1334.0, 685.0, 47.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956048979000, MOVE, {{1333.0, 679.0, 46.0}}));
+            generateMotionArgs(downTime, toNs(304ms), MOVE, {{1333.0, 679.0, 46.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956058813000, MOVE, {{1332.0, 672.0, 45.0}}));
+            generateMotionArgs(downTime, toNs(312ms), MOVE, {{1332.0, 672.0, 45.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956065592000, MOVE, {{1333.0, 666.0, 40.0}}));
+            generateMotionArgs(downTime, toNs(320ms), MOVE, {{1333.0, 666.0, 40.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956075276000, MOVE, {{1336.0, 661.0, 24.0}}));
+            generateMotionArgs(downTime, toNs(328ms), MOVE, {{1336.0, 661.0, 24.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956082198000, MOVE, {{1338.0, 656.0, 16.0}}));
+            generateMotionArgs(downTime, toNs(336ms), MOVE, {{1338.0, 656.0, 16.0}}));
     mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956092059000, MOVE, {{1341.0, 649.0, 1.0}}));
+            generateMotionArgs(downTime, toNs(344ms), MOVE, {{1341.0, 649.0, 1.0}}));
     argsList = mPalmRejector->processMotion(
-            generateMotionArgs(downTime, 255956098764000, UP, {{1341.0, 649.0, 1.0}}));
+            generateMotionArgs(downTime, toNs(352ms), UP, {{1341.0, 649.0, 1.0}}));
     ASSERT_TRUE(argsList.empty());
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index cccf907..ea856e4 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -261,7 +261,7 @@
     }
 
     if (isPowerHintSessionEnabled()) {
-        mPowerAdvisor->setValidateTiming(mId, startTime, systemTime());
+        mPowerAdvisor->setHwcValidateTiming(mId, startTime, systemTime());
         mPowerAdvisor->setRequiresClientComposition(mId, requiresClientComposition);
     }
 
@@ -371,7 +371,7 @@
         if (!getCompositionEngine().getHwComposer().getComposer()->isSupported(
                     Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
             getState().previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
-            mPowerAdvisor->setPresentDelayedTime(mId, getState().earliestPresentTime);
+            mPowerAdvisor->setHwcPresentDelayedTime(mId, getState().earliestPresentTime);
         }
     }
 
@@ -379,7 +379,7 @@
                                    getState().previousPresentFence);
 
     if (isPowerHintSessionEnabled()) {
-        mPowerAdvisor->setPresentTiming(mId, startTime, systemTime());
+        mPowerAdvisor->setHwcPresentTiming(mId, startTime, systemTime());
     }
 
     fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index c8b6d44..579636f 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -45,17 +45,17 @@
     MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
     MOCK_METHOD(void, setGpuFenceTime,
                 (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
-    MOCK_METHOD(void, setValidateTiming,
+    MOCK_METHOD(void, setHwcValidateTiming,
                 (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
                 (override));
-    MOCK_METHOD(void, setPresentTiming,
+    MOCK_METHOD(void, setHwcPresentTiming,
                 (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
                 (override));
     MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
     MOCK_METHOD(void, setRequiresClientComposition,
                 (DisplayId displayId, bool requiresClientComposition), (override));
     MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
-    MOCK_METHOD(void, setPresentDelayedTime,
+    MOCK_METHOD(void, setHwcPresentDelayedTime,
                 (DisplayId displayId,
                  std::chrono::steady_clock::time_point earliestFrameStartTime));
     MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 4c0a942..f844845 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -287,18 +287,18 @@
     displayData.gpuStartTime = systemTime();
 }
 
-void PowerAdvisor::setValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
-                                     nsecs_t validateEndTime) {
+void PowerAdvisor::setHwcValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
+                                        nsecs_t validateEndTime) {
     DisplayTimingData& displayData = mDisplayTimingData[displayId];
-    displayData.validateStartTime = validateStartTime;
-    displayData.validateEndTime = validateEndTime;
+    displayData.hwcValidateStartTime = validateStartTime;
+    displayData.hwcValidateEndTime = validateEndTime;
 }
 
-void PowerAdvisor::setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
-                                    nsecs_t presentEndTime) {
+void PowerAdvisor::setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
+                                       nsecs_t presentEndTime) {
     DisplayTimingData& displayData = mDisplayTimingData[displayId];
-    displayData.presentStartTime = presentStartTime;
-    displayData.presentEndTime = presentEndTime;
+    displayData.hwcPresentStartTime = presentStartTime;
+    displayData.hwcPresentEndTime = presentEndTime;
 }
 
 void PowerAdvisor::setSkippedValidate(DisplayId displayId, bool skipped) {
@@ -318,9 +318,9 @@
     mFrameDelayDuration = frameDelayDuration;
 }
 
-void PowerAdvisor::setPresentDelayedTime(
+void PowerAdvisor::setHwcPresentDelayedTime(
         DisplayId displayId, std::chrono::steady_clock::time_point earliestFrameStartTime) {
-    mDisplayTimingData[displayId].presentDelayedTime =
+    mDisplayTimingData[displayId].hwcPresentDelayedTime =
             (earliestFrameStartTime - std::chrono::steady_clock::now()).count() + systemTime();
 }
 
@@ -331,10 +331,11 @@
 void PowerAdvisor::setCompositeEnd(nsecs_t compositeEnd) {
     mLastCompositeEndTime = compositeEnd;
     // calculate the postcomp time here as well
-    std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::presentEndTime);
+    std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::hwcPresentEndTime);
     DisplayTimingData& timingData = mDisplayTimingData[displays.back()];
     mLastPostcompDuration = compositeEnd -
-            (timingData.skippedValidate ? *timingData.validateEndTime : *timingData.presentEndTime);
+            (timingData.skippedValidate ? *timingData.hwcValidateEndTime
+                                        : *timingData.hwcPresentEndTime);
 }
 
 void PowerAdvisor::setDisplays(std::vector<DisplayId>& displayIds) {
@@ -390,7 +391,7 @@
     // The timing info for the previously calculated display, if there was one
     std::optional<DisplayTimeline> previousDisplayReferenceTiming;
     std::vector<DisplayId>&& displayIds =
-            getOrderedDisplayIds(&DisplayTimingData::presentStartTime);
+            getOrderedDisplayIds(&DisplayTimingData::hwcPresentStartTime);
     DisplayTimeline referenceTiming, estimatedTiming;
 
     // Iterate over the displays in the same order they are presented
@@ -402,27 +403,26 @@
         auto& displayData = mDisplayTimingData.at(displayId);
         referenceTiming = displayData.calculateDisplayTimeline(referenceFenceTime);
 
-        // If this is the first display, add the pre-present time to the total
+        // If this is the first display, include the duration before hwc present starts
         if (!previousDisplayReferenceTiming.has_value()) {
-            estimatedEndTime += referenceTiming.prePresentTime - referenceFrameStartTime;
-        } else { // Otherwise add last display's postprocessing time to the total
-            estimatedEndTime += referenceTiming.prePresentTime -
-                    previousDisplayReferenceTiming->postPresentTime;
+            estimatedEndTime += referenceTiming.hwcPresentStartTime - referenceFrameStartTime;
+        } else { // Otherwise add the time since last display's hwc present finished
+            estimatedEndTime += referenceTiming.hwcPresentStartTime -
+                    previousDisplayReferenceTiming->hwcPresentEndTime;
         }
 
         estimatedTiming = referenceTiming.estimateTimelineFromReference(mExpectedPresentTimes[-1],
                                                                         estimatedEndTime);
         // Update predicted present finish time with this display's present time
-        estimatedEndTime = estimatedTiming.postPresentTime;
+        estimatedEndTime = estimatedTiming.hwcPresentEndTime;
 
         // Track how long we spent waiting for the fence, can be excluded from the timing estimate
-        idleDuration += estimatedTiming.probablyWaitsForFence
-                ? mExpectedPresentTimes[-1] - estimatedTiming.preFenceWaitTime
+        idleDuration += estimatedTiming.probablyWaitsForReleaseFence
+                ? mExpectedPresentTimes[-1] - estimatedTiming.releaseFenceWaitStartTime
                 : 0;
 
         // Track how long we spent waiting to present, can be excluded from the timing estimate
-        idleDuration +=
-                !earlyHint ? referenceTiming.presentStartTime - referenceTiming.prePresentTime : 0;
+        idleDuration += earlyHint ? 0 : referenceTiming.hwcPresentDelayDuration;
 
         // Estimate the reference frame's gpu timing
         auto gpuTiming = displayData.estimateGpuTiming(previousValidGpuEndTime);
@@ -431,7 +431,7 @@
 
             // Estimate the prediction frame's gpu end time from the reference frame
             estimatedGpuEndTime =
-                    std::max(estimatedTiming.prePresentTime, estimatedGpuEndTime.value_or(0)) +
+                    std::max(estimatedTiming.hwcPresentStartTime, estimatedGpuEndTime.value_or(0)) +
                     gpuTiming->duration;
         }
         previousDisplayReferenceTiming = referenceTiming;
@@ -470,48 +470,55 @@
 PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimeline::estimateTimelineFromReference(
         nsecs_t fenceTime, nsecs_t displayStartTime) {
     DisplayTimeline estimated;
-    estimated.prePresentTime = displayStartTime;
+    estimated.hwcPresentStartTime = displayStartTime;
 
     // We don't predict waiting for vsync alignment yet
-    estimated.presentStartTime = estimated.prePresentTime;
+    estimated.hwcPresentDelayDuration = 0;
 
     // For now just re-use last frame's post-present duration and assume it will not change much
     // How long we expect to run before we start waiting for the fence
-    estimated.preFenceWaitTime = estimated.presentStartTime + (preFenceWaitTime - presentStartTime);
-    estimated.probablyWaitsForFence = fenceTime > estimated.preFenceWaitTime;
-    estimated.postPresentTime = postFenceDuration +
-            (estimated.probablyWaitsForFence ? fenceTime : estimated.preFenceWaitTime);
+    // If it's the early hint we exclude time we spent waiting for a vsync, otherwise don't
+    estimated.releaseFenceWaitStartTime = estimated.hwcPresentStartTime +
+            (releaseFenceWaitStartTime - (hwcPresentStartTime + hwcPresentDelayDuration));
+    estimated.probablyWaitsForReleaseFence = fenceTime > estimated.releaseFenceWaitStartTime;
+    estimated.hwcPresentEndTime = postReleaseFenceHwcPresentDuration +
+            (estimated.probablyWaitsForReleaseFence ? fenceTime
+                                                    : estimated.releaseFenceWaitStartTime);
     return estimated;
 }
 
 PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayTimeline(
         nsecs_t fenceTime) {
     DisplayTimeline timeline;
-    // How long between calling present from flinger and trying to wait on the fence in HWC
-    const nsecs_t preFenceWaitDelay =
-            (skippedValidate ? kPrefenceDelaySkippedValidate : kPrefenceDelayValidated).count();
+    // How long between calling hwc present and trying to wait on the fence
+    const nsecs_t fenceWaitStartDelay =
+            (skippedValidate ? kFenceWaitStartDelaySkippedValidate : kFenceWaitStartDelayValidated)
+                    .count();
 
-    // Did our reference frame wait for an earliest present time before calling the HWC
-    const bool waitedOnPresentTime = presentDelayedTime.has_value() &&
-            *presentDelayedTime > *presentStartTime && *presentDelayedTime < *presentEndTime;
+    // Did our reference frame wait for an appropriate vsync before calling into hwc
+    const bool waitedOnHwcPresentTime = hwcPresentDelayedTime.has_value() &&
+            *hwcPresentDelayedTime > *hwcPresentStartTime &&
+            *hwcPresentDelayedTime < *hwcPresentEndTime;
 
     // Use validate start here if we skipped it because we did validate + present together
-    timeline.prePresentTime = skippedValidate ? *validateStartTime : *presentStartTime;
+    timeline.hwcPresentStartTime = skippedValidate ? *hwcValidateStartTime : *hwcPresentStartTime;
 
     // Use validate end here if we skipped it because we did validate + present together
-    timeline.postPresentTime = skippedValidate ? *validateEndTime : *presentEndTime;
+    timeline.hwcPresentEndTime = skippedValidate ? *hwcValidateEndTime : *hwcPresentEndTime;
 
-    // When we think we started waiting for the fence after calling into present
-    // This is after any time spent waiting for the earliest present time
-    timeline.presentStartTime =
-            (waitedOnPresentTime ? *presentDelayedTime : timeline.prePresentTime);
-    timeline.preFenceWaitTime = timeline.presentStartTime + preFenceWaitDelay;
-    timeline.probablyWaitsForFence =
-            fenceTime > timeline.preFenceWaitTime && fenceTime < timeline.postPresentTime;
+    // How long hwc present was delayed waiting for the next appropriate vsync
+    timeline.hwcPresentDelayDuration =
+            (waitedOnHwcPresentTime ? *hwcPresentDelayedTime - *hwcPresentStartTime : 0);
+    // When we started waiting for the release fence after calling into hwc present
+    timeline.releaseFenceWaitStartTime =
+            timeline.hwcPresentStartTime + timeline.hwcPresentDelayDuration + fenceWaitStartDelay;
+    timeline.probablyWaitsForReleaseFence = fenceTime > timeline.releaseFenceWaitStartTime &&
+            fenceTime < timeline.hwcPresentEndTime;
 
-    // How long we ran after we finished waiting for the fence but before present happened
-    timeline.postFenceDuration = timeline.postPresentTime -
-            (timeline.probablyWaitsForFence ? fenceTime : timeline.preFenceWaitTime);
+    // How long we ran after we finished waiting for the fence but before hwc present finished
+    timeline.postReleaseFenceHwcPresentDuration = timeline.hwcPresentEndTime -
+            (timeline.probablyWaitsForReleaseFence ? fenceTime
+                                                   : timeline.releaseFenceWaitStartTime);
     return timeline;
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 8e1e33f..bdc7927 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -64,20 +64,20 @@
     virtual bool startPowerHintSession(const std::vector<int32_t>& threadIds) = 0;
     // Provides PowerAdvisor with a copy of the gpu fence so it can determine the gpu end time
     virtual void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime) = 0;
-    // Reports the start and end times of a present call this frame for a given display
-    virtual void setValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
-                                   nsecs_t validateEndTime) = 0;
-    // Reports the start and end times of a present call this frame for a given display
-    virtual void setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
-                                  nsecs_t presentEndTime) = 0;
+    // Reports the start and end times of a hwc validate call this frame for a given display
+    virtual void setHwcValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
+                                      nsecs_t validateEndTime) = 0;
+    // Reports the start and end times of a hwc present call this frame for a given display
+    virtual void setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
+                                     nsecs_t presentEndTime) = 0;
     virtual void setExpectedPresentTime(nsecs_t expectedPresentTime) = 0;
     // Reports whether a display used client composition this frame
     virtual void setRequiresClientComposition(DisplayId displayId,
                                               bool requiresClientComposition) = 0;
     // Reports whether a given display skipped validation this frame
     virtual void setSkippedValidate(DisplayId displayId, bool skipped) = 0;
-    // Reports how much a given display delayed its present call this frame
-    virtual void setPresentDelayedTime(
+    // Reports when a hwc present is delayed, and the time that it will resume
+    virtual void setHwcPresentDelayedTime(
             DisplayId displayId, std::chrono::steady_clock::time_point earliestFrameStartTime) = 0;
     // Reports the start delay for SurfaceFlinger this frame
     virtual void setFrameDelay(nsecs_t frameDelayDuration) = 0;
@@ -132,14 +132,14 @@
     void enablePowerHint(bool enabled) override;
     bool startPowerHintSession(const std::vector<int32_t>& threadIds) override;
     void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime);
-    void setValidateTiming(DisplayId displayId, nsecs_t valiateStartTime,
-                           nsecs_t validateEndTime) override;
-    void setPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
-                          nsecs_t presentEndTime) override;
+    void setHwcValidateTiming(DisplayId displayId, nsecs_t valiateStartTime,
+                              nsecs_t validateEndTime) override;
+    void setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
+                             nsecs_t presentEndTime) override;
     void setSkippedValidate(DisplayId displayId, bool skipped) override;
     void setRequiresClientComposition(DisplayId displayId, bool requiresClientComposition) override;
     void setExpectedPresentTime(nsecs_t expectedPresentTime) override;
-    void setPresentDelayedTime(
+    void setHwcPresentDelayedTime(
             DisplayId displayId,
             std::chrono::steady_clock::time_point earliestFrameStartTime) override;
 
@@ -166,17 +166,19 @@
 
     // Higher-level timing data used for estimation
     struct DisplayTimeline {
-        nsecs_t prePresentTime = -1;
-        nsecs_t postPresentTime = -1;
-        // Usually equals prePresentTime but can be delayed if we wait for the next valid vsync
-        nsecs_t presentStartTime = -1;
-        // When we think we started waiting for the fence after calling into present and
+        // The start of hwc present, or the start of validate if it happened there instead
+        nsecs_t hwcPresentStartTime = -1;
+        // The end of hwc present or validate, whichever one actually presented
+        nsecs_t hwcPresentEndTime = -1;
+        // How long the actual hwc present was delayed after hwcPresentStartTime
+        nsecs_t hwcPresentDelayDuration = 0;
+        // When we think we started waiting for the release fence after calling into hwc present and
         // after potentially waiting for the earliest present time
-        nsecs_t preFenceWaitTime = -1;
-        // How long we ran after we finished waiting for the fence but before present happened
-        nsecs_t postFenceDuration = 0;
+        nsecs_t releaseFenceWaitStartTime = -1;
+        // How long we ran after we finished waiting for the fence but before hwc present finished
+        nsecs_t postReleaseFenceHwcPresentDuration = 0;
         // Are we likely to have waited for the present fence during composition
-        bool probablyWaitsForFence = false;
+        bool probablyWaitsForReleaseFence = false;
         // Estimate one frame's timeline from that of a previous frame
         DisplayTimeline estimateTimelineFromReference(nsecs_t fenceTime, nsecs_t displayStartTime);
     };
@@ -192,11 +194,11 @@
         std::optional<nsecs_t> gpuStartTime;
         std::optional<nsecs_t> lastValidGpuEndTime;
         std::optional<nsecs_t> lastValidGpuStartTime;
-        std::optional<nsecs_t> presentStartTime;
-        std::optional<nsecs_t> presentEndTime;
-        std::optional<nsecs_t> validateStartTime;
-        std::optional<nsecs_t> validateEndTime;
-        std::optional<nsecs_t> presentDelayedTime;
+        std::optional<nsecs_t> hwcPresentStartTime;
+        std::optional<nsecs_t> hwcPresentEndTime;
+        std::optional<nsecs_t> hwcValidateStartTime;
+        std::optional<nsecs_t> hwcValidateEndTime;
+        std::optional<nsecs_t> hwcPresentDelayedTime;
         bool usedClientComposition = false;
         bool skippedValidate = false;
         // Calculate high-level timing milestones from more granular display timing data
@@ -258,13 +260,13 @@
 
     // An adjustable safety margin which moves the "target" earlier to allow flinger to
     // go a bit over without dropping a frame, especially since we can't measure
-    // the exact time HWC finishes composition so "actual" durations are measured
+    // the exact time hwc finishes composition so "actual" durations are measured
     // from the end of present() instead, which is a bit later.
     static constexpr const std::chrono::nanoseconds kTargetSafetyMargin = 1ms;
 
     // How long we expect hwc to run after the present call until it waits for the fence
-    static constexpr const std::chrono::nanoseconds kPrefenceDelayValidated = 150us;
-    static constexpr const std::chrono::nanoseconds kPrefenceDelaySkippedValidate = 250us;
+    static constexpr const std::chrono::nanoseconds kFenceWaitStartDelayValidated = 150us;
+    static constexpr const std::chrono::nanoseconds kFenceWaitStartDelaySkippedValidate = 250us;
 };
 
 class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 47ccc50..b1f0ba1 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2221,6 +2221,37 @@
     return getCroppedBufferSize(getDrawingState());
 }
 
+// Applies the given transform to the region, while protecting against overflows caused by any
+// offsets. If applying the offset in the transform to any of the Rects in the region would result
+// in an overflow, they are not added to the output Region.
+static Region transformTouchableRegionSafely(const ui::Transform& t, const Region& r,
+                                             const std::string& debugWindowName) {
+    // Round the translation using the same rounding strategy used by ui::Transform.
+    const auto tx = static_cast<int32_t>(t.tx() + 0.5);
+    const auto ty = static_cast<int32_t>(t.ty() + 0.5);
+
+    ui::Transform transformWithoutOffset = t;
+    transformWithoutOffset.set(0.f, 0.f);
+
+    const Region transformed = transformWithoutOffset.transform(r);
+
+    // Apply the translation to each of the Rects in the region while discarding any that overflow.
+    Region ret;
+    for (const auto& rect : transformed) {
+        Rect newRect;
+        if (__builtin_add_overflow(rect.left, tx, &newRect.left) ||
+            __builtin_add_overflow(rect.top, ty, &newRect.top) ||
+            __builtin_add_overflow(rect.right, tx, &newRect.right) ||
+            __builtin_add_overflow(rect.bottom, ty, &newRect.bottom)) {
+            ALOGE("Applying transform to touchable region of window '%s' resulted in an overflow.",
+                  debugWindowName.c_str());
+            continue;
+        }
+        ret.orSelf(newRect);
+    }
+    return ret;
+}
+
 void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) {
     Rect tmpBounds = getInputBounds();
     if (!tmpBounds.isValid()) {
@@ -2283,7 +2314,8 @@
     info.transform = inputToDisplay.inverse();
 
     // The touchable region is specified in the input coordinate space. Change it to display space.
-    info.touchableRegion = inputToDisplay.transform(info.touchableRegion);
+    info.touchableRegion =
+            transformTouchableRegionSafely(inputToDisplay, info.touchableRegion, mName);
 }
 
 void Layer::fillTouchOcclusionMode(WindowInfo& info) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6a290a5..a7438f2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2170,6 +2170,7 @@
         // This will block and tracing should only be enabled for debugging.
         mLayerTracing.notify(mVisibleRegionsDirty, frameTime, vsyncId);
     }
+    mLastCommittedVsyncId = vsyncId;
 
     persistDisplayBrightness(mustComposite);
 
@@ -5851,7 +5852,7 @@
                         mScheduler
                                 ->schedule([&]() FTL_FAKE_GUARD(mStateLock) {
                                     mLayerTracing.notify(true /* visibleRegionDirty */,
-                                                         startingTime, -1 /* vsyncId */);
+                                                         startingTime, mLastCommittedVsyncId);
                                 })
                                 .wait();
                     }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f7e061f..6c7ed00 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1266,6 +1266,8 @@
     const std::unique_ptr<FrameTracer> mFrameTracer;
     const std::unique_ptr<frametimeline::FrameTimeline> mFrameTimeline;
 
+    int64_t mLastCommittedVsyncId = -1;
+
     // If blurs should be enabled on this device.
     bool mSupportsBlur = false;
     // If blurs are considered expensive and should require high GPU frequency.
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index 05cc544..e347883 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -43,17 +43,17 @@
     MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
     MOCK_METHOD(void, setGpuFenceTime,
                 (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
-    MOCK_METHOD(void, setValidateTiming,
+    MOCK_METHOD(void, setHwcValidateTiming,
                 (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
                 (override));
-    MOCK_METHOD(void, setPresentTiming,
+    MOCK_METHOD(void, setHwcPresentTiming,
                 (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
                 (override));
     MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
     MOCK_METHOD(void, setRequiresClientComposition,
                 (DisplayId displayId, bool requiresClientComposition), (override));
     MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
-    MOCK_METHOD(void, setPresentDelayedTime,
+    MOCK_METHOD(void, setHwcPresentDelayedTime,
                 (DisplayId displayId,
                  std::chrono::steady_clock::time_point earliestFrameStartTime));
     MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 48d6fd0..f866005 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1843,6 +1843,11 @@
             if (swapchain_result != VK_SUCCESS) {
                 OrphanSwapchain(device, &swapchain);
             }
+            // Android will only return VK_SUBOPTIMAL_KHR for vkQueuePresentKHR,
+            // and only when the window's transform/rotation changes.  Extent
+            // changes will not cause VK_SUBOPTIMAL_KHR because of the
+            // application issues that were caused when the following transform
+            // change was added.
             int window_transform_hint;
             err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT,
                                 &window_transform_hint);