async loadOfflineSession_(sessionId, sessionMetadata) {
    let session;

    const sessionType = 'persistent-license';

    try {
      shaka.log.v1('Attempting to load an offline session', sessionId);
      session = this.mediaKeys_.createSession(sessionType);
    } catch (exception) {
      const error = new shaka.util.Error(
          shaka.util.Error.Severity.CRITICAL,
          shaka.util.Error.Category.DRM,
          shaka.util.Error.Code.FAILED_TO_CREATE_SESSION,
          exception.message);
      this.onError_(error);
      return Promise.reject(error);
    }

    this.eventManager_.listen(session, 'message',
        /** @type {shaka.util.EventManager.ListenerType} */(
          (event) => this.onSessionMessage_(event)));
    this.eventManager_.listen(session, 'keystatuseschange',
        (event) => this.onKeyStatusesChange_(event));

    const metadata = {
      initData: sessionMetadata.initData,
      initDataType: sessionMetadata.initDataType,
      loaded: false,
      oldExpiration: Infinity,
      updatePromise: null,
      type: sessionType,
    };
    this.activeSessions_.set(session, metadata);

    try {
      const present = await session.load(sessionId);
      this.destroyer_.ensureNotDestroyed();
      shaka.log.v2('Loaded offline session', sessionId, present);

      if (!present) {
        this.activeSessions_.delete(session);

        const severity = this.config_.persistentSessionOnlinePlayback ?
            shaka.util.Error.Severity.RECOVERABLE :
            shaka.util.Error.Severity.CRITICAL;

        this.onError_(new shaka.util.Error(
            severity,
            shaka.util.Error.Category.DRM,
            shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));

        metadata.loaded = true;
      }

      this.setLoadSessionTimeoutTimer_(metadata);
      this.checkSessionsLoaded_();

      return session;
    } catch (error) {
      this.destroyer_.ensureNotDestroyed(error);

      this.activeSessions_.delete(session);

      const severity = this.config_.persistentSessionOnlinePlayback ?
          shaka.util.Error.Severity.RECOVERABLE :
          shaka.util.Error.Severity.CRITICAL;

      this.onError_(new shaka.util.Error(
          severity,
          shaka.util.Error.Category.DRM,
          shaka.util.Error.Code.FAILED_TO_CREATE_SESSION,
          error.message));

      metadata.loaded = true;

      this.checkSessionsLoaded_();
    }

    return Promise.resolve();
  }
@param {string} sessionId
@param {{initData: ?Uint8Array, initDataType: ?string}} sessionMetadata
@return {!Promise<MediaKeySession>}
@private