Send context URL as EXTRA_TEXT when available.

Also some minor test cleanups.

Bug: 242791070
Test: atest DefaultScreenshotActionsProviderTest
Flag: com.android.systemui.screenshot_context_url
Change-Id: Ieecd97fd281933207c2113905c8ad337420dfe61
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a21a805..719ddf4 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -644,6 +644,13 @@
 }
 
 flag {
+    name: "screenshot_context_url"
+    namespace: "systemui"
+    description: "Include optional app-provided context URL when sharing a screenshot."
+    bug: "242791070"
+}
+
+flag {
    name: "run_fingerprint_detect_on_dismissible_keyguard"
    namespace: "systemui"
    description: "Run fingerprint detect instead of authenticate if the keyguard is dismissible."
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index c216f1d..1c232e9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -18,13 +18,16 @@
 
 import android.app.assist.AssistContent
 import android.content.Context
+import android.net.Uri
 import android.util.Log
 import androidx.appcompat.content.res.AppCompatResources
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.Flags.screenshotContextUrl
 import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.res.R
 import com.android.systemui.screenshot.ActionIntentCreator.createEdit
 import com.android.systemui.screenshot.ActionIntentCreator.createShareWithSubject
+import com.android.systemui.screenshot.ActionIntentCreator.createShareWithText
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_EDIT_TAPPED
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
@@ -76,6 +79,7 @@
     private var onScrollClick: Runnable? = null
     private var pendingAction: ((ScreenshotSavedResult) -> Unit)? = null
     private var result: ScreenshotSavedResult? = null
+    private var webUri: Uri? = null
 
     init {
         actionsCallback.providePreviewAction(
@@ -86,7 +90,7 @@
                     actionExecutor.startSharedTransition(
                         createEdit(result.uri, context),
                         result.user,
-                        true
+                        true,
                     )
                 }
             }
@@ -103,11 +107,14 @@
             debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" }
             uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString)
             onDeferrableActionTapped { result ->
-                actionExecutor.startSharedTransition(
-                    createShareWithSubject(result.uri, result.subject),
-                    result.user,
-                    false
-                )
+                val uri = webUri
+                val shareIntent =
+                    if (screenshotContextUrl() && uri != null) {
+                        createShareWithText(result.uri, extraText = uri.toString())
+                    } else {
+                        createShareWithSubject(result.uri, result.subject)
+                    }
+                actionExecutor.startSharedTransition(shareIntent, result.user, false)
             }
         }
 
@@ -125,7 +132,7 @@
                 actionExecutor.startSharedTransition(
                     createEdit(result.uri, context),
                     result.user,
-                    true
+                    true,
                 )
             }
         }
@@ -161,6 +168,10 @@
         pendingAction?.invoke(result)
     }
 
+    override fun onAssistContent(assistContent: AssistContent?) {
+        webUri = assistContent?.webUri
+    }
+
     private fun onDeferrableActionTapped(onResult: (ScreenshotSavedResult) -> Unit) {
         result?.let { onResult.invoke(it) } ?: run { pendingAction = onResult }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
index 52266ee..ba6518f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
@@ -16,31 +16,32 @@
 
 package com.android.systemui.screenshot
 
+import android.app.assist.AssistContent
 import android.content.Intent
 import android.net.Uri
 import android.os.Process
 import android.os.UserHandle
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
 import kotlin.test.Test
-import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
+@RunWith(AndroidJUnit4::class)
 class DefaultScreenshotActionsProviderTest : SysuiTestCase() {
     private val actionExecutor = mock<ActionExecutor>()
     private val uiEventLogger = mock<UiEventLogger>()
@@ -76,7 +77,7 @@
     }
 
     @Test
-    fun actionAccessed_withResult_launchesIntent() = runTest {
+    fun actionAccessed_withResult_launchesIntent() {
         actionsProvider = createActionsProvider()
 
         actionsProvider.setCompletedScreenshot(validResult)
@@ -94,7 +95,32 @@
     }
 
     @Test
-    fun actionAccessed_whilePending_launchesMostRecentAction() = runTest {
+    @EnableFlags(Flags.FLAG_SCREENSHOT_CONTEXT_URL)
+    fun shareAction_includesAssistContentUri() {
+        actionsProvider = createActionsProvider()
+
+        actionsProvider.setCompletedScreenshot(validResult)
+
+        val uri = Uri.parse("http://www.android.com")
+        val assistContent = mock<AssistContent>() { on { webUri } doReturn uri }
+
+        actionsProvider.onAssistContent(assistContent)
+
+        val actionButtonCaptor = argumentCaptor<() -> Unit>()
+        verify(actionsCallback, times(2))
+            .provideActionButton(any(), any(), actionButtonCaptor.capture())
+        actionButtonCaptor.firstValue.invoke()
+
+        val intentCaptor = argumentCaptor<Intent>()
+        verify(actionExecutor)
+            .startSharedTransition(intentCaptor.capture(), eq(Process.myUserHandle()), eq(false))
+        val innerIntent =
+            intentCaptor.lastValue.extras?.getParcelable(Intent.EXTRA_INTENT, Intent::class.java)
+        assertThat(innerIntent?.getStringExtra(Intent.EXTRA_TEXT)).isEqualTo(uri.toString())
+    }
+
+    @Test
+    fun actionAccessed_whilePending_launchesMostRecentAction() {
         actionsProvider = createActionsProvider()
 
         val previewActionCaptor = argumentCaptor<PreviewAction>()
@@ -116,7 +142,7 @@
     }
 
     @Test
-    fun scrollChipClicked_callsOnClick() = runTest {
+    fun scrollChipClicked_callsOnClick() {
         actionsProvider = createActionsProvider()
 
         val onScrollClick = mock<Runnable>()
@@ -131,7 +157,7 @@
     }
 
     @Test
-    fun scrollChipClicked_afterInvalidate_doesNothing() = runTest {
+    fun scrollChipClicked_afterInvalidate_doesNothing() {
         actionsProvider = createActionsProvider()
 
         val onScrollClick = mock<Runnable>()
@@ -147,7 +173,7 @@
     }
 
     @Test
-    fun scrollChipClicked_afterUpdate_runsNewAction() = runTest {
+    fun scrollChipClicked_afterUpdate_runsNewAction() {
         actionsProvider = createActionsProvider()
 
         val onScrollClick = mock<Runnable>()