Merge "Add surface_control_input_receiver native API" into main
diff --git a/services/powermanager/Android.bp b/services/powermanager/Android.bp
index 3ea08fe..4f65e77 100644
--- a/services/powermanager/Android.bp
+++ b/services/powermanager/Android.bp
@@ -20,7 +20,6 @@
         "PowerHintSessionWrapper.cpp",
         "PowerSaveState.cpp",
         "Temperature.cpp",
-        "WorkDuration.cpp",
         "WorkSource.cpp",
         ":libpowermanager_aidl",
     ],
@@ -52,6 +51,10 @@
         "android.hardware.power@1.3",
     ],
 
+    whole_static_libs: [
+        "android.os.hintmanager_aidl-ndk",
+    ],
+
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/services/powermanager/WorkDuration.cpp b/services/powermanager/WorkDuration.cpp
deleted file mode 100644
index bd2b10a..0000000
--- a/services/powermanager/WorkDuration.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "WorkDuration"
-
-#include <android/WorkDuration.h>
-#include <android/performance_hint.h>
-#include <binder/Parcel.h>
-#include <utils/Log.h>
-
-namespace android::os {
-
-WorkDuration::WorkDuration(int64_t startTimestampNanos, int64_t totalDurationNanos,
-                           int64_t cpuDurationNanos, int64_t gpuDurationNanos)
-      : timestampNanos(0),
-        actualTotalDurationNanos(totalDurationNanos),
-        workPeriodStartTimestampNanos(startTimestampNanos),
-        actualCpuDurationNanos(cpuDurationNanos),
-        actualGpuDurationNanos(gpuDurationNanos) {}
-
-status_t WorkDuration::writeToParcel(Parcel* parcel) const {
-    if (parcel == nullptr) {
-        ALOGE("%s: Null parcel", __func__);
-        return BAD_VALUE;
-    }
-
-    parcel->writeInt64(workPeriodStartTimestampNanos);
-    parcel->writeInt64(actualTotalDurationNanos);
-    parcel->writeInt64(actualCpuDurationNanos);
-    parcel->writeInt64(actualGpuDurationNanos);
-    parcel->writeInt64(timestampNanos);
-    return OK;
-}
-
-status_t WorkDuration::readFromParcel(const Parcel*) {
-    return INVALID_OPERATION;
-}
-
-} // namespace android::os
diff --git a/services/powermanager/include/android/WorkDuration.h b/services/powermanager/include/android/WorkDuration.h
deleted file mode 100644
index 26a575f..0000000
--- a/services/powermanager/include/android/WorkDuration.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <binder/Parcelable.h>
-#include <math.h>
-
-struct AWorkDuration {};
-
-namespace android::os {
-
-/**
- * C++ Parcelable version of {@link PerformanceHintManager.WorkDuration} that can be used in
- * binder calls.
- * This file needs to be kept in sync with the WorkDuration in
- * frameworks/base/core/java/android/os/WorkDuration.java
- */
-struct WorkDuration : AWorkDuration, android::Parcelable {
-    WorkDuration() = default;
-    ~WorkDuration() = default;
-
-    WorkDuration(int64_t workPeriodStartTimestampNanos, int64_t actualTotalDurationNanos,
-                 int64_t actualCpuDurationNanos, int64_t actualGpuDurationNanos);
-    status_t writeToParcel(Parcel* parcel) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
-    inline bool equalsWithoutTimestamp(const WorkDuration& other) const {
-        return workPeriodStartTimestampNanos == other.workPeriodStartTimestampNanos &&
-                actualTotalDurationNanos == other.actualTotalDurationNanos &&
-                actualCpuDurationNanos == other.actualCpuDurationNanos &&
-                actualGpuDurationNanos == other.actualGpuDurationNanos;
-    }
-
-    bool operator==(const WorkDuration& other) const {
-        return timestampNanos == other.timestampNanos && equalsWithoutTimestamp(other);
-    }
-
-    bool operator!=(const WorkDuration& other) const { return !(*this == other); }
-
-    friend std::ostream& operator<<(std::ostream& os, const WorkDuration& workDuration) {
-        os << "{"
-           << "workPeriodStartTimestampNanos: " << workDuration.workPeriodStartTimestampNanos
-           << ", actualTotalDurationNanos: " << workDuration.actualTotalDurationNanos
-           << ", actualCpuDurationNanos: " << workDuration.actualCpuDurationNanos
-           << ", actualGpuDurationNanos: " << workDuration.actualGpuDurationNanos
-           << ", timestampNanos: " << workDuration.timestampNanos << "}";
-        return os;
-    }
-
-    int64_t timestampNanos;
-    int64_t actualTotalDurationNanos;
-    int64_t workPeriodStartTimestampNanos;
-    int64_t actualCpuDurationNanos;
-    int64_t actualGpuDurationNanos;
-};
-
-} // namespace android::os
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index db1930d..acb3760 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -377,15 +377,20 @@
     mRenderRateOpt = renderRate;
     const auto renderPeriodDelta =
             prevRenderRate ? prevRenderRate->getPeriodNsecs() - renderRate.getPeriodNsecs() : 0;
-    const bool newRenderRateIsHigher = renderPeriodDelta > renderRate.getPeriodNsecs() &&
-            mLastCommittedVsync.ns() - mClock->now() > 2 * renderRate.getPeriodNsecs();
     if (applyImmediately) {
+        ATRACE_FORMAT_INSTANT("applyImmediately");
         while (mTimelines.size() > 1) {
             mTimelines.pop_front();
         }
 
         mTimelines.front().setRenderRate(renderRate);
-    } else if (newRenderRateIsHigher) {
+        return;
+    }
+
+    const bool newRenderRateIsHigher = renderPeriodDelta > renderRate.getPeriodNsecs() &&
+            mLastCommittedVsync.ns() - mClock->now() > 2 * renderRate.getPeriodNsecs();
+    if (newRenderRateIsHigher) {
+        ATRACE_FORMAT_INSTANT("newRenderRateIsHigher");
         mTimelines.clear();
         mLastCommittedVsync = TimePoint::fromNs(0);
 
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 48707cb..aac1cac 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -944,6 +944,27 @@
     EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(6001), Eq(8000));
 }
 
+// b/329310308
+TEST_F(VSyncPredictorTest, renderRateChangeAfterAppliedImmediately) {
+    tracker.addVsyncTimestamp(1000);
+
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1), Eq(1000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1001), Eq(2000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(2001), Eq(3000));
+
+    tracker.setRenderRate(Fps::fromPeriodNsecs(2000), /*applyImmediately*/ true);
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1), Eq(1000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1001), Eq(3000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(3001), Eq(5000));
+
+    tracker.setRenderRate(Fps::fromPeriodNsecs(4000), /*applyImmediately*/ false);
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1), Eq(1000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(1001), Eq(3000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(3001), Eq(5000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(5001), Eq(9000));
+    EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(9001), Eq(13000));
+}
+
 } // namespace android::scheduler
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 6ba2eb1..74d3d9d 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -526,15 +526,12 @@
     *count = num_copied;
 }
 
-PixelFormat GetNativePixelFormat(VkFormat format,
-                                 VkCompositeAlphaFlagBitsKHR alpha) {
+PixelFormat GetNativePixelFormat(VkFormat format) {
     PixelFormat native_format = PixelFormat::RGBA_8888;
     switch (format) {
         case VK_FORMAT_R8G8B8A8_UNORM:
         case VK_FORMAT_R8G8B8A8_SRGB:
-            native_format = alpha == VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
-                                ? PixelFormat::RGBX_8888
-                                : PixelFormat::RGBA_8888;
+            native_format = PixelFormat::RGBA_8888;
             break;
         case VK_FORMAT_R5G6B5_UNORM_PACK16:
             native_format = PixelFormat::RGB_565;
@@ -904,7 +901,7 @@
     VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
     ATRACE_CALL();
 
-    auto surface_handle = pSurfaceInfo->surface;
+    auto surface = pSurfaceInfo->surface;
     auto capabilities = &pSurfaceCapabilities->surfaceCapabilities;
 
     VkSurfacePresentModeEXT const *pPresentMode = nullptr;
@@ -925,13 +922,7 @@
     int transform_hint;
     int max_buffer_count;
     int min_undequeued_buffers;
-    // On Android, window composition is a WindowManager property, not something
-    // associated with the bufferqueue. It can't be changed from here for a
-    // swapchain connected with SurfaceFlinger. For offscreen surfaces, it's
-    // allowed to report opaque being supported for RGBX preference.
-    VkCompositeAlphaFlagsKHR composite_alpha =
-        VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
-    if (surface_handle == VK_NULL_HANDLE) {
+    if (surface == VK_NULL_HANDLE) {
         const InstanceData& instance_data = GetData(physicalDevice);
         ProcHook::Extension surfaceless = ProcHook::GOOGLE_surfaceless_query;
         bool surfaceless_enabled =
@@ -952,8 +943,7 @@
         capabilities->minImageCount = 0xFFFFFFFF;
         capabilities->maxImageCount = 0xFFFFFFFF;
     } else {
-        Surface& surface = *SurfaceFromHandle(surface_handle);
-        ANativeWindow* window = surface.window.get();
+        ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
 
         err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
         if (err != android::OK) {
@@ -1028,11 +1018,6 @@
                     min_undequeued_buffers + default_additional_buffers);
             capabilities->maxImageCount = static_cast<uint32_t>(max_buffer_count);
         }
-
-        if (!(surface.consumer_usage &
-              AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY)) {
-            composite_alpha |= VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
-        }
     }
 
     capabilities->currentExtent =
@@ -1059,7 +1044,9 @@
     capabilities->currentTransform =
         TranslateNativeToVulkanTransform(transform_hint);
 
-    capabilities->supportedCompositeAlpha = composite_alpha;
+    // On Android, window composition is a WindowManager property, not something
+    // associated with the bufferqueue. It can't be changed from here.
+    capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
 
     capabilities->supportedUsageFlags =
         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
@@ -1658,21 +1645,20 @@
 
     ALOGV("vkCreateSwapchainKHR: surface=0x%" PRIx64
           " minImageCount=%u imageFormat=%u imageColorSpace=%u"
-          " imageExtent=%ux%u imageUsage=%#x preTransform=%u compositeAlpha=%u"
-          " presentMode=%u oldSwapchain=0x%" PRIx64,
+          " imageExtent=%ux%u imageUsage=%#x preTransform=%u presentMode=%u"
+          " oldSwapchain=0x%" PRIx64,
           reinterpret_cast<uint64_t>(create_info->surface),
           create_info->minImageCount, create_info->imageFormat,
           create_info->imageColorSpace, create_info->imageExtent.width,
           create_info->imageExtent.height, create_info->imageUsage,
-          create_info->preTransform, create_info->compositeAlpha,
-          create_info->presentMode,
+          create_info->preTransform, create_info->presentMode,
           reinterpret_cast<uint64_t>(create_info->oldSwapchain));
 
     if (!allocator)
         allocator = &GetData(device).allocator;
 
-    PixelFormat native_pixel_format = GetNativePixelFormat(
-        create_info->imageFormat, create_info->compositeAlpha);
+    PixelFormat native_pixel_format =
+        GetNativePixelFormat(create_info->imageFormat);
     DataSpace native_dataspace = GetNativeDataspace(
         create_info->imageColorSpace, create_info->imageFormat);
     if (native_dataspace == DataSpace::UNKNOWN) {