@@ -57,6 +57,7 @@ export const CATEGORIZATION_SETTINGS = {
5757 STARTING_RANK : 2 ,
5858 IDLE_TIMEOUT_SECONDS : 60 * 60 ,
5959 WAKE_TIMEOUT_MS : 60 * 60 * 1000 ,
60+ PING_SUBMISSION_THRESHOLD : 10 ,
6061} ;
6162
6263ChromeUtils . defineLazyGetter ( lazy , "logConsole" , ( ) => {
@@ -85,13 +86,22 @@ XPCOMUtils.defineLazyPreferenceGetter(
8586 if ( newValue ) {
8687 SearchSERPDomainToCategoriesMap . init ( ) ;
8788 SearchSERPCategorizationEventScheduler . init ( ) ;
89+ SERPCategorizationRecorder . init ( ) ;
8890 } else {
8991 SearchSERPDomainToCategoriesMap . uninit ( ) ;
9092 SearchSERPCategorizationEventScheduler . uninit ( ) ;
93+ SERPCategorizationRecorder . uninit ( ) ;
9194 }
9295 }
9396) ;
9497
98+ XPCOMUtils . defineLazyPreferenceGetter (
99+ lazy ,
100+ "activityLimit" ,
101+ "telemetry.fog.test.activity_limit" ,
102+ 120
103+ ) ;
104+
95105export const SearchSERPTelemetryUtils = {
96106 ACTIONS : {
97107 CLICKED : "clicked" ,
@@ -2114,6 +2124,58 @@ class CategorizationEventScheduler {
21142124 * Handles reporting SERP categorization telemetry to Glean.
21152125 */
21162126class CategorizationRecorder {
2127+ #init = false ;
2128+
2129+ // The number of SERP categorizations that have been recorded but not yet
2130+ // reported in a Glean ping.
2131+ #serpCategorizationsCount = 0 ;
2132+
2133+ // When the user started interacting with the SERP.
2134+ #userInteractionStartTime = null ;
2135+
2136+ async init ( ) {
2137+ if ( this . #init) {
2138+ return ;
2139+ }
2140+
2141+ Services . obs . addObserver ( this , "user-interaction-active" ) ;
2142+ Services . obs . addObserver ( this , "user-interaction-inactive" ) ;
2143+ this . #init = true ;
2144+ this . submitPing ( "startup" ) ;
2145+ }
2146+
2147+ uninit ( ) {
2148+ if ( this . #init) {
2149+ Services . obs . removeObserver ( this , "user-interaction-active" ) ;
2150+ Services . obs . removeObserver ( this , "user-interaction-inactive" ) ;
2151+ this . #resetCategorizationRecorderData( ) ;
2152+ this . #init = false ;
2153+ }
2154+ }
2155+
2156+ observe ( subject , topic , data ) {
2157+ switch ( topic ) {
2158+ case "user-interaction-active" :
2159+ // If the user is already active, we don't want to overwrite the start
2160+ // time.
2161+ if ( this . #userInteractionStartTime == null ) {
2162+ this . #userInteractionStartTime = Date . now ( ) ;
2163+ }
2164+ break ;
2165+ case "user-interaction-inactive" :
2166+ let currentTime = Date . now ( ) ;
2167+ let activityLimitInMs = lazy . activityLimit * 1000 ;
2168+ if (
2169+ this . #userInteractionStartTime &&
2170+ currentTime - this . #userInteractionStartTime >= activityLimitInMs
2171+ ) {
2172+ this . submitPing ( "inactivity" ) ;
2173+ }
2174+ this . #userInteractionStartTime = null ;
2175+ break ;
2176+ }
2177+ }
2178+
21172179 /**
21182180 * Helper function for recording the SERP categorization event.
21192181 *
@@ -2125,7 +2187,25 @@ class CategorizationRecorder {
21252187 "Reporting the following categorization result:" ,
21262188 resultToReport
21272189 ) ;
2128- // TODO: Bug 1868476 - Report result to Glean.
2190+ Glean . serp . categorization . record ( resultToReport ) ;
2191+
2192+ this . #serpCategorizationsCount++ ;
2193+ if (
2194+ this . #serpCategorizationsCount >=
2195+ CATEGORIZATION_SETTINGS . PING_SUBMISSION_THRESHOLD
2196+ ) {
2197+ this . submitPing ( "threshold_reached" ) ;
2198+ this . #serpCategorizationsCount = 0 ;
2199+ }
2200+ }
2201+
2202+ submitPing ( reason ) {
2203+ GleanPings . serpCategorization . submit ( reason ) ;
2204+ }
2205+
2206+ #resetCategorizationRecorderData( ) {
2207+ this . #serpCategorizationsCount = 0 ;
2208+ this . #userInteractionStartTime = null ;
21292209 }
21302210}
21312211
0 commit comments