Loading core/java/com/android/internal/app/ChooserActivity.java +65 −5 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ 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; import com.android.internal.widget.GridLayoutManager; import com.android.internal.widget.RecyclerView; import com.android.internal.widget.ResolverDrawerLayout; Loading Loading @@ -178,7 +179,7 @@ public class ChooserActivity extends ResolverActivity implements private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true; // TODO(b/123088566) Share these in a better way. private static final String APP_PREDICTION_SHARE_UI_SURFACE = "share"; public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share"; public static final String LAUNCH_LOCATION_DIRECT_SHARE = "direct_share"; private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20; public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"; Loading @@ -194,6 +195,14 @@ 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; // statsd logger wrapper protected ChooserActivityLogger mChooserActivityLogger; private static final boolean USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS = true; @IntDef(flag = false, prefix = { "TARGET_TYPE_" }, value = { Loading Loading @@ -270,9 +279,9 @@ public class ChooserActivity extends ResolverActivity implements // Starting at 1 since 0 is considered "undefined" for some of the database transformations // of tron logs. private static final int CONTENT_PREVIEW_IMAGE = 1; private static final int CONTENT_PREVIEW_FILE = 2; private static final int CONTENT_PREVIEW_TEXT = 3; protected static final int CONTENT_PREVIEW_IMAGE = 1; protected static final int CONTENT_PREVIEW_FILE = 2; protected static final int CONTENT_PREVIEW_TEXT = 3; protected MetricsLogger mMetricsLogger; private ContentPreviewCoordinator mPreviewCoord; Loading Loading @@ -500,6 +509,9 @@ public class ChooserActivity extends ResolverActivity implements case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT: mMinTimeoutPassed = true; if (!mServiceConnections.isEmpty()) { getChooserActivityLogger().logSharesheetDirectLoadTimeout(); } unbindRemainingServices(); maybeStopServiceRequestTimer(); break; Loading Loading @@ -533,6 +545,7 @@ public class ChooserActivity extends ResolverActivity implements logDirectShareTargetReceived( MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER); sendVoiceChoicesIfNeeded(); getChooserActivityLogger().logSharesheetDirectLoadComplete(); break; default: Loading @@ -544,6 +557,7 @@ public class ChooserActivity extends ResolverActivity implements @Override protected void onCreate(Bundle savedInstanceState) { final long intentReceivedTime = System.currentTimeMillis(); getChooserActivityLogger().logSharesheetTriggered(); // This is the only place this value is being set. Effectively final. mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable(); Loading Loading @@ -707,6 +721,8 @@ public class ChooserActivity extends ResolverActivity implements incrementNumSheetExpansions(); mWrittenOnce = true; } getChooserActivityLogger() .logSharesheetExpansionChanged(isCollapsed); } }); } Loading @@ -715,6 +731,16 @@ public class ChooserActivity extends ResolverActivity implements Log.d(TAG, "System Time Cost is " + systemCost); } getChooserActivityLogger().logShareStarted( FrameworkStatsLog.SHARESHEET_STARTED, getReferrerPackageName(), target.getType(), initialIntents == null ? 0 : initialIntents.length, mCallerChooserTargets == null ? 0 : mCallerChooserTargets.length, isWorkProfile(), findPreferredContentPreview(getTargetIntent(), getContentResolver()), target.getAction() ); mDirectShareShortcutInfoCache = new HashMap<>(); } Loading Loading @@ -969,6 +995,10 @@ public class ChooserActivity extends ResolverActivity implements LogMaker targetLogMaker = new LogMaker( MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1); getMetricsLogger().write(targetLogMaker); getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_COPY, "", -1); finish(); } Loading Loading @@ -1644,18 +1674,33 @@ public class ChooserActivity extends ResolverActivity implements if (mCallerChooserTargets != null) { numCallerProvided = mCallerChooserTargets.length; } getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_SERVICE, targetInfo.getResolveInfo().activityInfo.processName, value ); break; case ChooserListAdapter.TARGET_CALLER: case ChooserListAdapter.TARGET_STANDARD: cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET; value -= currentListAdapter.getSelectableServiceTargetCount(); numCallerProvided = currentListAdapter.getCallerTargetCount(); getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_APP, targetInfo.getResolveInfo().activityInfo.processName, value ); break; 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; getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_STANDARD, targetInfo.getResolveInfo().activityInfo.processName, value ); break; } Loading Loading @@ -2131,7 +2176,7 @@ public class ChooserActivity extends ResolverActivity implements if (appTarget != null) { directShareAppPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH) .setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) .setLaunchLocation(LAUNCH_LOCATION_DIRECT_SHARE) .build()); } } Loading Loading @@ -2290,6 +2335,13 @@ public class ChooserActivity extends ResolverActivity implements return mMetricsLogger; } protected ChooserActivityLogger getChooserActivityLogger() { if (mChooserActivityLogger == null) { mChooserActivityLogger = new ChooserActivityLoggerImpl(); } return mChooserActivityLogger; } public class ChooserListController extends ResolverListController { public ChooserListController(Context context, PackageManager pm, Loading Loading @@ -2601,6 +2653,7 @@ public class ChooserActivity extends ResolverActivity implements // don't support direct share on low ram devices if (ActivityManager.isLowRamDeviceStatic()) { getChooserActivityLogger().logSharesheetAppLoadComplete(); return; } Loading @@ -2619,6 +2672,8 @@ public class ChooserActivity extends ResolverActivity implements queryTargetServices(chooserListAdapter); } getChooserActivityLogger().logSharesheetAppLoadComplete(); } private void setupScrollListener() { Loading Loading @@ -3777,4 +3832,9 @@ public class ChooserActivity extends ResolverActivity implements canvas.drawRoundRect(x, y, width, height, mRadius, mRadius, mRoundRectPaint); } } @Override protected void maybeLogProfileChange() { getChooserActivityLogger().logShareheetProfileChanged(); } } core/java/com/android/internal/app/ChooserActivityLogger.java 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.internal.app; import android.content.Intent; import android.provider.MediaStore; import com.android.internal.logging.InstanceId; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.FrameworkStatsLog; /** * Interface for writing Sharesheet atoms to statsd log. * @hide */ public interface ChooserActivityLogger { /** Logs a UiEventReported event for the system sharesheet completing initial start-up. */ void logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent); /** Logs a UiEventReported event for the system sharesheet when the user selects a target. */ void logShareTargetSelected(int targetType, String packageName, int positionPicked); /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */ default void logSharesheetTriggered() { log(SharesheetStandardEvent.SHARESHEET_TRIGGERED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet completing loading app targets. */ default void logSharesheetAppLoadComplete() { log(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet completing loading service targets. */ default void logSharesheetDirectLoadComplete() { log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_COMPLETE, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet timing out loading service targets. */ default void logSharesheetDirectLoadTimeout() { log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet switching * between work and main profile. */ default void logShareheetProfileChanged() { log(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet getting expanded or collapsed. */ default void logSharesheetExpansionChanged(boolean isCollapsed) { log(isCollapsed ? SharesheetStandardEvent.SHARESHEET_COLLAPSED : SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId()); } /** * Logs a UiEventReported event for a given share activity * @param event * @param instanceId */ void log(UiEventLogger.UiEventEnum event, InstanceId instanceId); /** * * @return */ InstanceId getInstanceId(); /** * The UiEvent enums that this class can log. */ enum SharesheetStartedEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "Basic system Sharesheet has started and is visible.") SHARE_STARTED(228); private final int mId; SharesheetStartedEvent(int id) { mId = id; } @Override public int getId() { return mId; } } /** * The UiEvent enums that this class can log. */ enum SharesheetTargetSelectedEvent implements UiEventLogger.UiEventEnum { INVALID(0), @UiEvent(doc = "User selected a service target.") SHARESHEET_SERVICE_TARGET_SELECTED(232), @UiEvent(doc = "User selected an app target.") SHARESHEET_APP_TARGET_SELECTED(233), @UiEvent(doc = "User selected a standard target.") SHARESHEET_STANDARD_TARGET_SELECTED(234), @UiEvent(doc = "User selected the copy target.") SHARESHEET_COPY_TARGET_SELECTED(235); private final int mId; SharesheetTargetSelectedEvent(int id) { mId = id; } @Override public int getId() { return mId; } public static SharesheetTargetSelectedEvent fromTargetType(int targetType) { switch(targetType) { case ChooserActivity.SELECTION_TYPE_SERVICE: return SHARESHEET_SERVICE_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_APP: return SHARESHEET_APP_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_STANDARD: return SHARESHEET_STANDARD_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_COPY: return SHARESHEET_COPY_TARGET_SELECTED; default: return INVALID; } } } /** * The UiEvent enums that this class can log. */ enum SharesheetStandardEvent implements UiEventLogger.UiEventEnum { INVALID(0), @UiEvent(doc = "User clicked share.") SHARESHEET_TRIGGERED(227), @UiEvent(doc = "User changed from work to personal profile or vice versa.") SHARESHEET_PROFILE_CHANGED(229), @UiEvent(doc = "User expanded target list.") SHARESHEET_EXPANDED(230), @UiEvent(doc = "User collapsed target list.") SHARESHEET_COLLAPSED(231), @UiEvent(doc = "Sharesheet app targets is fully populated.") SHARESHEET_APP_LOAD_COMPLETE(322), @UiEvent(doc = "Sharesheet direct targets is fully populated.") SHARESHEET_DIRECT_LOAD_COMPLETE(323), @UiEvent(doc = "Sharesheet direct targets timed out.") SHARESHEET_DIRECT_LOAD_TIMEOUT(324); private final int mId; SharesheetStandardEvent(int id) { mId = id; } @Override public int getId() { return mId; } } /** * Returns the enum used in sharesheet started atom to indicate what preview type was used. */ default int typeFromPreviewInt(int previewType) { switch(previewType) { case ChooserActivity.CONTENT_PREVIEW_IMAGE: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_IMAGE; case ChooserActivity.CONTENT_PREVIEW_FILE: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE; case ChooserActivity.CONTENT_PREVIEW_TEXT: default: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TEXT; } } /** * Returns the enum used in sharesheet started atom to indicate what intent triggers the * ChooserActivity. */ default int typeFromIntentString(String intent) { switch (intent) { case Intent.ACTION_VIEW: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_VIEW; case Intent.ACTION_EDIT: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_EDIT; case Intent.ACTION_SEND: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND; case Intent.ACTION_SENDTO: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SENDTO; case Intent.ACTION_SEND_MULTIPLE: return FrameworkStatsLog .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND_MULTIPLE; case MediaStore.ACTION_IMAGE_CAPTURE: return FrameworkStatsLog .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_IMAGE_CAPTURE; case Intent.ACTION_MAIN: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_MAIN; default: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; } } } core/java/com/android/internal/app/ChooserActivityLoggerImpl.java 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.internal.app; import com.android.internal.logging.InstanceId; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.util.FrameworkStatsLog; /** * Standard implementation of ChooserActivityLogger interface. * @hide */ public class ChooserActivityLoggerImpl implements ChooserActivityLogger { private static final int SHARESHEET_INSTANCE_ID_MAX = (1 << 13); private UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); // A small per-notification ID, used for statsd logging. private InstanceId mInstanceId; private static InstanceIdSequence sInstanceIdSequence; @Override public void logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent) { FrameworkStatsLog.write(FrameworkStatsLog.SHARESHEET_STARTED, /* event_id = 1 */ SharesheetStartedEvent.SHARE_STARTED.getId(), /* package_name = 2 */ packageName, /* instance_id = 3 */ getInstanceId().getId(), /* mime_type = 4 */ mimeType, /* num_app_provided_direct_targets = 5 */ appProvidedDirect, /* num_app_provided_app_targets = 6 */ appProvidedApp, /* is_workprofile = 7 */ isWorkprofile, /* previewType = 8 */ typeFromPreviewInt(previewType), /* intentType = 9 */ typeFromIntentString(intent)); } @Override public void logShareTargetSelected(int targetType, String packageName, int positionPicked) { FrameworkStatsLog.write(FrameworkStatsLog.RANKING_SELECTED, /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), /* package_name = 2 */ packageName, /* instance_id = 3 */ getInstanceId().getId(), /* position_picked = 4 */ positionPicked); } @Override public void log(UiEventLogger.UiEventEnum event, InstanceId instanceId) { mUiEventLogger.logWithInstanceId( event, 0, null, instanceId); } @Override public InstanceId getInstanceId() { if (mInstanceId == null) { if (sInstanceIdSequence == null) { sInstanceIdSequence = new InstanceIdSequence(SHARESHEET_INSTANCE_ID_MAX); } mInstanceId = sInstanceIdSequence.newInstanceId(); } return mInstanceId; } } core/java/com/android/internal/app/ResolverActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -1578,6 +1578,7 @@ public class ResolverActivity extends Activity implements viewPager.setCurrentItem(1); } setupViewVisibilities(); maybeLogProfileChange(); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS) .setInt(viewPager.getCurrentItem()) Loading Loading @@ -1998,4 +1999,6 @@ public class ResolverActivity extends Activity implements } } } protected void maybeLogProfileChange() {} } core/java/com/android/internal/logging/testing/UiEventLoggerFake.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class UiEventLoggerFake implements UiEventLogger { } @Override public void logWithInstanceId(UiEventLogger.UiEventEnum event, int uid, String packageName, public void logWithInstanceId(UiEventEnum event, int uid, String packageName, InstanceId instance) { final int eventId = event.getId(); if (eventId > 0) { Loading Loading
core/java/com/android/internal/app/ChooserActivity.java +65 −5 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ 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; import com.android.internal.widget.GridLayoutManager; import com.android.internal.widget.RecyclerView; import com.android.internal.widget.ResolverDrawerLayout; Loading Loading @@ -178,7 +179,7 @@ public class ChooserActivity extends ResolverActivity implements private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true; // TODO(b/123088566) Share these in a better way. private static final String APP_PREDICTION_SHARE_UI_SURFACE = "share"; public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share"; public static final String LAUNCH_LOCATION_DIRECT_SHARE = "direct_share"; private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20; public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"; Loading @@ -194,6 +195,14 @@ 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; // statsd logger wrapper protected ChooserActivityLogger mChooserActivityLogger; private static final boolean USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS = true; @IntDef(flag = false, prefix = { "TARGET_TYPE_" }, value = { Loading Loading @@ -270,9 +279,9 @@ public class ChooserActivity extends ResolverActivity implements // Starting at 1 since 0 is considered "undefined" for some of the database transformations // of tron logs. private static final int CONTENT_PREVIEW_IMAGE = 1; private static final int CONTENT_PREVIEW_FILE = 2; private static final int CONTENT_PREVIEW_TEXT = 3; protected static final int CONTENT_PREVIEW_IMAGE = 1; protected static final int CONTENT_PREVIEW_FILE = 2; protected static final int CONTENT_PREVIEW_TEXT = 3; protected MetricsLogger mMetricsLogger; private ContentPreviewCoordinator mPreviewCoord; Loading Loading @@ -500,6 +509,9 @@ public class ChooserActivity extends ResolverActivity implements case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT: mMinTimeoutPassed = true; if (!mServiceConnections.isEmpty()) { getChooserActivityLogger().logSharesheetDirectLoadTimeout(); } unbindRemainingServices(); maybeStopServiceRequestTimer(); break; Loading Loading @@ -533,6 +545,7 @@ public class ChooserActivity extends ResolverActivity implements logDirectShareTargetReceived( MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER); sendVoiceChoicesIfNeeded(); getChooserActivityLogger().logSharesheetDirectLoadComplete(); break; default: Loading @@ -544,6 +557,7 @@ public class ChooserActivity extends ResolverActivity implements @Override protected void onCreate(Bundle savedInstanceState) { final long intentReceivedTime = System.currentTimeMillis(); getChooserActivityLogger().logSharesheetTriggered(); // This is the only place this value is being set. Effectively final. mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable(); Loading Loading @@ -707,6 +721,8 @@ public class ChooserActivity extends ResolverActivity implements incrementNumSheetExpansions(); mWrittenOnce = true; } getChooserActivityLogger() .logSharesheetExpansionChanged(isCollapsed); } }); } Loading @@ -715,6 +731,16 @@ public class ChooserActivity extends ResolverActivity implements Log.d(TAG, "System Time Cost is " + systemCost); } getChooserActivityLogger().logShareStarted( FrameworkStatsLog.SHARESHEET_STARTED, getReferrerPackageName(), target.getType(), initialIntents == null ? 0 : initialIntents.length, mCallerChooserTargets == null ? 0 : mCallerChooserTargets.length, isWorkProfile(), findPreferredContentPreview(getTargetIntent(), getContentResolver()), target.getAction() ); mDirectShareShortcutInfoCache = new HashMap<>(); } Loading Loading @@ -969,6 +995,10 @@ public class ChooserActivity extends ResolverActivity implements LogMaker targetLogMaker = new LogMaker( MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1); getMetricsLogger().write(targetLogMaker); getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_COPY, "", -1); finish(); } Loading Loading @@ -1644,18 +1674,33 @@ public class ChooserActivity extends ResolverActivity implements if (mCallerChooserTargets != null) { numCallerProvided = mCallerChooserTargets.length; } getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_SERVICE, targetInfo.getResolveInfo().activityInfo.processName, value ); break; case ChooserListAdapter.TARGET_CALLER: case ChooserListAdapter.TARGET_STANDARD: cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET; value -= currentListAdapter.getSelectableServiceTargetCount(); numCallerProvided = currentListAdapter.getCallerTargetCount(); getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_APP, targetInfo.getResolveInfo().activityInfo.processName, value ); break; 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; getChooserActivityLogger().logShareTargetSelected( SELECTION_TYPE_STANDARD, targetInfo.getResolveInfo().activityInfo.processName, value ); break; } Loading Loading @@ -2131,7 +2176,7 @@ public class ChooserActivity extends ResolverActivity implements if (appTarget != null) { directShareAppPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH) .setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) .setLaunchLocation(LAUNCH_LOCATION_DIRECT_SHARE) .build()); } } Loading Loading @@ -2290,6 +2335,13 @@ public class ChooserActivity extends ResolverActivity implements return mMetricsLogger; } protected ChooserActivityLogger getChooserActivityLogger() { if (mChooserActivityLogger == null) { mChooserActivityLogger = new ChooserActivityLoggerImpl(); } return mChooserActivityLogger; } public class ChooserListController extends ResolverListController { public ChooserListController(Context context, PackageManager pm, Loading Loading @@ -2601,6 +2653,7 @@ public class ChooserActivity extends ResolverActivity implements // don't support direct share on low ram devices if (ActivityManager.isLowRamDeviceStatic()) { getChooserActivityLogger().logSharesheetAppLoadComplete(); return; } Loading @@ -2619,6 +2672,8 @@ public class ChooserActivity extends ResolverActivity implements queryTargetServices(chooserListAdapter); } getChooserActivityLogger().logSharesheetAppLoadComplete(); } private void setupScrollListener() { Loading Loading @@ -3777,4 +3832,9 @@ public class ChooserActivity extends ResolverActivity implements canvas.drawRoundRect(x, y, width, height, mRadius, mRadius, mRoundRectPaint); } } @Override protected void maybeLogProfileChange() { getChooserActivityLogger().logShareheetProfileChanged(); } }
core/java/com/android/internal/app/ChooserActivityLogger.java 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.internal.app; import android.content.Intent; import android.provider.MediaStore; import com.android.internal.logging.InstanceId; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.FrameworkStatsLog; /** * Interface for writing Sharesheet atoms to statsd log. * @hide */ public interface ChooserActivityLogger { /** Logs a UiEventReported event for the system sharesheet completing initial start-up. */ void logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent); /** Logs a UiEventReported event for the system sharesheet when the user selects a target. */ void logShareTargetSelected(int targetType, String packageName, int positionPicked); /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */ default void logSharesheetTriggered() { log(SharesheetStandardEvent.SHARESHEET_TRIGGERED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet completing loading app targets. */ default void logSharesheetAppLoadComplete() { log(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet completing loading service targets. */ default void logSharesheetDirectLoadComplete() { log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_COMPLETE, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet timing out loading service targets. */ default void logSharesheetDirectLoadTimeout() { log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet switching * between work and main profile. */ default void logShareheetProfileChanged() { log(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet getting expanded or collapsed. */ default void logSharesheetExpansionChanged(boolean isCollapsed) { log(isCollapsed ? SharesheetStandardEvent.SHARESHEET_COLLAPSED : SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId()); } /** * Logs a UiEventReported event for a given share activity * @param event * @param instanceId */ void log(UiEventLogger.UiEventEnum event, InstanceId instanceId); /** * * @return */ InstanceId getInstanceId(); /** * The UiEvent enums that this class can log. */ enum SharesheetStartedEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "Basic system Sharesheet has started and is visible.") SHARE_STARTED(228); private final int mId; SharesheetStartedEvent(int id) { mId = id; } @Override public int getId() { return mId; } } /** * The UiEvent enums that this class can log. */ enum SharesheetTargetSelectedEvent implements UiEventLogger.UiEventEnum { INVALID(0), @UiEvent(doc = "User selected a service target.") SHARESHEET_SERVICE_TARGET_SELECTED(232), @UiEvent(doc = "User selected an app target.") SHARESHEET_APP_TARGET_SELECTED(233), @UiEvent(doc = "User selected a standard target.") SHARESHEET_STANDARD_TARGET_SELECTED(234), @UiEvent(doc = "User selected the copy target.") SHARESHEET_COPY_TARGET_SELECTED(235); private final int mId; SharesheetTargetSelectedEvent(int id) { mId = id; } @Override public int getId() { return mId; } public static SharesheetTargetSelectedEvent fromTargetType(int targetType) { switch(targetType) { case ChooserActivity.SELECTION_TYPE_SERVICE: return SHARESHEET_SERVICE_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_APP: return SHARESHEET_APP_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_STANDARD: return SHARESHEET_STANDARD_TARGET_SELECTED; case ChooserActivity.SELECTION_TYPE_COPY: return SHARESHEET_COPY_TARGET_SELECTED; default: return INVALID; } } } /** * The UiEvent enums that this class can log. */ enum SharesheetStandardEvent implements UiEventLogger.UiEventEnum { INVALID(0), @UiEvent(doc = "User clicked share.") SHARESHEET_TRIGGERED(227), @UiEvent(doc = "User changed from work to personal profile or vice versa.") SHARESHEET_PROFILE_CHANGED(229), @UiEvent(doc = "User expanded target list.") SHARESHEET_EXPANDED(230), @UiEvent(doc = "User collapsed target list.") SHARESHEET_COLLAPSED(231), @UiEvent(doc = "Sharesheet app targets is fully populated.") SHARESHEET_APP_LOAD_COMPLETE(322), @UiEvent(doc = "Sharesheet direct targets is fully populated.") SHARESHEET_DIRECT_LOAD_COMPLETE(323), @UiEvent(doc = "Sharesheet direct targets timed out.") SHARESHEET_DIRECT_LOAD_TIMEOUT(324); private final int mId; SharesheetStandardEvent(int id) { mId = id; } @Override public int getId() { return mId; } } /** * Returns the enum used in sharesheet started atom to indicate what preview type was used. */ default int typeFromPreviewInt(int previewType) { switch(previewType) { case ChooserActivity.CONTENT_PREVIEW_IMAGE: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_IMAGE; case ChooserActivity.CONTENT_PREVIEW_FILE: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE; case ChooserActivity.CONTENT_PREVIEW_TEXT: default: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TEXT; } } /** * Returns the enum used in sharesheet started atom to indicate what intent triggers the * ChooserActivity. */ default int typeFromIntentString(String intent) { switch (intent) { case Intent.ACTION_VIEW: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_VIEW; case Intent.ACTION_EDIT: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_EDIT; case Intent.ACTION_SEND: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND; case Intent.ACTION_SENDTO: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SENDTO; case Intent.ACTION_SEND_MULTIPLE: return FrameworkStatsLog .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND_MULTIPLE; case MediaStore.ACTION_IMAGE_CAPTURE: return FrameworkStatsLog .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_IMAGE_CAPTURE; case Intent.ACTION_MAIN: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_MAIN; default: return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; } } }
core/java/com/android/internal/app/ChooserActivityLoggerImpl.java 0 → 100644 +82 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.internal.app; import com.android.internal.logging.InstanceId; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.util.FrameworkStatsLog; /** * Standard implementation of ChooserActivityLogger interface. * @hide */ public class ChooserActivityLoggerImpl implements ChooserActivityLogger { private static final int SHARESHEET_INSTANCE_ID_MAX = (1 << 13); private UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); // A small per-notification ID, used for statsd logging. private InstanceId mInstanceId; private static InstanceIdSequence sInstanceIdSequence; @Override public void logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent) { FrameworkStatsLog.write(FrameworkStatsLog.SHARESHEET_STARTED, /* event_id = 1 */ SharesheetStartedEvent.SHARE_STARTED.getId(), /* package_name = 2 */ packageName, /* instance_id = 3 */ getInstanceId().getId(), /* mime_type = 4 */ mimeType, /* num_app_provided_direct_targets = 5 */ appProvidedDirect, /* num_app_provided_app_targets = 6 */ appProvidedApp, /* is_workprofile = 7 */ isWorkprofile, /* previewType = 8 */ typeFromPreviewInt(previewType), /* intentType = 9 */ typeFromIntentString(intent)); } @Override public void logShareTargetSelected(int targetType, String packageName, int positionPicked) { FrameworkStatsLog.write(FrameworkStatsLog.RANKING_SELECTED, /* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), /* package_name = 2 */ packageName, /* instance_id = 3 */ getInstanceId().getId(), /* position_picked = 4 */ positionPicked); } @Override public void log(UiEventLogger.UiEventEnum event, InstanceId instanceId) { mUiEventLogger.logWithInstanceId( event, 0, null, instanceId); } @Override public InstanceId getInstanceId() { if (mInstanceId == null) { if (sInstanceIdSequence == null) { sInstanceIdSequence = new InstanceIdSequence(SHARESHEET_INSTANCE_ID_MAX); } mInstanceId = sInstanceIdSequence.newInstanceId(); } return mInstanceId; } }
core/java/com/android/internal/app/ResolverActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -1578,6 +1578,7 @@ public class ResolverActivity extends Activity implements viewPager.setCurrentItem(1); } setupViewVisibilities(); maybeLogProfileChange(); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS) .setInt(viewPager.getCurrentItem()) Loading Loading @@ -1998,4 +1999,6 @@ public class ResolverActivity extends Activity implements } } } protected void maybeLogProfileChange() {} }
core/java/com/android/internal/logging/testing/UiEventLoggerFake.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class UiEventLoggerFake implements UiEventLogger { } @Override public void logWithInstanceId(UiEventLogger.UiEventEnum event, int uid, String packageName, public void logWithInstanceId(UiEventEnum event, int uid, String packageName, InstanceId instance) { final int eventId = event.getId(); if (eventId > 0) { Loading