composer: add seamlessPossible callback to composer 2.4

Add a callback to notify the client it should retry a
setActiveConfigWithConstraints call in case of SEAMLESS_NOT_POSSIBLE error.

Test: rev up composer to 2.4
Bug: 141329414
Change-Id: I6176638fde937e3916f58cc577d50cb755997c61
diff --git a/graphics/composer/2.4/IComposerCallback.hal b/graphics/composer/2.4/IComposerCallback.hal
index fea24a1..f343cee 100644
--- a/graphics/composer/2.4/IComposerCallback.hal
+++ b/graphics/composer/2.4/IComposerCallback.hal
@@ -42,4 +42,14 @@
      * @param updatedTimeline is the new timeline for the vsync period change.
      */
     oneway onVsyncPeriodTimingChanged(Display display, VsyncPeriodChangeTimeline updatedTimeline);
+
+    /**
+     * Notifies the client that the conditions which previously led to returning
+     * SEAMLESS_NOT_POSSIBLE from setActiveConfigWithConstraints have changed and now seamless may
+     * be possible. Client should retry calling setActiveConfigWithConstraints.
+     *
+     * @param display is a display setActiveConfigWithConstraints previously failed with
+     * SEAMLESS_NOT_POSSIBLE.
+     */
+    oneway onSeamlessPossible(Display display);
 };
diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index 06b4c5e..1b8170b 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -185,6 +185,9 @@
      *                              share the same config group as the current config.
      *         SEAMLESS_NOT_POSSIBLE when seamlessRequired was true but the display cannot achieve
      *                               the vsync period change without a noticeable visual artifact.
+     *                               When the conditions change and it may be possible to change
+     *                               the vsync period seamlessly, onSeamlessPossible callback
+     *                               must be called to indicate that caller should retry.
      * @return timeline is the timeline for the vsync period change.
      */
     setActiveConfigWithConstraints(Display display, Config config,
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index dcd959d..d48a9e7 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -83,6 +83,12 @@
                      ret.description().c_str());
         }
 
+        void onSeamlessPossible(Display display) override {
+            auto ret = mCallback->onSeamlessPossible(display);
+            ALOGE_IF(!ret.isOk(), "failed to send onSealmessPossible: %s",
+                     ret.description().c_str());
+        }
+
       protected:
         const sp<IComposerCallback> mCallback;
         V2_1::hal::ComposerResources* const mResources;
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index a1e56ae..bbc5405 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -49,6 +49,7 @@
                                  VsyncPeriodNanos vsyncPeriodNanos) = 0;
         virtual void onVsyncPeriodTimingChanged(Display display,
                                                 const VsyncPeriodChangeTimeline& timeline) = 0;
+        virtual void onSeamlessPossible(Display display) = 0;
     };
 
     virtual void registerEventCallback_2_4(EventCallback_2_4* callback) = 0;
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index a27582a..53e4404 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -64,10 +64,12 @@
         BaseType2_1::mDispatch.registerCallback(
                 mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
                 reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
-
         BaseType2_1::mDispatch.registerCallback(
                 mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
                 reinterpret_cast<hwc2_function_pointer_t>(vsyncPeriodTimingChangedHook));
+        BaseType2_1::mDispatch.registerCallback(
+                mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
+                reinterpret_cast<hwc2_function_pointer_t>(seamlessPossibleHook));
     }
 
     void unregisterEventCallback_2_4() override {
@@ -84,6 +86,8 @@
         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED,
                                                 this, nullptr);
+        BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
+                                                nullptr);
 
         mEventCallback_2_4 = nullptr;
     }
@@ -273,6 +277,11 @@
         hal->mEventCallback_2_4->onVsyncPeriodTimingChanged(display, timeline);
     }
 
+    static void seamlessPossibleHook(hwc2_callback_data_t callbackData, hwc2_display_t display) {
+        auto hal = static_cast<HwcHalImpl*>(callbackData);
+        hal->mEventCallback_2_4->onSeamlessPossible(display);
+    }
+
   private:
     struct {
         HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType;