| // Copyright 2015 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. |
| |
| #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UTIL_H_ |
| #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UTIL_H_ |
| |
| #include "base/metrics/histogram_macros.h" |
| #include "base/optional.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" |
| #include "chrome/common/page_load_metrics/page_load_metrics_util.h" |
| #include "third_party/blink/public/platform/web_loading_behavior_flag.h" |
| |
| // Up to 10 minutes, with 100 buckets. |
| #define PAGE_LOAD_HISTOGRAM(name, sample) \ |
| UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ |
| base::TimeDelta::FromMilliseconds(10), \ |
| base::TimeDelta::FromMinutes(10), 100) |
| |
| // Up to 1 hour, with 100 buckets. |
| #define PAGE_LOAD_LONG_HISTOGRAM(name, sample) \ |
| UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ |
| base::TimeDelta::FromMilliseconds(10), \ |
| base::TimeDelta::FromHours(1), 100) |
| |
| // Records |bytes| to |histogram_name| in kilobytes (i.e., bytes / 1024). |
| #define PAGE_BYTES_HISTOGRAM(histogram_name, bytes) \ |
| UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| histogram_name, static_cast<int>((bytes) / 1024), 1, 500 * 1024, 50) |
| |
| #define PAGE_RESOURCE_COUNT_HISTOGRAM UMA_HISTOGRAM_COUNTS_10000 |
| |
| namespace page_load_metrics { |
| |
| struct PageLoadExtraInfo; |
| |
| // Reasons a page load can be aborted. |
| enum PageAbortReason { |
| // Represents no abort. |
| ABORT_NONE, |
| |
| // The page was reloaded, possibly by the user. |
| ABORT_RELOAD, |
| |
| // The page was navigated away from, via a back or forward navigation. |
| ABORT_FORWARD_BACK, |
| |
| // If the page load is replaced by a new navigation. This includes link |
| // clicks, typing in the omnibox (not a reload), and form submissions. |
| ABORT_NEW_NAVIGATION, |
| |
| // The page load was stopped (e.g. the user presses the stop X button). |
| ABORT_STOP, |
| |
| // Page load ended due to closing the tab or browser. |
| ABORT_CLOSE, |
| |
| // The page load was backgrounded, e.g. the browser was minimized or the user |
| // switched tabs. Note that the same page may be foregrounded in the future, |
| // so this is not a 'terminal' abort type. |
| ABORT_BACKGROUND, |
| |
| // We don't know why the page load ended. This is the value we assign to a |
| // terminated provisional load if the only signal we get is the load finished |
| // without committing, either without error or with net::ERR_ABORTED. |
| ABORT_OTHER |
| }; |
| |
| // Information related to a page load abort. |
| struct PageAbortInfo { |
| PageAbortInfo() |
| : reason(ABORT_NONE), |
| user_initiated_info(UserInitiatedInfo::NotUserInitiated()) {} |
| PageAbortInfo(PageAbortReason reason, |
| UserInitiatedInfo user_initiated_info, |
| base::TimeDelta time_to_abort) |
| : reason(reason), |
| user_initiated_info(user_initiated_info), |
| time_to_abort(time_to_abort) {} |
| |
| // The reason / cause for the abort. |
| const PageAbortReason reason; |
| |
| // The fields below are only valid if reason != ABORT_NONE. |
| |
| // Information about whether the abort was initiated by a user. |
| const UserInitiatedInfo user_initiated_info; |
| |
| // The time from navigation start to the time the page load was aborted. |
| const base::TimeDelta time_to_abort; |
| }; |
| |
| // Returns true if: |
| // - We have timing information for the event. |
| // - The page load started while the page was in the foreground. |
| // - The event occurred prior to the page being moved to the background. |
| // When a page is backgrounded, some events (e.g. paint) are delayed. Since |
| // these data points can skew the mean, they should not be mixed with timing |
| // events that occurred in the foreground. |
| // If the event time delta and background time delta are equal, we still |
| // consider the event to be logged in the foreground histogram since any |
| // background specific handling would not yet have been applied to that event. |
| bool WasStartedInForegroundOptionalEventInForeground( |
| const base::Optional<base::TimeDelta>& event, |
| const PageLoadExtraInfo& info); |
| |
| // Returns true if: |
| // - We have timing information for the event. |
| // - The page load started in the background. |
| // - Moved to the foreground prior to the event. |
| // - Not moved back to the background prior to the event. |
| bool WasStartedInBackgroundOptionalEventInForeground( |
| const base::Optional<base::TimeDelta>& event, |
| const PageLoadExtraInfo& info); |
| |
| PageAbortInfo GetPageAbortInfo(const PageLoadExtraInfo& info); |
| |
| // Get the duration of time that the page spent in the foreground, from |
| // navigation start until one of the following events: |
| // * the load of the main resource fails |
| // * the page load is stopped |
| // * the tab hosting the page is closed |
| // * the render process hosting the page goes away |
| // * a new navigation which later commits is initiated in the same tab |
| // * the tab hosting the page is backgrounded |
| base::Optional<base::TimeDelta> GetInitialForegroundDuration( |
| const PageLoadExtraInfo& info, |
| base::TimeTicks app_background_time); |
| |
| // Whether the given loading behavior was observed in any frame (either the main |
| // frame or a subframe). |
| bool DidObserveLoadingBehaviorInAnyFrame( |
| const page_load_metrics::PageLoadExtraInfo& info, |
| blink::WebLoadingBehaviorFlag behavior); |
| |
| // Whether the given url has a Google Search hostname. |
| // Examples: |
| // https://www.google.com -> true |
| // https://www.google.co.jp -> true |
| // https://www.google.example.com -> false |
| // https://docs.google.com -> false |
| bool IsGoogleSearchHostname(const GURL& url); |
| |
| // Whether the given url is for a Google Search results page. See |
| // https://docs.google.com/document/d/1jNPZ6Aeh0KV6umw1yZrrkfXRfxWNruwu7FELLx_cpOg/edit |
| // for additional details. |
| // Examples: |
| // https://www.google.com/#q=test -> true |
| // https://www.google.com/search?q=test -> true |
| // https://www.google.com/ -> false |
| // https://www.google.com/about/ -> false |
| bool IsGoogleSearchResultUrl(const GURL& url); |
| |
| // Whether the given url is a Google Search redirector URL. |
| bool IsGoogleSearchRedirectorUrl(const GURL& url); |
| |
| // Whether the given query string contains the given component. The query |
| // parameter should contain the query string of a URL (the portion following |
| // the question mark, excluding the question mark). The component must fully |
| // match a component in the query string. For example, 'foo=bar' would match |
| // the query string 'a=b&foo=bar&c=d' but would not match 'a=b&zzzfoo=bar&c=d' |
| // since, though foo=bar appears in the query string, the key specified in the |
| // component 'foo' does not match the full key in the query string |
| // 'zzzfoo'. For QueryContainsComponent, the component should of the form |
| // 'key=value'. For QueryContainsComponentPrefix, the component should be of |
| // the form 'key=' (where the value is not specified). |
| // Note: The heuristic used by these functions will not find a component at the |
| // beginning of the query string if the component starts with a delimiter |
| // character ('?' or '#'). For example, '?foo=bar' will match the query string |
| // 'a=b&?foo=bar' but not the query string '?foo=bar&a=b'. |
| bool QueryContainsComponent(const base::StringPiece query, |
| const base::StringPiece component); |
| bool QueryContainsComponentPrefix(const base::StringPiece query, |
| const base::StringPiece component); |
| |
| } // namespace page_load_metrics |
| |
| #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_METRICS_UTIL_H_ |