[UI Lib] Enable IntegrationTests on S- devices

1. Guard calls to registerFrameCommitCallback since it doesn't exist
   below API 29
2. Remove check for matching configuration with previous configuration in
   onConfigurationChanged method.
   - It was always coming up true for API-26.
3. Create SandboxedSdkView on UiThread to avoid RTE for creating View on
   a thread that has not called Looper.prepare()
4. Replaced activity.RunOnUiThread with corresponding
   ActivityScenarioRule equivalent
  - This is less flaky. Former ends up sometimes leaving lateinit var
    view uninitialized.
  - This removes squiggly line on Android Studio

Bug: 300397160
Bug: 298658350
Bug: 301605964
Bug: 300396631
Test: presubmit
Change-Id: Iae1e44cfd5897b8a7b49c3170147ef4359a7a2ad
diff --git a/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
index 36da7d5..36cfba0 100644
--- a/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
+++ b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
@@ -134,7 +134,6 @@
     private var previousWidth = -1
     private var previousHeight = -1
     private var currentClippingBounds = Rect()
-    private var currentConfig = context.resources.configuration
     internal val stateListenerManager: StateListenerManager = StateListenerManager()
 
     /**
@@ -313,10 +312,16 @@
         } else {
             super.addView(contentView, 0, contentView.layoutParams)
         }
-        // Wait for the next frame commit before sending an ACTIVE state change to listeners.
-        viewTreeObserver.registerFrameCommitCallback {
-            stateListenerManager.currentUiSessionState =
-                SandboxedSdkUiSessionState.Active
+
+        // TODO(b/301605964): registerFrameCommitCallback not supported below API 29
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            // Wait for the next frame commit before sending an ACTIVE state change to listeners.
+            viewTreeObserver.registerFrameCommitCallback {
+                stateListenerManager.currentUiSessionState =
+                    SandboxedSdkUiSessionState.Active
+            }
+        } else {
+            stateListenerManager.currentUiSessionState = SandboxedSdkUiSessionState.Active
         }
 
         if (contentView is SurfaceView) {
@@ -408,13 +413,10 @@
         super.onDetachedFromWindow()
     }
 
+    // TODO(b/298658350): Cache previous config properly to avoid unnecessary binder calls
     override fun onConfigurationChanged(config: Configuration?) {
         requireNotNull(config) { "Config cannot be null" }
-        if (config == currentConfig) {
-            return
-        }
         super.onConfigurationChanged(config)
-        currentConfig = config
         client?.notifyConfigurationChanged(config)
         checkClientOpenSession()
     }
diff --git a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
index fe1d0c2..8dbd3f8 100644
--- a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
+++ b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
@@ -30,7 +30,6 @@
 import android.view.ViewGroup
 import android.widget.LinearLayout
 import androidx.annotation.RequiresApi
-import androidx.appcompat.app.AppCompatActivity
 import androidx.privacysandbox.ui.client.SandboxedUiAdapterFactory
 import androidx.privacysandbox.ui.client.view.SandboxedSdkUiSessionState
 import androidx.privacysandbox.ui.client.view.SandboxedSdkUiSessionStateChangedListener
@@ -70,37 +69,37 @@
         const val INITIAL_WIDTH = 20
 
         @JvmStatic
-        @Parameterized.Parameters(name = "{index}: invokeBackwardsCompatFlow={0}")
+        @Parameterized.Parameters(name = "invokeBackwardsCompatFlow={0}")
         fun data(): Array<Any> = arrayOf(
             arrayOf(true),
             arrayOf(false),
         )
     }
 
-    private lateinit var context: Context
-    private lateinit var activity: AppCompatActivity
+    private val context = InstrumentationRegistry.getInstrumentation().context
+
     private lateinit var view: SandboxedSdkView
     private lateinit var stateChangeListener: TestStateChangeListener
     private lateinit var errorLatch: CountDownLatch
 
     @Before
     fun setup() {
-        // TODO(b/300397160): Enable backward compat test on S- devices
-        assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
+        if (!invokeBackwardsCompatFlow) {
+            // SdkSandbox is only supported on U+ devices
+            assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        }
 
-        context = InstrumentationRegistry.getInstrumentation().context
-        activity = activityScenarioRule.withActivity { this }
-        view = SandboxedSdkView(context)
-        errorLatch = CountDownLatch(1)
-        stateChangeListener = TestStateChangeListener(errorLatch)
-        view.addStateChangedListener(stateChangeListener)
-        activity.runOnUiThread {
+        activityScenarioRule.withActivity {
+            view = SandboxedSdkView(context)
+            errorLatch = CountDownLatch(1)
+            stateChangeListener = TestStateChangeListener(errorLatch)
+            view.addStateChangedListener(stateChangeListener)
             val linearLayout = LinearLayout(context)
             linearLayout.layoutParams = LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.MATCH_PARENT,
                 LinearLayout.LayoutParams.MATCH_PARENT
             )
-            activity.setContentView(linearLayout)
+            setContentView(linearLayout)
             view.layoutParams = LinearLayout.LayoutParams(100, 100)
             linearLayout.addView(view)
         }
@@ -167,8 +166,8 @@
     fun testConfigurationChanged() {
         val sdkAdapter = createAdapterAndEstablishSession()
 
-        activity.runOnUiThread {
-            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+        activityScenarioRule.withActivity {
+            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
         }
 
         val testSession = sdkAdapter.session as TestSandboxedUiAdapter.TestSession
@@ -352,7 +351,7 @@
     }
 
     private fun injectInputEventOnView() {
-        activity.runOnUiThread {
+        activityScenarioRule.withActivity {
             val location = IntArray(2)
             view.getLocationOnScreen(location)
             InstrumentationRegistry.getInstrumentation().uiAutomation.injectInputEvent(