From c1fdc6cb1540098cb9feed1147141c9a28df7043 Mon Sep 17 00:00:00 2001 From: Matt Casey Date: Tue, 21 Feb 2023 16:43:04 +0000 Subject: Add logging for modify share and custom action clicks Just a regular UiEvent log for modify share. Include position information for custom actions (*just* the position within the custom action set, ignoring other system actions that may be within the display container). Bug: 265504112 Test: atest ChooserActivityLoggerTest Test: atest ChooserActivityFactoryTest Change-Id: If64db5c1afccf6571d23395624d6ffbbef677188 --- .../intentresolver/ChooserActionFactory.java | 57 ++++++++++++++++------ .../intentresolver/ChooserActivityLogger.java | 27 +++++++++- .../ChooserIntegratedDeviceComponents.java | 2 +- 3 files changed, 68 insertions(+), 18 deletions(-) (limited to 'java/src') diff --git a/java/src/com/android/intentresolver/ChooserActionFactory.java b/java/src/com/android/intentresolver/ChooserActionFactory.java index 1fe55890..566b2546 100644 --- a/java/src/com/android/intentresolver/ChooserActionFactory.java +++ b/java/src/com/android/intentresolver/ChooserActionFactory.java @@ -49,7 +49,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.function.Consumer; -import java.util.stream.Collectors; /** * Implementation of {@link ChooserContentPreviewUi.ActionFactory} specialized to the application @@ -96,9 +95,10 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio private final TargetInfo mNearbySharingTarget; private final Runnable mOnNearbyButtonClicked; private final ImmutableList mCustomActions; - private final PendingIntent mReselectionIntent; + private final Runnable mOnModifyShareClicked; private final Consumer mExcludeSharedTextAction; private final Consumer mFinishCallback; + private final ChooserActivityLogger mLogger; /** * @param context @@ -160,8 +160,13 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio logger), chooserRequest.getChooserActions(), (featureFlagRepository.isEnabled(Flags.SHARESHEET_RESELECTION_ACTION) - ? chooserRequest.getModifyShareAction() : null), + ? createModifyShareRunnable( + chooserRequest.getModifyShareAction(), + finishCallback, + logger) + : null), onUpdateSharedTextIsExcluded, + logger, finishCallback); } @@ -176,8 +181,9 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio TargetInfo nearbySharingTarget, Runnable onNearbyButtonClicked, List customActions, - @Nullable PendingIntent reselectionIntent, + @Nullable Runnable onModifyShareClicked, Consumer onUpdateSharedTextIsExcluded, + ChooserActivityLogger logger, Consumer finishCallback) { mContext = context; mCopyButtonLabel = copyButtonLabel; @@ -188,8 +194,9 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio mNearbySharingTarget = nearbySharingTarget; mOnNearbyButtonClicked = onNearbyButtonClicked; mCustomActions = ImmutableList.copyOf(customActions); - mReselectionIntent = reselectionIntent; + mOnModifyShareClicked = onModifyShareClicked; mExcludeSharedTextAction = onUpdateSharedTextIsExcluded; + mLogger = logger; mFinishCallback = finishCallback; } @@ -236,10 +243,15 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio /** Create custom actions */ @Override public List createCustomActions() { - return mCustomActions.stream() - .map(target -> createCustomAction(mContext, target, mFinishCallback)) - .filter(action -> action != null) - .collect(Collectors.toList()); + List actions = new ArrayList<>(); + for (int i = 0; i < mCustomActions.size(); i++) { + ActionRow.Action actionRow = createCustomAction( + mContext, mCustomActions.get(i), mFinishCallback, i, mLogger); + if (actionRow != null) { + actions.add(actionRow); + } + } + return actions; } /** @@ -248,18 +260,25 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio @Override @Nullable public Runnable getModifyShareAction() { - return (mReselectionIntent == null) ? null : createReselectionRunnable(mReselectionIntent); + return mOnModifyShareClicked; } - private Runnable createReselectionRunnable(PendingIntent pendingIntent) { + private static Runnable createModifyShareRunnable( + PendingIntent pendingIntent, + Consumer finishCallback, + ChooserActivityLogger logger) { + if (pendingIntent == null) { + return null; + } + return () -> { try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { Log.d(TAG, "Payload reselection action has been cancelled"); } - // TODO: add reporting - mFinishCallback.accept(Activity.RESULT_OK); + logger.logActionSelected(ChooserActivityLogger.SELECTION_TYPE_MODIFY_SHARE); + finishCallback.accept(Activity.RESULT_OK); }; } @@ -402,7 +421,9 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio Intent originalIntent, ChooserIntegratedDeviceComponents integratedComponents) { final ComponentName cn = integratedComponents.getNearbySharingComponent(); - if (cn == null) return null; + if (cn == null) { + return null; + } final Intent resolveIntent = new Intent(originalIntent); resolveIntent.setComponent(cn); @@ -455,7 +476,11 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio @Nullable private static ActionRow.Action createCustomAction( - Context context, ChooserAction action, Consumer finishCallback) { + Context context, + ChooserAction action, + Consumer finishCallback, + int position, + ChooserActivityLogger logger) { Drawable icon = action.getIcon().loadDrawable(context); if (icon == null && TextUtils.isEmpty(action.getLabel())) { return null; @@ -469,7 +494,7 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio } catch (PendingIntent.CanceledException e) { Log.d(TAG, "Custom action, " + action.getLabel() + ", has been cancelled"); } - // TODO: add reporting + logger.logCustomActionSelected(position); finishCallback.accept(Activity.RESULT_OK); } ); diff --git a/java/src/com/android/intentresolver/ChooserActivityLogger.java b/java/src/com/android/intentresolver/ChooserActivityLogger.java index 1725a7bf..f298955b 100644 --- a/java/src/com/android/intentresolver/ChooserActivityLogger.java +++ b/java/src/com/android/intentresolver/ChooserActivityLogger.java @@ -48,6 +48,8 @@ public class ChooserActivityLogger { public static final int SELECTION_TYPE_COPY = 4; public static final int SELECTION_TYPE_NEARBY = 5; public static final int SELECTION_TYPE_EDIT = 6; + public static final int SELECTION_TYPE_MODIFY_SHARE = 7; + public static final int SELECTION_TYPE_CUSTOM_ACTION = 8; /** * This shim is provided only for testing. In production, clients will only ever use a @@ -133,6 +135,21 @@ public class ChooserActivityLogger { /* reselection_action_provided = 11 */ false); } + /** + * Log that a custom action has been tapped by the user. + * + * @param positionPicked index of the custom action within the list of custom actions. + */ + public void logCustomActionSelected(int positionPicked) { + mFrameworkStatsLogger.write(FrameworkStatsLog.RANKING_SELECTED, + /* event_id = 1 */ + SharesheetTargetSelectedEvent.SHARESHEET_CUSTOM_ACTION_SELECTED.getId(), + /* package_name = 2 */ null, + /* instance_id = 3 */ getInstanceId().getId(), + /* position_picked = 4 */ positionPicked, + /* is_pinned = 5 */ false); + } + /** * 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 @@ -332,7 +349,11 @@ public class ChooserActivityLogger { @UiEvent(doc = "User selected the nearby target.") SHARESHEET_NEARBY_TARGET_SELECTED(626), @UiEvent(doc = "User selected the edit target.") - SHARESHEET_EDIT_TARGET_SELECTED(669); + SHARESHEET_EDIT_TARGET_SELECTED(669), + @UiEvent(doc = "User selected the modify share target.") + SHARESHEET_MODIFY_SHARE_SELECTED(1316), + @UiEvent(doc = "User selected a custom action.") + SHARESHEET_CUSTOM_ACTION_SELECTED(1317); private final int mId; SharesheetTargetSelectedEvent(int id) { @@ -356,6 +377,10 @@ public class ChooserActivityLogger { return SHARESHEET_NEARBY_TARGET_SELECTED; case SELECTION_TYPE_EDIT: return SHARESHEET_EDIT_TARGET_SELECTED; + case SELECTION_TYPE_MODIFY_SHARE: + return SHARESHEET_MODIFY_SHARE_SELECTED; + case SELECTION_TYPE_CUSTOM_ACTION: + return SHARESHEET_CUSTOM_ACTION_SELECTED; default: return INVALID; } diff --git a/java/src/com/android/intentresolver/ChooserIntegratedDeviceComponents.java b/java/src/com/android/intentresolver/ChooserIntegratedDeviceComponents.java index 9b124c20..14255ca0 100644 --- a/java/src/com/android/intentresolver/ChooserIntegratedDeviceComponents.java +++ b/java/src/com/android/intentresolver/ChooserIntegratedDeviceComponents.java @@ -32,7 +32,7 @@ import com.android.internal.annotations.VisibleForTesting; * Because this describes the app's external execution environment, test methods may prefer to * provide explicit values to override the default lookup logic. */ -public final class ChooserIntegratedDeviceComponents { +public class ChooserIntegratedDeviceComponents { @Nullable private final ComponentName mEditSharingComponent; -- cgit v1.2.3-59-g8ed1b