diff options
| author | 2024-02-15 15:26:09 +0000 | |
|---|---|---|
| committer | 2024-02-15 15:26:09 +0000 | |
| commit | e0d0d0658d2547d4edab56e3a6b46c52f5b29fdc (patch) | |
| tree | d38192b03421088b797d7dea6e5235215baf9c0c | |
| parent | 5c69324432495571e7fcf52cee7180a088e55ed1 (diff) | |
| parent | 98120650d1177cb17e42cd8209d2a26f5f24473f (diff) | |
Merge "Fix infinite loop in edit/copy callbacks" into main
4 files changed, 32 insertions, 16 deletions
diff --git a/java/src/com/android/intentresolver/v2/ChooserActionFactory.java b/java/src/com/android/intentresolver/v2/ChooserActionFactory.java index f9de9f4b..9077a18d 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActionFactory.java +++ b/java/src/com/android/intentresolver/v2/ChooserActionFactory.java @@ -131,11 +131,12 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio Callable</* @Nullable */ View> firstVisibleImageQuery, ActionActivityStarter activityStarter, @Nullable ShareResultSender shareResultSender, - Consumer</* @Nullable */ Integer> finishCallback) { + Consumer</* @Nullable */ Integer> finishCallback, + ClipboardManager clipboardManager) { this( context, makeCopyButtonRunnable( - context, + clipboardManager, targetIntent, referrerPackageName, finishCallback, @@ -181,13 +182,12 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio if (mShareResultSender != null) { mEditButtonRunnable = () -> { mShareResultSender.onActionSelected(ShareAction.SYSTEM_EDIT); - mEditButtonRunnable.run(); + editButtonRunnable.run(); }; if (mCopyButtonRunnable != null) { mCopyButtonRunnable = () -> { mShareResultSender.onActionSelected(ShareAction.SYSTEM_COPY); - //noinspection DataFlowIssue - mCopyButtonRunnable.run(); + copyButtonRunnable.run(); }; } } @@ -245,7 +245,7 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio @Nullable private static Runnable makeCopyButtonRunnable( - Context context, + ClipboardManager clipboardManager, Intent targetIntent, String referrerPackageName, Consumer<Integer> finishCallback, @@ -261,8 +261,6 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio return null; } return () -> { - ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService( - Context.CLIPBOARD_SERVICE); clipboardManager.setPrimaryClipAsPackage(clipData, referrerPackageName); log.logActionSelected(EventLog.SELECTION_TYPE_COPY); diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java index 1a7dd9d6..510d3bc9 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActivity.java +++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java @@ -47,6 +47,7 @@ import android.app.prediction.AppPredictor; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; import android.app.prediction.AppTargetId; +import android.content.ClipboardManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -278,6 +279,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements @Inject public TargetDataLoader mTargetDataLoader; @Inject public DevicePolicyResources mDevicePolicyResources; @Inject public PackageManager mPackageManager; + @Inject public ClipboardManager mClipboardManager; @Inject public IntentForwarding mIntentForwarding; @Inject public ShareResultSenderFactory mShareResultSenderFactory; @Nullable @@ -2149,7 +2151,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements setResult(status); } finish(); - }); + }, + mClipboardManager); } /* diff --git a/tests/unit/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt b/tests/unit/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt index 717d26bd..95e4c377 100644 --- a/tests/unit/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt +++ b/tests/unit/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt @@ -31,6 +31,8 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.intentresolver.ChooserRequestParameters import com.android.intentresolver.logging.EventLog import com.android.intentresolver.mock +import com.android.intentresolver.v2.ui.ShareResultSender +import com.android.intentresolver.v2.ui.model.ShareAction import com.android.intentresolver.whenever import com.google.common.collect.ImmutableList import com.google.common.truth.Truth.assertThat @@ -45,7 +47,9 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito +import org.mockito.Mockito.eq +import org.mockito.Mockito.times +import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) class ChooserActionFactoryTest { @@ -94,7 +98,7 @@ class ChooserActionFactoryTest { // click it customActions[0].onClicked.run() - Mockito.verify(logger).logCustomActionSelected(eq(0)) + verify(logger).logCustomActionSelected(eq(0)) assertEquals(Activity.RESULT_OK, resultConsumer.latestReturn) // Verify the pending intent has been called assertTrue("Timed out waiting for broadcast", countdown.await(2500, TimeUnit.MILLISECONDS)) @@ -114,7 +118,7 @@ class ChooserActionFactoryTest { val action = factory.modifyShareAction ?: error("Modify share action should not be null") action.onClicked.run() - Mockito.verify(logger).logActionSelected(eq(EventLog.SELECTION_TYPE_MODIFY_SHARE)) + verify(logger).logActionSelected(eq(EventLog.SELECTION_TYPE_MODIFY_SHARE)) assertEquals(Activity.RESULT_OK, resultConsumer.latestReturn) // Verify the pending intent has been called assertTrue("Timed out waiting for broadcast", countdown.await(2500, TimeUnit.MILLISECONDS)) @@ -146,6 +150,7 @@ class ChooserActionFactoryTest { /* activityStarter = */ mock(), /* shareResultSender = */ null, /* finishCallback = */ {}, + /* clipboardManager = */ mock(), ) assertThat(testSubject.copyButtonRunnable).isNull() } @@ -173,12 +178,13 @@ class ChooserActionFactoryTest { /* activityStarter = */ mock(), /* shareResultSender = */ null, /* finishCallback = */ {}, + /* clipboardManager = */ mock(), ) assertThat(testSubject.copyButtonRunnable).isNull() } @Test - fun sendActionWithText_nonNullCopyRunnable() { + fun sendActionWithTextCopyRunnable() { val targetIntent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_TEXT, "Text") } val chooserRequest = @@ -186,6 +192,8 @@ class ChooserActionFactoryTest { whenever(this.targetIntent).thenReturn(targetIntent) whenever(chooserActions).thenReturn(ImmutableList.of()) } + + val resultSender = mock<ShareResultSender>() val testSubject = ChooserActionFactory( /* context = */ context, @@ -198,10 +206,15 @@ class ChooserActionFactoryTest { /* onUpdateSharedTextIsExcluded = */ {}, /* firstVisibleImageQuery = */ { null }, /* activityStarter = */ mock(), - /* shareResultSender = */ null, + /* shareResultSender = */ resultSender, /* finishCallback = */ {}, + /* clipboardManager = */ mock(), ) assertThat(testSubject.copyButtonRunnable).isNotNull() + + testSubject.copyButtonRunnable?.run() + + verify(resultSender, times(1)).onActionSelected(ShareAction.SYSTEM_COPY) } private fun createFactory(includeModifyShare: Boolean = false): ChooserActionFactory { @@ -242,7 +255,8 @@ class ChooserActionFactoryTest { /* firstVisibleImageQuery = */ { null }, /* activityStarter = */ mock(), /* shareResultSender = */ null, - /* finishCallback = */ resultConsumer + /* finishCallback = */ resultConsumer, + /* clipboardManager = */ mock(), ) } } diff --git a/tests/unit/src/com/android/intentresolver/v2/ChooserMutableActionFactoryTest.kt b/tests/unit/src/com/android/intentresolver/v2/ChooserMutableActionFactoryTest.kt index 42702cef..ec2b807d 100644 --- a/tests/unit/src/com/android/intentresolver/v2/ChooserMutableActionFactoryTest.kt +++ b/tests/unit/src/com/android/intentresolver/v2/ChooserMutableActionFactoryTest.kt @@ -110,7 +110,8 @@ class ChooserMutableActionFactoryTest { /* firstVisibleImageQuery = */ { null }, /* activityStarter = */ mock(), /* shareResultSender = */ null, - /* finishCallback = */ resultConsumer + /* finishCallback = */ resultConsumer, + mock() ) } |