0

Histograms for Custom Tab backpress

Bug: 40285983
Change-Id: I3cfd48bb9a46d359149c112090130c0a1970b09d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5536079
Commit-Queue: Zach Katz <katzz@google.com>
Reviewed-by: Jinsuk Kim <jinsukkim@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Lijin Shen <lazzzis@google.com>
Cr-Commit-Position: refs/heads/main@{#1301651}
This commit is contained in:
Zach Katz
2024-05-15 23:28:57 +00:00
committed by Chromium LUCI CQ
parent 1186f4ecb2
commit ac69673bee
5 changed files with 120 additions and 3 deletions
chrome
android
java
src
org
chromium
chrome
junit
src
org
chromium
browser
back_press
android
tools/metrics/histograms/metadata/android

@ -245,6 +245,11 @@ public class CustomTabActivityNavigationController
public boolean navigateOnBack() {
if (!mChromeBrowserInitializer.isFullBrowserInitialized()) return false;
boolean separateTask =
(mIntentDataProvider.getIntent().getFlags()
& (Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_NEW_DOCUMENT))
!= 0;
RecordUserAction.record("CustomTabs.SystemBack");
if (mTabProvider.getTab() == null) return false;
if (!BackPressManager.isEnabled()) {
@ -255,17 +260,23 @@ public class CustomTabActivityNavigationController
RenderFrameHost focusedFrame = webContents.getFocusedFrame();
if (focusedFrame != null && focusedFrame.signalCloseWatcherIfActive()) {
BackPressManager.record(BackPressHandler.Type.CLOSE_WATCHER);
BackPressManager.recordForCustomTab(
BackPressHandler.Type.CLOSE_WATCHER, separateTask);
return true;
}
}
if (mToolbarManager != null && mToolbarManager.back()) {
BackPressManager.record(BackPressHandler.Type.TAB_HISTORY);
BackPressManager.recordForCustomTab(
BackPressHandler.Type.TAB_HISTORY, separateTask);
return true;
}
// If enabled, BackPressManager will record this internally. Otherwise, this should
// be recorded manually.
BackPressManager.record(BackPressHandler.Type.MINIMIZE_APP_AND_CLOSE_TAB);
BackPressManager.recordForCustomTab(
BackPressHandler.Type.MINIMIZE_APP_AND_CLOSE_TAB, separateTask);
} else if (BackPressManager.correctTabNavigationOnFallback()) {
if (mTabProvider.getTab().canGoBack()) {
return false;
@ -274,29 +285,35 @@ public class CustomTabActivityNavigationController
if (ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_BEFORE_UNLOAD)
&& mTabController.onlyOneTabRemaining()) {
finishActivity();
finishActivity(separateTask);
return true;
}
if (mTabController.dispatchBeforeUnloadIfNeeded()) {
MinimizeAppAndCloseTabBackPressHandler.record(MinimizeAppAndCloseTabType.CLOSE_TAB);
MinimizeAppAndCloseTabBackPressHandler.recordForCustomTab(
MinimizeAppAndCloseTabType.CLOSE_TAB, separateTask);
return true;
}
if (mTabController.onlyOneTabRemaining()) {
finishActivity();
finishActivity(separateTask);
} else {
MinimizeAppAndCloseTabBackPressHandler.record(MinimizeAppAndCloseTabType.CLOSE_TAB);
MinimizeAppAndCloseTabBackPressHandler.recordForCustomTab(
MinimizeAppAndCloseTabType.CLOSE_TAB, separateTask);
mTabController.closeTab();
}
return true;
}
private void finishActivity() {
private void finishActivity(boolean separateTask) {
// If we're closing the last tab and it doesn't have beforeunload, just finish the Activity
// manually. If we had called mTabController.closeTab() and waited for the Activity to close
// as a result we would have a visual glitch: https://crbug.com/1087108.
MinimizeAppAndCloseTabBackPressHandler.record(MinimizeAppAndCloseTabType.MINIMIZE_APP);
MinimizeAppAndCloseTabBackPressHandler.recordForCustomTab(
MinimizeAppAndCloseTabType.MINIMIZE_APP, separateTask);
finish(USER_NAVIGATION);
}

@ -111,6 +111,16 @@ public class CustomTabActivityNavigationControllerTest {
MinimizeAppAndCloseTabBackPressHandler.getHistogramNameForTesting(),
MinimizeAppAndCloseTabType.MINIMIZE_APP)
.expectNoRecords(BackPressManager.getHistogramForTesting())
.expectNoRecords(
MinimizeAppAndCloseTabBackPressHandler
.getCustomTabSeparateTaskHistogramNameForTesting())
.expectIntRecord(
MinimizeAppAndCloseTabBackPressHandler
.getCustomTabSameTaskHistogramNameForTesting(),
MinimizeAppAndCloseTabType.MINIMIZE_APP)
.expectNoRecords(
BackPressManager.getCustomTabSeparateTaskHistogramForTesting())
.expectNoRecords(BackPressManager.getCustomTabSameTaskHistogramForTesting())
.build();
when(mTabController.onlyOneTabRemaining()).thenReturn(true);
when(mTabController.dispatchBeforeUnloadIfNeeded()).thenReturn(false);
@ -132,6 +142,16 @@ public class CustomTabActivityNavigationControllerTest {
MinimizeAppAndCloseTabBackPressHandler.getHistogramNameForTesting(),
MinimizeAppAndCloseTabType.MINIMIZE_APP)
.expectNoRecords(BackPressManager.getHistogramForTesting())
.expectNoRecords(
MinimizeAppAndCloseTabBackPressHandler
.getCustomTabSeparateTaskHistogramNameForTesting())
.expectIntRecord(
MinimizeAppAndCloseTabBackPressHandler
.getCustomTabSameTaskHistogramNameForTesting(),
MinimizeAppAndCloseTabType.MINIMIZE_APP)
.expectNoRecords(
BackPressManager.getCustomTabSeparateTaskHistogramForTesting())
.expectNoRecords(BackPressManager.getCustomTabSameTaskHistogramForTesting())
.build();
when(mTabController.onlyOneTabRemaining()).thenReturn(true);
when(mTabController.dispatchBeforeUnloadIfNeeded()).thenReturn(true);

@ -131,6 +131,10 @@ public class BackPressManager implements Destroyable {
};
static final String HISTOGRAM = "Android.BackPress.Intercept";
static final String HISTOGRAM_CUSTOM_TAB_SAME_TASK =
"Android.BackPress.Intercept.CustomTab.SameTask";
static final String HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK =
"Android.BackPress.Intercept.CustomTab.SeparateTask";
static final String FAILURE_HISTOGRAM = "Android.BackPress.Failure";
private final BackPressHandler[] mHandlers = new BackPressHandler[Type.NUM_TYPES];
@ -183,6 +187,19 @@ public class BackPressManager implements Destroyable {
HISTOGRAM, sMetricsMap.get(type), sMetricsMaxValue);
}
/**
* Record when the back press is consumed by a custom tab.
*
* @param type The {@link Type} which consumes the back press event.
* @param separateTask Whether the custom tab runs in a separate task.
*/
public static void recordForCustomTab(@Type int type, boolean separateTask) {
RecordHistogram.recordEnumeratedHistogram(
separateTask ? HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK : HISTOGRAM_CUSTOM_TAB_SAME_TASK,
sMetricsMap.get(type),
sMetricsMaxValue);
}
/**
* @param type The {@link Type} of the back press handler.
* @return The corresponding histogram value.
@ -399,4 +416,11 @@ public class BackPressManager implements Destroyable {
return HISTOGRAM;
}
public static String getCustomTabSameTaskHistogramForTesting() {
return HISTOGRAM_CUSTOM_TAB_SAME_TASK;
}
public static String getCustomTabSeparateTaskHistogramForTesting() {
return HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK;
}
}

@ -38,6 +38,10 @@ import java.util.function.Predicate;
public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler, Destroyable {
private static final String TAG = "MinimizeAppCloseTab";
static final String HISTOGRAM = "Android.BackPress.MinimizeAppAndCloseTab";
static final String HISTOGRAM_CUSTOM_TAB_SAME_TASK =
"Android.BackPress.MinimizeAppAndCloseTab.CustomTab.SameTask";
static final String HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK =
"Android.BackPress.MinimizeAppAndCloseTab.CustomTab.SeparateTask";
// A conditionally enabled supplier, whose value is false only when minimizing app without
// closing tabs in the 'system back' arm.
@ -81,6 +85,20 @@ public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler,
HISTOGRAM, type, MinimizeAppAndCloseTabType.NUM_TYPES);
}
/**
* Record metrics of how back press is finally consumed by the custom tab.
*
* @param type The action we do when back press is consumed.
* @param separateTask Whether the custom tab runs in a separate task.
*/
public static void recordForCustomTab(
@MinimizeAppAndCloseTabType int type, boolean separateTask) {
RecordHistogram.recordEnumeratedHistogram(
separateTask ? HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK : HISTOGRAM_CUSTOM_TAB_SAME_TASK,
type,
MinimizeAppAndCloseTabType.NUM_TYPES);
}
public static void assertOnLastBackPress(
@Nullable Tab currentTab,
@Nullable Tab activityTab,
@ -273,4 +291,12 @@ public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler,
public static String getHistogramNameForTesting() {
return HISTOGRAM;
}
public static String getCustomTabSameTaskHistogramNameForTesting() {
return HISTOGRAM_CUSTOM_TAB_SAME_TASK;
}
public static String getCustomTabSeparateTaskHistogramNameForTesting() {
return HISTOGRAM_CUSTOM_TAB_SEPARATE_TASK;
}
}

@ -657,6 +657,21 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>
<histogram name="Android.BackPress.Intercept.CustomTab{Task}"
enum="BackPressConsumer" expires_after="2025-05-15">
<owner>lazzzis@chromium.org</owner>
<owner>src/chrome/browser/back_press/android/OWNERS</owner>
<summary>
Recorded when a custom tabs feature intercepted the system's back press
gesture {Task}.
</summary>
<token key="Task">
<variant name=".SameTask" summary="custom tab is from the same task."/>
<variant name=".SeparateTask"
summary="custom tab is from a separate task."/>
</token>
</histogram>
<histogram name="Android.BackPress.Intercept{Direction}"
enum="BackPressConsumer" expires_after="2024-09-15">
<owner>lazzzis@chromium.org</owner>
@ -682,6 +697,21 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>
<histogram name="Android.BackPress.MinimizeAppAndCloseTab.CustomTab.{Task}"
enum="MinimizeAppAndCloseTabType" expires_after="2025-05-15">
<owner>lazzzis@chromium.org</owner>
<owner>src/chrome/browser/back_press/android/OWNERS</owner>
<summary>
Records that the custom tabs back press causes the app to be minimized or
the current tab to be closed {Task}.
</summary>
<token key="Task">
<variant name=".SameTask" summary="custom tab is from the same task."/>
<variant name=".SeparateTask"
summary="custom tab is from a separate task."/>
</token>
</histogram>
<histogram name="Android.BackPress.SecondaryActivity" enum="SecondaryActivity"
expires_after="2024-09-15">
<owner>lazzzis@chromium.org</owner>