diff options
| author | 2022-12-15 18:06:12 +0000 | |
|---|---|---|
| committer | 2022-12-15 18:06:12 +0000 | |
| commit | 9c7e76d8aa02b599dd54b261f786487571bacfca (patch) | |
| tree | 3849f27d978bbe7d78b7a2f40798feec5ebbba9b /java | |
| parent | 9a6b4b476e56b9898fd5d7eca2005285697b9309 (diff) | |
| parent | 9ebd81953ce60236381a068a0b7c52c8164bbfea (diff) | |
Extract remainining ChooserActivity logging am: 9ebd81953c
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/IntentResolver/+/20713556
Change-Id: I6ca2a7d20baee9852156065fcc33cb491cbbbad2
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'java')
6 files changed, 442 insertions, 299 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index 4682ec50..6d5304d9 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -58,7 +58,6 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.drawable.Drawable; -import android.metrics.LogMaker; import android.net.Uri; import android.os.Bundle; import android.os.Environment; @@ -74,7 +73,6 @@ import android.provider.DeviceConfig; import android.provider.Settings; import android.service.chooser.ChooserTarget; import android.text.TextUtils; -import android.util.HashedStringCache; import android.util.Log; import android.util.Size; import android.util.Slog; @@ -114,7 +112,6 @@ import com.android.intentresolver.widget.ResolverDrawerLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.content.PackageMonitor; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; @@ -186,13 +183,6 @@ public class ChooserActivity extends ResolverActivity implements public static final int TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER = 2; public static final int TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE = 3; - public static final int SELECTION_TYPE_SERVICE = 1; - public static final int SELECTION_TYPE_APP = 2; - public static final int SELECTION_TYPE_STANDARD = 3; - public static final int SELECTION_TYPE_COPY = 4; - public static final int SELECTION_TYPE_NEARBY = 5; - public static final int SELECTION_TYPE_EDIT = 6; - private static final int SCROLL_STATUS_IDLE = 0; private static final int SCROLL_STATUS_SCROLLING_VERTICAL = 1; private static final int SCROLL_STATUS_SCROLLING_HORIZONTAL = 2; @@ -251,8 +241,6 @@ public class ChooserActivity extends ResolverActivity implements private SharedPreferences mPinnedSharedPrefs; private static final String PINNED_SHARED_PREFS_NAME = "chooser_pin_settings"; - protected MetricsLogger mMetricsLogger; - private final ExecutorService mBackgroundThreadPoolExecutor = Executors.newFixedThreadPool(5); @Nullable @@ -346,13 +334,8 @@ public class ChooserActivity extends ResolverActivity implements mChooserShownTime = System.currentTimeMillis(); final long systemCost = mChooserShownTime - intentReceivedTime; - - getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN) - .setSubtype(isWorkProfile() ? MetricsEvent.MANAGED_PROFILE : - MetricsEvent.PARENT_PROFILE) - .addTaggedData( - MetricsEvent.FIELD_SHARESHEET_MIMETYPE, mChooserRequest.getTargetType()) - .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); + getChooserActivityLogger().logChooserActivityShown( + isWorkProfile(), mChooserRequest.getTargetType(), systemCost); if (mResolverDrawerLayout != null) { mResolverDrawerLayout.addOnLayoutChangeListener(this::handleLayoutChange); @@ -593,7 +576,9 @@ public class ChooserActivity extends ResolverActivity implements if (shouldShowStickyContentPreview() || mChooserMultiProfilePagerAdapter .getCurrentRootAdapter().getSystemRowCount() != 0) { - logActionShareWithPreview(); + getChooserActivityLogger().logActionShareWithPreview( + ChooserContentPreviewUi.findPreferredContentPreview( + getTargetIntent(), getContentResolver(), this::isImageType)); } return postRebuildListInternal(rebuildCompleted); } @@ -682,15 +667,7 @@ public class ChooserActivity extends ResolverActivity implements Context.CLIPBOARD_SERVICE); clipboardManager.setPrimaryClipAsPackage(clipData, getReferrerPackageName()); - // Log share completion via copy - LogMaker targetLogMaker = new LogMaker( - MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1); - getMetricsLogger().write(targetLogMaker); - getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_COPY, - "", - -1, - false); + getChooserActivityLogger().logActionSelected(ChooserActivityLogger.SELECTION_TYPE_COPY); setResult(RESULT_OK); finish(); @@ -954,12 +931,8 @@ public class ChooserActivity extends ResolverActivity implements ti.getDisplayIconHolder().getDisplayIcon(), ti.getDisplayLabel(), (View unused) -> { - // Log share completion via nearby - getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_NEARBY, - "", - -1, - false); + getChooserActivityLogger().logActionSelected( + ChooserActivityLogger.SELECTION_TYPE_NEARBY); // Action bar is user-independent, always start as primary safelyStartActivityAsUser(ti, getPersonalProfileUserHandle()); finish(); @@ -978,11 +951,8 @@ public class ChooserActivity extends ResolverActivity implements ti.getDisplayLabel(), (View unused) -> { // Log share completion via edit - getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_EDIT, - "", - -1, - false); + getChooserActivityLogger().logActionSelected( + ChooserActivityLogger.SELECTION_TYPE_EDIT); View firstImgView = getFirstVisibleImgPreviewView(); // Action bar is user-independent, always start as primary if (firstImgView == null) { @@ -1032,14 +1002,6 @@ public class ChooserActivity extends ResolverActivity implements return mimeType != null && mimeType.startsWith("image/"); } - private void logContentPreviewWarning(Uri uri) { - // The ContentResolver already logs the exception. Log something more informative. - Log.w(TAG, "Could not load (" + uri.toString() + ") thumbnail/name for preview. If " - + "desired, consider using Intent#createChooser to launch the ChooserActivity, " - + "and set your Intent's clipData and flags in accordance with that method's " - + "documentation"); - } - private int getNumSheetExpansions() { return getPreferences(Context.MODE_PRIVATE).getInt(PREF_NUM_SHEET_EXPANSIONS, 0); } @@ -1249,78 +1211,51 @@ public class ChooserActivity extends ResolverActivity implements super.startSelected(which, always, filtered); if (currentListAdapter.getCount() > 0) { - // Log the index of which type of target the user picked. - // Lower values mean the ranking was better. - int cat = 0; - int value = which; - int directTargetAlsoRanked = -1; - int numCallerProvided = 0; - HashedStringCache.HashResult directTargetHashed = null; switch (currentListAdapter.getPositionTargetType(which)) { case ChooserListAdapter.TARGET_SERVICE: - cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET; - directTargetHashed = targetInfo.getHashedTargetIdForMetrics(this); - directTargetAlsoRanked = getRankedPosition(targetInfo); - - numCallerProvided = mChooserRequest.getCallerChooserTargets().size(); getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_SERVICE, + ChooserActivityLogger.SELECTION_TYPE_SERVICE, targetInfo.getResolveInfo().activityInfo.processName, - value, - targetInfo.isPinned() + which, + /* directTargetAlsoRanked= */ getRankedPosition(targetInfo), + mChooserRequest.getCallerChooserTargets().size(), + targetInfo.getHashedTargetIdForMetrics(this), + targetInfo.isPinned(), + mIsSuccessfullySelected, + selectionCost ); - break; + return; case ChooserListAdapter.TARGET_CALLER: case ChooserListAdapter.TARGET_STANDARD: - cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET; - value -= currentListAdapter.getSurfacedTargetInfo().size(); - numCallerProvided = currentListAdapter.getCallerTargetCount(); getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_APP, + ChooserActivityLogger.SELECTION_TYPE_APP, targetInfo.getResolveInfo().activityInfo.processName, - value, - targetInfo.isPinned() + (which - currentListAdapter.getSurfacedTargetInfo().size()), + /* directTargetAlsoRanked= */ -1, + currentListAdapter.getCallerTargetCount(), + /* directTargetHashed= */ null, + targetInfo.isPinned(), + mIsSuccessfullySelected, + selectionCost ); - break; + return; case ChooserListAdapter.TARGET_STANDARD_AZ: - // A-Z targets are unranked standard targets; we use -1 to mark that they - // are from the alphabetical pool. - value = -1; - cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET; + // A-Z targets are unranked standard targets; we use a value of -1 to mark that + // they are from the alphabetical pool. + // TODO: why do we log a different selection type if the -1 value already + // designates the same condition? getChooserActivityLogger().logShareTargetSelected( - SELECTION_TYPE_STANDARD, + ChooserActivityLogger.SELECTION_TYPE_STANDARD, targetInfo.getResolveInfo().activityInfo.processName, - value, - false + /* value= */ -1, + /* directTargetAlsoRanked= */ -1, + /* numCallerProvided= */ 0, + /* directTargetHashed= */ null, + /* isPinned= */ false, + mIsSuccessfullySelected, + selectionCost ); - break; - } - - if (cat != 0) { - LogMaker targetLogMaker = new LogMaker(cat).setSubtype(value); - if (directTargetHashed != null) { - targetLogMaker.addTaggedData( - MetricsEvent.FIELD_HASHED_TARGET_NAME, directTargetHashed.hashedString); - targetLogMaker.addTaggedData( - MetricsEvent.FIELD_HASHED_TARGET_SALT_GEN, - directTargetHashed.saltGeneration); - targetLogMaker.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, - directTargetAlsoRanked); - } - targetLogMaker.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, - numCallerProvided); - getMetricsLogger().write(targetLogMaker); - } - - if (mIsSuccessfullySelected) { - if (DEBUG) { - Log.d(TAG, "User Selection Time Cost is " + selectionCost); - Log.d(TAG, "position of selected app/service/caller is " + - Integer.toString(value)); - } - MetricsLogger.histogram(null, "user_selection_cost_for_smart_sharing", - (int) selectionCost); - MetricsLogger.histogram(null, "app_position_for_smart_sharing", value); + return; } } } @@ -1396,15 +1331,14 @@ public class ChooserActivity extends ResolverActivity implements } } - private void logDirectShareTargetReceived(int logCategory, UserHandle forUser) { + private void logDirectShareTargetReceived(UserHandle forUser) { ProfileRecord profileRecord = getProfileRecord(forUser); if (profileRecord == null) { return; } - - final int apiLatency = - (int) (SystemClock.elapsedRealtime() - profileRecord.loadingStartTime); - getMetricsLogger().write(new LogMaker(logCategory).setSubtype(apiLatency)); + getChooserActivityLogger().logDirectShareTargetReceived( + MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER, + (int) (SystemClock.elapsedRealtime() - profileRecord.loadingStartTime)); } void updateModelAndChooserCounts(TargetInfo info) { @@ -1546,13 +1480,6 @@ public class ChooserActivity extends ResolverActivity implements } } - protected MetricsLogger getMetricsLogger() { - if (mMetricsLogger == null) { - mMetricsLogger = new MetricsLogger(); - } - return mMetricsLogger; - } - protected ChooserActivityLogger getChooserActivityLogger() { if (mChooserActivityLogger == null) { mChooserActivityLogger = new ChooserActivityLogger(); @@ -1736,7 +1663,7 @@ public class ChooserActivity extends ResolverActivity implements try { return getContentResolver().loadThumbnail(uri, size, null); } catch (IOException | NullPointerException | SecurityException ex) { - logContentPreviewWarning(uri); + getChooserActivityLogger().logContentPreviewWarning(uri); } return null; } @@ -1996,10 +1923,7 @@ public class ChooserActivity extends ResolverActivity implements adapter.completeServiceTargetLoading(); } - logDirectShareTargetReceived( - MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER, - userHandle); - + logDirectShareTargetReceived(userHandle); sendVoiceChoicesIfNeeded(); getChooserActivityLogger().logSharesheetDirectLoadComplete(); } @@ -2130,14 +2054,6 @@ public class ChooserActivity extends ResolverActivity implements contentPreviewContainer.setVisibility(View.GONE); } - private void logActionShareWithPreview() { - Intent targetIntent = getTargetIntent(); - int previewType = ChooserContentPreviewUi.findPreferredContentPreview( - targetIntent, getContentResolver(), this::isImageType); - getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW) - .setSubtype(previewType)); - } - private void startFinishAnimation() { View rootView = findRootView(); if (rootView != null) { diff --git a/java/src/com/android/intentresolver/ChooserActivityLogger.java b/java/src/com/android/intentresolver/ChooserActivityLogger.java index 811d5f3e..9109bf93 100644 --- a/java/src/com/android/intentresolver/ChooserActivityLogger.java +++ b/java/src/com/android/intentresolver/ChooserActivityLogger.java @@ -16,15 +16,22 @@ package com.android.intentresolver; +import android.annotation.Nullable; import android.content.Intent; +import android.metrics.LogMaker; +import android.net.Uri; import android.provider.MediaStore; +import android.util.HashedStringCache; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; /** @@ -32,6 +39,16 @@ import com.android.internal.util.FrameworkStatsLog; * @hide */ public class ChooserActivityLogger { + private static final String TAG = "ChooserActivity"; + private static final boolean DEBUG = true; + + public static final int SELECTION_TYPE_SERVICE = 1; + public static final int SELECTION_TYPE_APP = 2; + public static final int SELECTION_TYPE_STANDARD = 3; + public static final int SELECTION_TYPE_COPY = 4; + public static final int SELECTION_TYPE_NEARBY = 5; + public static final int SELECTION_TYPE_EDIT = 6; + /** * This shim is provided only for testing. In production, clients will only ever use a * {@link DefaultFrameworkStatsLogger}. @@ -70,15 +87,30 @@ public class ChooserActivityLogger { private final UiEventLogger mUiEventLogger; private final FrameworkStatsLogger mFrameworkStatsLogger; + private final MetricsLogger mMetricsLogger; public ChooserActivityLogger() { - this(new UiEventLoggerImpl(), new DefaultFrameworkStatsLogger()); + this(new UiEventLoggerImpl(), new DefaultFrameworkStatsLogger(), new MetricsLogger()); } @VisibleForTesting - ChooserActivityLogger(UiEventLogger uiEventLogger, FrameworkStatsLogger frameworkLogger) { + ChooserActivityLogger( + UiEventLogger uiEventLogger, + FrameworkStatsLogger frameworkLogger, + MetricsLogger metricsLogger) { mUiEventLogger = uiEventLogger; mFrameworkStatsLogger = frameworkLogger; + mMetricsLogger = metricsLogger; + } + + /** Records metrics for the start time of the {@link ChooserActivity}. */ + public void logChooserActivityShown( + boolean isWorkProfile, String targetMimeType, long systemCost) { + mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN) + .setSubtype( + isWorkProfile ? MetricsEvent.MANAGED_PROFILE : MetricsEvent.PARENT_PROFILE) + .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, targetMimeType) + .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); } /** Logs a UiEventReported event for the system sharesheet completing initial start-up. */ @@ -97,15 +129,92 @@ public class ChooserActivityLogger { /* intentType = 9 */ typeFromIntentString(intent)); } - /** Logs a UiEventReported event for the system sharesheet when the user selects a target. */ - public void logShareTargetSelected(int targetType, String packageName, int positionPicked, - boolean isPinned) { + /** + * Logs a UiEventReported event for the system sharesheet when the user selects a target. + * TODO: document parameters and/or consider breaking up by targetType so we don't have to + * support an overly-generic signature. + */ + public void logShareTargetSelected( + int targetType, + String packageName, + int positionPicked, + int directTargetAlsoRanked, + int numCallerProvided, + @Nullable HashedStringCache.HashResult directTargetHashed, + boolean isPinned, + boolean successfullySelected, + long selectionCost) { mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), /* package_name = 2 */ packageName, /* instance_id = 3 */ getInstanceId().getId(), /* position_picked = 4 */ positionPicked, /* is_pinned = 5 */ isPinned); + + int category = getTargetSelectionCategory(targetType); + if (category != 0) { + LogMaker targetLogMaker = new LogMaker(category).setSubtype(positionPicked); + if (directTargetHashed != null) { + targetLogMaker.addTaggedData( + MetricsEvent.FIELD_HASHED_TARGET_NAME, directTargetHashed.hashedString); + targetLogMaker.addTaggedData( + MetricsEvent.FIELD_HASHED_TARGET_SALT_GEN, + directTargetHashed.saltGeneration); + targetLogMaker.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, + directTargetAlsoRanked); + } + targetLogMaker.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, numCallerProvided); + mMetricsLogger.write(targetLogMaker); + } + + if (successfullySelected) { + if (DEBUG) { + Log.d(TAG, "User Selection Time Cost is " + selectionCost); + Log.d(TAG, "position of selected app/service/caller is " + positionPicked); + } + MetricsLogger.histogram( + null, "user_selection_cost_for_smart_sharing", (int) selectionCost); + MetricsLogger.histogram(null, "app_position_for_smart_sharing", positionPicked); + } + } + + /** Log when direct share targets were received. */ + public void logDirectShareTargetReceived(int category, int latency) { + mMetricsLogger.write(new LogMaker(category).setSubtype(latency)); + } + + /** + * Log when we display a preview UI of the specified {@code previewType} as part of our + * Sharesheet session. + */ + public void logActionShareWithPreview(int previewType) { + mMetricsLogger.write( + new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW).setSubtype(previewType)); + } + + /** Log when the user selects an action button with the specified {@code targetType}. */ + public void logActionSelected(int targetType) { + if (targetType == SELECTION_TYPE_COPY) { + LogMaker targetLogMaker = new LogMaker( + MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1); + mMetricsLogger.write(targetLogMaker); + } + mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, + /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), + /* package_name = 2 */ "", + /* instance_id = 3 */ getInstanceId().getId(), + /* position_picked = 4 */ -1, + /* is_pinned = 5 */ false); + } + + /** Log a warning that we couldn't display the content preview from the supplied {@code uri}. */ + public void logContentPreviewWarning(Uri uri) { + // The ContentResolver already logs the exception. Log something more informative. + Log.w(TAG, "Could not load (" + uri.toString() + ") thumbnail/name for preview. If " + + "desired, consider using Intent#createChooser to launch the ChooserActivity, " + + "and set your Intent's clipData and flags in accordance with that method's " + + "documentation"); + } /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */ @@ -231,17 +340,17 @@ public class ChooserActivityLogger { public static SharesheetTargetSelectedEvent fromTargetType(int targetType) { switch(targetType) { - case ChooserActivity.SELECTION_TYPE_SERVICE: + case SELECTION_TYPE_SERVICE: return SHARESHEET_SERVICE_TARGET_SELECTED; - case ChooserActivity.SELECTION_TYPE_APP: + case SELECTION_TYPE_APP: return SHARESHEET_APP_TARGET_SELECTED; - case ChooserActivity.SELECTION_TYPE_STANDARD: + case SELECTION_TYPE_STANDARD: return SHARESHEET_STANDARD_TARGET_SELECTED; - case ChooserActivity.SELECTION_TYPE_COPY: + case SELECTION_TYPE_COPY: return SHARESHEET_COPY_TARGET_SELECTED; - case ChooserActivity.SELECTION_TYPE_NEARBY: + case SELECTION_TYPE_NEARBY: return SHARESHEET_NEARBY_TARGET_SELECTED; - case ChooserActivity.SELECTION_TYPE_EDIT: + case SELECTION_TYPE_EDIT: return SHARESHEET_EDIT_TARGET_SELECTED; default: return INVALID; @@ -328,6 +437,20 @@ public class ChooserActivityLogger { } } + @VisibleForTesting + static int getTargetSelectionCategory(int targetType) { + switch (targetType) { + case SELECTION_TYPE_SERVICE: + return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET; + case SELECTION_TYPE_APP: + return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET; + case SELECTION_TYPE_STANDARD: + return MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET; + default: + return 0; + } + } + private static class DefaultFrameworkStatsLogger implements FrameworkStatsLogger { @Override public void write( diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java b/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java index 702e725a..705a3228 100644 --- a/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java +++ b/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java @@ -30,14 +30,17 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import android.content.Intent; +import android.metrics.LogMaker; import com.android.intentresolver.ChooserActivityLogger.FrameworkStatsLogger; import com.android.intentresolver.ChooserActivityLogger.SharesheetStandardEvent; import com.android.intentresolver.ChooserActivityLogger.SharesheetStartedEvent; import com.android.intentresolver.ChooserActivityLogger.SharesheetTargetSelectedEvent; import com.android.internal.logging.InstanceId; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger.UiEventEnum; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; import org.junit.After; @@ -52,18 +55,59 @@ import org.mockito.junit.MockitoJUnitRunner; public final class ChooserActivityLoggerTest { @Mock private UiEventLogger mUiEventLog; @Mock private FrameworkStatsLogger mFrameworkLog; + @Mock private MetricsLogger mMetricsLogger; private ChooserActivityLogger mChooserLogger; @Before public void setUp() { - mChooserLogger = new ChooserActivityLogger(mUiEventLog, mFrameworkLog); + //Mockito.reset(mUiEventLog, mFrameworkLog, mMetricsLogger); + mChooserLogger = new ChooserActivityLogger(mUiEventLog, mFrameworkLog, mMetricsLogger); } @After public void tearDown() { verifyNoMoreInteractions(mUiEventLog); verifyNoMoreInteractions(mFrameworkLog); + verifyNoMoreInteractions(mMetricsLogger); + } + + @Test + public void testLogChooserActivityShown_personalProfile() { + final boolean isWorkProfile = false; + final String mimeType = "application/TestType"; + final long systemCost = 456; + + mChooserLogger.logChooserActivityShown(isWorkProfile, mimeType, systemCost); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + + assertThat(event.getCategory()).isEqualTo(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN); + assertThat(event.getSubtype()).isEqualTo(MetricsEvent.PARENT_PROFILE); + assertThat(event.getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE)).isEqualTo(mimeType); + assertThat(event.getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS)) + .isEqualTo(systemCost); + } + + @Test + public void testLogChooserActivityShown_workProfile() { + final boolean isWorkProfile = true; + final String mimeType = "application/TestType"; + final long systemCost = 456; + + mChooserLogger.logChooserActivityShown(isWorkProfile, mimeType, systemCost); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + + assertThat(event.getCategory()).isEqualTo(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN); + assertThat(event.getSubtype()).isEqualTo(MetricsEvent.MANAGED_PROFILE); + assertThat(event.getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE)).isEqualTo(mimeType); + assertThat(event.getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS)) + .isEqualTo(systemCost); } @Test @@ -102,20 +146,87 @@ public final class ChooserActivityLoggerTest { @Test public void testLogShareTargetSelected() { - final int targetType = ChooserActivity.SELECTION_TYPE_COPY; + final int targetType = ChooserActivityLogger.SELECTION_TYPE_SERVICE; final String packageName = "com.test.foo"; final int positionPicked = 123; - final boolean pinned = true; - - mChooserLogger.logShareTargetSelected(targetType, packageName, positionPicked, pinned); + final int directTargetAlsoRanked = -1; + final int callerTargetCount = 0; + final boolean isPinned = true; + final boolean isSuccessfullySelected = true; + final long selectionCost = 456; + + mChooserLogger.logShareTargetSelected( + targetType, + packageName, + positionPicked, + directTargetAlsoRanked, + callerTargetCount, + /* directTargetHashed= */ null, + isPinned, + isSuccessfullySelected, + selectionCost); verify(mFrameworkLog).write( eq(FrameworkStatsLog.RANKING_SELECTED), - eq(SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId()), + eq(SharesheetTargetSelectedEvent.SHARESHEET_SERVICE_TARGET_SELECTED.getId()), eq(packageName), /* instanceId=*/ gt(0), eq(positionPicked), - eq(pinned)); + eq(isPinned)); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + assertThat(event.getCategory()).isEqualTo( + MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET); + assertThat(event.getSubtype()).isEqualTo(positionPicked); + } + + @Test + public void testLogActionSelected() { + mChooserLogger.logActionSelected(ChooserActivityLogger.SELECTION_TYPE_COPY); + + verify(mFrameworkLog).write( + eq(FrameworkStatsLog.RANKING_SELECTED), + eq(SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId()), + eq(""), + /* instanceId=*/ gt(0), + eq(-1), + eq(false)); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + assertThat(event.getCategory()).isEqualTo( + MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET); + assertThat(event.getSubtype()).isEqualTo(1); + } + + @Test + public void testLogDirectShareTargetReceived() { + final int category = MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER; + final int latency = 123; + + mChooserLogger.logDirectShareTargetReceived(category, latency); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + assertThat(event.getCategory()).isEqualTo(category); + assertThat(event.getSubtype()).isEqualTo(latency); + } + + @Test + public void testLogActionShareWithPreview() { + final int previewType = ChooserContentPreviewUi.CONTENT_PREVIEW_TEXT; + + mChooserLogger.logActionShareWithPreview(previewType); + + ArgumentCaptor<LogMaker> eventCaptor = ArgumentCaptor.forClass(LogMaker.class); + verify(mMetricsLogger).write(eventCaptor.capture()); + LogMaker event = eventCaptor.getValue(); + assertThat(event.getCategory()).isEqualTo(MetricsEvent.ACTION_SHARE_WITH_PREVIEW); + assertThat(event.getSubtype()).isEqualTo(previewType); } @Test @@ -194,15 +305,38 @@ public final class ChooserActivityLoggerTest { public void testDifferentLoggerInstancesUseDifferentInstanceIds() { ArgumentCaptor<Integer> idIntCaptor = ArgumentCaptor.forClass(Integer.class); ChooserActivityLogger chooserLogger2 = - new ChooserActivityLogger(mUiEventLog, mFrameworkLog); + new ChooserActivityLogger(mUiEventLog, mFrameworkLog, mMetricsLogger); - final int targetType = ChooserActivity.SELECTION_TYPE_COPY; + final int targetType = ChooserActivityLogger.SELECTION_TYPE_COPY; final String packageName = "com.test.foo"; final int positionPicked = 123; - final boolean pinned = true; - - mChooserLogger.logShareTargetSelected(targetType, packageName, positionPicked, pinned); - chooserLogger2.logShareTargetSelected(targetType, packageName, positionPicked, pinned); + final int directTargetAlsoRanked = -1; + final int callerTargetCount = 0; + final boolean isPinned = true; + final boolean isSuccessfullySelected = true; + final long selectionCost = 456; + + mChooserLogger.logShareTargetSelected( + targetType, + packageName, + positionPicked, + directTargetAlsoRanked, + callerTargetCount, + /* directTargetHashed= */ null, + isPinned, + isSuccessfullySelected, + selectionCost); + + chooserLogger2.logShareTargetSelected( + targetType, + packageName, + positionPicked, + directTargetAlsoRanked, + callerTargetCount, + /* directTargetHashed= */ null, + isPinned, + isSuccessfullySelected, + selectionCost); verify(mFrameworkLog, times(2)).write( anyInt(), anyInt(), anyString(), idIntCaptor.capture(), anyInt(), anyBoolean()); @@ -220,12 +354,26 @@ public final class ChooserActivityLoggerTest { ArgumentCaptor<Integer> idIntCaptor = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<InstanceId> idObjectCaptor = ArgumentCaptor.forClass(InstanceId.class); - final int targetType = ChooserActivity.SELECTION_TYPE_COPY; + final int targetType = ChooserActivityLogger.SELECTION_TYPE_COPY; final String packageName = "com.test.foo"; final int positionPicked = 123; - final boolean pinned = true; + final int directTargetAlsoRanked = -1; + final int callerTargetCount = 0; + final boolean isPinned = true; + final boolean isSuccessfullySelected = true; + final long selectionCost = 456; + + mChooserLogger.logShareTargetSelected( + targetType, + packageName, + positionPicked, + directTargetAlsoRanked, + callerTargetCount, + /* directTargetHashed= */ null, + isPinned, + isSuccessfullySelected, + selectionCost); - mChooserLogger.logShareTargetSelected(targetType, packageName, positionPicked, pinned); verify(mFrameworkLog).write( anyInt(), anyInt(), anyString(), idIntCaptor.capture(), anyInt(), anyBoolean()); @@ -236,4 +384,23 @@ public final class ChooserActivityLoggerTest { assertThat(idIntCaptor.getValue()).isGreaterThan(0); assertThat(idObjectCaptor.getValue().getId()).isEqualTo(idIntCaptor.getValue()); } + + @Test + public void testTargetSelectionCategories() { + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_SERVICE)) + .isEqualTo(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET); + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_APP)) + .isEqualTo(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET); + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_STANDARD)) + .isEqualTo(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET); + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_COPY)).isEqualTo(0); + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_NEARBY)).isEqualTo(0); + assertThat(ChooserActivityLogger.getTargetSelectionCategory( + ChooserActivityLogger.SELECTION_TYPE_EDIT)).isEqualTo(0); + } } diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java index 5acdb42c..5df0d4a2 100644 --- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java +++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java @@ -32,7 +32,6 @@ import com.android.intentresolver.AbstractMultiProfilePagerAdapter.MyUserIdProvi import com.android.intentresolver.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.intentresolver.chooser.TargetInfo; import com.android.intentresolver.shortcuts.ShortcutLoader; -import com.android.internal.logging.MetricsLogger; import java.util.function.Consumer; import java.util.function.Function; @@ -66,7 +65,6 @@ public class ChooserActivityOverrideData { public Cursor resolverCursor; public boolean resolverForceException; public Bitmap previewThumbnail; - public MetricsLogger metricsLogger; public ChooserActivityLogger chooserActivityLogger; public int alternateProfileSetting; public Resources resources; @@ -89,7 +87,6 @@ public class ChooserActivityOverrideData { resolverForceException = false; resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); - metricsLogger = mock(MetricsLogger.class); chooserActivityLogger = mock(ChooserActivityLogger.class); alternateProfileSetting = 0; resources = null; diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java index 04e727ba..9f1dab77 100644 --- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java @@ -44,7 +44,6 @@ import com.android.intentresolver.chooser.NotSelectableTargetInfo; import com.android.intentresolver.chooser.TargetInfo; import com.android.intentresolver.grid.ChooserGridAdapter; import com.android.intentresolver.shortcuts.ShortcutLoader; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.List; @@ -223,11 +222,6 @@ public class ChooserWrapperActivity } @Override - protected MetricsLogger getMetricsLogger() { - return sOverrides.metricsLogger; - } - - @Override public ChooserActivityLogger getChooserActivityLogger() { return sOverrides.chooserActivityLogger; } diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index ff166fb7..af2557ef 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -43,15 +43,13 @@ import static junit.framework.Assert.assertNull; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.notNullValue; 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.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -77,12 +75,12 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.Icon; -import android.metrics.LogMaker; import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.provider.DeviceConfig; import android.service.chooser.ChooserTarget; +import android.util.HashedStringCache; import android.util.Pair; import android.util.SparseArray; import android.view.View; @@ -99,7 +97,6 @@ import com.android.intentresolver.ResolverActivity.ResolvedComponentInfo; import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.intentresolver.shortcuts.ShortcutLoader; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import org.hamcrest.Description; @@ -786,26 +783,15 @@ public class UnbundledChooserActivityTest { Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - - mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(com.android.internal.R.id.chooser_copy_button)).check(matches(isDisplayed())); onView(withId(com.android.internal.R.id.chooser_copy_button)).perform(click()); - verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture()); - - // The last captured event is the selection of the target. - boolean containsTargetEvent = logMakerCaptor.getAllValues() - .stream() - .anyMatch(item -> - item.getCategory() - == MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET); - assertTrue( - "ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET is expected", containsTargetEvent); - assertThat(logMakerCaptor.getValue().getSubtype(), is(1)); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); + verify(logger, times(1)).logActionSelected(eq(ChooserActivityLogger.SELECTION_TYPE_COPY)); } @Test @@ -979,25 +965,12 @@ public class UnbundledChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); - waitForIdle(); - verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture()); - assertThat(logMakerCaptor.getAllValues().get(0).getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN)); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS), - is(notNullValue())); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE), - is(TEST_MIME_TYPE)); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getSubtype(), - is(MetricsEvent.PARENT_PROFILE)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); + waitForIdle(); + + verify(logger).logChooserActivityShown(eq(false), eq(TEST_MIME_TYPE), anyLong()); } @Test @@ -1006,49 +979,32 @@ public class UnbundledChooserActivityTest { sendIntent.setType(TEST_MIME_TYPE); ChooserActivityOverrideData.getInstance().alternateProfileSetting = MetricsEvent.MANAGED_PROFILE; - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); - waitForIdle(); - verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture()); - assertThat(logMakerCaptor.getAllValues().get(0).getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN)); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS), - is(notNullValue())); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE), - is(TEST_MIME_TYPE)); - assertThat(logMakerCaptor - .getAllValues().get(0) - .getSubtype(), - is(MetricsEvent.MANAGED_PROFILE)); + + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); + waitForIdle(); + + verify(logger).logChooserActivityShown(eq(true), eq(TEST_MIME_TYPE), anyLong()); } @Test public void testEmptyPreviewLogging() { Intent sendIntent = createSendTextIntentWithPreview(null, null); - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "empty preview logger test")); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity( + Intent.createChooser(sendIntent, "empty preview logger test")); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); waitForIdle(); - verify(mockLogger, Mockito.times(1)).write(logMakerCaptor.capture()); - // First invocation is from onCreate - assertThat(logMakerCaptor.getAllValues().get(0).getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN)); + verify(logger).logChooserActivityShown(eq(false), eq(null), anyLong()); } @Test public void testTitlePreviewLogging() { Intent sendIntent = createSendTextIntentWithPreview("TestTitle", null); - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( @@ -1057,14 +1013,13 @@ public class UnbundledChooserActivityTest { Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); + // Second invocation is from onCreate - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); - assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(), - is(CONTENT_PREVIEW_TEXT)); - assertThat(logMakerCaptor.getAllValues().get(0).getCategory(), - is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); + Mockito.verify(logger, times(1)).logActionShareWithPreview(eq(CONTENT_PREVIEW_TEXT)); } @Test @@ -1092,16 +1047,11 @@ public class UnbundledChooserActivityTest { Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); - // First invocation is from onCreate - assertThat(logMakerCaptor.getAllValues().get(0).getSubtype(), - is(CONTENT_PREVIEW_IMAGE)); - assertThat(logMakerCaptor.getAllValues().get(0).getCategory(), - is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); + ChooserActivityLogger logger = activity.getChooserActivityLogger(); + Mockito.verify(logger, times(1)).logActionShareWithPreview(eq(CONTENT_PREVIEW_IMAGE)); } @Test @@ -1302,10 +1252,6 @@ public class UnbundledChooserActivityTest { Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); - // Set up resources - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - // create test shortcut loader factory, remember loaders and their callbacks SparseArray<Pair<ShortcutLoader, Consumer<ShortcutLoader.Result>>> shortcutLoaders = createShortcutLoaderFactory(); @@ -1361,25 +1307,22 @@ public class UnbundledChooserActivityTest { .perform(click()); waitForIdle(); - // Currently we're seeing 4 invocations - // 1. ChooserActivity.logActionShareWithPreview() - // 2. ChooserActivity.onCreate() - // 3. ChooserActivity.logDirectShareTargetReceived() - // 4. ChooserActivity.startSelected -- which is the one we're after - verify(mockLogger, Mockito.times(4)).write(logMakerCaptor.capture()); - LogMaker selectionLog = logMakerCaptor.getAllValues().get(3); - assertThat( - selectionLog.getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET)); - String hashedName = (String) selectionLog.getTaggedData( - MetricsEvent.FIELD_HASHED_TARGET_NAME); + ArgumentCaptor<HashedStringCache.HashResult> hashCaptor = + ArgumentCaptor.forClass(HashedStringCache.HashResult.class); + verify(activity.getChooserActivityLogger(), times(1)).logShareTargetSelected( + eq(ChooserActivityLogger.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))); - assertThat( - "The packages shouldn't match for app target and direct target", - selectionLog.getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), - is(-1)); } // This test is too long and too slow and should not be taken as an example for future tests. @@ -1399,10 +1342,6 @@ public class UnbundledChooserActivityTest { Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); - // Set up resources - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - // create test shortcut loader factory, remember loaders and their callbacks SparseArray<Pair<ShortcutLoader, Consumer<ShortcutLoader.Result>>> shortcutLoaders = createShortcutLoaderFactory(); @@ -1460,16 +1399,16 @@ public class UnbundledChooserActivityTest { .perform(click()); waitForIdle(); - // Currently we're seeing 4 invocations - // 1. ChooserActivity.logActionShareWithPreview() - // 2. ChooserActivity.onCreate() - // 3. ChooserActivity.logDirectShareTargetReceived() - // 4. ChooserActivity.startSelected -- which is the one we're after - verify(mockLogger, Mockito.times(4)).write(logMakerCaptor.capture()); - assertThat(logMakerCaptor.getAllValues().get(3).getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET)); - assertThat("The packages should match for app target and direct target", logMakerCaptor - .getAllValues().get(3).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(0)); + verify(activity.getChooserActivityLogger(), times(1)).logShareTargetSelected( + eq(ChooserActivityLogger.SELECTION_TYPE_SERVICE), + /* packageName= */ any(), + /* positionPicked= */ anyInt(), + /* directTargetAlsoRanked= */ eq(0), + /* numCallerProvided= */ anyInt(), + /* directTargetHashed= */ any(), + /* isPinned= */ anyBoolean(), + /* successfullySelected= */ anyBoolean(), + /* selectionCost= */ anyLong()); } @Test @@ -1787,9 +1726,6 @@ public class UnbundledChooserActivityTest { Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); - // Set up resources - MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; - ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); // Create direct share target List<ChooserTarget> serviceTargets = createDirectShareTargets(1, resolvedComponentInfos.get(14).getResolveInfoAt(0).activityInfo.packageName); @@ -1830,15 +1766,18 @@ public class UnbundledChooserActivityTest { .perform(click()); waitForIdle(); - // Currently we're seeing 3 invocations - // 1. ChooserActivity.onCreate() - // 2. ChooserActivity$ChooserRowAdapter.createContentPreviewView() - // 3. ChooserActivity.startSelected -- which is the one we're after - verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture()); - assertThat(logMakerCaptor.getAllValues().get(2).getCategory(), - is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET)); - assertThat("The packages shouldn't match for app target and direct target", logMakerCaptor - .getAllValues().get(2).getTaggedData(MetricsEvent.FIELD_RANKED_POSITION), is(-1)); + ChooserActivityLogger logger = wrapper.getChooserActivityLogger(); + verify(logger, times(1)).logShareTargetSelected( + eq(ChooserActivityLogger.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()); } @Test @@ -2179,9 +2118,16 @@ public class UnbundledChooserActivityTest { ChooserActivityLogger logger = activity.getChooserActivityLogger(); ArgumentCaptor<Integer> typeCaptor = ArgumentCaptor.forClass(Integer.class); - Mockito.verify(logger, times(1)) - .logShareTargetSelected(typeCaptor.capture(), any(), anyInt(), anyBoolean()); - assertThat(typeCaptor.getValue(), is(ChooserActivity.SELECTION_TYPE_SERVICE)); + verify(logger, times(1)).logShareTargetSelected( + eq(ChooserActivityLogger.SELECTION_TYPE_SERVICE), + /* packageName= */ any(), + /* positionPicked= */ anyInt(), + /* directTargetAlsoRanked= */ anyInt(), + /* numCallerProvided= */ anyInt(), + /* directTargetHashed= */ any(), + /* isPinned= */ anyBoolean(), + /* successfullySelected= */ anyBoolean(), + /* selectionCost= */ anyLong()); } @Test @Ignore |