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

Commit 0623e241 authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Minor cleanups and fixes for ActionIntentCreator" into...

Merge "Merge "Minor cleanups and fixes for ActionIntentCreator" into udc-qpr-dev am: 62e6b210" into udc-qpr-dev-plus-aosp
parents f5c1eaa6 627245b9
Loading
Loading
Loading
Loading
+11 −16
Original line number Diff line number Diff line
@@ -26,21 +26,17 @@ import com.android.systemui.R

object ActionIntentCreator {
    /** @return a chooser intent to share the given URI. */
    fun createShareIntent(uri: Uri) = createShareIntent(uri, null, null)
    fun createShare(uri: Uri): Intent = createShare(uri, subject = null, text = null)

    /** @return a chooser intent to share the given URI with the optional provided subject. */
    fun createShareIntentWithSubject(uri: Uri, subject: String?) =
        createShareIntent(uri, subject = subject)
    fun createShareWithSubject(uri: Uri, subject: String): Intent =
        createShare(uri, subject = subject)

    /** @return a chooser intent to share the given URI with the optional provided extra text. */
    fun createShareIntentWithExtraText(uri: Uri, extraText: String?) =
        createShareIntent(uri, extraText = extraText)
    fun createShareWithText(uri: Uri, extraText: String): Intent =
        createShare(uri, text = extraText)

    private fun createShareIntent(
        uri: Uri,
        subject: String? = null,
        extraText: String? = null
    ): Intent {
    private fun createShare(uri: Uri, subject: String? = null, text: String? = null): Intent {
        // Create a share intent, this will always go through the chooser activity first
        // which should not trigger auto-enter PiP
        val sharingIntent =
@@ -56,8 +52,8 @@ object ActionIntentCreator {
                        ClipData.Item(uri)
                    )

                putExtra(Intent.EXTRA_SUBJECT, subject)
                putExtra(Intent.EXTRA_TEXT, extraText)
                subject?.let { putExtra(Intent.EXTRA_SUBJECT, subject) }
                text?.let { putExtra(Intent.EXTRA_TEXT, text) }
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
@@ -75,10 +71,9 @@ object ActionIntentCreator {
    fun createEditIntent(uri: Uri, context: Context): Intent {
        val editIntent = Intent(Intent.ACTION_EDIT)

        context.getString(R.string.config_screenshotEditor)?.let {
            if (it.isNotEmpty()) {
                editIntent.component = ComponentName.unflattenFromString(it)
            }
        val editor = context.getString(R.string.config_screenshotEditor)
        if (editor.isNotEmpty()) {
            editIntent.component = ComponentName.unflattenFromString(editor)
        }

        return editIntent
+19 −14
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Process.myUserHandle
import android.os.RemoteException
import android.os.UserHandle
import android.util.Log
@@ -44,10 +45,10 @@ import kotlinx.coroutines.withContext
class ActionIntentExecutor
@Inject
constructor(
    private val context: Context,
    @Application private val applicationScope: CoroutineScope,
    @Main private val mainDispatcher: CoroutineDispatcher,
    private val context: Context,
    private val displayTracker: DisplayTracker
    private val displayTracker: DisplayTracker,
) {
    /**
     * Execute the given intent with startActivity while performing operations for screenshot action
@@ -58,25 +59,25 @@ constructor(
     */
    fun launchIntentAsync(
        intent: Intent,
        bundle: Bundle,
        userId: Int,
        options: Bundle?,
        user: UserHandle,
        overrideTransition: Boolean,
    ) {
        applicationScope.launch { launchIntent(intent, bundle, userId, overrideTransition) }
        applicationScope.launch { launchIntent(intent, options, user, overrideTransition) }
    }

    suspend fun launchIntent(
        intent: Intent,
        bundle: Bundle,
        userId: Int,
        options: Bundle?,
        user: UserHandle,
        overrideTransition: Boolean,
    ) {
        dismissKeyguard()

        if (userId == UserHandle.myUserId()) {
            withContext(mainDispatcher) { context.startActivity(intent, bundle) }
        if (user == myUserHandle()) {
            withContext(mainDispatcher) { context.startActivity(intent, options) }
        } else {
            launchCrossProfileIntent(userId, intent, bundle)
            launchCrossProfileIntent(user, intent, options)
        }

        if (overrideTransition) {
@@ -111,17 +112,21 @@ constructor(
        completion.await()
    }

    private fun getCrossProfileConnector(userId: Int): ServiceConnector<ICrossProfileService> =
    private fun getCrossProfileConnector(user: UserHandle): ServiceConnector<ICrossProfileService> =
        ServiceConnector.Impl<ICrossProfileService>(
            context,
            Intent(context, ScreenshotCrossProfileService::class.java),
            Context.BIND_AUTO_CREATE or Context.BIND_WAIVE_PRIORITY or Context.BIND_NOT_VISIBLE,
            userId,
            user.identifier,
            ICrossProfileService.Stub::asInterface,
        )

    private suspend fun launchCrossProfileIntent(userId: Int, intent: Intent, bundle: Bundle) {
        val connector = getCrossProfileConnector(userId)
    private suspend fun launchCrossProfileIntent(
        user: UserHandle,
        intent: Intent,
        bundle: Bundle?
    ) {
        val connector = getCrossProfileConnector(user)
        val completion = CompletableDeferred<Unit>()
        connector.post {
            it.launchIntent(intent, bundle)
+3 −4
Original line number Diff line number Diff line
@@ -336,7 +336,7 @@ public class LongScreenshotActivity extends Activity {
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(uri, this),
                    null,
                    mScreenshotUserHandle.getIdentifier(), false);
                    mScreenshotUserHandle, false);
        } else {
            String editorPackage = getString(R.string.config_screenshotEditor);
            Intent intent = new Intent(Intent.ACTION_EDIT);
@@ -362,9 +362,8 @@ public class LongScreenshotActivity extends Activity {
    }

    private void doShare(Uri uri) {
        Intent shareIntent = ActionIntentCreator.INSTANCE.createShareIntent(uri);
        mActionExecutor.launchIntentAsync(shareIntent, null,
                mScreenshotUserHandle.getIdentifier(), false);
        Intent shareIntent = ActionIntentCreator.INSTANCE.createShare(uri);
        mActionExecutor.launchIntentAsync(shareIntent, null, mScreenshotUserHandle, false);
    }

    private void onClicked(View v) {
+5 −5
Original line number Diff line number Diff line
@@ -801,15 +801,15 @@ public class ScreenshotView extends FrameLayout implements
            Intent shareIntent;
            if (mFlags.isEnabled(Flags.SCREENSHOT_METADATA) && mScreenshotData != null
                    && mScreenshotData.getContextUrl() != null) {
                shareIntent = ActionIntentCreator.INSTANCE.createShareIntentWithExtraText(
                shareIntent = ActionIntentCreator.INSTANCE.createShareWithText(
                        imageData.uri, mScreenshotData.getContextUrl().toString());
            } else {
                shareIntent = ActionIntentCreator.INSTANCE.createShareIntentWithSubject(
                shareIntent = ActionIntentCreator.INSTANCE.createShareWithSubject(
                        imageData.uri, imageData.subject);
            }
            mActionExecutor.launchIntentAsync(shareIntent,
                    imageData.shareTransition.get().bundle,
                    imageData.owner.getIdentifier(), false);
                    imageData.owner, false);
        });
        mEditChip.setOnClickListener(v -> {
            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED, 0, mPackageName);
@@ -817,7 +817,7 @@ public class ScreenshotView extends FrameLayout implements
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(imageData.uri, mContext),
                    imageData.editTransition.get().bundle,
                    imageData.owner.getIdentifier(), true);
                    imageData.owner, true);
        });
        mScreenshotPreview.setOnClickListener(v -> {
            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED, 0, mPackageName);
@@ -825,7 +825,7 @@ public class ScreenshotView extends FrameLayout implements
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(imageData.uri, mContext),
                    imageData.editTransition.get().bundle,
                    imageData.owner.getIdentifier(), true);
                    imageData.owner, true);
        });
        if (mQuickShareChip != null) {
            if (imageData.quickShareAction != null) {
+61 −62
Original line number Diff line number Diff line
@@ -20,12 +20,13 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.test.ext.truth.content.IntentSubject.assertThat
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Test
import org.mockito.Mockito.`when` as whenever

@@ -36,24 +37,25 @@ class ActionIntentCreatorTest : SysuiTestCase() {
    fun testCreateShareIntent() {
        val uri = Uri.parse("content://fake")

        val output = ActionIntentCreator.createShareIntent(uri)
        val output = ActionIntentCreator.createShare(uri)

        assertThat(output.action).isEqualTo(Intent.ACTION_CHOOSER)
        assertFlagsSet(
        assertThat(output).hasAction(Intent.ACTION_CHOOSER)
        assertThat(output)
            .hasFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TASK or
                Intent.FLAG_GRANT_READ_URI_PERMISSION,
            output.flags
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
            )

        assertThat(output).extras().parcelable<Intent>(Intent.EXTRA_INTENT).isNotNull()
        val wrappedIntent = output.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
        assertThat(wrappedIntent?.action).isEqualTo(Intent.ACTION_SEND)
        assertThat(wrappedIntent?.data).isEqualTo(uri)
        assertThat(wrappedIntent?.type).isEqualTo("image/png")
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_SUBJECT)).isNull()
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_TEXT)).isNull()
        assertThat(wrappedIntent?.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))
            .isEqualTo(uri)

        assertThat(wrappedIntent).hasAction(Intent.ACTION_SEND)
        assertThat(wrappedIntent).hasData(uri)
        assertThat(wrappedIntent).hasType("image/png")
        assertThat(wrappedIntent).extras().doesNotContainKey(Intent.EXTRA_SUBJECT)
        assertThat(wrappedIntent).extras().doesNotContainKey(Intent.EXTRA_TEXT)
        assertThat(wrappedIntent).extras().parcelable<Uri>(Intent.EXTRA_STREAM).isEqualTo(uri)
    }

    @Test
@@ -61,24 +63,23 @@ class ActionIntentCreatorTest : SysuiTestCase() {
        val uri = Uri.parse("content://fake")
        val subject = "Example subject"

        val output = ActionIntentCreator.createShareIntentWithSubject(uri, subject)
        val output = ActionIntentCreator.createShareWithSubject(uri, subject)

        assertThat(output.action).isEqualTo(Intent.ACTION_CHOOSER)
        assertFlagsSet(
        assertThat(output).hasAction(Intent.ACTION_CHOOSER)
        assertThat(output)
            .hasFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TASK or
                Intent.FLAG_GRANT_READ_URI_PERMISSION,
            output.flags
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
            )

        val wrappedIntent = output.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
        assertThat(wrappedIntent?.action).isEqualTo(Intent.ACTION_SEND)
        assertThat(wrappedIntent?.data).isEqualTo(uri)
        assertThat(wrappedIntent?.type).isEqualTo("image/png")
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_SUBJECT)).isEqualTo(subject)
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_TEXT)).isNull()
        assertThat(wrappedIntent?.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))
            .isEqualTo(uri)
        assertThat(wrappedIntent).hasAction(Intent.ACTION_SEND)
        assertThat(wrappedIntent).hasData(uri)
        assertThat(wrappedIntent).hasType("image/png")
        assertThat(wrappedIntent).extras().string(Intent.EXTRA_SUBJECT).isEqualTo(subject)
        assertThat(wrappedIntent).extras().doesNotContainKey(Intent.EXTRA_TEXT)
        assertThat(wrappedIntent).extras().parcelable<Uri>(Intent.EXTRA_STREAM).isEqualTo(uri)
    }

    @Test
@@ -86,24 +87,23 @@ class ActionIntentCreatorTest : SysuiTestCase() {
        val uri = Uri.parse("content://fake")
        val extraText = "Extra text"

        val output = ActionIntentCreator.createShareIntentWithExtraText(uri, extraText)
        val output = ActionIntentCreator.createShareWithText(uri, extraText)

        assertThat(output.action).isEqualTo(Intent.ACTION_CHOOSER)
        assertFlagsSet(
        assertThat(output).hasAction(Intent.ACTION_CHOOSER)
        assertThat(output)
            .hasFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TASK or
                Intent.FLAG_GRANT_READ_URI_PERMISSION,
            output.flags
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
            )

        val wrappedIntent = output.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
        assertThat(wrappedIntent?.action).isEqualTo(Intent.ACTION_SEND)
        assertThat(wrappedIntent?.data).isEqualTo(uri)
        assertThat(wrappedIntent?.type).isEqualTo("image/png")
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_SUBJECT)).isNull()
        assertThat(wrappedIntent?.getStringExtra(Intent.EXTRA_TEXT)).isEqualTo(extraText)
        assertThat(wrappedIntent?.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))
            .isEqualTo(uri)
        assertThat(wrappedIntent).hasAction(Intent.ACTION_SEND)
        assertThat(wrappedIntent).hasData(uri)
        assertThat(wrappedIntent).hasType("image/png")
        assertThat(wrappedIntent).extras().doesNotContainKey(Intent.EXTRA_SUBJECT)
        assertThat(wrappedIntent).extras().string(Intent.EXTRA_TEXT).isEqualTo(extraText)
        assertThat(wrappedIntent).extras().parcelable<Uri>(Intent.EXTRA_STREAM).isEqualTo(uri)
    }

    @Test
@@ -111,35 +111,34 @@ class ActionIntentCreatorTest : SysuiTestCase() {
        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)

        assertThat(output.action).isEqualTo(Intent.ACTION_EDIT)
        assertThat(output.data).isEqualTo(uri)
        assertThat(output.type).isEqualTo("image/png")
        assertThat(output.component).isNull()
        val expectedFlags =
        assertThat(output).hasAction(Intent.ACTION_EDIT)
        assertThat(output).hasData(uri)
        assertThat(output).hasType("image/png")
        assertWithMessage("getComponent()").that(output.component).isNull()
        assertThat(output)
            .hasFlags(
                Intent.FLAG_GRANT_READ_URI_PERMISSION or
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
                    Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TASK
        assertFlagsSet(expectedFlags, output.flags)
            )
    }

    @Test
    fun testCreateEditIntent_withEditor() {
        val uri = Uri.parse("content://fake")
        val context = mock<Context>()
        var component = ComponentName("com.android.foo", "com.android.foo.Something")
        val component = ComponentName("com.android.foo", "com.android.foo.Something")

        whenever(context.getString(eq(R.string.config_screenshotEditor)))
            .thenReturn(component.flattenToString())

        val output = ActionIntentCreator.createEditIntent(uri, context)

        assertThat(output.component).isEqualTo(component)
    }

    private fun assertFlagsSet(expected: Int, observed: Int) {
        assertThat(observed and expected).isEqualTo(expected)
        assertThat(output).hasComponent(component)
    }
}