mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | 
						|
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
import {
 | 
						|
  actionCreators as ac,
 | 
						|
  actionTypes as at,
 | 
						|
} from "../../common/Actions.mjs";
 | 
						|
import { perfService as perfSvc } from "./perf-service.mjs";
 | 
						|
 | 
						|
const VISIBLE = "visible";
 | 
						|
const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 | 
						|
 | 
						|
export class DetectUserSessionStart {
 | 
						|
  constructor(store, options = {}) {
 | 
						|
    this._store = store;
 | 
						|
    // Overrides for testing
 | 
						|
    this.document = options.document || globalThis.document;
 | 
						|
    this._perfService = options.perfService || perfSvc;
 | 
						|
    this._onVisibilityChange = this._onVisibilityChange.bind(this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * sendEventOrAddListener - Notify immediately if the page is already visible,
 | 
						|
   *                    or else set up a listener for when visibility changes.
 | 
						|
   *                    This is needed for accurate session tracking for telemetry,
 | 
						|
   *                    because tabs are pre-loaded.
 | 
						|
   */
 | 
						|
  sendEventOrAddListener() {
 | 
						|
    if (this.document.visibilityState === VISIBLE) {
 | 
						|
      // If the document is already visible, to the user, send a notification
 | 
						|
      // immediately that a session has started.
 | 
						|
      this._sendEvent();
 | 
						|
    } else {
 | 
						|
      // If the document is not visible, listen for when it does become visible.
 | 
						|
      this.document.addEventListener(
 | 
						|
        VISIBILITY_CHANGE_EVENT,
 | 
						|
        this._onVisibilityChange
 | 
						|
      );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * _sendEvent - Sends a message to the main process to indicate the current
 | 
						|
   *              tab is now visible to the user, includes the
 | 
						|
   *              visibility_event_rcvd_ts time in ms from the UNIX epoch.
 | 
						|
   */
 | 
						|
  _sendEvent() {
 | 
						|
    this._perfService.mark("visibility_event_rcvd_ts");
 | 
						|
 | 
						|
    try {
 | 
						|
      let visibility_event_rcvd_ts =
 | 
						|
        this._perfService.getMostRecentAbsMarkStartByName(
 | 
						|
          "visibility_event_rcvd_ts"
 | 
						|
        );
 | 
						|
 | 
						|
      this._store.dispatch(
 | 
						|
        ac.AlsoToMain({
 | 
						|
          type: at.SAVE_SESSION_PERF_DATA,
 | 
						|
          data: { visibility_event_rcvd_ts },
 | 
						|
        })
 | 
						|
      );
 | 
						|
    } catch (ex) {
 | 
						|
      // If this failed, it's likely because the `privacy.resistFingerprinting`
 | 
						|
      // pref is true.  We should at least not blow up.
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * _onVisibilityChange - If the visibility has changed to visible, sends a notification
 | 
						|
   *                      and removes the event listener. This should only be called once per tab.
 | 
						|
   */
 | 
						|
  _onVisibilityChange() {
 | 
						|
    if (this.document.visibilityState === VISIBLE) {
 | 
						|
      this._sendEvent();
 | 
						|
      this.document.removeEventListener(
 | 
						|
        VISIBILITY_CHANGE_EVENT,
 | 
						|
        this._onVisibilityChange
 | 
						|
      );
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |