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

Commit cf605f0e authored by Mark Renouf's avatar Mark Renouf
Browse files

Strip embedded userId from shared URIs

When screenshot saving images, the userId is explicitly attached to
the resulting URI to support cross-profile actions. This is only
necessary for internal operations and does not need to be present
in the resulting share intent which is already scoped to the target
user.

Bug: 291706486
Test: On pixel, set R.string.config_systemImageEditor to
      'com.google.android.apps.photos/.editor.intents.EditActivity'
      take screenshot, share, edit -> verify Photos opens

Change-Id: If417620c1aa4a4fc3a4d291a1384e7aff137af5c
parent a6c8f32a
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot
import android.content.ClipData
import android.content.ClipDescription
import android.content.ComponentName
import android.content.ContentProvider
import android.content.Context
import android.content.Intent
import android.net.Uri
@@ -36,7 +37,9 @@ object ActionIntentCreator {
    fun createShareWithText(uri: Uri, extraText: String): Intent =
        createShare(uri, text = extraText)

    private fun createShare(uri: Uri, subject: String? = null, text: String? = null): Intent {
    private fun createShare(rawUri: Uri, subject: String? = null, text: String? = null): Intent {
        val uri = uriWithoutUserId(rawUri)

        // Create a share intent, this will always go through the chooser activity first
        // which should not trigger auto-enter PiP
        val sharingIntent =
@@ -68,7 +71,8 @@ object ActionIntentCreator {
     * @return an ACTION_EDIT intent for the given URI, directed to config_screenshotEditor if
     *   available.
     */
    fun createEditIntent(uri: Uri, context: Context): Intent {
    fun createEdit(rawUri: Uri, context: Context): Intent {
        val uri = uriWithoutUserId(rawUri)
        val editIntent = Intent(Intent.ACTION_EDIT)

        val editor = context.getString(R.string.config_screenshotEditor)
@@ -84,3 +88,12 @@ object ActionIntentCreator {
            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
    }
}

/**
 * URIs here are passed only via Intent which are sent to the target user via Intent. Because of
 * this, the userId component can be removed to prevent compatibility issues when an app attempts
 * valid a URI containing a userId within the authority.
 */
private fun uriWithoutUserId(uri: Uri): Uri {
    return ContentProvider.getUriWithoutUserId(uri)
}
+1 −1
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ public class LongScreenshotActivity extends Activity {
        if (mScreenshotUserHandle != Process.myUserHandle()) {
            // TODO: Fix transition for work profile. Omitting it in the meantime.
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(uri, this),
                    ActionIntentCreator.INSTANCE.createEdit(uri, this),
                    null,
                    mScreenshotUserHandle, false);
        } else {
+2 −2
Original line number Diff line number Diff line
@@ -815,7 +815,7 @@ public class ScreenshotView extends FrameLayout implements
            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED, 0, mPackageName);
            prepareSharedTransition();
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(imageData.uri, mContext),
                    ActionIntentCreator.INSTANCE.createEdit(imageData.uri, mContext),
                    imageData.editTransition.get().bundle,
                    imageData.owner, true);
        });
@@ -823,7 +823,7 @@ public class ScreenshotView extends FrameLayout implements
            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED, 0, mPackageName);
            prepareSharedTransition();
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(imageData.uri, mContext),
                    ActionIntentCreator.INSTANCE.createEdit(imageData.uri, mContext),
                    imageData.editTransition.get().bundle,
                    imageData.owner, true);
        });
+28 −7
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import org.mockito.Mockito.`when` as whenever
class ActionIntentCreatorTest : SysuiTestCase() {

    @Test
    fun testCreateShareIntent() {
    fun testCreateShare() {
        val uri = Uri.parse("content://fake")

        val output = ActionIntentCreator.createShare(uri)
@@ -59,7 +59,17 @@ class ActionIntentCreatorTest : SysuiTestCase() {
    }

    @Test
    fun testCreateShareIntentWithSubject() {
    fun testCreateShare_embeddedUserIdRemoved() {
        val uri = Uri.parse("content://555@fake")

        val output = ActionIntentCreator.createShare(uri)

        assertThat(output.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java))
            .hasData(Uri.parse("content://fake"))
    }

    @Test
    fun testCreateShareWithSubject() {
        val uri = Uri.parse("content://fake")
        val subject = "Example subject"

@@ -83,7 +93,7 @@ class ActionIntentCreatorTest : SysuiTestCase() {
    }

    @Test
    fun testCreateShareIntentWithExtraText() {
    fun testCreateShareWithText() {
        val uri = Uri.parse("content://fake")
        val extraText = "Extra text"

@@ -107,13 +117,13 @@ class ActionIntentCreatorTest : SysuiTestCase() {
    }

    @Test
    fun testCreateEditIntent() {
    fun testCreateEdit() {
        val uri = Uri.parse("content://fake")
        val context = mock<Context>()

        whenever(context.getString(eq(R.string.config_screenshotEditor))).thenReturn("")

        val output = ActionIntentCreator.createEditIntent(uri, context)
        val output = ActionIntentCreator.createEdit(uri, context)

        assertThat(output).hasAction(Intent.ACTION_EDIT)
        assertThat(output).hasData(uri)
@@ -129,7 +139,18 @@ class ActionIntentCreatorTest : SysuiTestCase() {
    }

    @Test
    fun testCreateEditIntent_withEditor() {
    fun testCreateEdit_embeddedUserIdRemoved() {
        val uri = Uri.parse("content://555@fake")
        val context = mock<Context>()
        whenever(context.getString(eq(R.string.config_screenshotEditor))).thenReturn("")

        val output = ActionIntentCreator.createEdit(uri, context)

        assertThat(output).hasData(Uri.parse("content://fake"))
    }

    @Test
    fun testCreateEdit_withEditor() {
        val uri = Uri.parse("content://fake")
        val context = mock<Context>()
        val component = ComponentName("com.android.foo", "com.android.foo.Something")
@@ -137,7 +158,7 @@ class ActionIntentCreatorTest : SysuiTestCase() {
        whenever(context.getString(eq(R.string.config_screenshotEditor)))
            .thenReturn(component.flattenToString())

        val output = ActionIntentCreator.createEditIntent(uri, context)
        val output = ActionIntentCreator.createEdit(uri, context)

        assertThat(output).hasComponent(component)
    }