summaryrefslogtreecommitdiff
path: root/java/tests
diff options
context:
space:
mode:
author Mark Renouf <mrenouf@google.com> 2023-09-13 16:06:05 -0400
committer Mark Renouf <mrenouf@google.com> 2023-09-14 11:21:56 -0400
commitae322c4ddbcb552979fba17a22b931081020014e (patch)
treed74c1b22fa51dd9d281fa016fe110e09d1bd37c1 /java/tests
parenta7382f3265d0bb76532b561059e56bafa855542e (diff)
Injects EventLog, provides FakeEventLog within tests
Using Hilt we are able to declaratively replace modules within integration tests. This is the first such instance within IntentResolver. Scope: An InstanceIdSequence in @Singleton scope provides a new InstanceId value to each EventLog created. EventLog is @ActivityScoped or one-per-activity instance. This matches the existing behavior. By adding [TestEventLogModule], all integration tests are now using a FakeEventLog by default (migrated away from 'override data' scheme). Bug: 299610743 Bug: 300157408 Test: atest IntentResolverUnitTests Change-Id: I33d6f4d1241a890ab88b631859652117ce20f7be
Diffstat (limited to 'java/tests')
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserActionFactoryTest.kt3
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java3
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java6
-rw-r--r--java/tests/src/com/android/intentresolver/IChooserWrapper.java2
-rw-r--r--java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java205
-rw-r--r--java/tests/src/com/android/intentresolver/logging/EventLogImplTest.java10
-rw-r--r--java/tests/src/com/android/intentresolver/logging/FakeEventLog.kt197
-rw-r--r--java/tests/src/com/android/intentresolver/logging/FakeFrameworkStatsLogger.kt95
-rw-r--r--java/tests/src/com/android/intentresolver/logging/TestEventLogModule.kt39
9 files changed, 439 insertions, 121 deletions
diff --git a/java/tests/src/com/android/intentresolver/ChooserActionFactoryTest.kt b/java/tests/src/com/android/intentresolver/ChooserActionFactoryTest.kt
index e2b987c2..2d1ac4e4 100644
--- a/java/tests/src/com/android/intentresolver/ChooserActionFactoryTest.kt
+++ b/java/tests/src/com/android/intentresolver/ChooserActionFactoryTest.kt
@@ -28,13 +28,12 @@ import android.graphics.drawable.Icon
import android.service.chooser.ChooserAction
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.intentresolver.logging.EventLogImpl
+import com.android.intentresolver.logging.EventLog
import com.google.common.collect.ImmutableList
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
-import com.android.intentresolver.logging.EventLog
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
index b5c14ff1..d77aa099 100644
--- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
+++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
@@ -29,7 +29,6 @@ import android.os.UserHandle;
import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
import com.android.intentresolver.chooser.TargetInfo;
import com.android.intentresolver.contentpreview.ImageLoader;
-import com.android.intentresolver.logging.EventLogImpl;
import com.android.intentresolver.shortcuts.ShortcutLoader;
import java.util.function.Consumer;
@@ -64,7 +63,6 @@ public class ChooserActivityOverrideData {
public Cursor resolverCursor;
public boolean resolverForceException;
public ImageLoader imageLoader;
- public EventLogImpl mEventLog;
public int alternateProfileSetting;
public Resources resources;
public UserHandle workProfileUserHandle;
@@ -86,7 +84,6 @@ public class ChooserActivityOverrideData {
resolverForceException = false;
resolverListController = mock(ChooserActivity.ChooserListController.class);
workResolverListController = mock(ChooserActivity.ChooserListController.class);
- mEventLog = mock(EventLogImpl.class);
alternateProfileSetting = 0;
resources = null;
workProfileUserHandle = null;
diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
index d488e02b..27b7037f 100644
--- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
+++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
@@ -39,7 +39,6 @@ import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.TargetInfo;
import com.android.intentresolver.grid.ChooserGridAdapter;
import com.android.intentresolver.icons.TargetDataLoader;
-import com.android.intentresolver.logging.EventLogImpl;
import com.android.intentresolver.shortcuts.ShortcutLoader;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -204,11 +203,6 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW
}
@Override
- public EventLogImpl getEventLog() {
- return sOverrides.mEventLog;
- }
-
- @Override
public Cursor queryResolver(ContentResolver resolver, Uri uri) {
if (sOverrides.resolverCursor != null) {
return sOverrides.resolverCursor;
diff --git a/java/tests/src/com/android/intentresolver/IChooserWrapper.java b/java/tests/src/com/android/intentresolver/IChooserWrapper.java
index 54e4da9e..d439b037 100644
--- a/java/tests/src/com/android/intentresolver/IChooserWrapper.java
+++ b/java/tests/src/com/android/intentresolver/IChooserWrapper.java
@@ -23,7 +23,6 @@ import android.content.pm.ResolveInfo;
import android.os.UserHandle;
import com.android.intentresolver.chooser.DisplayResolveInfo;
-import com.android.intentresolver.logging.EventLogImpl;
import java.util.concurrent.Executor;
@@ -42,6 +41,5 @@ public interface IChooserWrapper {
CharSequence pLabel, CharSequence pInfo, Intent replacementIntent,
@Nullable TargetPresentationGetter resolveInfoPresentationGetter);
UserHandle getCurrentUserHandle();
- EventLogImpl getEventLog();
Executor getMainExecutor();
}
diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
index 0b3cb20a..9f16ced5 100644
--- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
+++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
@@ -36,6 +36,7 @@ import static com.android.intentresolver.ChooserListAdapter.CALLER_TARGET_SCORE_
import static com.android.intentresolver.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST;
import static com.android.intentresolver.MatcherUtils.first;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static junit.framework.Assert.assertNull;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.is;
@@ -44,9 +45,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -93,7 +92,6 @@ import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
-import android.util.HashedStringCache;
import android.util.Pair;
import android.util.SparseArray;
import android.view.View;
@@ -113,11 +111,14 @@ import androidx.test.rule.ActivityTestRule;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.contentpreview.ImageLoader;
import com.android.intentresolver.logging.EventLog;
-import com.android.intentresolver.logging.EventLogImpl;
+import com.android.intentresolver.logging.FakeEventLog;
import com.android.intentresolver.shortcuts.ShortcutLoader;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import dagger.hilt.android.testing.HiltAndroidRule;
+import dagger.hilt.android.testing.HiltAndroidTest;
+
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
@@ -146,9 +147,6 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
-import dagger.hilt.android.testing.HiltAndroidRule;
-import dagger.hilt.android.testing.HiltAndroidTest;
-
/**
* Instrumentation tests for ChooserActivity.
* <p>
@@ -159,6 +157,10 @@ import dagger.hilt.android.testing.HiltAndroidTest;
@HiltAndroidTest
public class UnbundledChooserActivityTest {
+ private static FakeEventLog getEventLog(ChooserWrapperActivity activity) {
+ return (FakeEventLog) activity.mEventLog;
+ }
+
private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
.getInstrumentation().getTargetContext().getUser();
private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm;
@@ -179,6 +181,20 @@ public class UnbundledChooserActivityTest {
});
}
+ private static final String TEST_MIME_TYPE = "application/TestType";
+
+ private static final int CONTENT_PREVIEW_IMAGE = 1;
+ private static final int CONTENT_PREVIEW_FILE = 2;
+ private static final int CONTENT_PREVIEW_TEXT = 3;
+
+
+ @Rule(order = 0)
+ public HiltAndroidRule mHiltAndroidRule = new HiltAndroidRule(this);
+
+ @Rule(order = 1)
+ public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
+ new ActivityTestRule<>(ChooserWrapperActivity.class, false, false);
+
@Before
public void setUp() {
// TODO: use the other form of `adoptShellPermissionIdentity()` where we explicitly list the
@@ -189,21 +205,9 @@ public class UnbundledChooserActivityTest {
.adoptShellPermissionIdentity();
cleanOverrideData();
+ mHiltAndroidRule.inject();
}
- @Rule(order = 0)
- public HiltAndroidRule mHiltAndroidRule = new HiltAndroidRule(this);
-
- @Rule(order = 1)
- public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
- new ActivityTestRule<>(ChooserWrapperActivity.class, false, false);
-
- private static final String TEST_MIME_TYPE = "application/TestType";
-
- private static final int CONTENT_PREVIEW_IMAGE = 1;
- private static final int CONTENT_PREVIEW_FILE = 2;
- private static final int CONTENT_PREVIEW_TEXT = 3;
-
private final Function<PackageManager, PackageManager> mPackageManagerOverride;
public UnbundledChooserActivityTest(
@@ -845,15 +849,16 @@ public class UnbundledChooserActivityTest {
setupResolverControllers(resolvedComponentInfos);
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
onView(withId(R.id.copy)).check(matches(isDisplayed()));
onView(withId(R.id.copy)).perform(click());
-
- EventLog logger = activity.getEventLog();
- verify(logger, times(1)).logActionSelected(eq(EventLogImpl.SELECTION_TYPE_COPY));
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getActionSelected())
+ .isEqualTo(new FakeEventLog.ActionSelected(
+ /* targetType = */ EventLog.SELECTION_TYPE_COPY));
}
@Test
@@ -864,8 +869,7 @@ public class UnbundledChooserActivityTest {
setupResolverControllers(resolvedComponentInfos);
- final IChooserWrapper activity = (IChooserWrapper)
- mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
onView(withId(com.android.internal.R.id.chooser_nearby_button))
@@ -888,8 +892,7 @@ public class UnbundledChooserActivityTest {
setupResolverControllers(resolvedComponentInfos);
- final IChooserWrapper activity = (IChooserWrapper)
- mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
onView(withId(com.android.internal.R.id.chooser_edit_button)).check(matches(isDisplayed()));
@@ -1200,12 +1203,15 @@ public class UnbundledChooserActivityTest {
Intent sendIntent = createSendTextIntent();
sendIntent.setType(TEST_MIME_TYPE);
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
- EventLog logger = activity.getEventLog();
waitForIdle();
- verify(logger).logChooserActivityShown(eq(false), eq(TEST_MIME_TYPE), anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ FakeEventLog.ChooserActivityShown event = eventLog.getChooserActivityShown();
+ assertThat(event).isNotNull();
+ assertThat(event.isWorkProfile()).isFalse();
+ assertThat(event.getTargetMimeType()).isEqualTo(TEST_MIME_TYPE);
}
@Test
@@ -1215,25 +1221,31 @@ public class UnbundledChooserActivityTest {
ChooserActivityOverrideData.getInstance().alternateProfileSetting =
MetricsEvent.MANAGED_PROFILE;
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
- EventLog logger = activity.getEventLog();
waitForIdle();
- verify(logger).logChooserActivityShown(eq(true), eq(TEST_MIME_TYPE), anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ FakeEventLog.ChooserActivityShown event = eventLog.getChooserActivityShown();
+ assertThat(event).isNotNull();
+ assertThat(event.isWorkProfile()).isTrue();
+ assertThat(event.getTargetMimeType()).isEqualTo(TEST_MIME_TYPE);
}
@Test
public void testEmptyPreviewLogging() {
Intent sendIntent = createSendTextIntentWithPreview(null, null);
- final IChooserWrapper activity = (IChooserWrapper)
- mActivityRule.launchActivity(
- Intent.createChooser(sendIntent, "empty preview logger test"));
- EventLog logger = activity.getEventLog();
+ ChooserWrapperActivity activity =
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent,
+ "empty preview logger test"));
waitForIdle();
- verify(logger).logChooserActivityShown(eq(false), eq(null), anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ FakeEventLog.ChooserActivityShown event = eventLog.getChooserActivityShown();
+ assertThat(event).isNotNull();
+ assertThat(event.isWorkProfile()).isFalse();
+ assertThat(event.getTargetMimeType()).isNull();
}
@Test
@@ -1244,13 +1256,14 @@ public class UnbundledChooserActivityTest {
setupResolverControllers(resolvedComponentInfos);
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- // Second invocation is from onCreate
- EventLog logger = activity.getEventLog();
- Mockito.verify(logger, times(1)).logActionShareWithPreview(eq(CONTENT_PREVIEW_TEXT));
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getActionShareWithPreview())
+ .isEqualTo(new FakeEventLog.ActionShareWithPreview(
+ /* previewType = */ CONTENT_PREVIEW_TEXT));
}
@Test
@@ -1268,11 +1281,14 @@ public class UnbundledChooserActivityTest {
setupResolverControllers(resolvedComponentInfos);
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- EventLog logger = activity.getEventLog();
- Mockito.verify(logger, times(1)).logActionShareWithPreview(eq(CONTENT_PREVIEW_IMAGE));
+
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getActionShareWithPreview())
+ .isEqualTo(new FakeEventLog.ActionShareWithPreview(
+ /* previewType = */ CONTENT_PREVIEW_IMAGE));
}
@Test
@@ -1421,7 +1437,7 @@ public class UnbundledChooserActivityTest {
createShortcutLoaderFactory();
// Start activity
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
@@ -1471,22 +1487,15 @@ public class UnbundledChooserActivityTest {
.perform(click());
waitForIdle();
- ArgumentCaptor<HashedStringCache.HashResult> hashCaptor =
- ArgumentCaptor.forClass(HashedStringCache.HashResult.class);
- verify(activity.getEventLog(), times(1)).logShareTargetSelected(
- eq(EventLogImpl.SELECTION_TYPE_SERVICE),
- /* packageName= */ any(),
- /* positionPicked= */ anyInt(),
- /* directTargetAlsoRanked= */ eq(-1),
- /* numCallerProvided= */ anyInt(),
- /* directTargetHashed= */ hashCaptor.capture(),
- /* isPinned= */ anyBoolean(),
- /* successfullySelected= */ anyBoolean(),
- /* selectionCost= */ anyLong());
- String hashedName = hashCaptor.getValue().hashedString;
- assertThat(
- "Hash is not predictable but must be obfuscated",
- hashedName, is(not(name)));
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getShareTargetSelected()).hasSize(1);
+ FakeEventLog.ShareTargetSelected call = eventLog.getShareTargetSelected().get(0);
+ assertThat(call.getTargetType()).isEqualTo(EventLog.SELECTION_TYPE_SERVICE);
+ assertThat(call.getDirectTargetAlsoRanked()).isEqualTo(-1);
+ var hashResult = call.getDirectTargetHashed();
+ var hash = hashResult == null ? "" : hashResult.hashedString;
+ assertWithMessage("Hash is not predictable but must be obfuscated")
+ .that(hash).isNotEqualTo(name);
}
// This test is too long and too slow and should not be taken as an example for future tests.
@@ -1502,7 +1511,7 @@ public class UnbundledChooserActivityTest {
createShortcutLoaderFactory();
// Start activity
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
@@ -1554,16 +1563,12 @@ public class UnbundledChooserActivityTest {
.perform(click());
waitForIdle();
- verify(activity.getEventLog(), times(1)).logShareTargetSelected(
- eq(EventLogImpl.SELECTION_TYPE_SERVICE),
- /* packageName= */ any(),
- /* positionPicked= */ anyInt(),
- /* directTargetAlsoRanked= */ eq(0),
- /* numCallerProvided= */ anyInt(),
- /* directTargetHashed= */ any(),
- /* isPinned= */ anyBoolean(),
- /* successfullySelected= */ anyBoolean(),
- /* selectionCost= */ anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getShareTargetSelected()).hasSize(1);
+ FakeEventLog.ShareTargetSelected call = eventLog.getShareTargetSelected().get(0);
+
+ assertThat(call.getTargetType()).isEqualTo(EventLog.SELECTION_TYPE_SERVICE);
+ assertThat(call.getDirectTargetAlsoRanked()).isEqualTo(0);
}
@Test
@@ -1935,14 +1940,14 @@ public class UnbundledChooserActivityTest {
ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0, PERSONAL_USER_HANDLE);
// Start activity
- final IChooserWrapper wrapper = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
// Insert the direct share target
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
directShareToShortcutInfos.put(serviceTargets.get(0), null);
InstrumentationRegistry.getInstrumentation().runOnMainSync(
- () -> wrapper.getAdapter().addServiceResults(
- wrapper.createTestDisplayResolveInfo(sendIntent,
+ () -> activity.getAdapter().addServiceResults(
+ activity.createTestDisplayResolveInfo(sendIntent,
ri,
"testLabel",
"testInfo",
@@ -1957,11 +1962,11 @@ public class UnbundledChooserActivityTest {
assertThat(
String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
appTargetsExpected + 16, appTargetsExpected),
- wrapper.getAdapter().getCount(), is(appTargetsExpected + 16));
+ activity.getAdapter().getCount(), is(appTargetsExpected + 16));
assertThat("Chooser should have exactly one selectable direct target",
- wrapper.getAdapter().getSelectableServiceTargetCount(), is(1));
+ activity.getAdapter().getSelectableServiceTargetCount(), is(1));
assertThat("The resolver info must match the resolver info used to create the target",
- wrapper.getAdapter().getItem(0).getResolveInfo(), is(ri));
+ activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
// Click on the direct target
String name = serviceTargets.get(0).getTitle().toString();
@@ -1969,18 +1974,16 @@ public class UnbundledChooserActivityTest {
.perform(click());
waitForIdle();
- EventLog logger = wrapper.getEventLog();
- verify(logger, times(1)).logShareTargetSelected(
- eq(EventLogImpl.SELECTION_TYPE_SERVICE),
- /* packageName= */ any(),
- /* positionPicked= */ anyInt(),
- // The packages sholdn't match for app target and direct target:
- /* directTargetAlsoRanked= */ eq(-1),
- /* numCallerProvided= */ anyInt(),
- /* directTargetHashed= */ any(),
- /* isPinned= */ anyBoolean(),
- /* successfullySelected= */ anyBoolean(),
- /* selectionCost= */ anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ var invocations = eventLog.getShareTargetSelected();
+ assertWithMessage("Only one ShareTargetSelected event logged")
+ .that(invocations).hasSize(1);
+ FakeEventLog.ShareTargetSelected call = invocations.get(0);
+ assertWithMessage("targetType should be SELECTION_TYPE_SERVICE")
+ .that(call.getTargetType()).isEqualTo(EventLog.SELECTION_TYPE_SERVICE);
+ assertWithMessage(
+ "The packages shouldn't match for app target and direct target")
+ .that(call.getDirectTargetAlsoRanked()).isEqualTo(-1);
}
@Test
@@ -2253,7 +2256,7 @@ public class UnbundledChooserActivityTest {
};
// Start activity
- final IChooserWrapper activity = (IChooserWrapper)
+ ChooserWrapperActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
@@ -2301,18 +2304,10 @@ public class UnbundledChooserActivityTest {
.perform(click());
waitForIdle();
- EventLog logger = activity.getEventLog();
- ArgumentCaptor<Integer> typeCaptor = ArgumentCaptor.forClass(Integer.class);
- verify(logger, times(1)).logShareTargetSelected(
- eq(EventLogImpl.SELECTION_TYPE_SERVICE),
- /* packageName= */ any(),
- /* positionPicked= */ anyInt(),
- /* directTargetAlsoRanked= */ anyInt(),
- /* numCallerProvided= */ anyInt(),
- /* directTargetHashed= */ any(),
- /* isPinned= */ anyBoolean(),
- /* successfullySelected= */ anyBoolean(),
- /* selectionCost= */ anyLong());
+ FakeEventLog eventLog = getEventLog(activity);
+ assertThat(eventLog.getShareTargetSelected()).hasSize(1);
+ FakeEventLog.ShareTargetSelected call = eventLog.getShareTargetSelected().get(0);
+ assertThat(call.getTargetType()).isEqualTo(EventLog.SELECTION_TYPE_SERVICE);
}
@Test
diff --git a/java/tests/src/com/android/intentresolver/logging/EventLogImplTest.java b/java/tests/src/com/android/intentresolver/logging/EventLogImplTest.java
index 19177798..d75ea99b 100644
--- a/java/tests/src/com/android/intentresolver/logging/EventLogImplTest.java
+++ b/java/tests/src/com/android/intentresolver/logging/EventLogImplTest.java
@@ -37,6 +37,7 @@ import com.android.intentresolver.logging.EventLogImpl.SharesheetStartedEvent;
import com.android.intentresolver.logging.EventLogImpl.SharesheetTargetSelectedEvent;
import com.android.intentresolver.contentpreview.ContentPreviewType;
import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLogger.UiEventEnum;
@@ -59,10 +60,12 @@ public final class EventLogImplTest {
private EventLogImpl mChooserLogger;
+ private final InstanceIdSequence mSequence = EventLogImpl.newIdSequence();
+
@Before
public void setUp() {
- //Mockito.reset(mUiEventLog, mFrameworkLog, mMetricsLogger);
- mChooserLogger = new EventLogImpl(mUiEventLog, mFrameworkLog, mMetricsLogger);
+ mChooserLogger = new EventLogImpl(mUiEventLog, mFrameworkLog, mMetricsLogger,
+ mSequence.newInstanceId());
}
@After
@@ -320,7 +323,8 @@ public final class EventLogImplTest {
public void testDifferentLoggerInstancesUseDifferentInstanceIds() {
ArgumentCaptor<Integer> idIntCaptor = ArgumentCaptor.forClass(Integer.class);
EventLogImpl chooserLogger2 =
- new EventLogImpl(mUiEventLog, mFrameworkLog, mMetricsLogger);
+ new EventLogImpl(mUiEventLog, mFrameworkLog, mMetricsLogger,
+ mSequence.newInstanceId());
final int targetType = EventLogImpl.SELECTION_TYPE_COPY;
final String packageName = "com.test.foo";
diff --git a/java/tests/src/com/android/intentresolver/logging/FakeEventLog.kt b/java/tests/src/com/android/intentresolver/logging/FakeEventLog.kt
new file mode 100644
index 00000000..9ed47db6
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/logging/FakeEventLog.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.intentresolver.logging
+
+import android.net.Uri
+import android.util.HashedStringCache
+import android.util.Log
+import com.android.internal.logging.InstanceId
+import javax.inject.Inject
+
+private const val TAG = "EventLog"
+private const val LOG = true
+
+/** A fake EventLog. */
+class FakeEventLog @Inject constructor(private val instanceId: InstanceId) : EventLog {
+
+ var chooserActivityShown: ChooserActivityShown? = null
+ var actionSelected: ActionSelected? = null
+ var customActionSelected: CustomActionSelected? = null
+ var actionShareWithPreview: ActionShareWithPreview? = null
+ val shareTargetSelected: MutableList<ShareTargetSelected> = mutableListOf()
+
+ private fun log(message: () -> Any?) {
+ if (LOG) {
+ Log.d(TAG, "[%04x] ".format(instanceId.id) + message())
+ }
+ }
+
+ override fun logChooserActivityShown(
+ isWorkProfile: Boolean,
+ targetMimeType: String?,
+ systemCost: Long
+ ) {
+ chooserActivityShown = ChooserActivityShown(isWorkProfile, targetMimeType, systemCost)
+ log { chooserActivityShown }
+ }
+
+ override fun logShareStarted(
+ packageName: String?,
+ mimeType: String?,
+ appProvidedDirect: Int,
+ appProvidedApp: Int,
+ isWorkprofile: Boolean,
+ previewType: Int,
+ intent: String?,
+ customActionCount: Int,
+ modifyShareActionProvided: Boolean
+ ) {
+ log {
+ ShareStarted(
+ packageName,
+ mimeType,
+ appProvidedDirect,
+ appProvidedApp,
+ isWorkprofile,
+ previewType,
+ intent,
+ customActionCount,
+ modifyShareActionProvided
+ )
+ }
+ }
+
+ override fun logCustomActionSelected(positionPicked: Int) {
+ customActionSelected = CustomActionSelected(positionPicked)
+ log { "logCustomActionSelected(positionPicked=$positionPicked)" }
+ }
+
+ override fun logShareTargetSelected(
+ targetType: Int,
+ packageName: String?,
+ positionPicked: Int,
+ directTargetAlsoRanked: Int,
+ numCallerProvided: Int,
+ directTargetHashed: HashedStringCache.HashResult?,
+ isPinned: Boolean,
+ successfullySelected: Boolean,
+ selectionCost: Long
+ ) {
+ shareTargetSelected.add(
+ ShareTargetSelected(
+ targetType,
+ packageName,
+ positionPicked,
+ directTargetAlsoRanked,
+ numCallerProvided,
+ directTargetHashed,
+ isPinned,
+ successfullySelected,
+ selectionCost
+ )
+ )
+ log { shareTargetSelected.last() }
+ shareTargetSelected.limitSize(10)
+ }
+
+ private fun MutableList<*>.limitSize(n: Int) {
+ while (size > n) {
+ removeFirst()
+ }
+ }
+
+ override fun logDirectShareTargetReceived(category: Int, latency: Int) {
+ log { "logDirectShareTargetReceived(category=$category, latency=$latency)" }
+ }
+
+ override fun logActionShareWithPreview(previewType: Int) {
+ actionShareWithPreview = ActionShareWithPreview(previewType)
+ log { actionShareWithPreview }
+ }
+
+ override fun logActionSelected(targetType: Int) {
+ actionSelected = ActionSelected(targetType)
+ log { actionSelected }
+ }
+
+ override fun logContentPreviewWarning(uri: Uri?) {
+ log { "logContentPreviewWarning(uri=$uri)" }
+ }
+
+ override fun logSharesheetTriggered() {
+ log { "logSharesheetTriggered()" }
+ }
+
+ override fun logSharesheetAppLoadComplete() {
+ log { "logSharesheetAppLoadComplete()" }
+ }
+
+ override fun logSharesheetDirectLoadComplete() {
+ log { "logSharesheetAppLoadComplete()" }
+ }
+
+ override fun logSharesheetDirectLoadTimeout() {
+ log { "logSharesheetDirectLoadTimeout()" }
+ }
+
+ override fun logSharesheetProfileChanged() {
+ log { "logSharesheetProfileChanged()" }
+ }
+
+ override fun logSharesheetExpansionChanged(isCollapsed: Boolean) {
+ log { "logSharesheetExpansionChanged(isCollapsed=$isCollapsed)" }
+ }
+
+ override fun logSharesheetAppShareRankingTimeout() {
+ log { "logSharesheetAppShareRankingTimeout()" }
+ }
+
+ override fun logSharesheetEmptyDirectShareRow() {
+ log { "logSharesheetEmptyDirectShareRow()" }
+ }
+
+ data class ActionSelected(val targetType: Int)
+ data class CustomActionSelected(val positionPicked: Int)
+ data class ActionShareWithPreview(val previewType: Int)
+ data class ChooserActivityShown(
+ val isWorkProfile: Boolean,
+ val targetMimeType: String?,
+ val systemCost: Long
+ )
+ data class ShareStarted(
+ val packageName: String?,
+ val mimeType: String?,
+ val appProvidedDirect: Int,
+ val appProvidedApp: Int,
+ val isWorkprofile: Boolean,
+ val previewType: Int,
+ val intent: String?,
+ val customActionCount: Int,
+ val modifyShareActionProvided: Boolean
+ )
+ data class ShareTargetSelected(
+ val targetType: Int,
+ val packageName: String?,
+ val positionPicked: Int,
+ val directTargetAlsoRanked: Int,
+ val numCallerProvided: Int,
+ val directTargetHashed: HashedStringCache.HashResult?,
+ val pinned: Boolean,
+ val successfullySelected: Boolean,
+ val selectionCost: Long
+ )
+}
diff --git a/java/tests/src/com/android/intentresolver/logging/FakeFrameworkStatsLogger.kt b/java/tests/src/com/android/intentresolver/logging/FakeFrameworkStatsLogger.kt
new file mode 100644
index 00000000..dcf8d23f
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/logging/FakeFrameworkStatsLogger.kt
@@ -0,0 +1,95 @@
+package com.android.intentresolver.logging
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.android.internal.util.FrameworkStatsLog
+
+internal data class ShareSheetStarted(
+ val frameworkEventId: Int = FrameworkStatsLog.SHARESHEET_STARTED,
+ val appEventId: Int,
+ val packageName: String?,
+ val instanceId: Int,
+ val mimeType: String?,
+ val numAppProvidedDirectTargets: Int,
+ val numAppProvidedAppTargets: Int,
+ val isWorkProfile: Boolean,
+ val previewType: Int,
+ val intentType: Int,
+ val numCustomActions: Int,
+ val modifyShareActionProvided: Boolean
+)
+
+internal data class RankingSelected(
+ val frameworkEventId: Int = FrameworkStatsLog.RANKING_SELECTED,
+ val appEventId: Int,
+ val packageName: String?,
+ val instanceId: Int,
+ val positionPicked: Int,
+ val isPinned: Boolean
+)
+
+internal class FakeFrameworkStatsLogger : FrameworkStatsLogger {
+ var shareSheetStarted: ShareSheetStarted? = null
+ var rankingSelected: RankingSelected? = null
+ override fun write(
+ frameworkEventId: Int,
+ appEventId: Int,
+ packageName: String?,
+ instanceId: Int,
+ mimeType: String?,
+ numAppProvidedDirectTargets: Int,
+ numAppProvidedAppTargets: Int,
+ isWorkProfile: Boolean,
+ previewType: Int,
+ intentType: Int,
+ numCustomActions: Int,
+ modifyShareActionProvided: Boolean
+ ) {
+ shareSheetStarted =
+ ShareSheetStarted(
+ frameworkEventId,
+ appEventId,
+ packageName,
+ instanceId,
+ mimeType,
+ numAppProvidedDirectTargets,
+ numAppProvidedAppTargets,
+ isWorkProfile,
+ previewType,
+ intentType,
+ numCustomActions,
+ modifyShareActionProvided
+ )
+ }
+ override fun write(
+ frameworkEventId: Int,
+ appEventId: Int,
+ packageName: String?,
+ instanceId: Int,
+ positionPicked: Int,
+ isPinned: Boolean
+ ) {
+ rankingSelected =
+ RankingSelected(
+ frameworkEventId,
+ appEventId,
+ packageName,
+ instanceId,
+ positionPicked,
+ isPinned
+ )
+ }
+}
diff --git a/java/tests/src/com/android/intentresolver/logging/TestEventLogModule.kt b/java/tests/src/com/android/intentresolver/logging/TestEventLogModule.kt
new file mode 100644
index 00000000..cd808af4
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/logging/TestEventLogModule.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.intentresolver.logging
+
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.InstanceIdSequence
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.android.components.ActivityComponent
+import dagger.hilt.android.scopes.ActivityScoped
+import dagger.hilt.testing.TestInstallIn
+
+/** Binds a [FakeEventLog] as [EventLog] in tests. */
+@Module
+@TestInstallIn(components = [ActivityComponent::class], replaces = [EventLogModule::class])
+interface TestEventLogModule {
+
+ @Binds @ActivityScoped fun fakeEventLog(impl: FakeEventLog): EventLog
+
+ companion object {
+ @Provides
+ fun instanceId(sequence: InstanceIdSequence): InstanceId = sequence.newInstanceId()
+ }
+}