Commit 63fbc307 authored by Benoit Lize's avatar Benoit Lize Committed by Commit Bot

customtabs: Don't send page load metrics by default.

Only sends page load metrics to sessions that are allowed to get them.

Bug: 842648
Change-Id: Ifc82941096d02f448af261656811aca4c9097b2b
Reviewed-on: https://chromium-review.googlesource.com/1057232
Commit-Queue: Benoit L <lizeb@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558337}
parent 386ea326
...@@ -148,6 +148,7 @@ class ClientManager { ...@@ -148,6 +148,7 @@ class ClientManager {
private long mLastMayLaunchUrlTimestamp; private long mLastMayLaunchUrlTimestamp;
private boolean mCanUseHiddenTab; private boolean mCanUseHiddenTab;
private boolean mAllowParallelRequest; private boolean mAllowParallelRequest;
private boolean mShouldGetPageLoadMetrics;
public SessionParams(Context context, int uid, DisconnectCallback callback, public SessionParams(Context context, int uid, DisconnectCallback callback,
PostMessageHandler postMessageHandler) { PostMessageHandler postMessageHandler) {
...@@ -654,6 +655,17 @@ class ClientManager { ...@@ -654,6 +655,17 @@ class ClientManager {
return params != null ? params.mAllowParallelRequest : false; return params != null ? params.mAllowParallelRequest : false;
} }
public synchronized void setShouldGetPageLoadMetricsForSession(
CustomTabsSessionToken session, boolean allowed) {
SessionParams params = mSessionParams.get(session);
if (params != null) params.mShouldGetPageLoadMetrics = allowed;
}
public synchronized boolean shouldGetPageLoadMetrics(CustomTabsSessionToken session) {
SessionParams params = mSessionParams.get(session);
return params != null ? params.mShouldGetPageLoadMetrics : false;
}
/** /**
* Returns whether an origin is first-party with respect to a session, that is if the * Returns whether an origin is first-party with respect to a session, that is if the
* application linked to the session has a relation with the provided origin. This does not * application linked to the session has a relation with the provided origin. This does not
......
...@@ -1094,9 +1094,12 @@ public class CustomTabsConnection { ...@@ -1094,9 +1094,12 @@ public class CustomTabsConnection {
* @param metricName Name of the page load metric. * @param metricName Name of the page load metric.
* @param navigationStartTick Absolute navigation start time, as TimeTicks taken from native. * @param navigationStartTick Absolute navigation start time, as TimeTicks taken from native.
* @param offsetMs Offset in ms from navigationStart for the page load metric. * @param offsetMs Offset in ms from navigationStart for the page load metric.
*
* @return Whether the metric has been dispatched to the client.
*/ */
boolean notifySinglePageLoadMetric(CustomTabsSessionToken session, String metricName, boolean notifySinglePageLoadMetric(CustomTabsSessionToken session, String metricName,
long navigationStartTick, long offsetMs) { long navigationStartTick, long offsetMs) {
if (!mClientManager.shouldGetPageLoadMetrics(session)) return false;
if (!mNativeTickOffsetUsComputed) { if (!mNativeTickOffsetUsComputed) {
// Compute offset from time ticks to uptimeMillis. // Compute offset from time ticks to uptimeMillis.
mNativeTickOffsetUsComputed = true; mNativeTickOffsetUsComputed = true;
......
...@@ -1326,77 +1326,22 @@ public class CustomTabActivityTest { ...@@ -1326,77 +1326,22 @@ public class CustomTabActivityTest {
} }
/** /**
* Tests that Time To First Contentful Paint and Load Event Start timings are sent. * Tests that page load metrice are sent.
*/ */
@Test @Test
@SmallTest @SmallTest
@RetryOnFailure @RetryOnFailure
public void testPageLoadMetricIsSent() throws Exception { public void testPageLoadMetricsAreSent() throws Exception {
final AtomicReference<Long> firstContentfulPaintMs = new AtomicReference<>(-1L); checkPageLoadMetrics(true);
final AtomicReference<Long> activityStartTimeMs = new AtomicReference<>(-1L);
final AtomicReference<Long> loadEventStartMs = new AtomicReference<>(-1L);
final AtomicReference<Boolean> sawNetworkQualityEstimates = new AtomicReference<>(false);
CustomTabsCallback cb = new CustomTabsCallback() {
@Override
public void extraCallback(String callbackName, Bundle args) {
Assert.assertEquals(CustomTabsConnection.PAGE_LOAD_METRICS_CALLBACK, callbackName);
if (-1 != args.getLong(PageLoadMetrics.EFFECTIVE_CONNECTION_TYPE, -1)) {
sawNetworkQualityEstimates.set(true);
}
long navigationStart = args.getLong(PageLoadMetrics.NAVIGATION_START, -1);
if (navigationStart == -1) {
// Untested metric callback.
return;
}
long current = SystemClock.uptimeMillis();
Assert.assertTrue(navigationStart <= current);
Assert.assertTrue(navigationStart >= activityStartTimeMs.get());
long firstContentfulPaint =
args.getLong(PageLoadMetrics.FIRST_CONTENTFUL_PAINT, -1);
if (firstContentfulPaint > 0) {
Assert.assertTrue(firstContentfulPaint <= (current - navigationStart));
firstContentfulPaintMs.set(firstContentfulPaint);
}
long loadEventStart = args.getLong(PageLoadMetrics.LOAD_EVENT_START, -1);
if (loadEventStart > 0) {
Assert.assertTrue(loadEventStart <= (current - navigationStart));
loadEventStartMs.set(loadEventStart);
}
} }
};
CustomTabsSession session = CustomTabsTestUtils.bindWithCallback(cb);
Intent intent = new CustomTabsIntent.Builder(session).build().intent;
intent.setData(Uri.parse(mTestPage));
intent.setComponent(new ComponentName(
InstrumentationRegistry.getTargetContext(), ChromeLauncherActivity.class));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activityStartTimeMs.set(SystemClock.uptimeMillis()); /**
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); * Tests that page load metrics are not sent when the client is not whitelisted.
CriteriaHelper.pollInstrumentationThread(new Criteria() { */
@Override @Test
public boolean isSatisfied() { @SmallTest
return firstContentfulPaintMs.get() > 0; public void testPageLoadMetricsAreNotSentByDefault() throws Exception {
} checkPageLoadMetrics(false);
});
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
return loadEventStartMs.get() > 0;
}
});
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
return sawNetworkQualityEstimates.get();
}
});
} }
private static void assertSuffixedHistogramTotalCount(long expected, String histogramPrefix) { private static void assertSuffixedHistogramTotalCount(long expected, String histogramPrefix) {
...@@ -2637,6 +2582,77 @@ public class CustomTabActivityTest { ...@@ -2637,6 +2582,77 @@ public class CustomTabActivityTest {
return newActivity; return newActivity;
} }
private void checkPageLoadMetrics(boolean allowMetrics)
throws InterruptedException, TimeoutException {
final AtomicReference<Long> firstContentfulPaintMs = new AtomicReference<>(-1L);
final AtomicReference<Long> activityStartTimeMs = new AtomicReference<>(-1L);
final AtomicReference<Long> loadEventStartMs = new AtomicReference<>(-1L);
final AtomicReference<Boolean> sawNetworkQualityEstimates = new AtomicReference<>(false);
CustomTabsCallback cb = new CustomTabsCallback() {
@Override
public void extraCallback(String callbackName, Bundle args) {
if (callbackName.equals(CustomTabsConnection.ON_WARMUP_COMPLETED)) return;
Assert.assertEquals(CustomTabsConnection.PAGE_LOAD_METRICS_CALLBACK, callbackName);
if (-1 != args.getLong(PageLoadMetrics.EFFECTIVE_CONNECTION_TYPE, -1)) {
sawNetworkQualityEstimates.set(true);
}
long navigationStart = args.getLong(PageLoadMetrics.NAVIGATION_START, -1);
if (navigationStart == -1) {
// Untested metric callback.
return;
}
long current = SystemClock.uptimeMillis();
Assert.assertTrue(navigationStart <= current);
Assert.assertTrue(navigationStart >= activityStartTimeMs.get());
long firstContentfulPaint =
args.getLong(PageLoadMetrics.FIRST_CONTENTFUL_PAINT, -1);
if (firstContentfulPaint > 0) {
Assert.assertTrue(firstContentfulPaint <= (current - navigationStart));
firstContentfulPaintMs.set(firstContentfulPaint);
}
long loadEventStart = args.getLong(PageLoadMetrics.LOAD_EVENT_START, -1);
if (loadEventStart > 0) {
Assert.assertTrue(loadEventStart <= (current - navigationStart));
loadEventStartMs.set(loadEventStart);
}
}
};
CustomTabsSession session = CustomTabsTestUtils.bindWithCallback(cb);
Intent intent = new CustomTabsIntent.Builder(session).build().intent;
if (allowMetrics) {
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
connection.mClientManager.setShouldGetPageLoadMetricsForSession(token, true);
}
intent.setData(Uri.parse(mTestPage));
intent.setComponent(new ComponentName(
InstrumentationRegistry.getTargetContext(), ChromeLauncherActivity.class));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activityStartTimeMs.set(SystemClock.uptimeMillis());
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
if (allowMetrics) {
CriteriaHelper.pollInstrumentationThread(() -> firstContentfulPaintMs.get() > 0);
CriteriaHelper.pollInstrumentationThread(() -> loadEventStartMs.get() > 0);
CriteriaHelper.pollInstrumentationThread(() -> sawNetworkQualityEstimates.get());
} else {
try {
CriteriaHelper.pollInstrumentationThread(() -> firstContentfulPaintMs.get() > 0);
} catch (AssertionError e) {
// Expected.
}
Assert.assertEquals(-1L, (long) firstContentfulPaintMs.get());
}
}
private CustomTabsSessionToken warmUpAndLaunchUrlWithSession(Intent intentWithSession) private CustomTabsSessionToken warmUpAndLaunchUrlWithSession(Intent intentWithSession)
throws Exception { throws Exception {
CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait(); CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment