Merge "Add logging for profile switching for sharesheet"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b5de2782de
@@ -381,6 +381,8 @@ public class ChooserActivity extends ResolverActivity {
|
||||
final long systemCost = mChooserShownTime - intentReceivedTime;
|
||||
|
||||
getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN)
|
||||
.setSubtype(isWorkProfile() ? MetricsEvent.MANAGED_PROFILE :
|
||||
MetricsEvent.PARENT_PROFILE)
|
||||
.addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType())
|
||||
.addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost));
|
||||
|
||||
@@ -417,6 +419,16 @@ public class ChooserActivity extends ResolverActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the profile currently used is a work profile.
|
||||
* @return true if it is work profile, false if it is parent profile (or no work profile is
|
||||
* set up)
|
||||
*/
|
||||
protected boolean isWorkProfile() {
|
||||
return ((UserManager) getSystemService(Context.USER_SERVICE))
|
||||
.getUserInfo(UserHandle.myUserId()).isManagedProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override method to add content preview area, specific to the chooser activity.
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
@@ -39,6 +40,8 @@ import android.util.Slog;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -66,6 +69,8 @@ public class IntentForwarderActivity extends Activity {
|
||||
|
||||
private Injector mInjector;
|
||||
|
||||
private MetricsLogger mMetricsLogger;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -78,9 +83,17 @@ public class IntentForwarderActivity extends Activity {
|
||||
if (className.equals(FORWARD_INTENT_TO_PARENT)) {
|
||||
userMessageId = com.android.internal.R.string.forward_intent_to_owner;
|
||||
targetUserId = getProfileParent();
|
||||
|
||||
getMetricsLogger().write(
|
||||
new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE)
|
||||
.setSubtype(MetricsEvent.PARENT_PROFILE));
|
||||
} else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
|
||||
userMessageId = com.android.internal.R.string.forward_intent_to_work;
|
||||
targetUserId = getManagedProfile();
|
||||
|
||||
getMetricsLogger().write(
|
||||
new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE)
|
||||
.setSubtype(MetricsEvent.MANAGED_PROFILE));
|
||||
} else {
|
||||
Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
|
||||
userMessageId = -1;
|
||||
@@ -257,6 +270,13 @@ public class IntentForwarderActivity extends Activity {
|
||||
intent.setComponent(null);
|
||||
}
|
||||
|
||||
protected MetricsLogger getMetricsLogger() {
|
||||
if (mMetricsLogger == null) {
|
||||
mMetricsLogger = new MetricsLogger();
|
||||
}
|
||||
return mMetricsLogger;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected Injector createInjector() {
|
||||
return new InjectorImpl();
|
||||
|
||||
@@ -57,7 +57,7 @@ import androidx.test.rule.ActivityTestRule;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -524,15 +524,45 @@ public class ChooserActivityTest {
|
||||
waitForIdle();
|
||||
verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
|
||||
assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
|
||||
is(MetricsProto.MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
|
||||
is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getTaggedData(MetricsProto.MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
|
||||
.getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
|
||||
is(notNullValue()));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getTaggedData(MetricsProto.MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
|
||||
.getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
|
||||
is("TestType"));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getSubtype(),
|
||||
is(MetricsEvent.PARENT_PROFILE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateLoggingFromWorkProfile() {
|
||||
Intent sendIntent = createSendTextIntent();
|
||||
sendIntent.setType("TestType");
|
||||
sOverrides.alternateProfileSetting = MetricsEvent.MANAGED_PROFILE;
|
||||
MetricsLogger mockLogger = sOverrides.metricsLogger;
|
||||
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
|
||||
mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
|
||||
waitForIdle();
|
||||
verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
|
||||
assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
|
||||
is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
|
||||
is(notNullValue()));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
|
||||
is("TestType"));
|
||||
assertThat(logMakerCaptor
|
||||
.getAllValues().get(0)
|
||||
.getSubtype(),
|
||||
is(MetricsEvent.MANAGED_PROFILE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -547,7 +577,7 @@ public class ChooserActivityTest {
|
||||
verify(mockLogger, Mockito.times(1)).write(logMakerCaptor.capture());
|
||||
// First invocation is from onCreate
|
||||
assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
|
||||
is(MetricsProto.MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
|
||||
is(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -569,7 +599,7 @@ public class ChooserActivityTest {
|
||||
verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
|
||||
// First invocation is from onCreate
|
||||
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
|
||||
is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
|
||||
is(CONTENT_PREVIEW_TEXT));
|
||||
}
|
||||
@@ -599,11 +629,11 @@ public class ChooserActivityTest {
|
||||
verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
|
||||
// First invocation is from onCreate
|
||||
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
|
||||
is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
|
||||
is(CONTENT_PREVIEW_IMAGE));
|
||||
assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
|
||||
is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
|
||||
assertThat(logMakerCaptor.getAllValues().get(2).getSubtype(),
|
||||
is(CONTENT_PREVIEW_IMAGE));
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.net.Uri;
|
||||
import android.util.Size;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -112,6 +113,14 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
return super.queryResolver(resolver, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWorkProfile() {
|
||||
if (sOverrides.alternateProfileSetting != 0) {
|
||||
return sOverrides.alternateProfileSetting == MetricsEvent.MANAGED_PROFILE;
|
||||
}
|
||||
return super.isWorkProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
* We cannot directly mock the activity created since instrumentation creates it.
|
||||
* <p>
|
||||
@@ -128,6 +137,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
public boolean resolverForceException;
|
||||
public Bitmap previewThumbnail;
|
||||
public MetricsLogger metricsLogger;
|
||||
public int alternateProfileSetting;
|
||||
|
||||
public void reset() {
|
||||
onSafelyStartCallback = null;
|
||||
@@ -139,6 +149,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
resolverForceException = false;
|
||||
resolverListController = mock(ResolverListController.class);
|
||||
metricsLogger = mock(MetricsLogger.class);
|
||||
alternateProfileSetting = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -40,6 +41,7 @@ import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.metrics.LogMaker;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -51,6 +53,9 @@ import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -70,6 +75,11 @@ public class IntentForwarderActivityTest {
|
||||
"android",
|
||||
IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE
|
||||
);
|
||||
private static final ComponentName FORWARD_TO_PARENT_COMPONENT_NAME =
|
||||
new ComponentName(
|
||||
"android",
|
||||
IntentForwarderActivity.FORWARD_INTENT_TO_PARENT
|
||||
);
|
||||
private static final String TYPE_PLAIN_TEXT = "text/plain";
|
||||
|
||||
private static UserInfo MANAGED_PROFILE_INFO = new UserInfo();
|
||||
@@ -522,6 +532,60 @@ public class IntentForwarderActivityTest {
|
||||
verify(sInjector).showToast(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardToManagedProfile_LoggingTest() throws Exception {
|
||||
sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
|
||||
|
||||
// Intent can be forwarded.
|
||||
when(mIPm.canForwardTo(
|
||||
any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
|
||||
|
||||
// Managed profile exists.
|
||||
List<UserInfo> profiles = new ArrayList<>();
|
||||
profiles.add(CURRENT_USER_INFO);
|
||||
profiles.add(MANAGED_PROFILE_INFO);
|
||||
when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
|
||||
|
||||
Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType(TYPE_PLAIN_TEXT);
|
||||
IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
|
||||
|
||||
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
|
||||
verify(activity.getMetricsLogger()).write(logMakerCaptor.capture());
|
||||
assertEquals(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE,
|
||||
logMakerCaptor.getValue().getCategory());
|
||||
assertEquals(MetricsEvent.MANAGED_PROFILE,
|
||||
logMakerCaptor.getValue().getSubtype());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardToParent_LoggingTest() throws Exception {
|
||||
sComponentName = FORWARD_TO_PARENT_COMPONENT_NAME;
|
||||
|
||||
// Intent can be forwarded.
|
||||
when(mIPm.canForwardTo(
|
||||
any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
|
||||
|
||||
// Managed profile exists.
|
||||
List<UserInfo> profiles = new ArrayList<>();
|
||||
profiles.add(CURRENT_USER_INFO);
|
||||
profiles.add(MANAGED_PROFILE_INFO);
|
||||
when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
|
||||
|
||||
Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType(TYPE_PLAIN_TEXT);
|
||||
IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
|
||||
|
||||
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
|
||||
verify(activity.getMetricsLogger()).write(logMakerCaptor.capture());
|
||||
assertEquals(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE,
|
||||
logMakerCaptor.getValue().getCategory());
|
||||
assertEquals(MetricsEvent.PARENT_PROFILE,
|
||||
logMakerCaptor.getValue().getSubtype());
|
||||
}
|
||||
|
||||
private void setupShouldSkipDisclosureTest() throws RemoteException {
|
||||
sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
|
||||
sActivityName = "MyTestActivity";
|
||||
@@ -541,6 +605,7 @@ public class IntentForwarderActivityTest {
|
||||
|
||||
private Intent mStartActivityIntent;
|
||||
private int mUserIdActivityLaunchedIn;
|
||||
private MetricsLogger mMetricsLogger = mock(MetricsLogger.class);
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@@ -559,6 +624,11 @@ public class IntentForwarderActivityTest {
|
||||
mStartActivityIntent = intent;
|
||||
mUserIdActivityLaunchedIn = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetricsLogger getMetricsLogger() {
|
||||
return mMetricsLogger;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestInjector implements IntentForwarderActivity.Injector {
|
||||
|
||||
@@ -247,6 +247,12 @@ message MetricsEvent {
|
||||
LOCATION_GONE = 6; // the view isn't laid out at all
|
||||
}
|
||||
|
||||
// Subtypes for profile logging
|
||||
enum ActiveUserProfile {
|
||||
PARENT_PROFILE = 1;
|
||||
MANAGED_PROFILE = 2;
|
||||
}
|
||||
|
||||
// Known visual elements: views or controls.
|
||||
enum View {
|
||||
// Unknown view
|
||||
@@ -7007,6 +7013,10 @@ message MetricsEvent {
|
||||
// Different display can have different orientations, so need to log display id
|
||||
FIELD_DISPLAY_ID = 1660;
|
||||
|
||||
// ACTION: Changing from work to parent profile or vice versa
|
||||
// OS: Q
|
||||
ACTION_SWITCH_SHARE_PROFILE = 1661;
|
||||
|
||||
// ---- End Q Constants, all Q constants go above this line ----
|
||||
// Add new aosp constants above this line.
|
||||
// END OF AOSP CONSTANTS
|
||||
|
||||
Reference in New Issue
Block a user