Commit bbac322d authored by Ran Ji's avatar Ran Ji Committed by Commit Bot

Log time spent in customtab for Webapp and WebApk

Add an extra to the intent that sent to CCT to indicate where it comes from.
Currently the extra is only set by Webapp/WebApk

Bug: 769728
Change-Id: I38ddbf9a5e797e602513de098a890645419d90c3
Reviewed-on: https://chromium-review.googlesource.com/751302Reviewed-by: default avatarIlya Sherman <isherman@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Commit-Queue: Ran Ji <ranj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517460}
parent 2ce46749
......@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.customtabs;
import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.CUSTOM_TABS_UI_TYPE_DEFAULT;
import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.CUSTOM_TABS_UI_TYPE_INFO_PAGE;
import static org.chromium.chrome.browser.webapps.WebappActivity.ACTIVITY_TYPE_OTHER;
import android.app.Activity;
import android.app.PendingIntent;
......@@ -80,6 +81,7 @@ import org.chromium.chrome.browser.toolbar.ToolbarControlContainer;
import org.chromium.chrome.browser.util.ColorUtils;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.chrome.browser.webapps.WebappInterceptNavigationDelegate;
import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
......@@ -142,6 +144,8 @@ public class CustomTabActivity extends ChromeActivity {
private final CustomTabsConnection mConnection = CustomTabsConnection.getInstance();
private WebappInterceptNavigationDelegate.CustomTabTimeSpentLogger mWebappTimeSpentLogger;
private static class PageLoadMetricsObserver implements PageLoadMetrics.Observer {
private final CustomTabsConnection mConnection;
private final CustomTabsSessionToken mSession;
......@@ -681,12 +685,20 @@ public class CustomTabActivity extends ChromeActivity {
}
}
mIsInitialResume = false;
mWebappTimeSpentLogger =
WebappInterceptNavigationDelegate.CustomTabTimeSpentLogger
.createInstanceAndStartTimer(getIntent().getIntExtra(
CustomTabIntentDataProvider.EXTRA_BROWSER_LAUNCH_SOURCE,
ACTIVITY_TYPE_OTHER));
}
@Override
public void onPauseWithNative() {
super.onPauseWithNative();
mConnection.notifyNavigationEvent(mSession, CustomTabsCallback.TAB_HIDDEN);
if (mWebappTimeSpentLogger != null) {
mWebappTimeSpentLogger.onPause();
}
}
@Override
......
......@@ -90,6 +90,14 @@ public class CustomTabIntentDataProvider extends BrowserSessionDataProvider {
public static final String EXTRA_DISABLE_DOWNLOAD_BUTTON =
"org.chromium.chrome.browser.customtabs.EXTRA_DISABLE_DOWNLOAD_BUTTON";
/**
* Indicates the source where the Custom Tab is launched. This is only used for
* WebApp/WebAPK/TrustedWebActivity. The value is defined as {@link
* ActivityType#WebappActivity}.
*/
public static final String EXTRA_BROWSER_LAUNCH_SOURCE =
"org.chromium.chrome.browser.customtabs.EXTRA_BROWSER_LAUNCH_SOURCE";
// TODO(yusufo): Move this to CustomTabsIntent.
/** Signals custom tabs to favor sending initial urls to external handler apps if possible. */
public static final String EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER =
......
......@@ -16,6 +16,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.customtabs.CustomTabsSessionToken;
import android.text.TextUtils;
......@@ -62,6 +63,8 @@ import org.chromium.net.NetworkChangeNotifier;
import org.chromium.ui.base.PageTransition;
import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
......@@ -71,6 +74,14 @@ import java.util.concurrent.TimeUnit;
*/
public class WebappActivity extends SingleTabActivity {
public static final String WEBAPP_SCHEME = "webapp";
// The activity type of WebappActivity.
@Retention(RetentionPolicy.SOURCE)
@IntDef({ACTIVITY_TYPE_WEBAPP, ACTIVITY_TYPE_WEBAPK, ACTIVITY_TYPE_TWA})
public @interface ActivityType {}
public static final int ACTIVITY_TYPE_OTHER = -1;
public static final int ACTIVITY_TYPE_WEBAPP = 0;
public static final int ACTIVITY_TYPE_WEBAPK = 1;
public static final int ACTIVITY_TYPE_TWA = 2;
private static final String TAG = "WebappActivity";
private static final String HISTOGRAM_NAVIGATION_STATUS = "Webapp.NavigationStatus";
......@@ -681,9 +692,24 @@ public class WebappActivity extends SingleTabActivity {
* this is a Trusted Web Activity.
*/
public CustomTabsSessionToken getBrowserSession() {
if (mTrustedWebContentProvider == null) return null;
return mTrustedWebContentProvider.getSession();
}
/**
* @return The actual activity type of {@link WebappActivity}, which to be one of the values in
* {@link ActivityType}.
*
* This function is needed because Webapp, WebAPK and Trusted Web Activity all use {@link
* WebappActivity}. This doesn't check whether the TWA is valid as the point is to capture time
* by use-case.
*/
public @ActivityType int getActivityType() {
if (getBrowserSession() != null) return ACTIVITY_TYPE_TWA;
if (getNativeClientPackageName() != null) return ACTIVITY_TYPE_WEBAPK;
return ACTIVITY_TYPE_WEBAPP;
}
/**
* @return Whether this activity hosts the web content in a way that can be verified either
* through Digital Asset Links (DAL) or browser level confirmation.
......@@ -852,7 +878,7 @@ public class WebappActivity extends SingleTabActivity {
@Override
protected TabDelegate createTabDelegate(boolean incognito) {
return new WebappTabDelegate(incognito);
return new WebappTabDelegate(incognito, getActivityType());
}
// We're temporarily disable CS on webapp since there are some issues. (http://crbug.com/471950)
......
......@@ -5,8 +5,10 @@
package org.chromium.chrome.browser.webapps;
import android.net.Uri;
import android.os.SystemClock;
import android.support.customtabs.CustomTabsIntent;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
import org.chromium.chrome.browser.externalnav.ExternalNavigationParams;
import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl;
......@@ -15,10 +17,61 @@ import org.chromium.chrome.browser.tab.TabRedirectHandler;
import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.components.navigation_interception.NavigationParams;
import java.util.concurrent.TimeUnit;
/**
* Intercepts navigations made by the Web App and sends off-origin http(s) ones to a Custom Tab.
*/
public class WebappInterceptNavigationDelegate extends InterceptNavigationDelegateImpl {
/**
* Log the time spent on CCT opened by WebappActivity.
*/
public static class CustomTabTimeSpentLogger {
private long mStartTime;
private @WebappActivity.ActivityType int mActivityType;
private CustomTabTimeSpentLogger(@WebappActivity.ActivityType int activityType) {
mActivityType = activityType;
mStartTime = SystemClock.elapsedRealtime();
}
/**
* Create {@link CustomTabTimeSpentLogger} instance and start timer if activity type is one
* of WebAPP, WebApk and Trusted Web Activity,
* @param type of the activity that opens the CCT.
* @return {@link CustomTabTimeSpentLogger} instance if activity is WebAPP/WebApk/TWA,
* otherwise null.
*/
public static CustomTabTimeSpentLogger createInstanceAndStartTimer(
@WebappActivity.ActivityType int activityType) {
return new CustomTabTimeSpentLogger(activityType);
}
/**
* Stop timer and log uma.
*/
public void onPause() {
long timeSpent = SystemClock.elapsedRealtime() - mStartTime;
String umaSuffix;
switch (mActivityType) {
case WebappActivity.ACTIVITY_TYPE_WEBAPP:
umaSuffix = ".Webapp";
break;
case WebappActivity.ACTIVITY_TYPE_WEBAPK:
umaSuffix = ".WebApk";
break;
case WebappActivity.ACTIVITY_TYPE_TWA:
umaSuffix = ".TWA";
break;
default:
umaSuffix = ".Other";
break;
}
RecordHistogram.recordLongTimesHistogram(
"CustomTab.SessionDuration" + umaSuffix, timeSpent, TimeUnit.MILLISECONDS);
}
}
private final WebappActivity mActivity;
public WebappInterceptNavigationDelegate(WebappActivity activity, Tab tab) {
......@@ -44,6 +97,8 @@ public class WebappInterceptNavigationDelegate extends InterceptNavigationDelega
customTabIntent.intent.setPackage(mActivity.getPackageName());
customTabIntent.intent.putExtra(
CustomTabIntentDataProvider.EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER, true);
customTabIntent.intent.putExtra(CustomTabIntentDataProvider.EXTRA_BROWSER_LAUNCH_SOURCE,
mActivity.getActivityType());
customTabIntent.launchUrl(mActivity, Uri.parse(navigationParams.url));
return true;
}
......
......@@ -30,9 +30,11 @@ import java.net.URISyntaxException;
*/
public class WebappTabDelegate extends TabDelegate {
private static final String TAG = "WebappTabDelegate";
private @WebappActivity.ActivityType int mActivityType;
public WebappTabDelegate(boolean incognito) {
public WebappTabDelegate(boolean incognito, @WebappActivity.ActivityType int activityType) {
super(incognito);
mActivityType = activityType;
}
@Override
......@@ -49,6 +51,7 @@ public class WebappTabDelegate extends TabDelegate {
intent.setData(Uri.parse(url));
intent.putExtra(CustomTabIntentDataProvider.EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER, true);
intent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME, true);
intent.putExtra(CustomTabIntentDataProvider.EXTRA_BROWSER_LAUNCH_SOURCE, mActivityType);
addAsyncTabExtras(asyncParams, parentId, false /* isChromeUI */, assignedTabId, intent);
IntentHandler.startActivityForTrustedIntent(intent);
......
......@@ -12056,6 +12056,18 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram base="true" name="CustomTab.SessionDuration" units="ms">
<owner>ranj@chromium.org</owner>
<owner>yfriedman@chromium.org</owner>
<!-- Name completed by histogram_suffixes name="CustomTabOpenSource" -->
<summary>
Records the time duration in CustomTab Activity from onStart/onResume to
onStop/onPause, if that activity is opened by Webapp/WebApk/Trusted Web
Activity.
</summary>
</histogram>
<histogram name="CustomTabs.ClientAppId" enum="ClientAppId">
<owner>yusufo@chromium.org</owner>
<summary>
......@@ -99009,6 +99021,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<affected-histogram name="Tabs.StateTransfer.Time"/>
</histogram_suffixes>
<histogram_suffixes name="CustomTabOpenSource" separator=".">
<affected-histogram name="CustomTab.SessionDuration"/>
<suffix name="TWA" label="CustomTab opened by Trusted Web Activity."/>
<suffix name="Webapp" label="CustomTab opened by Webapp."/>
<suffix name="WebApk" label="CustomTab opened by WebApk."/>
<suffix name="Other" label="CustomTab opened by other apps."/>
</histogram_suffixes>
<histogram_suffixes name="DataReductionProxy" separator="_">
<obsolete>
Deprecated 9/2016.
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