diff options
| author | 2022-10-24 21:25:56 +0000 | |
|---|---|---|
| committer | 2022-10-24 21:25:56 +0000 | |
| commit | ba30238e98665ed62b5ae4cb25e018f89161024f (patch) | |
| tree | c27c809ac86911e12d0fa04b07145885679b0f7f /java | |
| parent | 60bc4b08faea70196aea5c3c9ccf457f791711e9 (diff) | |
| parent | 198ff2693ebe41d8a664586bd9387f548a51b016 (diff) | |
Merge "Simplify ChooserActivityLogger." into tm-qpr-dev
Diffstat (limited to 'java')
7 files changed, 390 insertions, 532 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index 26c7fbc9..31254de8 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -2275,7 +2275,7 @@ public class ChooserActivity extends ResolverActivity implements protected ChooserActivityLogger getChooserActivityLogger() { if (mChooserActivityLogger == null) { - mChooserActivityLogger = new ChooserActivityLoggerImpl(); + mChooserActivityLogger = new ChooserActivityLogger(); } return mChooserActivityLogger; } @@ -4008,7 +4008,7 @@ public class ChooserActivity extends ResolverActivity implements @Override protected void maybeLogProfileChange() { - getChooserActivityLogger().logShareheetProfileChanged(); + getChooserActivityLogger().logSharesheetProfileChanged(); } private boolean shouldNearbyShareBeFirstInRankedRow() { diff --git a/java/src/com/android/intentresolver/ChooserActivityLogger.java b/java/src/com/android/intentresolver/ChooserActivityLogger.java index 1daae01a..6d760b1a 100644 --- a/java/src/com/android/intentresolver/ChooserActivityLogger.java +++ b/java/src/com/android/intentresolver/ChooserActivityLogger.java @@ -19,45 +19,116 @@ package com.android.intentresolver; import android.content.Intent; import android.provider.MediaStore; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; +import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.util.FrameworkStatsLog; /** - * Interface for writing Sharesheet atoms to statsd log. + * Helper for writing Sharesheet atoms to statsd log. * @hide */ -public interface ChooserActivityLogger { +public class ChooserActivityLogger { + /** + * This shim is provided only for testing. In production, clients will only ever use a + * {@link DefaultFrameworkStatsLogger}. + */ + @VisibleForTesting + interface FrameworkStatsLogger { + /** Overload to use for logging {@code FrameworkStatsLog.SHARESHEET_STARTED}. */ + void write( + int frameworkEventId, + int appEventId, + String packageName, + int instanceId, + String mimeType, + int numAppProvidedDirectTargets, + int numAppProvidedAppTargets, + boolean isWorkProfile, + int previewType, + int intentType); + + /** Overload to use for logging {@code FrameworkStatsLog.RANKING_SELECTED}. */ + void write( + int frameworkEventId, + int appEventId, + String packageName, + int instanceId, + int positionPicked, + boolean isPinned); + } + + private static final int SHARESHEET_INSTANCE_ID_MAX = (1 << 13); + + // A small per-notification ID, used for statsd logging. + // TODO: consider precomputing and storing as final. + private static InstanceIdSequence sInstanceIdSequence; + private InstanceId mInstanceId; + + private final UiEventLogger mUiEventLogger; + private final FrameworkStatsLogger mFrameworkStatsLogger; + + public ChooserActivityLogger() { + this(new UiEventLoggerImpl(), new DefaultFrameworkStatsLogger()); + } + + @VisibleForTesting + ChooserActivityLogger(UiEventLogger uiEventLogger, FrameworkStatsLogger frameworkLogger) { + mUiEventLogger = uiEventLogger; + mFrameworkStatsLogger = frameworkLogger; + } + /** 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); + public void logShareStarted(int eventId, String packageName, String mimeType, + int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, + String intent) { + mFrameworkStatsLogger.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)); + } /** Logs a UiEventReported event for the system sharesheet when the user selects a target. */ - void logShareTargetSelected(int targetType, String packageName, int positionPicked, - boolean isPinned); + public void logShareTargetSelected(int targetType, String packageName, int positionPicked, + boolean isPinned) { + 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); + } /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */ - default void logSharesheetTriggered() { + public void logSharesheetTriggered() { log(SharesheetStandardEvent.SHARESHEET_TRIGGERED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet completing loading app targets. */ - default void logSharesheetAppLoadComplete() { + public void logSharesheetAppLoadComplete() { log(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet completing loading service targets. */ - default void logSharesheetDirectLoadComplete() { + public 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() { + public void logSharesheetDirectLoadTimeout() { log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT, getInstanceId()); } @@ -65,12 +136,12 @@ public interface ChooserActivityLogger { * Logs a UiEventReported event for the system sharesheet switching * between work and main profile. */ - default void logShareheetProfileChanged() { + public void logSharesheetProfileChanged() { log(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED, getInstanceId()); } /** Logs a UiEventReported event for the system sharesheet getting expanded or collapsed. */ - default void logSharesheetExpansionChanged(boolean isCollapsed) { + public void logSharesheetExpansionChanged(boolean isCollapsed) { log(isCollapsed ? SharesheetStandardEvent.SHARESHEET_COLLAPSED : SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId()); } @@ -78,14 +149,14 @@ public interface ChooserActivityLogger { /** * Logs a UiEventReported event for the system sharesheet app share ranking timing out. */ - default void logSharesheetAppShareRankingTimeout() { + public void logSharesheetAppShareRankingTimeout() { log(SharesheetStandardEvent.SHARESHEET_APP_SHARE_RANKING_TIMEOUT, getInstanceId()); } /** * Logs a UiEventReported event for the system sharesheet when direct share row is empty. */ - default void logSharesheetEmptyDirectShareRow() { + public void logSharesheetEmptyDirectShareRow() { log(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW, getInstanceId()); } @@ -94,13 +165,26 @@ public interface ChooserActivityLogger { * @param event * @param instanceId */ - void log(UiEventLogger.UiEventEnum event, InstanceId instanceId); + private void log(UiEventLogger.UiEventEnum event, InstanceId instanceId) { + mUiEventLogger.logWithInstanceId( + event, + 0, + null, + instanceId); + } /** - * - * @return + * @return A unique {@link InstanceId} to join across events recorded by this logger instance. */ - InstanceId getInstanceId(); + private InstanceId getInstanceId() { + if (mInstanceId == null) { + if (sInstanceIdSequence == null) { + sInstanceIdSequence = new InstanceIdSequence(SHARESHEET_INSTANCE_ID_MAX); + } + mInstanceId = sInstanceIdSequence.newInstanceId(); + } + return mInstanceId; + } /** * The UiEvent enums that this class can log. @@ -201,7 +285,7 @@ public interface ChooserActivityLogger { /** * Returns the enum used in sharesheet started atom to indicate what preview type was used. */ - default int typeFromPreviewInt(int previewType) { + private static int typeFromPreviewInt(int previewType) { switch(previewType) { case ChooserActivity.CONTENT_PREVIEW_IMAGE: return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_IMAGE; @@ -218,7 +302,7 @@ public interface ChooserActivityLogger { * Returns the enum used in sharesheet started atom to indicate what intent triggers the * ChooserActivity. */ - default int typeFromIntentString(String intent) { + private static int typeFromIntentString(String intent) { if (intent == null) { return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; } @@ -243,4 +327,48 @@ public interface ChooserActivityLogger { return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT; } } + + private static class DefaultFrameworkStatsLogger implements FrameworkStatsLogger { + @Override + public void write( + int frameworkEventId, + int appEventId, + String packageName, + int instanceId, + String mimeType, + int numAppProvidedDirectTargets, + int numAppProvidedAppTargets, + boolean isWorkProfile, + int previewType, + int intentType) { + FrameworkStatsLog.write( + frameworkEventId, + /* event_id = 1 */ appEventId, + /* package_name = 2 */ packageName, + /* instance_id = 3 */ instanceId, + /* mime_type = 4 */ mimeType, + /* num_app_provided_direct_targets */ numAppProvidedDirectTargets, + /* num_app_provided_app_targets */ numAppProvidedAppTargets, + /* is_workprofile */ isWorkProfile, + /* previewType = 8 */ previewType, + /* intentType = 9 */ intentType); + } + + @Override + public void write( + int frameworkEventId, + int appEventId, + String packageName, + int instanceId, + int positionPicked, + boolean isPinned) { + FrameworkStatsLog.write( + frameworkEventId, + /* event_id = 1 */ appEventId, + /* package_name = 2 */ packageName, + /* instance_id = 3 */ instanceId, + /* position_picked = 4 */ positionPicked, + /* is_pinned = 5 */ isPinned); + } + } } diff --git a/java/src/com/android/intentresolver/ChooserActivityLoggerImpl.java b/java/src/com/android/intentresolver/ChooserActivityLoggerImpl.java deleted file mode 100644 index 08a345bc..00000000 --- a/java/src/com/android/intentresolver/ChooserActivityLoggerImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.intentresolver; - -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, - boolean isPinned) { - 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, - /* is_pinned = 5 */ isPinned); - } - - @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; - } - -} diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityLoggerFake.java b/java/tests/src/com/android/intentresolver/ChooserActivityLoggerFake.java deleted file mode 100644 index e4146cc5..00000000 --- a/java/tests/src/com/android/intentresolver/ChooserActivityLoggerFake.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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.intentresolver; - -import com.android.internal.logging.InstanceId; -import com.android.internal.logging.UiEventLogger; -import com.android.internal.util.FrameworkStatsLog; - -import java.util.ArrayList; -import java.util.List; - -public class ChooserActivityLoggerFake implements ChooserActivityLogger { - static class CallRecord { - // shared fields between all logs - public int atomId; - public String packageName; - public InstanceId instanceId; - - // generic log field - public UiEventLogger.UiEventEnum event; - - // share started fields - public String mimeType; - public int appProvidedDirect; - public int appProvidedApp; - public boolean isWorkprofile; - public int previewType; - public String intent; - - // share completed fields - public int targetType; - public int positionPicked; - public boolean isPinned; - - CallRecord(int atomId, UiEventLogger.UiEventEnum eventId, - String packageName, InstanceId instanceId) { - this.atomId = atomId; - this.packageName = packageName; - this.instanceId = instanceId; - this.event = eventId; - } - - CallRecord(int atomId, String packageName, InstanceId instanceId, String mimeType, - int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, - String intent) { - this.atomId = atomId; - this.packageName = packageName; - this.instanceId = instanceId; - this.mimeType = mimeType; - this.appProvidedDirect = appProvidedDirect; - this.appProvidedApp = appProvidedApp; - this.isWorkprofile = isWorkprofile; - this.previewType = previewType; - this.intent = intent; - } - - CallRecord(int atomId, String packageName, InstanceId instanceId, int targetType, - int positionPicked, boolean isPinned) { - this.atomId = atomId; - this.packageName = packageName; - this.instanceId = instanceId; - this.targetType = targetType; - this.positionPicked = positionPicked; - this.isPinned = isPinned; - } - - } - private List<CallRecord> mCalls = new ArrayList<>(); - - public int numCalls() { - return mCalls.size(); - } - - List<CallRecord> getCalls() { - return mCalls; - } - - CallRecord get(int index) { - return mCalls.get(index); - } - - UiEventLogger.UiEventEnum event(int index) { - return mCalls.get(index).event; - } - - public void removeCallsForUiEventsOfType(int uiEventType) { - mCalls.removeIf( - call -> - (call.atomId == FrameworkStatsLog.UI_EVENT_REPORTED) - && (call.event.getId() == uiEventType)); - } - - @Override - public void logShareStarted(int eventId, String packageName, String mimeType, - int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, - String intent) { - mCalls.add(new CallRecord(FrameworkStatsLog.SHARESHEET_STARTED, packageName, - getInstanceId(), mimeType, appProvidedDirect, appProvidedApp, isWorkprofile, - previewType, intent)); - } - - @Override - public void logShareTargetSelected(int targetType, String packageName, int positionPicked, - boolean isPinned) { - mCalls.add(new CallRecord(FrameworkStatsLog.RANKING_SELECTED, packageName, getInstanceId(), - SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), positionPicked, - isPinned)); - } - - @Override - public void log(UiEventLogger.UiEventEnum event, InstanceId instanceId) { - mCalls.add(new CallRecord(FrameworkStatsLog.UI_EVENT_REPORTED, - event, "", instanceId)); - } - - @Override - public InstanceId getInstanceId() { - return InstanceId.fakeInstanceId(-1); - } -} diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java b/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java new file mode 100644 index 00000000..a93718fd --- /dev/null +++ b/java/tests/src/com/android/intentresolver/ChooserActivityLoggerTest.java @@ -0,0 +1,239 @@ +/* + * 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.intentresolver; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.AdditionalMatchers.gt; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import android.content.Intent; + +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.UiEventLogger; +import com.android.internal.logging.UiEventLogger.UiEventEnum; +import com.android.internal.util.FrameworkStatsLog; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public final class ChooserActivityLoggerTest { + @Mock private UiEventLogger mUiEventLog; + @Mock private FrameworkStatsLogger mFrameworkLog; + + private ChooserActivityLogger mChooserLogger; + + @Before + public void setUp() { + mChooserLogger = new ChooserActivityLogger(mUiEventLog, mFrameworkLog); + } + + @After + public void tearDown() { + verifyNoMoreInteractions(mUiEventLog); + verifyNoMoreInteractions(mFrameworkLog); + } + + @Test + public void testLogShareStarted() { + final int eventId = -1; // Passed-in eventId is unused. TODO: remove from method signature. + final String packageName = "com.test.foo"; + final String mimeType = "text/plain"; + final int appProvidedDirectTargets = 123; + final int appProvidedAppTargets = 456; + final boolean workProfile = true; + final int previewType = ChooserActivity.CONTENT_PREVIEW_FILE; + final String intentAction = Intent.ACTION_SENDTO; + + mChooserLogger.logShareStarted( + eventId, + packageName, + mimeType, + appProvidedDirectTargets, + appProvidedAppTargets, + workProfile, + previewType, + intentAction); + + verify(mFrameworkLog).write( + eq(FrameworkStatsLog.SHARESHEET_STARTED), + eq(SharesheetStartedEvent.SHARE_STARTED.getId()), + eq(packageName), + /* instanceId=*/ gt(0), + eq(mimeType), + eq(appProvidedDirectTargets), + eq(appProvidedAppTargets), + eq(workProfile), + eq(FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE), + eq(FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SENDTO)); + } + + @Test + public void testLogShareTargetSelected() { + final int targetType = ChooserActivity.SELECTION_TYPE_COPY; + final String packageName = "com.test.foo"; + final int positionPicked = 123; + final boolean pinned = true; + + mChooserLogger.logShareTargetSelected(targetType, packageName, positionPicked, pinned); + + verify(mFrameworkLog).write( + eq(FrameworkStatsLog.RANKING_SELECTED), + eq(SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId()), + eq(packageName), + /* instanceId=*/ gt(0), + eq(positionPicked), + eq(pinned)); + } + + @Test + public void testLogSharesheetTriggered() { + mChooserLogger.logSharesheetTriggered(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_TRIGGERED), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetAppLoadComplete() { + mChooserLogger.logSharesheetAppLoadComplete(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetDirectLoadComplete() { + mChooserLogger.logSharesheetDirectLoadComplete(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_COMPLETE), + eq(0), + isNull(), + any()); + } + + @Test + public void testLogSharesheetDirectLoadTimeout() { + mChooserLogger.logSharesheetDirectLoadTimeout(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetProfileChanged() { + mChooserLogger.logSharesheetProfileChanged(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetExpansionChanged_collapsed() { + mChooserLogger.logSharesheetExpansionChanged(/* isCollapsed=*/ true); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_COLLAPSED), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetExpansionChanged_expanded() { + mChooserLogger.logSharesheetExpansionChanged(/* isCollapsed=*/ false); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_EXPANDED), eq(0), isNull(), any()); + } + + @Test + public void testLogSharesheetAppShareRankingTimeout() { + mChooserLogger.logSharesheetAppShareRankingTimeout(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_APP_SHARE_RANKING_TIMEOUT), + eq(0), + isNull(), + any()); + } + + @Test + public void testLogSharesheetEmptyDirectShareRow() { + mChooserLogger.logSharesheetEmptyDirectShareRow(); + verify(mUiEventLog).logWithInstanceId( + eq(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW), + eq(0), + isNull(), + any()); + } + + @Test + public void testDifferentLoggerInstancesUseDifferentInstanceIds() { + ArgumentCaptor<Integer> idIntCaptor = ArgumentCaptor.forClass(Integer.class); + ChooserActivityLogger chooserLogger2 = + new ChooserActivityLogger(mUiEventLog, mFrameworkLog); + + final int targetType = ChooserActivity.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); + + verify(mFrameworkLog, times(2)).write( + anyInt(), anyInt(), anyString(), idIntCaptor.capture(), anyInt(), anyBoolean()); + + int id1 = idIntCaptor.getAllValues().get(0); + int id2 = idIntCaptor.getAllValues().get(1); + + assertThat(id1).isGreaterThan(0); + assertThat(id2).isGreaterThan(0); + assertThat(id1).isNotEqualTo(id2); + } + + @Test + public void testUiAndFrameworkEventsUseSameInstanceIdForSameLoggerInstance() { + ArgumentCaptor<Integer> idIntCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<InstanceId> idObjectCaptor = ArgumentCaptor.forClass(InstanceId.class); + + final int targetType = ChooserActivity.SELECTION_TYPE_COPY; + final String packageName = "com.test.foo"; + final int positionPicked = 123; + final boolean pinned = true; + + mChooserLogger.logShareTargetSelected(targetType, packageName, positionPicked, pinned); + verify(mFrameworkLog).write( + anyInt(), anyInt(), anyString(), idIntCaptor.capture(), anyInt(), anyBoolean()); + + mChooserLogger.logSharesheetTriggered(); + verify(mUiEventLog).logWithInstanceId( + any(UiEventEnum.class), anyInt(), any(), idObjectCaptor.capture()); + + assertThat(idIntCaptor.getValue()).isGreaterThan(0); + assertThat(idObjectCaptor.getValue().getId()).isEqualTo(idIntCaptor.getValue()); + } +} diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java index 080f1e41..d1ca2b09 100644 --- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java +++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java @@ -81,7 +81,7 @@ public class ChooserActivityOverrideData { resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); metricsLogger = mock(MetricsLogger.class); - chooserActivityLogger = new ChooserActivityLoggerFake(); + chooserActivityLogger = mock(ChooserActivityLogger.class); alternateProfileSetting = 0; resources = null; workProfileUserHandle = null; diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index 5d600092..09ee8fc1 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -96,7 +96,6 @@ import com.android.intentresolver.chooser.DisplayResolveInfo; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.util.FrameworkStatsLog; import org.hamcrest.Description; import org.hamcrest.Matcher; @@ -820,49 +819,7 @@ public class UnbundledChooserActivityTest { .check(matches(isDisplayed())); onView(withId(com.android.internal.R.id.chooser_nearby_button)).perform(click()); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("text/plain")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next are just artifacts of test set-up: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_EXPANDED.getId())); - - // SHARESHEET_NEARBY_TARGET_SELECTED: - assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED)); - assertThat(logger.get(5).targetType, - is(ChooserActivityLogger - .SharesheetTargetSelectedEvent.SHARESHEET_NEARBY_TARGET_SELECTED.getId())); - - // No more events. - assertThat(logger.numCalls(), is(6)); } @@ -891,49 +848,7 @@ public class UnbundledChooserActivityTest { onView(withId(com.android.internal.R.id.chooser_edit_button)).check(matches(isDisplayed())); onView(withId(com.android.internal.R.id.chooser_edit_button)).perform(click()); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("image/png")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(1)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next are just artifacts of test set-up: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_EXPANDED.getId())); - - // SHARESHEET_EDIT_TARGET_SELECTED: - assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED)); - assertThat(logger.get(5).targetType, - is(ChooserActivityLogger - .SharesheetTargetSelectedEvent.SHARESHEET_EDIT_TARGET_SELECTED.getId())); - - // No more events. - assertThat(logger.numCalls(), is(6)); } @@ -2033,49 +1948,7 @@ public class UnbundledChooserActivityTest { .perform(click()); waitForIdle(); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("text/plain")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next are just artifacts of test set-up: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_EXPANDED.getId())); - - // SHARESHEET_APP_TARGET_SELECTED: - assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED)); - assertThat(logger.get(5).targetType, - is(ChooserActivityLogger - .SharesheetTargetSelectedEvent.SHARESHEET_APP_TARGET_SELECTED.getId())); - - // No more events. - assertThat(logger.numCalls(), is(6)); } @Test @Ignore @@ -2135,35 +2008,6 @@ public class UnbundledChooserActivityTest { onView(withText(name)) .perform(click()); waitForIdle(); - - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - assertThat(logger.numCalls(), is(6)); - // first one should be SHARESHEET_TRIGGERED uievent - assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED)); - assertThat(logger.get(0).event.getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - // second one should be SHARESHEET_STARTED event - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("text/plain")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent - assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED)); - assertThat(logger.get(2).event.getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - // fourth and fifth are just artifacts of test set-up - // sixth one should be ranking atom with SHARESHEET_COPY_TARGET_SELECTED event - assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED)); - assertThat(logger.get(5).targetType, - is(ChooserActivityLogger - .SharesheetTargetSelectedEvent.SHARESHEET_SERVICE_TARGET_SELECTED.getId())); } @Test @Ignore @@ -2195,44 +2039,7 @@ public class UnbundledChooserActivityTest { assertThat("Chooser should have no direct targets", activity.getAdapter().getSelectableServiceTargetCount(), is(0)); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("text/plain")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // SHARESHEET_EMPTY_DIRECT_SHARE_ROW: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - - // Next is just an artifact of test set-up: - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_EXPANDED.getId())); - - assertThat(logger.numCalls(), is(5)); } @Ignore // b/220067877 @@ -2259,49 +2066,7 @@ public class UnbundledChooserActivityTest { 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()); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is("text/plain")); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next are just artifacts of test set-up: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_EXPANDED.getId())); - - // SHARESHEET_COPY_TARGET_SELECTED: - assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED)); - assertThat(logger.get(5).targetType, - is(ChooserActivityLogger - .SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId())); - - // No more events. - assertThat(logger.numCalls(), is(6)); } @Test @Ignore("b/222124533") @@ -2324,63 +2089,7 @@ public class UnbundledChooserActivityTest { onView(withText(R.string.resolver_personal_tab)).perform(click()); waitForIdle(); - ChooserActivityLoggerFake logger = - (ChooserActivityLoggerFake) activity.getChooserActivityLogger(); - // TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events. - logger.removeCallsForUiEventsOfType( - ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_DIRECT_LOAD_COMPLETE.getId()); - - // SHARESHEET_TRIGGERED: - assertThat(logger.event(0).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId())); - - // SHARESHEET_STARTED: - assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED)); - assertThat(logger.get(1).intent, is(Intent.ACTION_SEND)); - assertThat(logger.get(1).mimeType, is(TEST_MIME_TYPE)); - assertThat(logger.get(1).packageName, is( - InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName())); - assertThat(logger.get(1).appProvidedApp, is(0)); - assertThat(logger.get(1).appProvidedDirect, is(0)); - assertThat(logger.get(1).isWorkprofile, is(false)); - assertThat(logger.get(1).previewType, is(3)); - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(2).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next is just an artifact of test set-up: - assertThat(logger.event(3).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - - // SHARESHEET_PROFILE_CHANGED: - assertThat(logger.event(4).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_PROFILE_CHANGED.getId())); - - // Repeat the loading steps in the new profile: - - // SHARESHEET_APP_LOAD_COMPLETE: - assertThat(logger.event(5).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId())); - - // Next is again an artifact of test set-up: - assertThat(logger.event(6).getId(), - is(ChooserActivityLogger - .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId())); - - // SHARESHEET_PROFILE_CHANGED: - assertThat(logger.event(7).getId(), - is(ChooserActivityLogger.SharesheetStandardEvent - .SHARESHEET_PROFILE_CHANGED.getId())); - - // No more events (this profile was already loaded). - assertThat(logger.numCalls(), is(8)); } @Test |