Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d9a5e17 authored by Miranda Kephart's avatar Miranda Kephart
Browse files

Add display id to screenshot intent activity options

Ensure that activities are started in the correct window when taking
multidisplay screenshots.

Bug: 423958940
Test: manual (on tablet), atest ActionExecutorTest
Flag: com.android.systemui.screenshot_multidisplay_focus_change
Change-Id: Ie8758d9f8b5785c7cd9cbb2cdae464d01e489373
parent 710ca857
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -16,13 +16,17 @@

package com.android.systemui.screenshot

import android.app.ActivityOptions
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.UserHandle
import android.platform.test.annotations.EnableFlags
import android.view.Window
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
@@ -38,6 +42,7 @@ import org.mockito.kotlin.capture
import org.mockito.kotlin.eq
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyBlocking
import org.mockito.kotlin.whenever

@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -51,21 +56,33 @@ class ActionExecutorTest : SysuiTestCase() {
    private val viewProxy = mock<ScreenshotShelfViewProxy>()
    private val onDismiss = mock<(() -> Unit)>()
    private val pendingIntent = mock<PendingIntent>()
    private val fakeContext = mock<Context>()

    private lateinit var actionExecutor: ActionExecutor

    @Test
    @EnableFlags(FLAG_SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE)
    fun startSharedTransition_callsLaunchIntent() = runTest {
        actionExecutor = createActionExecutor()
        whenever(fakeContext.displayId).thenReturn(17)
        whenever(window.context).thenReturn(fakeContext)

        actionExecutor.startSharedTransition(Intent(Intent.ACTION_EDIT), UserHandle.CURRENT, true)
        scheduler.advanceUntilIdle()

        val intentCaptor = argumentCaptor<Intent>()
        val activityOptionsCaptor = argumentCaptor<ActivityOptions>()
        verifyBlocking(intentExecutor) {
            launchIntent(capture(intentCaptor), eq(UserHandle.CURRENT), eq(true), any(), any())
            launchIntent(
                capture(intentCaptor),
                eq(UserHandle.CURRENT),
                eq(true),
                capture(activityOptionsCaptor),
                any(),
            )
        }
        assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_EDIT)
        assertThat(activityOptionsCaptor.value.launchDisplayId).isEqualTo(17)
    }

    @Test
+24 −10
Original line number Diff line number Diff line
@@ -26,8 +26,10 @@ import android.os.UserHandle
import android.util.Log
import android.util.Pair
import android.view.Window
import android.window.DesktopExperienceFlags
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.app.ChooserActivity
import com.android.systemui.Flags
import com.android.systemui.dagger.qualifiers.Application
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -57,7 +59,7 @@ constructor(
                user,
                overrideTransition,
                windowTransition.first,
                windowTransition.second
                windowTransition.second,
            )
        }
    }
@@ -94,15 +96,20 @@ constructor(

                override fun onFinish() {}
            }
        return ActivityOptions.startSharedElementAnimation(
        val transition =
            ActivityOptions.startSharedElementAnimation(
                window,
                callbacks,
                null,
                Pair.create(
                    viewProxy.screenshotPreview,
                ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME
            )
                    ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME,
                ),
            )
        if (SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE.isTrue) {
            transition.first.launchDisplayId = window.context.displayId
        }
        return transition
    }

    @AssistedFactory
@@ -110,11 +117,18 @@ constructor(
        fun create(
            window: Window,
            viewProxy: ScreenshotShelfViewProxy,
            finishDismiss: (() -> Unit)
            finishDismiss: (() -> Unit),
        ): ActionExecutor
    }

    companion object {
        private const val TAG = "ActionExecutor"

        val SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE =
            DesktopExperienceFlags.DesktopExperienceFlag(
                Flags::screenshotMultidisplayFocusChange,
                /* shouldOverrideByDevOption= */ true,
                Flags.FLAG_SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE,
            )
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui.screenshot

import android.animation.Animator
import android.app.ActivityOptions
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -37,10 +38,12 @@ import android.view.ScrollCaptureResponse
import android.view.ViewRootImpl.ActivityConfigCallback
import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
import android.widget.Toast
import android.window.DesktopExperienceFlags
import android.window.WindowContext
import androidx.core.animation.doOnEnd
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.applications.InterestingConfigChanges
import com.android.systemui.Flags
import com.android.systemui.Flags.screenshotAnnounceLiveRegion
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.broadcast.BroadcastSender
@@ -418,7 +421,13 @@ internal constructor(
            response,
            {
                val intent = actionIntentCreator.createLongScreenshotIntent(owner)
                if (SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE.isTrue) {
                    val options = ActivityOptions.makeBasic()
                    options.setLaunchDisplayId(context.displayId)
                    context.startActivity(intent, options.toBundle())
                } else {
                    context.startActivity(intent)
                }
            },
            { viewProxy.restoreNonScrollingUi() },
            { transitionDestination: Rect, onTransitionEnd: Runnable, longScreenshot: LongScreenshot
@@ -576,6 +585,13 @@ internal constructor(

        const val SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS: Int = 6000

        val SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE =
            DesktopExperienceFlags.DesktopExperienceFlag(
                Flags::screenshotMultidisplayFocusChange,
                /* shouldOverrideByDevOption= */ true,
                Flags.FLAG_SCREENSHOT_MULTIDISPLAY_FOCUS_CHANGE,
            )

        /** Does the aspect ratio of the bitmap with insets removed match the bounds. */
        private fun aspectRatiosMatch(
            bitmap: Bitmap,