| Index: ui/latency/latency_tracker.cc | 
| diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/ui/latency/latency_tracker.cc | 
| similarity index 28% | 
| copy from content/browser/renderer_host/input/render_widget_host_latency_tracker.cc | 
| copy to ui/latency/latency_tracker.cc | 
| index 10a9f126db0e3b043f7d10a3f1c2ce9980739532..06701f05d48a8cd2947722f2bb5001a93213d4d4 100644 | 
| --- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc | 
| +++ b/ui/latency/latency_tracker.cc | 
| @@ -1,133 +1,15 @@ | 
| -// Copyright 2014 The Chromium Authors. All rights reserved. | 
| +// Copyright 2017 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 "content/browser/renderer_host/input/render_widget_host_latency_tracker.h" | 
| +#include "ui/latency/latency_tracker.h" | 
|  | 
| -#include <stddef.h> | 
| - | 
| -#include "base/logging.h" | 
| #include "base/metrics/histogram_functions.h" | 
| #include "base/metrics/histogram_macros.h" | 
| -#include "build/build_config.h" | 
| -#include "components/rappor/public/rappor_utils.h" | 
| -#include "content/browser/renderer_host/render_widget_host_delegate.h" | 
| -#include "content/public/browser/content_browser_client.h" | 
| -#include "content/public/common/content_client.h" | 
| -#include "ui/events/blink/web_input_event_traits.h" | 
| - | 
| -using blink::WebGestureEvent; | 
| -using blink::WebInputEvent; | 
| -using blink::WebMouseEvent; | 
| -using blink::WebMouseWheelEvent; | 
| -using blink::WebTouchEvent; | 
| -using ui::LatencyInfo; | 
| - | 
| -namespace content { | 
| -namespace { | 
| - | 
| -void UpdateLatencyCoordinatesImpl(const blink::WebTouchEvent& touch, | 
| -                                  LatencyInfo* latency, | 
| -                                  float device_scale_factor) { | 
| -  for (uint32_t i = 0; i < touch.touches_length; ++i) { | 
| -    gfx::PointF coordinate(touch.touches[i].position.x * device_scale_factor, | 
| -                           touch.touches[i].position.y * device_scale_factor); | 
| -    if (!latency->AddInputCoordinate(coordinate)) | 
| -      break; | 
| -  } | 
| -} | 
| - | 
| -void UpdateLatencyCoordinatesImpl(const WebGestureEvent& gesture, | 
| -                                  LatencyInfo* latency, | 
| -                                  float device_scale_factor) { | 
| -  latency->AddInputCoordinate(gfx::PointF(gesture.x * device_scale_factor, | 
| -                                          gesture.y * device_scale_factor)); | 
| -} | 
| - | 
| -void UpdateLatencyCoordinatesImpl(const WebMouseEvent& mouse, | 
| -                                  LatencyInfo* latency, | 
| -                                  float device_scale_factor) { | 
| -  latency->AddInputCoordinate( | 
| -      gfx::PointF(mouse.PositionInWidget().x * device_scale_factor, | 
| -                  mouse.PositionInWidget().y * device_scale_factor)); | 
| -} | 
| - | 
| -void UpdateLatencyCoordinatesImpl(const WebMouseWheelEvent& wheel, | 
| -                                  LatencyInfo* latency, | 
| -                                  float device_scale_factor) { | 
| -  latency->AddInputCoordinate( | 
| -      gfx::PointF(wheel.PositionInWidget().x * device_scale_factor, | 
| -                  wheel.PositionInWidget().y * device_scale_factor)); | 
| -} | 
| +#include "ui/latency/latency_histogram_macros.h" | 
|  | 
| -void UpdateLatencyCoordinates(const WebInputEvent& event, | 
| -                              float device_scale_factor, | 
| -                              LatencyInfo* latency) { | 
| -  if (WebInputEvent::IsMouseEventType(event.GetType())) { | 
| -    UpdateLatencyCoordinatesImpl(static_cast<const WebMouseEvent&>(event), | 
| -                                 latency, device_scale_factor); | 
| -  } else if (WebInputEvent::IsGestureEventType(event.GetType())) { | 
| -    UpdateLatencyCoordinatesImpl(static_cast<const WebGestureEvent&>(event), | 
| -                                 latency, device_scale_factor); | 
| -  } else if (WebInputEvent::IsTouchEventType(event.GetType())) { | 
| -    UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event), | 
| -                                 latency, device_scale_factor); | 
| -  } else if (event.GetType() == WebInputEvent::kMouseWheel) { | 
| -    UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event), | 
| -                                 latency, device_scale_factor); | 
| -  } | 
| -} | 
| - | 
| -// Check valid timing for start and end latency components. | 
| -#define CONFIRM_VALID_TIMING(start, end)     \ | 
| -  DCHECK(!start.first_event_time.is_null()); \ | 
| -  DCHECK(!end.last_event_time.is_null());    \ | 
| -  DCHECK_GE(end.last_event_time, start.first_event_time); | 
| - | 
| -// Event latency that is mostly under 1 second. We should only use 100 buckets | 
| -// when needed. | 
| -#define UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS(name, start, \ | 
| -                                                                 end)         \ | 
| -  CONFIRM_VALID_TIMING(start, end)                                            \ | 
| -  base::UmaHistogramCustomCounts(                                             \ | 
| -      name, (end.last_event_time - start.first_event_time).InMicroseconds(),  \ | 
| -      1, 1000000, 100); | 
| - | 
| -#define UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS(name, start, end)           \ | 
| -  CONFIRM_VALID_TIMING(start, end)                                           \ | 
| -  base::UmaHistogramCustomCounts(                                            \ | 
| -      name, (end.last_event_time - start.first_event_time).InMilliseconds(), \ | 
| -      1, 1000, 50); | 
| - | 
| -// Touch/wheel to scroll latency using Rappor. | 
| -#define RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY(delegate, name, start, end) \ | 
| -  CONFIRM_VALID_TIMING(start, end)                                       \ | 
| -  rappor::RapporService* rappor_service =                                \ | 
| -      GetContentClient()->browser()->GetRapporService();                 \ | 
| -  if (rappor_service && delegate) {                                      \ | 
| -    std::unique_ptr<rappor::Sample> sample =                             \ | 
| -        rappor_service->CreateSample(rappor::UMA_RAPPOR_TYPE);           \ | 
| -    delegate->AddDomainInfoToRapporSample(sample.get());                 \ | 
| -    sample->SetUInt64Field(                                              \ | 
| -        "Latency",                                                       \ | 
| -        (end.last_event_time - start.first_event_time).InMicroseconds(), \ | 
| -        rappor::NO_NOISE);                                               \ | 
| -    rappor_service->RecordSample(name, std::move(sample));               \ | 
| -  } | 
| - | 
| -// Long touch/wheel scroll latency component that is mostly under 200ms. | 
| -#define UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2(name, start, end)                 \ | 
| -  CONFIRM_VALID_TIMING(start, end)                                            \ | 
| -  base::Histogram::FactoryGet(name, 1000, 200000, 50,                         \ | 
| -                              base::HistogramBase::kUmaTargetedHistogramFlag) \ | 
| -      ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); | 
| - | 
| -// Short touch/wheel scroll latency component that is mostly under 50ms. | 
| -#define UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2(name, start, end)                \ | 
| -  CONFIRM_VALID_TIMING(start, end)                                            \ | 
| -  base::Histogram::FactoryGet(name, 1, 50000, 50,                             \ | 
| -                              base::HistogramBase::kUmaTargetedHistogramFlag) \ | 
| -      ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); | 
| +namespace ui { | 
| +namespace { | 
|  | 
| std::string LatencySourceEventTypeToInputModalityString( | 
| ui::SourceEventType type) { | 
| @@ -141,23 +23,9 @@ std::string LatencySourceEventTypeToInputModalityString( | 
| } | 
| } | 
|  | 
| -std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) { | 
| -  if (type == blink::WebInputEvent::kMouseWheel) { | 
| -    return "Wheel"; | 
| -  } else if (WebInputEvent::IsKeyboardEventType(type)) { | 
| -    return "Key"; | 
| -  } else if (WebInputEvent::IsMouseEventType(type)) { | 
| -    return "Mouse"; | 
| -  } else if (WebInputEvent::IsTouchEventType(type)) { | 
| -    return "Touch"; | 
| -  } | 
| -  return ""; | 
| -} | 
| - | 
| void ComputeScrollLatencyHistograms( | 
| const LatencyInfo::LatencyComponent& gpu_swap_begin_component, | 
| const LatencyInfo::LatencyComponent& gpu_swap_end_component, | 
| -    int64_t latency_component_id, | 
| const LatencyInfo& latency) { | 
| DCHECK(!latency.coalesced()); | 
| if (latency.coalesced()) | 
| @@ -168,18 +36,18 @@ void ComputeScrollLatencyHistograms( | 
| LatencyInfo::LatencyComponent original_component; | 
| if (latency.FindLatency( | 
| ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 
| -          latency_component_id, &original_component)) { | 
| +          &original_component)) { | 
| // This UMA metric tracks the time between the final frame swap for the | 
| // first scroll event in a sequence and the original timestamp of that | 
| // scroll event's underlying touch event. | 
| for (size_t i = 0; i < original_component.event_count; i++) { | 
| UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | 
| -          "Event.Latency.TouchToFirstScrollUpdateSwapBegin", | 
| -          original_component, gpu_swap_begin_component); | 
| +          "Event.Latency.TouchToFirstScrollUpdateSwapBegin", original_component, | 
| +          gpu_swap_begin_component); | 
| } | 
| } else if (!latency.FindLatency( | 
| ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 
| -                 latency_component_id, &original_component)) { | 
| +                 &original_component)) { | 
| return; | 
| } | 
|  | 
| @@ -192,11 +60,63 @@ void ComputeScrollLatencyHistograms( | 
| } | 
| } | 
|  | 
| -void ComputeTouchAndWheelScrollLatencyHistograms( | 
| -    RenderWidgetHostDelegate* render_widget_host_delegate, | 
| +}  // namespace | 
| + | 
| +void LatencyTracker::OnGpuSwapBuffersCompleted(const LatencyInfo& latency) { | 
| +  LatencyInfo::LatencyComponent gpu_swap_end_component; | 
| +  if (!latency.FindLatency( | 
| +          ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, | 
| +          &gpu_swap_end_component)) { | 
| +    return; | 
| +  } | 
| + | 
| +  LatencyInfo::LatencyComponent gpu_swap_begin_component; | 
| +  if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, | 
| +                           &gpu_swap_begin_component)) { | 
| +    return; | 
| +  } | 
| + | 
| +  LatencyInfo::LatencyComponent tab_switch_component; | 
| +  if (latency.FindLatency(ui::TAB_SHOW_COMPONENT, &tab_switch_component)) { | 
| +    base::TimeDelta delta = | 
| +        gpu_swap_end_component.event_time - tab_switch_component.event_time; | 
| +    for (size_t i = 0; i < tab_switch_component.event_count; i++) { | 
| +      UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); | 
| +    } | 
| +  } | 
| + | 
| +  if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 
| +                           nullptr)) { | 
| +    return; | 
| +  } | 
| + | 
| +  ui::SourceEventType source_event_type = latency.source_event_type(); | 
| +  if (source_event_type == ui::SourceEventType::WHEEL || | 
| +      source_event_type == ui::SourceEventType::TOUCH) { | 
| +    ComputeTouchAndWheelScrollLatencyHistograms( | 
| +        gpu_swap_begin_component, gpu_swap_end_component, latency); | 
| +  } | 
| + | 
| +  // Compute the old scroll update latency metrics. They are exclusively | 
| +  // calculated for touch scrolls, and will be deprecated on M56. | 
| +  // (https://crbug.com/649754) | 
| +  LatencyInfo::LatencyComponent mouse_wheel_scroll_update_component; | 
| +  if (!latency.FindLatency( | 
| +          ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, | 
| +          &mouse_wheel_scroll_update_component)) { | 
| +    ComputeScrollLatencyHistograms(gpu_swap_begin_component, | 
| +                                   gpu_swap_end_component, latency); | 
| +  } | 
| +} | 
| + | 
| +void LatencyTracker::ReportRapporScrollLatency( | 
| +    const std::string& name, | 
| +    const LatencyInfo::LatencyComponent& start_component, | 
| +    const LatencyInfo::LatencyComponent& end_component) {} | 
| + | 
| +void LatencyTracker::ComputeTouchAndWheelScrollLatencyHistograms( | 
| const ui::LatencyInfo::LatencyComponent& gpu_swap_begin_component, | 
| const ui::LatencyInfo::LatencyComponent& gpu_swap_end_component, | 
| -    int64_t latency_component_id, | 
| const ui::LatencyInfo& latency) { | 
| DCHECK(!latency.coalesced()); | 
| if (latency.coalesced()) | 
| @@ -210,7 +130,7 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
|  | 
| if (latency.FindLatency( | 
| ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 
| -          latency_component_id, &original_component)) { | 
| +          &original_component)) { | 
| scroll_name = "ScrollBegin"; | 
| // This UMA metric tracks the time between the final frame swap for the | 
| // first scroll event in a sequence and the original timestamp of that | 
| @@ -220,11 +140,9 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
| ".TimeToScrollUpdateSwapBegin2", | 
| original_component, gpu_swap_begin_component); | 
|  | 
| -    RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( | 
| -        render_widget_host_delegate, | 
| -        "Event.Latency.ScrollBegin." + input_modality + | 
| -            ".TimeToScrollUpdateSwapBegin2", | 
| -        original_component, gpu_swap_begin_component); | 
| +    ReportRapporScrollLatency("Event.Latency.ScrollBegin." + input_modality + | 
| +                                  ".TimeToScrollUpdateSwapBegin2", | 
| +                              original_component, gpu_swap_begin_component); | 
|  | 
| // TODO(lanwei): Will remove them when M56 is stable, see | 
| // https://crbug.com/669618. | 
| @@ -234,7 +152,7 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
| original_component, gpu_swap_begin_component); | 
| } else if (latency.FindLatency( | 
| ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 
| -                 latency_component_id, &original_component)) { | 
| +                 &original_component)) { | 
| // This UMA metric tracks the time from when the original touch event is | 
| // created to when the scroll gesture results in final frame swap. | 
| // First scroll events are excluded from this metric. | 
| @@ -243,8 +161,7 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
| "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | 
| original_component, gpu_swap_begin_component); | 
|  | 
| -      RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( | 
| -          render_widget_host_delegate, | 
| +      ReportRapporScrollLatency( | 
| "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | 
| original_component, gpu_swap_begin_component); | 
| } | 
| @@ -282,9 +199,8 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
| rendering_scheduled_component, renderer_swap_component); | 
|  | 
| LatencyInfo::LatencyComponent browser_received_swap_component; | 
| -  if (!latency.FindLatency( | 
| -          ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, | 
| -          &browser_received_swap_component)) | 
| +  if (!latency.FindLatency(ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, 0, | 
| +                           &browser_received_swap_component)) | 
| return; | 
|  | 
| UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2( | 
| @@ -301,308 +217,5 @@ void ComputeTouchAndWheelScrollLatencyHistograms( | 
| "Event.Latency." + scroll_name + "." + input_modality + ".GpuSwap2", | 
| gpu_swap_begin_component, gpu_swap_end_component); | 
| } | 
| -// LatencyComponents generated in the renderer must have component IDs | 
| -// provided to them by the browser process. This function adds the correct | 
| -// component ID where necessary. | 
| -void AddLatencyInfoComponentIds(LatencyInfo* latency, | 
| -                                int64_t latency_component_id) { | 
| -  std::vector<std::pair<ui::LatencyComponentType, int64_t>> new_components_key; | 
| -  std::vector<LatencyInfo::LatencyComponent> new_components_value; | 
| -  for (const auto& lc : latency->latency_components()) { | 
| -    ui::LatencyComponentType component_type = lc.first.first; | 
| -    if (component_type == ui::BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT) { | 
| -      // Generate a new component entry with the correct component ID | 
| -      new_components_key.push_back(std::make_pair(component_type, | 
| -                                                  latency_component_id)); | 
| -      new_components_value.push_back(lc.second); | 
| -    } | 
| -  } | 
| - | 
| -  // Remove the entries with invalid component IDs. | 
| -  latency->RemoveLatency(ui::BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT); | 
| - | 
| -  // Add newly generated components into the latency info | 
| -  for (size_t i = 0; i < new_components_key.size(); i++) { | 
| -    latency->AddLatencyNumberWithTimestamp( | 
| -        new_components_key[i].first, | 
| -        new_components_key[i].second, | 
| -        new_components_value[i].sequence_number, | 
| -        new_components_value[i].event_time, | 
| -        new_components_value[i].event_count); | 
| -  } | 
| -} | 
| - | 
| -}  // namespace | 
| - | 
| -RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker() | 
| -    : last_event_id_(0), | 
| -      latency_component_id_(0), | 
| -      device_scale_factor_(1), | 
| -      has_seen_first_gesture_scroll_update_(false), | 
| -      active_multi_finger_gesture_(false), | 
| -      touch_start_default_prevented_(false), | 
| -      render_widget_host_delegate_(nullptr) {} | 
| - | 
| -RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() {} | 
| - | 
| -void RenderWidgetHostLatencyTracker::Initialize(int routing_id, | 
| -                                                int process_id) { | 
| -  DCHECK_EQ(0, last_event_id_); | 
| -  DCHECK_EQ(0, latency_component_id_); | 
| -  last_event_id_ = static_cast<int64_t>(process_id) << 32; | 
| -  latency_component_id_ = routing_id | last_event_id_; | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms( | 
| -    WebInputEvent::Type type, | 
| -    int64_t latency_component_id, | 
| -    const LatencyInfo& latency, | 
| -    InputEventAckState ack_result) { | 
| -  // If this event was coalesced into another event, ignore it, as the event it | 
| -  // was coalesced into will reflect the full latency. | 
| -  if (latency.coalesced()) | 
| -    return; | 
| - | 
| -  if (type != blink::WebInputEvent::kMouseWheel && | 
| -      !WebInputEvent::IsTouchEventType(type)) { | 
| -    return; | 
| -  } | 
| - | 
| -  LatencyInfo::LatencyComponent rwh_component; | 
| -  if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 
| -                           latency_component_id, &rwh_component)) { | 
| -    return; | 
| -  } | 
| -  DCHECK_EQ(rwh_component.event_count, 1u); | 
| - | 
| -  bool multi_finger_touch_gesture = | 
| -      WebInputEvent::IsTouchEventType(type) && active_multi_finger_gesture_; | 
| - | 
| -  LatencyInfo::LatencyComponent ui_component; | 
| -  if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, | 
| -                          &ui_component)) { | 
| -    DCHECK_EQ(ui_component.event_count, 1u); | 
| -    base::TimeDelta ui_delta = | 
| -        rwh_component.last_event_time - ui_component.first_event_time; | 
| - | 
| -    if (type == blink::WebInputEvent::kMouseWheel) { | 
| -      UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelUI", | 
| -                                  ui_delta.InMicroseconds(), 1, 20000, 100); | 
| -    } else { | 
| -      DCHECK(WebInputEvent::IsTouchEventType(type)); | 
| -      UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchUI", | 
| -                                  ui_delta.InMicroseconds(), 1, 20000, 100); | 
| -    } | 
| -  } | 
| - | 
| -  // Both tap and scroll gestures depend on the disposition of the touch start | 
| -  // and the current touch. For touch start, touch_start_default_prevented_ == | 
| -  // (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED). | 
| -  bool action_prevented = touch_start_default_prevented_ || | 
| -                          ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; | 
| - | 
| -  std::string event_name = WebInputEvent::GetName(type); | 
| - | 
| -  std::string default_action_status = | 
| -      action_prevented ? "DefaultPrevented" : "DefaultAllowed"; | 
| - | 
| -  LatencyInfo::LatencyComponent main_component; | 
| -  if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0, | 
| -                          &main_component)) { | 
| -    DCHECK_EQ(main_component.event_count, 1u); | 
| -    if (!multi_finger_touch_gesture) { | 
| -      UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( | 
| -          "Event.Latency.QueueingTime." + event_name + default_action_status, | 
| -          rwh_component, main_component); | 
| -    } | 
| -  } | 
| - | 
| -  LatencyInfo::LatencyComponent acked_component; | 
| -  if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, | 
| -                          &acked_component)) { | 
| -    DCHECK_EQ(acked_component.event_count, 1u); | 
| -    if (!multi_finger_touch_gesture && | 
| -        main_component.event_time != base::TimeTicks()) { | 
| -      UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( | 
| -          "Event.Latency.BlockingTime." + event_name + default_action_status, | 
| -          main_component, acked_component); | 
| -    } | 
| - | 
| -    std::string input_modality = WebInputEventTypeToInputModalityString(type); | 
| -    if (input_modality != "") { | 
| -      UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | 
| -          "Event.Latency.Browser." + input_modality + "Acked", rwh_component, | 
| -          acked_component); | 
| -    } | 
| -  } | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::OnInputEvent( | 
| -    const blink::WebInputEvent& event, | 
| -    LatencyInfo* latency) { | 
| -  DCHECK(latency); | 
| - | 
| -  if (event.GetType() == WebInputEvent::kTouchStart) { | 
| -    const WebTouchEvent& touch_event = | 
| -        *static_cast<const WebTouchEvent*>(&event); | 
| -    DCHECK(touch_event.touches_length >= 1); | 
| -    active_multi_finger_gesture_ = touch_event.touches_length != 1; | 
| -  } | 
| - | 
| -  if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 
| -                           latency_component_id_, NULL)) { | 
| -    return; | 
| -  } | 
| - | 
| -  if (event.TimeStampSeconds() && | 
| -      !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | 
| -                            NULL)) { | 
| -    base::TimeTicks timestamp_now = base::TimeTicks::Now(); | 
| -    base::TimeTicks timestamp_original = | 
| -        base::TimeTicks() + | 
| -        base::TimeDelta::FromSecondsD(event.TimeStampSeconds()); | 
| - | 
| -    // Timestamp from platform input can wrap, e.g. 32 bits timestamp | 
| -    // for Xserver and Window MSG time will wrap about 49.6 days. Do a | 
| -    // sanity check here and if wrap does happen, use TimeTicks::Now() | 
| -    // as the timestamp instead. | 
| -    if ((timestamp_now - timestamp_original).InDays() > 0) | 
| -      timestamp_original = timestamp_now; | 
| - | 
| -    latency->AddLatencyNumberWithTimestamp( | 
| -        ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | 
| -        0, | 
| -        0, | 
| -        timestamp_original, | 
| -        1); | 
| -  } | 
| - | 
| -  latency->AddLatencyNumberWithTraceName( | 
| -      ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_, | 
| -      ++last_event_id_, WebInputEvent::GetName(event.GetType())); | 
| - | 
| -  UpdateLatencyCoordinates(event, device_scale_factor_, latency); | 
| - | 
| -  if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) { | 
| -    has_seen_first_gesture_scroll_update_ = false; | 
| -  } else if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) { | 
| -    // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a | 
| -    // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. | 
| -    // So we can track the latency specifically for scroll update events. | 
| -    LatencyInfo::LatencyComponent original_component; | 
| -    if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | 
| -                             &original_component)) { | 
| -      latency->AddLatencyNumberWithTimestamp( | 
| -          has_seen_first_gesture_scroll_update_ | 
| -              ? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT | 
| -              : ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 
| -          latency_component_id_, original_component.sequence_number, | 
| -          original_component.event_time, original_component.event_count); | 
| -    } | 
| - | 
| -    has_seen_first_gesture_scroll_update_ = true; | 
| -  } | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::OnInputEventAck( | 
| -    const blink::WebInputEvent& event, | 
| -    LatencyInfo* latency, InputEventAckState ack_result) { | 
| -  DCHECK(latency); | 
| - | 
| -  // Latency ends if an event is acked but does not cause render scheduling. | 
| -  bool rendering_scheduled = latency->FindLatency( | 
| -      ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr); | 
| -  rendering_scheduled |= latency->FindLatency( | 
| -      ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr); | 
| - | 
| -  if (WebInputEvent::IsTouchEventType(event.GetType())) { | 
| -    const WebTouchEvent& touch_event = | 
| -        *static_cast<const WebTouchEvent*>(&event); | 
| -    if (event.GetType() == WebInputEvent::kTouchStart) { | 
| -      touch_start_default_prevented_ = | 
| -          ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; | 
| -    } else if (event.GetType() == WebInputEvent::kTouchEnd || | 
| -               event.GetType() == WebInputEvent::kTouchCancel) { | 
| -      active_multi_finger_gesture_ = touch_event.touches_length > 2; | 
| -    } | 
| -  } | 
| - | 
| -  latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); | 
| -  // If this event couldn't have caused a gesture event, and it didn't trigger | 
| -  // rendering, we're done processing it. | 
| -  if (!rendering_scheduled) { | 
| -    latency->AddLatencyNumber( | 
| -        ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, 0); | 
| -  } | 
| - | 
| -  ComputeInputLatencyHistograms(event.GetType(), latency_component_id_, | 
| -                                *latency, ack_result); | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::OnSwapCompositorFrame( | 
| -    std::vector<LatencyInfo>* latencies) { | 
| -  DCHECK(latencies); | 
| -  for (LatencyInfo& latency : *latencies) { | 
| -    AddLatencyInfoComponentIds(&latency, latency_component_id_); | 
| -    latency.AddLatencyNumber( | 
| -        ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, 0); | 
| -  } | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::OnGpuSwapBuffersCompleted( | 
| -    const LatencyInfo& latency) { | 
| -  LatencyInfo::LatencyComponent gpu_swap_end_component; | 
| -  if (!latency.FindLatency( | 
| -          ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, | 
| -          &gpu_swap_end_component)) { | 
| -    return; | 
| -  } | 
| - | 
| -  LatencyInfo::LatencyComponent gpu_swap_begin_component; | 
| -  if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, | 
| -                           &gpu_swap_begin_component)) { | 
| -    return; | 
| -  } | 
| - | 
| -  LatencyInfo::LatencyComponent tab_switch_component; | 
| -  if (latency.FindLatency(ui::TAB_SHOW_COMPONENT, latency_component_id_, | 
| -                          &tab_switch_component)) { | 
| -    base::TimeDelta delta = | 
| -        gpu_swap_end_component.event_time - tab_switch_component.event_time; | 
| -    for (size_t i = 0; i < tab_switch_component.event_count; i++) { | 
| -      UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); | 
| -    } | 
| -  } | 
| - | 
| -  if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 
| -                           latency_component_id_, nullptr)) { | 
| -    return; | 
| -  } | 
| - | 
| -  ui::SourceEventType source_event_type = latency.source_event_type(); | 
| -  if (source_event_type == ui::SourceEventType::WHEEL || | 
| -      source_event_type == ui::SourceEventType::TOUCH) { | 
| -    ComputeTouchAndWheelScrollLatencyHistograms( | 
| -        render_widget_host_delegate_, gpu_swap_begin_component, | 
| -        gpu_swap_end_component, latency_component_id_, latency); | 
| -  } | 
| - | 
| -  // Compute the old scroll update latency metrics. They are exclusively | 
| -  // calculated for touch scrolls, and will be deprecated on M56. | 
| -  // (https://crbug.com/649754) | 
| -  LatencyInfo::LatencyComponent mouse_wheel_scroll_update_component; | 
| -  if (!latency.FindLatency( | 
| -          ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, | 
| -          &mouse_wheel_scroll_update_component)) { | 
| -    ComputeScrollLatencyHistograms(gpu_swap_begin_component, | 
| -                                   gpu_swap_end_component, | 
| -                                   latency_component_id_, latency); | 
| -  } | 
| -} | 
| - | 
| -void RenderWidgetHostLatencyTracker::SetDelegate( | 
| -    RenderWidgetHostDelegate* delegate) { | 
| -  render_widget_host_delegate_ = delegate; | 
| -} | 
|  | 
| -}  // namespace content | 
| +}  // namespace ui | 
|  |