forked from mirrors/gecko-dev
		
	Differential Revision: https://phabricator.services.mozilla.com/D5914 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			65 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
 | 
						|
import {perfService as perfSvc} from "common/PerfService.jsm";
 | 
						|
 | 
						|
const VISIBLE = "visible";
 | 
						|
const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 | 
						|
 | 
						|
export class DetectUserSessionStart {
 | 
						|
  constructor(store, options = {}) {
 | 
						|
    this._store = store;
 | 
						|
    // Overrides for testing
 | 
						|
    this.document = options.document || global.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);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |