Merge "Add sharesheet logging for empty direct share row and app share prediction timeout." into sc-dev
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 static final int WATCHDOG_TIMEOUT_MILLIS = 500;
|
||||||
|
|
||||||
private final Comparator<ResolveInfo> mAzComparator;
|
private final Comparator<ResolveInfo> mAzComparator;
|
||||||
|
private ChooserActivityLogger mChooserActivityLogger;
|
||||||
|
|
||||||
protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
@@ -85,6 +86,9 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
|||||||
}
|
}
|
||||||
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
||||||
afterCompute();
|
afterCompute();
|
||||||
|
if (mChooserActivityLogger != null) {
|
||||||
|
mChooserActivityLogger.logSharesheetAppShareRankingTimeout();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -131,6 +135,14 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
|||||||
mAfterCompute = afterCompute;
|
mAfterCompute = afterCompute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setChooserActivityLogger(ChooserActivityLogger chooserActivityLogger) {
|
||||||
|
mChooserActivityLogger = chooserActivityLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChooserActivityLogger getChooserActivityLogger() {
|
||||||
|
return mChooserActivityLogger;
|
||||||
|
}
|
||||||
|
|
||||||
protected final void afterCompute() {
|
protected final void afterCompute() {
|
||||||
final AfterCompute afterCompute = mAfterCompute;
|
final AfterCompute afterCompute = mAfterCompute;
|
||||||
if (afterCompute != null) {
|
if (afterCompute != null) {
|
||||||
|
|||||||
@@ -65,13 +65,15 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
|||||||
Intent intent,
|
Intent intent,
|
||||||
String referrerPackage,
|
String referrerPackage,
|
||||||
AppPredictor appPredictor,
|
AppPredictor appPredictor,
|
||||||
UserHandle user) {
|
UserHandle user,
|
||||||
|
ChooserActivityLogger chooserActivityLogger) {
|
||||||
super(context, intent);
|
super(context, intent);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mIntent = intent;
|
mIntent = intent;
|
||||||
mAppPredictor = appPredictor;
|
mAppPredictor = appPredictor;
|
||||||
mUser = user;
|
mUser = user;
|
||||||
mReferrerPackage = referrerPackage;
|
mReferrerPackage = referrerPackage;
|
||||||
|
setChooserActivityLogger(chooserActivityLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -117,7 +119,8 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
|||||||
mResolverRankerService =
|
mResolverRankerService =
|
||||||
new ResolverRankerServiceResolverComparator(
|
new ResolverRankerServiceResolverComparator(
|
||||||
mContext, mIntent, mReferrerPackage,
|
mContext, mIntent, mReferrerPackage,
|
||||||
() -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT));
|
() -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT),
|
||||||
|
getChooserActivityLogger());
|
||||||
mResolverRankerService.compute(targets);
|
mResolverRankerService.compute(targets);
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "AppPredictionService response received");
|
Log.i(TAG, "AppPredictionService response received");
|
||||||
|
|||||||
@@ -2591,7 +2591,8 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
boolean filterLastUsed, ResolverListController resolverListController) {
|
boolean filterLastUsed, ResolverListController resolverListController) {
|
||||||
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
||||||
filterLastUsed, resolverListController, this,
|
filterLastUsed, resolverListController, this,
|
||||||
this, context.getPackageManager());
|
this, context.getPackageManager(),
|
||||||
|
getChooserActivityLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -2600,11 +2601,11 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
AbstractResolverComparator resolverComparator;
|
AbstractResolverComparator resolverComparator;
|
||||||
if (appPredictor != null) {
|
if (appPredictor != null) {
|
||||||
resolverComparator = new AppPredictionServiceResolverComparator(this, getTargetIntent(),
|
resolverComparator = new AppPredictionServiceResolverComparator(this, getTargetIntent(),
|
||||||
getReferrerPackageName(), appPredictor, userHandle);
|
getReferrerPackageName(), appPredictor, userHandle, getChooserActivityLogger());
|
||||||
} else {
|
} else {
|
||||||
resolverComparator =
|
resolverComparator =
|
||||||
new ResolverRankerServiceResolverComparator(this, getTargetIntent(),
|
new ResolverRankerServiceResolverComparator(this, getTargetIntent(),
|
||||||
getReferrerPackageName(), null);
|
getReferrerPackageName(), null, getChooserActivityLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ChooserListController(
|
return new ChooserListController(
|
||||||
|
|||||||
@@ -74,6 +74,20 @@ public interface ChooserActivityLogger {
|
|||||||
SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId());
|
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
|
* Logs a UiEventReported event for a given share activity
|
||||||
* @param event
|
* @param event
|
||||||
@@ -168,7 +182,11 @@ public interface ChooserActivityLogger {
|
|||||||
@UiEvent(doc = "Sharesheet direct targets is fully populated.")
|
@UiEvent(doc = "Sharesheet direct targets is fully populated.")
|
||||||
SHARESHEET_DIRECT_LOAD_COMPLETE(323),
|
SHARESHEET_DIRECT_LOAD_COMPLETE(323),
|
||||||
@UiEvent(doc = "Sharesheet direct targets timed out.")
|
@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;
|
private final int mId;
|
||||||
SharesheetStandardEvent(int id) {
|
SharesheetStandardEvent(int id) {
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
private final ChooserListCommunicator mChooserListCommunicator;
|
private final ChooserListCommunicator mChooserListCommunicator;
|
||||||
private final SelectableTargetInfo.SelectableTargetInfoCommunicator
|
private final SelectableTargetInfo.SelectableTargetInfoCommunicator
|
||||||
mSelectableTargetInfoCommunicator;
|
mSelectableTargetInfoCommunicator;
|
||||||
|
private final ChooserActivityLogger mChooserActivityLogger;
|
||||||
|
|
||||||
private int mNumShortcutResults = 0;
|
private int mNumShortcutResults = 0;
|
||||||
private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
|
private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
|
||||||
@@ -104,7 +105,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
boolean filterLastUsed, ResolverListController resolverListController,
|
boolean filterLastUsed, ResolverListController resolverListController,
|
||||||
ChooserListCommunicator chooserListCommunicator,
|
ChooserListCommunicator chooserListCommunicator,
|
||||||
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
|
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
|
||||||
PackageManager packageManager) {
|
PackageManager packageManager,
|
||||||
|
ChooserActivityLogger chooserActivityLogger) {
|
||||||
// Don't send the initial intents through the shared ResolverActivity path,
|
// Don't send the initial intents through the shared ResolverActivity path,
|
||||||
// we want to separate them into a different section.
|
// we want to separate them into a different section.
|
||||||
super(context, payloadIntents, null, rList, filterLastUsed,
|
super(context, payloadIntents, null, rList, filterLastUsed,
|
||||||
@@ -115,6 +117,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
mChooserListCommunicator = chooserListCommunicator;
|
mChooserListCommunicator = chooserListCommunicator;
|
||||||
createPlaceHolders();
|
createPlaceHolders();
|
||||||
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
|
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
|
||||||
|
mChooserActivityLogger = chooserActivityLogger;
|
||||||
|
|
||||||
if (initialIntents != null) {
|
if (initialIntents != null) {
|
||||||
for (int i = 0; i < initialIntents.length; i++) {
|
for (int i = 0; i < initialIntents.length; i++) {
|
||||||
@@ -590,6 +593,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
|
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
|
||||||
if (mServiceTargets.isEmpty()) {
|
if (mServiceTargets.isEmpty()) {
|
||||||
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
|
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
|
||||||
|
mChooserActivityLogger.logSharesheetEmptyDirectShareRow();
|
||||||
}
|
}
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class ResolverListController {
|
|||||||
UserHandle userHandle) {
|
UserHandle userHandle) {
|
||||||
this(context, pm, targetIntent, referrerPackage, launchedFromUid, userHandle,
|
this(context, pm, targetIntent, referrerPackage, launchedFromUid, userHandle,
|
||||||
new ResolverRankerServiceResolverComparator(
|
new ResolverRankerServiceResolverComparator(
|
||||||
context, targetIntent, referrerPackage, null));
|
context, targetIntent, referrerPackage, null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResolverListController(
|
public ResolverListController(
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
|||||||
private CountDownLatch mConnectSignal;
|
private CountDownLatch mConnectSignal;
|
||||||
|
|
||||||
public ResolverRankerServiceResolverComparator(Context context, Intent intent,
|
public ResolverRankerServiceResolverComparator(Context context, Intent intent,
|
||||||
String referrerPackage, AfterCompute afterCompute) {
|
String referrerPackage, AfterCompute afterCompute,
|
||||||
|
ChooserActivityLogger chooserActivityLogger) {
|
||||||
super(context, intent);
|
super(context, intent);
|
||||||
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
|
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
|
||||||
mReferrerPackage = referrerPackage;
|
mReferrerPackage = referrerPackage;
|
||||||
@@ -97,6 +98,7 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
|||||||
mAction = intent.getAction();
|
mAction = intent.getAction();
|
||||||
mRankerServiceName = new ComponentName(mContext, this.getClass());
|
mRankerServiceName = new ComponentName(mContext, this.getClass());
|
||||||
setCallBack(afterCompute);
|
setCallBack(afterCompute);
|
||||||
|
setChooserActivityLogger(chooserActivityLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1856,6 +1856,57 @@ public class ChooserActivityTest {
|
|||||||
.SharesheetTargetSelectedEvent.SHARESHEET_SERVICE_TARGET_SELECTED.getId()));
|
.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
|
@Test
|
||||||
public void testCopyTextToClipboardLogging() throws Exception {
|
public void testCopyTextToClipboardLogging() throws Exception {
|
||||||
Intent sendIntent = createSendTextIntent();
|
Intent sendIntent = createSendTextIntent();
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
|||||||
: sOverrides.packageManager;
|
: sOverrides.packageManager;
|
||||||
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
|
||||||
filterLastUsed, resolverListController,
|
filterLastUsed, resolverListController,
|
||||||
this, this, packageManager);
|
this, this, packageManager,
|
||||||
|
getChooserActivityLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChooserListAdapter getAdapter() {
|
ChooserListAdapter getAdapter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user