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