diff options
5 files changed, 99 insertions, 101 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt index a8f99bef2423..76d0f6e714f2 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt index 187019a4851d..ecd456887fa4 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt @@ -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) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java index e6e1faccc3e2..010658beca9a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 093c09fff995..204b5e6ec536 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -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) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt index 7ba2cf7f6374..77e4d89a5215 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt @@ -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( - Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_CLEAR_TASK or - Intent.FLAG_GRANT_READ_URI_PERMISSION, - output.flags - ) + 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 + ) + 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( - Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_CLEAR_TASK or - Intent.FLAG_GRANT_READ_URI_PERMISSION, - output.flags - ) + 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 + ) 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( - Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_CLEAR_TASK or - Intent.FLAG_GRANT_READ_URI_PERMISSION, - output.flags - ) + 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 + ) 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 = - 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) + 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 + ) } @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) } } |