cleanup_() {
    // No-op if the listener was already removed.
    chrome.tabs.onUpdated.removeListener(this.onTabUpdated_);

    const streamToCleanUp = this.currentMediaStream_;
    this.currentMediaStream_ = null;
    if (streamToCleanUp) {
      // Clear the "on ended" callback to prevent recursive calls to this method
      // while the session and MediaStream are being torn down (below).
      streamToCleanUp.setOnStreamEnded(null);
    }

    const sessionToCleanUp = this.currentSession;
    this.currentSession = null;

    // Create a promise chain to execute the stopping of the session, invoke the
    // before/after stop callbacks, and thereafter stop the MediaStream. The
    // MediaStream is stopped after the session to avoid any extra churn in the
    // session shutdown process. All of this is conditional on whether a session
    // and/or MediaStream was ever started since cleanup_() is also used as an
    // all-purpose failed-start recovery handler.
    let cleanupPromise;
    if (sessionToCleanUp) {
      cleanupPromise =
          this.beforeCleanUpSession(sessionToCleanUp)
              .catch(
                  err =>
                      this.logger.error('Error in before-cleanup steps', err))
              .then(() => sessionToCleanUp.stop())
              .catch(err => this.logger.error('Error stopping session', err))
              .then(() => {
                this.mirrorServiceCallbacks_.onMirrorSessionEnded(
                    sessionToCleanUp.getRoute().id);
              })
              .catch(err => this.logger.error('Error in ended callbacks', err))
              .then(() => true);
    } else {
      cleanupPromise = Promise.resolve(false);
    }
    if (streamToCleanUp) {
      cleanupPromise = cleanupPromise.then(hadSession => {
        streamToCleanUp.stop();
        this.recordStreamEnded();
        return hadSession;
      });
    }

    return cleanupPromise;
  }
/**
   * @return {!Promise<boolean>} Fulfilled with true if there was a session
   *     and it was stopped. This promise never rejects.
   * @private
   */
@return {!Promise} Fulfilled with true if there was a session
and it was stopped. This promise never rejects.
@private
@return { !Promise } Fulfilled with true if there was a session and it was stopped . This promise never rejects . @private
cleanup_() {
    chrome.tabs.onUpdated.removeListener(this.onTabUpdated_);
    const streamToCleanUp = this.currentMediaStream_;
    this.currentMediaStream_ = null;
    if (streamToCleanUp) {
      streamToCleanUp.setOnStreamEnded(null);
    }
    const sessionToCleanUp = this.currentSession;
    this.currentSession = null;
    let cleanupPromise;
    if (sessionToCleanUp) {
      cleanupPromise =
          this.beforeCleanUpSession(sessionToCleanUp)
              .catch(
                  err =>
                      this.logger.error('Error in before-cleanup steps', err))
              .then(() => sessionToCleanUp.stop())
              .catch(err => this.logger.error('Error stopping session', err))
              .then(() => {
                this.mirrorServiceCallbacks_.onMirrorSessionEnded(
                    sessionToCleanUp.getRoute().id);
              })
              .catch(err => this.logger.error('Error in ended callbacks', err))
              .then(() => true);
    } else {
      cleanupPromise = Promise.resolve(false);
    }
    if (streamToCleanUp) {
      cleanupPromise = cleanupPromise.then(hadSession => {
        streamToCleanUp.stop();
        this.recordStreamEnded();
        return hadSession;
      });
    }
    return cleanupPromise;
  }
cleanup_ ( ) { chrome . tabs . onUpdated . removeListener ( this . onTabUpdated_ ) ; const streamToCleanUp = this . currentMediaStream_ ; this . currentMediaStream_ = null ; if ( streamToCleanUp ) { streamToCleanUp . setOnStreamEnded ( null ) ; } const sessionToCleanUp = this . currentSession ; this . currentSession = null ; let cleanupPromise ; if ( sessionToCleanUp ) { cleanupPromise = this . beforeCleanUpSession ( sessionToCleanUp ) . catch ( err => this . logger . error ( 'Error in before-cleanup steps' , err ) ) . then ( ( ) => sessionToCleanUp . stop ( ) ) . catch ( err => this . logger . error ( 'Error stopping session' , err ) ) . then ( ( ) => { this . mirrorServiceCallbacks_ . onMirrorSessionEnded ( sessionToCleanUp . getRoute ( ) . id ) ; } ) . catch ( err => this . logger . error ( 'Error in ended callbacks' , err ) ) . then ( ( ) => true ) ; } else { cleanupPromise = Promise . resolve ( false ) ; } if ( streamToCleanUp ) { cleanupPromise = cleanupPromise . then ( hadSession => { streamToCleanUp . stop ( ) ; this . recordStreamEnded ( ) ; return hadSession ; } ) ; } return cleanupPromise ; }
@return {!Promise<boolean>} Fulfilled with true if there was a session
     and it was stopped.
@return { !Promise<boolean > } Fulfilled with true if there was a session and it was stopped .
// No-op if the listener was already removed. // Clear the "on ended" callback to prevent recursive calls to this method // while the session and MediaStream are being torn down (below). // Create a promise chain to execute the stopping of the session, invoke the // before/after stop callbacks, and thereafter stop the MediaStream. The // MediaStream is stopped after the session to avoid any extra churn in the // session shutdown process. All of this is conditional on whether a session // and/or MediaStream was ever started since cleanup_() is also used as an // all-purpose failed-start recovery handler.