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

Commit 627245b9 authored by Mark Renouf's avatar Mark Renouf Committed by Automerger Merge Worker
Browse files

Merge "Minor cleanups and fixes for ActionIntentCreator" into udc-qpr-dev am: 62e6b210

parents 6be32296 62e6b210
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)
    }
}