blob: ae5953b1738f45cf16599bf92e51d71c6712cb15 [file] [log] [blame]
// 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.
#include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
#include <algorithm>
#include "chrome/common/page_load_metrics/page_load_timing.h"
namespace page_load_metrics {
namespace {
bool IsBackgroundAbort(const PageLoadExtraInfo& info) {
if (!info.started_in_foreground || !info.first_background_time)
return false;
if (!info.page_end_time)
return true;
return info.first_background_time <= info.page_end_time;
}
PageAbortReason GetAbortReasonForEndReason(PageEndReason end_reason) {
switch (end_reason) {
case END_RELOAD:
return ABORT_RELOAD;
case END_FORWARD_BACK:
return ABORT_FORWARD_BACK;
case END_NEW_NAVIGATION:
return ABORT_NEW_NAVIGATION;
case END_STOP:
return ABORT_STOP;
case END_CLOSE:
return ABORT_CLOSE;
case END_OTHER:
return ABORT_OTHER;
default:
return ABORT_NONE;
}
}
} // namespace
bool WasStartedInForegroundOptionalEventInForeground(
const base::Optional<base::TimeDelta>& event,
const PageLoadExtraInfo& info) {
return info.started_in_foreground && event &&
(!info.first_background_time ||
event.value() <= info.first_background_time.value());
}
PageAbortInfo GetPageAbortInfo(const PageLoadExtraInfo& info) {
if (IsBackgroundAbort(info)) {
// Though most cases where a tab is backgrounded are user initiated, we
// can't be certain that we were backgrounded due to a user action. For
// example, on Android, the screen times out after a period of inactivity,
// resulting in a non-user-initiated backgrounding.
return {ABORT_BACKGROUND, UserInitiatedInfo::NotUserInitiated(),
info.first_background_time.value()};
}
PageAbortReason abort_reason =
GetAbortReasonForEndReason(info.page_end_reason);
if (abort_reason == ABORT_NONE)
return PageAbortInfo();
return {abort_reason, info.page_end_user_initiated_info,
info.page_end_time.value()};
}
base::Optional<base::TimeDelta> GetInitialForegroundDuration(
const PageLoadExtraInfo& info,
base::TimeTicks app_background_time) {
if (!info.started_in_foreground)
return base::Optional<base::TimeDelta>();
base::Optional<base::TimeDelta> time_on_page =
OptionalMin(info.first_background_time, info.page_end_time);
// If we don't have a time_on_page value yet, and we have an app background
// time, use the app background time as our end time. This addresses cases
// where the Chrome app is backgrounded before the page load is complete, on
// platforms where Chrome may be killed once it goes into the background
// (Android). In these cases, we use the app background time as the 'end
// time'.
if (!time_on_page && !app_background_time.is_null()) {
time_on_page = app_background_time - info.navigation_start;
}
return time_on_page;
}
base::Optional<base::TimeDelta> OptionalMin(
const base::Optional<base::TimeDelta>& a,
const base::Optional<base::TimeDelta>& b) {
if (a && !b)
return a;
if (b && !a)
return b;
if (!a && !b)
return a; // doesn't matter which
return base::Optional<base::TimeDelta>(std::min(a.value(), b.value()));
}
} // namespace page_load_metrics