tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ScrollingMetrics.cpp (4005B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ScrollingMetrics.h"
      8 
      9 #include "mozilla/StaticPrefs_browser.h"
     10 #include "mozilla/dom/ContentParent.h"
     11 
     12 namespace mozilla {
     13 
     14 static TimeStamp gScrollingStartTime;
     15 static TimeStamp gScrollingEndTime;
     16 static uint32_t gScrollDistanceCSSPixels = 0;
     17 MOZ_RUNINIT static dom::InteractionData gScrollingInteraction = {};
     18 
     19 void ScrollingMetrics::OnScrollingInteractionEnded() {
     20  // We are only interested in content process scrolling
     21  if (XRE_IsParentProcess()) {
     22    return;
     23  }
     24 
     25  if (!gScrollingStartTime.IsNull() && !gScrollingEndTime.IsNull()) {
     26    gScrollingInteraction.mInteractionCount++;
     27    gScrollingInteraction.mInteractionTimeInMilliseconds +=
     28        static_cast<uint32_t>(
     29            (gScrollingEndTime - gScrollingStartTime).ToMilliseconds());
     30 
     31    gScrollingInteraction.mScrollingDistanceInPixels +=
     32        gScrollDistanceCSSPixels;
     33  }
     34 
     35  gScrollDistanceCSSPixels = 0;
     36  gScrollingStartTime = TimeStamp();
     37  gScrollingEndTime = TimeStamp();
     38 }
     39 
     40 void ScrollingMetrics::OnScrollingInteraction(CSSCoord distanceScrolled) {
     41  // We are only interested in content process scrolling
     42  if (XRE_IsParentProcess()) {
     43    return;
     44  }
     45 
     46  TimeStamp now = TimeStamp::Now();
     47  if (gScrollingEndTime.IsNull()) {
     48    gScrollingEndTime = now;
     49  }
     50 
     51  TimeDuration delay = now - gScrollingEndTime;
     52 
     53  // Has it been too long since the last scroll input event to consider it part
     54  // of the same interaction?
     55  if (delay >
     56      TimeDuration::FromMilliseconds(
     57          StaticPrefs::browser_places_interactions_scrolling_timeout_ms())) {
     58    OnScrollingInteractionEnded();
     59  }
     60 
     61  if (gScrollingStartTime.IsNull()) {
     62    gScrollingStartTime = now;
     63  }
     64  gScrollingEndTime = now;
     65  gScrollDistanceCSSPixels += static_cast<uint32_t>(distanceScrolled);
     66 }
     67 
     68 StaticAutoPtr<ScrollingMetrics> ScrollingMetrics::sSingleton;
     69 
     70 ScrollingMetrics* ScrollingMetrics::GetSingleton() {
     71  if (!sSingleton) {
     72    sSingleton = new ScrollingMetrics;
     73  }
     74 
     75  return sSingleton.get();
     76 }
     77 
     78 struct ScrollingMetricsCollector {
     79  void AppendScrollingMetrics(const std::tuple<uint32_t, uint32_t>& aMetrics,
     80                              dom::ContentParent* aParent) {
     81    mTimeScrolledMS += std::get<0>(aMetrics);
     82    mDistanceScrolledPixels += std::get<1>(aMetrics);
     83  }
     84 
     85  ~ScrollingMetricsCollector() {
     86    mPromiseHolder.Resolve(
     87        std::make_tuple(mTimeScrolledMS, mDistanceScrolledPixels), __func__);
     88  }
     89 
     90  uint32_t mTimeScrolledMS = 0;
     91  uint32_t mDistanceScrolledPixels = 0;
     92  MozPromiseHolder<ScrollingMetrics::ScrollingMetricsPromise> mPromiseHolder;
     93 };
     94 
     95 auto ScrollingMetrics::CollectScrollingMetricsInternal()
     96    -> RefPtr<ScrollingMetrics::ScrollingMetricsPromise> {
     97  std::shared_ptr<ScrollingMetricsCollector> collector =
     98      std::make_shared<ScrollingMetricsCollector>();
     99 
    100  nsTArray<dom::ContentParent*> contentParents;
    101  dom::ContentParent::GetAll(contentParents);
    102  for (dom::ContentParent* parent : contentParents) {
    103    RefPtr<dom::ContentParent> parentRef = parent;
    104    parent->SendCollectScrollingMetrics(
    105        [collector, parentRef](const std::tuple<uint32_t, uint32_t>& aMetrics) {
    106          collector->AppendScrollingMetrics(aMetrics, parentRef.get());
    107        },
    108        [](mozilla::ipc::ResponseRejectReason) {});
    109  }
    110 
    111  return collector->mPromiseHolder.Ensure(__func__);
    112 }
    113 
    114 std::tuple<uint32_t, uint32_t>
    115 ScrollingMetrics::CollectLocalScrollingMetricsInternal() {
    116  OnScrollingInteractionEnded();
    117 
    118  std::tuple<uint32_t, uint32_t> metrics =
    119      std::make_tuple(gScrollingInteraction.mInteractionTimeInMilliseconds,
    120                      gScrollingInteraction.mScrollingDistanceInPixels);
    121  gScrollingInteraction = {};
    122  return metrics;
    123 }
    124 
    125 }  // namespace mozilla