Commit 58aed3cf authored by Henrique Nakashima's avatar Henrique Nakashima Committed by Commit Bot

Move tab switch latency logging to new TabSwitchMetrics

This breaks some dependencies from classes outside .tabmodel to
TabModelImpl.

Bug: 1139081
Change-Id: Ifda5b205f2cbe1cbc5f6d1b62de57ed258361503
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2477534Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820017}
parent 0aa0b85b
...@@ -30,7 +30,7 @@ import org.chromium.chrome.browser.compositor.resources.StaticResourcePreloads; ...@@ -30,7 +30,7 @@ import org.chromium.chrome.browser.compositor.resources.StaticResourcePreloads;
import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
import org.chromium.chrome.browser.externalnav.IntentWithRequestMetadataHandler; import org.chromium.chrome.browser.externalnav.IntentWithRequestMetadataHandler;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.tabmodel.TabModelImpl; import org.chromium.chrome.browser.tabmodel.TabSwitchMetrics;
import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.styles.ChromeColors;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -538,7 +538,7 @@ public class CompositorView ...@@ -538,7 +538,7 @@ public class CompositorView
CompositorViewJni.get().setSceneLayer( CompositorViewJni.get().setSceneLayer(
mNativeCompositorView, CompositorView.this, sceneLayer); mNativeCompositorView, CompositorView.this, sceneLayer);
TabModelImpl.flushActualTabSwitchLatencyMetric(); TabSwitchMetrics.flushActualTabSwitchLatencyMetric();
CompositorViewJni.get().finalizeLayers(mNativeCompositorView, CompositorView.this); CompositorViewJni.get().finalizeLayers(mNativeCompositorView, CompositorView.this);
TraceEvent.end("CompositorView:finalizeLayers"); TraceEvent.end("CompositorView:finalizeLayers");
} }
......
...@@ -27,10 +27,10 @@ import org.chromium.chrome.browser.tab.SadTab; ...@@ -27,10 +27,10 @@ import org.chromium.chrome.browser.tab.SadTab;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.chrome.browser.tab.TabThemeColorHelper; import org.chromium.chrome.browser.tab.TabThemeColorHelper;
import org.chromium.chrome.browser.tabmodel.TabModelImpl;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.tabmodel.TabSwitchMetrics;
import org.chromium.chrome.browser.toolbar.ToolbarColors; import org.chromium.chrome.browser.toolbar.ToolbarColors;
import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -446,7 +446,7 @@ public class StaticLayout extends Layout { ...@@ -446,7 +446,7 @@ public class StaticLayout extends Layout {
// restore. Potentially move to show(). // restore. Potentially move to show().
if (tabContentManager != null if (tabContentManager != null
&& tabContentManager.hasFullCachedThumbnail(mModel.get(LayoutTab.TAB_ID))) { && tabContentManager.hasFullCachedThumbnail(mModel.get(LayoutTab.TAB_ID))) {
TabModelImpl.logPerceivedTabSwitchLatencyMetric(); TabSwitchMetrics.logPerceivedTabSwitchLatencyMetric();
} }
} }
......
...@@ -34,9 +34,9 @@ import org.chromium.chrome.browser.tab.SadTab; ...@@ -34,9 +34,9 @@ import org.chromium.chrome.browser.tab.SadTab;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper;
import org.chromium.chrome.browser.tab.TabBrowserControlsOffsetHelper; import org.chromium.chrome.browser.tab.TabBrowserControlsOffsetHelper;
import org.chromium.chrome.browser.tabmodel.TabModelImpl;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.tabmodel.TabSwitchMetrics;
import org.chromium.chrome.browser.toolbar.ControlContainer; import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.vr.VrModuleProvider;
import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate; import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
...@@ -598,7 +598,7 @@ public class BrowserControlsManager ...@@ -598,7 +598,7 @@ public class BrowserControlsManager
updateBrowserControlsOffsets(false, topControlsOffsetY, bottomControlsOffsetY, updateBrowserControlsOffsets(false, topControlsOffsetY, bottomControlsOffsetY,
contentOffsetY, topControlsMinHeightOffsetY, bottomControlsMinHeightOffsetY); contentOffsetY, topControlsMinHeightOffsetY, bottomControlsMinHeightOffsetY);
} }
TabModelImpl.setActualTabSwitchLatencyMetricRequired(); TabSwitchMetrics.setActualTabSwitchLatencyMetricRequired();
} }
@Override @Override
......
...@@ -4,18 +4,14 @@ ...@@ -4,18 +4,14 @@
package org.chromium.chrome.browser.tabmodel; package org.chromium.chrome.browser.tabmodel;
import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.common.ResourceRequestBody; import org.chromium.content_public.common.ResourceRequestBody;
...@@ -27,13 +23,6 @@ import org.chromium.url.Origin; ...@@ -27,13 +23,6 @@ import org.chromium.url.Origin;
public abstract class TabModelJniBridge implements TabModel { public abstract class TabModelJniBridge implements TabModel {
private final boolean mIsIncognito; private final boolean mIsIncognito;
// TODO(dtrainor, simonb): Make these non-static so we don't break if we have multiple instances
// of chrome running. Also investigate how this affects document mode.
private static long sTabSwitchStartTime;
private static @TabSelectionType int sTabSelectionType;
private static boolean sTabSwitchLatencyMetricRequired;
private static boolean sPerceivedTabSwitchLatencyMetricLogged;
/** Native TabModelJniBridge pointer, which will be set by {@link #initializeNative()}. */ /** Native TabModelJniBridge pointer, which will be set by {@link #initializeNative()}. */
private long mNativeTabModelJniBridge; private long mNativeTabModelJniBridge;
...@@ -167,75 +156,6 @@ public abstract class TabModelJniBridge implements TabModel { ...@@ -167,75 +156,6 @@ public abstract class TabModelJniBridge implements TabModel {
@Override @Override
public abstract boolean isCurrentModel(); public abstract boolean isCurrentModel();
/**
* Register the start of tab switch latency timing. Called when setIndex() indicates a tab
* switch event.
* @param type The type of action that triggered the tab selection.
*/
public static void startTabSwitchLatencyTiming(final @TabSelectionType int type) {
sTabSwitchStartTime = SystemClock.uptimeMillis();
sTabSelectionType = type;
sTabSwitchLatencyMetricRequired = false;
sPerceivedTabSwitchLatencyMetricLogged = false;
}
/**
* Should be called a visible {@link Tab} gets a frame to render in the browser process.
* If we don't get this call, we ignore requests to
* {@link #flushActualTabSwitchLatencyMetric()}.
*/
public static void setActualTabSwitchLatencyMetricRequired() {
if (sTabSwitchStartTime <= 0) return;
sTabSwitchLatencyMetricRequired = true;
}
/**
* Logs the perceived tab switching latency metric. This will automatically be logged if
* the actual metric is set and flushed.
*/
public static void logPerceivedTabSwitchLatencyMetric() {
if (sTabSwitchStartTime <= 0 || sPerceivedTabSwitchLatencyMetricLogged) return;
flushTabSwitchLatencyMetric(true);
sPerceivedTabSwitchLatencyMetricLogged = true;
}
/**
* Flush the latency metric if called after the indication that a frame is ready.
*/
public static void flushActualTabSwitchLatencyMetric() {
if (sTabSwitchStartTime <= 0 || !sTabSwitchLatencyMetricRequired) return;
logPerceivedTabSwitchLatencyMetric();
flushTabSwitchLatencyMetric(false);
sTabSwitchStartTime = 0;
sTabSwitchLatencyMetricRequired = false;
}
private static void flushTabSwitchLatencyMetric(boolean perceived) {
if (sTabSwitchStartTime <= 0) return;
final long ms = SystemClock.uptimeMillis() - sTabSwitchStartTime;
String baseHistogram;
switch (sTabSelectionType) {
case TabSelectionType.FROM_CLOSE:
baseHistogram = "Tabs.SwitchFromCloseLatency";
break;
case TabSelectionType.FROM_EXIT:
baseHistogram = "Tabs.SwitchFromExitLatency";
break;
case TabSelectionType.FROM_NEW:
baseHistogram = "Tabs.SwitchFromNewLatency";
break;
case TabSelectionType.FROM_USER:
baseHistogram = "Tabs.SwitchFromUserLatency";
break;
default:
return;
}
String histogramSuffix = perceived ? "_Perceived" : "_Actual";
RecordHistogram.recordTimesHistogram(baseHistogram + histogramSuffix, ms);
}
@NativeMethods @NativeMethods
interface Natives { interface Natives {
long init(TabModelJniBridge caller, Profile profile, boolean isTabbedActivity); long init(TabModelJniBridge caller, Profile profile, boolean isTabbedActivity);
......
...@@ -361,7 +361,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod ...@@ -361,7 +361,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
boolean isFromExternalApp = boolean isFromExternalApp =
tab != null && tab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP; tab != null && tab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP;
if (mVisibleTab != tab && tab != null && !tab.isNativePage()) { if (mVisibleTab != tab && tab != null && !tab.isNativePage()) {
TabModelImpl.startTabSwitchLatencyTiming(type); TabSwitchMetrics.startTabSwitchLatencyTiming(type);
} }
if (mVisibleTab != null && mVisibleTab != tab && !mVisibleTab.needsReload()) { if (mVisibleTab != null && mVisibleTab != tab && !mVisibleTab.needsReload()) {
boolean attached = mVisibleTab.getWebContents() != null boolean attached = mVisibleTab.getWebContents() != null
......
...@@ -37,6 +37,7 @@ android_library("java") { ...@@ -37,6 +37,7 @@ android_library("java") {
"android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java", "android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java", "android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabReparentingParams.java", "android/java/src/org/chromium/chrome/browser/tabmodel/TabReparentingParams.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabSwitchMetrics.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java", "android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManager.java",
] ]
deps = [ deps = [
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tabmodel;
import android.os.SystemClock;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabSelectionType;
/**
* Logs tab switching latency metrics
*/
public class TabSwitchMetrics {
// TODO(dtrainor, simonb): Make these non-static so we don't break if we have multiple instances
// of chrome running. Also investigate how this affects document mode.
private static long sTabSwitchStartTime;
private static @TabSelectionType int sTabSelectionType;
private static boolean sTabSwitchLatencyMetricRequired;
private static boolean sPerceivedTabSwitchLatencyMetricLogged;
/**
* Register the start of tab switch latency timing. Called when setIndex() indicates a tab
* switch event.
* @param type The type of action that triggered the tab selection.
*/
public static void startTabSwitchLatencyTiming(final @TabSelectionType int type) {
sTabSwitchStartTime = SystemClock.uptimeMillis();
sTabSelectionType = type;
sTabSwitchLatencyMetricRequired = false;
sPerceivedTabSwitchLatencyMetricLogged = false;
}
/**
* Should be called a visible {@link Tab} gets a frame to render in the browser process.
* If we don't get this call, we ignore requests to
* {@link #flushActualTabSwitchLatencyMetric()}.
*/
public static void setActualTabSwitchLatencyMetricRequired() {
if (sTabSwitchStartTime <= 0) return;
sTabSwitchLatencyMetricRequired = true;
}
/**
* Logs the perceived tab switching latency metric. This will automatically be logged if
* the actual metric is set and flushed.
*/
public static void logPerceivedTabSwitchLatencyMetric() {
if (sTabSwitchStartTime <= 0 || sPerceivedTabSwitchLatencyMetricLogged) return;
flushTabSwitchLatencyMetric(true);
sPerceivedTabSwitchLatencyMetricLogged = true;
}
/**
* Flush the latency metric if called after the indication that a frame is ready.
*/
public static void flushActualTabSwitchLatencyMetric() {
if (sTabSwitchStartTime <= 0 || !sTabSwitchLatencyMetricRequired) return;
logPerceivedTabSwitchLatencyMetric();
flushTabSwitchLatencyMetric(false);
sTabSwitchStartTime = 0;
sTabSwitchLatencyMetricRequired = false;
}
private static void flushTabSwitchLatencyMetric(boolean perceived) {
if (sTabSwitchStartTime <= 0) return;
final long ms = SystemClock.uptimeMillis() - sTabSwitchStartTime;
String baseHistogram;
switch (sTabSelectionType) {
case TabSelectionType.FROM_CLOSE:
baseHistogram = "Tabs.SwitchFromCloseLatency";
break;
case TabSelectionType.FROM_EXIT:
baseHistogram = "Tabs.SwitchFromExitLatency";
break;
case TabSelectionType.FROM_NEW:
baseHistogram = "Tabs.SwitchFromNewLatency";
break;
case TabSelectionType.FROM_USER:
baseHistogram = "Tabs.SwitchFromUserLatency";
break;
default:
return;
}
String histogramSuffix = perceived ? "_Perceived" : "_Actual";
RecordHistogram.recordTimesHistogram(baseHistogram + histogramSuffix, ms);
}
}
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