Merge "Add sharesheet statsd logging" into rvc-dev am: f9617e33f9
Change-Id: I37b38005b051074cf7dbfa16dcbeec991ae1842b
This commit is contained in:
@@ -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;
|
||||
@@ -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";
|
||||
|
||||
@@ -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 = {
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -533,6 +545,7 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
logDirectShareTargetReceived(
|
||||
MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER);
|
||||
sendVoiceChoicesIfNeeded();
|
||||
getChooserActivityLogger().logSharesheetDirectLoadComplete();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -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();
|
||||
|
||||
@@ -707,6 +721,8 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
incrementNumSheetExpansions();
|
||||
mWrittenOnce = true;
|
||||
}
|
||||
getChooserActivityLogger()
|
||||
.logSharesheetExpansionChanged(isCollapsed);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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<>();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -2619,6 +2672,8 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
|
||||
queryTargetServices(chooserListAdapter);
|
||||
}
|
||||
|
||||
getChooserActivityLogger().logSharesheetAppLoadComplete();
|
||||
}
|
||||
|
||||
private void setupScrollListener() {
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
215
core/java/com/android/internal/app/ChooserActivityLogger.java
Normal file
215
core/java/com/android/internal/app/ChooserActivityLogger.java
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1578,6 +1578,7 @@ public class ResolverActivity extends Activity implements
|
||||
viewPager.setCurrentItem(1);
|
||||
}
|
||||
setupViewVisibilities();
|
||||
maybeLogProfileChange();
|
||||
DevicePolicyEventLogger
|
||||
.createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS)
|
||||
.setInt(viewPager.getCurrentItem())
|
||||
@@ -1998,4 +1999,6 @@ public class ResolverActivity extends Activity implements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void maybeLogProfileChange() {}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
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) {
|
||||
this.atomId = atomId;
|
||||
this.packageName = packageName;
|
||||
this.instanceId = instanceId;
|
||||
this.targetType = targetType;
|
||||
this.positionPicked = positionPicked;
|
||||
}
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@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) {
|
||||
mCalls.add(new CallRecord(FrameworkStatsLog.RANKING_SELECTED, packageName, getInstanceId(),
|
||||
SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), positionPicked));
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,7 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
|
||||
import com.android.internal.app.chooser.DisplayResolveInfo;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
@@ -1430,6 +1431,251 @@ public class ChooserActivityTest {
|
||||
.check(matches(isDisplayed()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppTargetLogging() throws InterruptedException {
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
|
||||
|
||||
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
|
||||
|
||||
final ChooserWrapperActivity activity = mActivityRule
|
||||
.launchActivity(Intent.createChooser(sendIntent, null));
|
||||
waitForIdle();
|
||||
|
||||
assertThat(activity.getAdapter().getCount(), is(2));
|
||||
onView(withId(R.id.profile_button)).check(doesNotExist());
|
||||
|
||||
ResolveInfo[] chosen = new ResolveInfo[1];
|
||||
sOverrides.onSafelyStartCallback = targetInfo -> {
|
||||
chosen[0] = targetInfo.getResolveInfo();
|
||||
return true;
|
||||
};
|
||||
|
||||
ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
|
||||
onView(withText(toChoose.activityInfo.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("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_APP_TARGET_SELECTED event
|
||||
assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED));
|
||||
assertThat(logger.get(5).targetType,
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetTargetSelectedEvent.SHARESHEET_APP_TARGET_SELECTED.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectTargetLogging() 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);
|
||||
|
||||
// Create direct share target
|
||||
List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
|
||||
resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
|
||||
ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
|
||||
|
||||
// Start activity
|
||||
final ChooserWrapperActivity activity = mActivityRule
|
||||
.launchActivity(Intent.createChooser(sendIntent, null));
|
||||
|
||||
// Insert the direct share target
|
||||
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos = new HashMap<>();
|
||||
directShareToShortcutInfos.put(serviceTargets.get(0), null);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> activity.getAdapter().addServiceResults(
|
||||
activity.createTestDisplayResolveInfo(sendIntent,
|
||||
ri,
|
||||
"testLabel",
|
||||
"testInfo",
|
||||
sendIntent,
|
||||
/* resolveInfoPresentationGetter */ null),
|
||||
serviceTargets,
|
||||
TARGET_TYPE_CHOOSER_TARGET,
|
||||
directShareToShortcutInfos,
|
||||
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
|
||||
// TODO: restructure the tests b/129870719
|
||||
Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
|
||||
|
||||
assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
|
||||
activity.getAdapter().getCount(), is(3));
|
||||
assertThat("Chooser should have exactly one selectable direct target",
|
||||
activity.getAdapter().getSelectableServiceTargetCount(), is(1));
|
||||
assertThat("The resolver info must match the resolver info used to create the target",
|
||||
activity.getAdapter().getItem(0).getResolveInfo(), is(ri));
|
||||
|
||||
// Click on the direct target
|
||||
String name = serviceTargets.get(0).getTitle().toString();
|
||||
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("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_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
|
||||
public void testCopyTextToClipboardLogging() throws Exception {
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
|
||||
|
||||
when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
|
||||
|
||||
final ChooserWrapperActivity activity = mActivityRule
|
||||
.launchActivity(Intent.createChooser(sendIntent, null));
|
||||
waitForIdle();
|
||||
|
||||
onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
|
||||
onView(withId(R.id.chooser_copy_button)).perform(click());
|
||||
|
||||
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_COPY_TARGET_SELECTED event
|
||||
assertThat(logger.get(5).atomId, is(FrameworkStatsLog.RANKING_SELECTED));
|
||||
assertThat(logger.get(5).targetType,
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetTargetSelectedEvent.SHARESHEET_COPY_TARGET_SELECTED.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchProfileLogging() throws InterruptedException {
|
||||
// enable the work tab feature flag
|
||||
ResolverActivity.ENABLE_TABBED_VIEW = true;
|
||||
markWorkProfileUserAvailable();
|
||||
int workProfileTargets = 4;
|
||||
List<ResolvedComponentInfo> personalResolvedComponentInfos =
|
||||
createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
|
||||
List<ResolvedComponentInfo> workResolvedComponentInfos =
|
||||
createResolvedComponentsForTest(workProfileTargets);
|
||||
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
sendIntent.setType("TestType");
|
||||
|
||||
final ChooserWrapperActivity activity =
|
||||
mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
|
||||
waitForIdle();
|
||||
onView(withText(R.string.resolver_work_tab)).perform(click());
|
||||
waitForIdle();
|
||||
onView(withText(R.string.resolver_personal_tab)).perform(click());
|
||||
waitForIdle();
|
||||
|
||||
ChooserActivityLoggerFake logger =
|
||||
(ChooserActivityLoggerFake) activity.getChooserActivityLogger();
|
||||
assertThat(logger.numCalls(), is(8));
|
||||
// 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("TestType"));
|
||||
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 one is artifact of test setup
|
||||
// fifth one is switch to work profile
|
||||
assertThat(logger.get(4).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
|
||||
assertThat(logger.get(4).event.getId(),
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED.getId()));
|
||||
// sixth one should be SHARESHEET_APP_LOAD_COMPLETE uievent
|
||||
assertThat(logger.get(5).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
|
||||
assertThat(logger.get(5).event.getId(),
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
|
||||
// seventh one is artifact of test setup
|
||||
// eigth one is switch to work profile
|
||||
assertThat(logger.get(7).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
|
||||
assertThat(logger.get(7).event.getId(),
|
||||
is(ChooserActivityLogger
|
||||
.SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED.getId()));
|
||||
}
|
||||
|
||||
private Intent createSendTextIntent() {
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
|
||||
@@ -145,6 +145,11 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
return sOverrides.metricsLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ChooserActivityLogger getChooserActivityLogger() {
|
||||
return sOverrides.chooserActivityLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor queryResolver(ContentResolver resolver, Uri uri) {
|
||||
if (sOverrides.resolverCursor != null) {
|
||||
@@ -205,6 +210,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
public boolean resolverForceException;
|
||||
public Bitmap previewThumbnail;
|
||||
public MetricsLogger metricsLogger;
|
||||
public ChooserActivityLogger chooserActivityLogger;
|
||||
public int alternateProfileSetting;
|
||||
public Resources resources;
|
||||
public UserHandle workProfileUserHandle;
|
||||
@@ -223,6 +229,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
resolverListController = mock(ResolverListController.class);
|
||||
workResolverListController = mock(ResolverListController.class);
|
||||
metricsLogger = mock(MetricsLogger.class);
|
||||
chooserActivityLogger = new ChooserActivityLoggerFake();
|
||||
alternateProfileSetting = 0;
|
||||
resources = null;
|
||||
workProfileUserHandle = null;
|
||||
|
||||
@@ -220,7 +220,7 @@ public class DataManager {
|
||||
String mimeType = intentFilter != null ? intentFilter.getDataType(0) : null;
|
||||
@Event.EventType int eventType = mimeTypeToShareEventType(mimeType);
|
||||
EventHistoryImpl eventHistory;
|
||||
if (ChooserActivity.LAUNCH_LOCATON_DIRECT_SHARE.equals(event.getLaunchLocation())) {
|
||||
if (ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE.equals(event.getLaunchLocation())) {
|
||||
// Direct share event
|
||||
if (appTarget.getShortcutInfo() == null) {
|
||||
return;
|
||||
|
||||
@@ -299,7 +299,7 @@ public final class DataManagerTest {
|
||||
.build();
|
||||
AppTargetEvent appTargetEvent =
|
||||
new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATON_DIRECT_SHARE)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE)
|
||||
.build();
|
||||
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SEND, "image/jpg");
|
||||
mDataManager.reportShareTargetEvent(appTargetEvent, intentFilter);
|
||||
@@ -319,7 +319,7 @@ public final class DataManagerTest {
|
||||
.build();
|
||||
AppTargetEvent appTargetEvent =
|
||||
new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATON_DIRECT_SHARE)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE)
|
||||
.build();
|
||||
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SEND, "image/jpg");
|
||||
|
||||
@@ -667,7 +667,7 @@ public final class DataManagerTest {
|
||||
.build();
|
||||
AppTargetEvent appTargetEvent =
|
||||
new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATON_DIRECT_SHARE)
|
||||
.setLaunchLocation(ChooserActivity.LAUNCH_LOCATION_DIRECT_SHARE)
|
||||
.build();
|
||||
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SEND, "image/jpg");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user