Merge "Add sharesheet logging for empty direct share row and app share prediction timeout." into sc-dev am: 2ab80e4562
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14788759 Change-Id: Iee0aa9612ec59c7f24e6c46fdc9b74c58c10d79f
This commit is contained in:
@@ -64,6 +64,7 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
||||
private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
|
||||
|
||||
private final Comparator<ResolveInfo> mAzComparator;
|
||||
private ChooserActivityLogger mChooserActivityLogger;
|
||||
|
||||
protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
public void handleMessage(Message msg) {
|
||||
@@ -85,6 +86,9 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
||||
}
|
||||
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
||||
afterCompute();
|
||||
if (mChooserActivityLogger != null) {
|
||||
mChooserActivityLogger.logSharesheetAppShareRankingTimeout();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -131,6 +135,14 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
||||
mAfterCompute = afterCompute;
|
||||
}
|
||||
|
||||
void setChooserActivityLogger(ChooserActivityLogger chooserActivityLogger) {
|
||||
mChooserActivityLogger = chooserActivityLogger;
|
||||
}
|
||||
|
||||
ChooserActivityLogger getChooserActivityLogger() {
|
||||
return mChooserActivityLogger;
|
||||
}
|
||||
|
||||
protected final void afterCompute() {
|
||||
final AfterCompute afterCompute = mAfterCompute;
|
||||
if (afterCompute != null) {
|
||||
|
||||
@@ -61,17 +61,19 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
||||
private ResolverRankerServiceResolverComparator mResolverRankerService;
|
||||
|
||||
AppPredictionServiceResolverComparator(
|
||||
Context context,
|
||||
Intent intent,
|
||||
String referrerPackage,
|
||||
AppPredictor appPredictor,
|
||||
UserHandle user) {
|
||||
Context context,
|
||||
Intent intent,
|
||||
String referrerPackage,
|
||||
AppPredictor appPredictor,
|
||||
UserHandle user,
|
||||
ChooserActivityLogger chooserActivityLogger) {
|
||||
super(context, intent);
|
||||
mContext = context;
|
||||
mIntent = intent;
|
||||
mAppPredictor = appPredictor;
|
||||
mUser = user;
|
||||
mReferrerPackage = referrerPackage;
|
||||
setChooserActivityLogger(chooserActivityLogger);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,8 +118,9 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
||||
// APS for chooser is disabled. Fallback to resolver.
|
||||
mResolverRankerService =
|
||||
new ResolverRankerServiceResolverComparator(
|
||||
mContext, mIntent, mReferrerPackage,
|
||||
() -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT));
|
||||
mContext, mIntent, mReferrerPackage,
|
||||
() -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT),
|
||||
getChooserActivityLogger());
|
||||
mResolverRankerService.compute(targets);
|
||||
} else {
|
||||
Log.i(TAG, "AppPredictionService response received");
|
||||
|
||||
@@ -2591,7 +2591,8 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
boolean filterLastUsed, ResolverListController resolverListController) {
|
||||
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
||||
filterLastUsed, resolverListController, this,
|
||||
this, context.getPackageManager());
|
||||
this, context.getPackageManager(),
|
||||
getChooserActivityLogger());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -2600,11 +2601,11 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
AbstractResolverComparator resolverComparator;
|
||||
if (appPredictor != null) {
|
||||
resolverComparator = new AppPredictionServiceResolverComparator(this, getTargetIntent(),
|
||||
getReferrerPackageName(), appPredictor, userHandle);
|
||||
getReferrerPackageName(), appPredictor, userHandle, getChooserActivityLogger());
|
||||
} else {
|
||||
resolverComparator =
|
||||
new ResolverRankerServiceResolverComparator(this, getTargetIntent(),
|
||||
getReferrerPackageName(), null);
|
||||
getReferrerPackageName(), null, getChooserActivityLogger());
|
||||
}
|
||||
|
||||
return new ChooserListController(
|
||||
|
||||
@@ -74,6 +74,20 @@ public interface ChooserActivityLogger {
|
||||
SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a UiEventReported event for the system sharesheet app share ranking timing out.
|
||||
*/
|
||||
default 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() {
|
||||
log(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW, getInstanceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a UiEventReported event for a given share activity
|
||||
* @param event
|
||||
@@ -168,7 +182,11 @@ public interface ChooserActivityLogger {
|
||||
@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);
|
||||
SHARESHEET_DIRECT_LOAD_TIMEOUT(324),
|
||||
@UiEvent(doc = "Sharesheet app share ranking timed out.")
|
||||
SHARESHEET_APP_SHARE_RANKING_TIMEOUT(831),
|
||||
@UiEvent(doc = "Sharesheet empty direct share row.")
|
||||
SHARESHEET_EMPTY_DIRECT_SHARE_ROW(828);
|
||||
|
||||
private final int mId;
|
||||
SharesheetStandardEvent(int id) {
|
||||
|
||||
@@ -79,6 +79,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
||||
private final ChooserListCommunicator mChooserListCommunicator;
|
||||
private final SelectableTargetInfo.SelectableTargetInfoCommunicator
|
||||
mSelectableTargetInfoCommunicator;
|
||||
private final ChooserActivityLogger mChooserActivityLogger;
|
||||
|
||||
private int mNumShortcutResults = 0;
|
||||
private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
|
||||
@@ -104,7 +105,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
||||
boolean filterLastUsed, ResolverListController resolverListController,
|
||||
ChooserListCommunicator chooserListCommunicator,
|
||||
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
|
||||
PackageManager packageManager) {
|
||||
PackageManager packageManager,
|
||||
ChooserActivityLogger chooserActivityLogger) {
|
||||
// Don't send the initial intents through the shared ResolverActivity path,
|
||||
// we want to separate them into a different section.
|
||||
super(context, payloadIntents, null, rList, filterLastUsed,
|
||||
@@ -115,6 +117,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
||||
mChooserListCommunicator = chooserListCommunicator;
|
||||
createPlaceHolders();
|
||||
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
|
||||
mChooserActivityLogger = chooserActivityLogger;
|
||||
|
||||
if (initialIntents != null) {
|
||||
for (int i = 0; i < initialIntents.length; i++) {
|
||||
@@ -590,6 +593,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
||||
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
|
||||
if (mServiceTargets.isEmpty()) {
|
||||
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
|
||||
mChooserActivityLogger.logSharesheetEmptyDirectShareRow();
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ResolverListController {
|
||||
UserHandle userHandle) {
|
||||
this(context, pm, targetIntent, referrerPackage, launchedFromUid, userHandle,
|
||||
new ResolverRankerServiceResolverComparator(
|
||||
context, targetIntent, referrerPackage, null));
|
||||
context, targetIntent, referrerPackage, null, null));
|
||||
}
|
||||
|
||||
public ResolverListController(
|
||||
|
||||
@@ -85,7 +85,8 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
private CountDownLatch mConnectSignal;
|
||||
|
||||
public ResolverRankerServiceResolverComparator(Context context, Intent intent,
|
||||
String referrerPackage, AfterCompute afterCompute) {
|
||||
String referrerPackage, AfterCompute afterCompute,
|
||||
ChooserActivityLogger chooserActivityLogger) {
|
||||
super(context, intent);
|
||||
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
|
||||
mReferrerPackage = referrerPackage;
|
||||
@@ -97,6 +98,7 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
mAction = intent.getAction();
|
||||
mRankerServiceName = new ComponentName(mContext, this.getClass());
|
||||
setCallBack(afterCompute);
|
||||
setChooserActivityLogger(chooserActivityLogger);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1856,6 +1856,57 @@ public class ChooserActivityTest {
|
||||
.SharesheetTargetSelectedEvent.SHARESHEET_SERVICE_TARGET_SELECTED.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyDirectRowLogging() throws InterruptedException {
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
// We need app targets for direct targets to get displayed
|
||||
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
|
||||
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
|
||||
|
||||
// Start activity
|
||||
final ChooserWrapperActivity activity = mActivityRule
|
||||
.launchActivity(Intent.createChooser(sendIntent, null));
|
||||
|
||||
// Thread.sleep shouldn't be a thing in an integration test but it's
|
||||
// necessary here because of the way the code is structured
|
||||
Thread.sleep(3000);
|
||||
|
||||
assertThat("Chooser should have 2 app targets",
|
||||
activity.getAdapter().getCount(), is(2));
|
||||
assertThat("Chooser should have no direct targets",
|
||||
activity.getAdapter().getSelectableServiceTargetCount(), is(0));
|
||||
|
||||
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("com.android.frameworks.coretests"));
|
||||
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_EMPTY_DIRECT_SHARE_ROW event
|
||||
assertThat(logger.get(5).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
|
||||
assertThat(logger.get(5).event.getId(),
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyTextToClipboardLogging() throws Exception {
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
|
||||
@@ -68,7 +68,8 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
: sOverrides.packageManager;
|
||||
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
||||
filterLastUsed, resolverListController,
|
||||
this, this, packageManager);
|
||||
this, this, packageManager,
|
||||
getChooserActivityLogger());
|
||||
}
|
||||
|
||||
ChooserListAdapter getAdapter() {
|
||||
|
||||
Reference in New Issue
Block a user