// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) {
  loadScript('mojo_bindings');
}
mojo.config.autoLoadMojomDeps = false;

loadScript('chrome/common/media_router/mojo/media_controller.mojom');
loadScript('chrome/common/media_router/mojo/media_router.mojom');
loadScript('chrome/common/media_router/mojo/media_status.mojom');
loadScript('extensions/common/mojo/keep_alive.mojom');
loadScript('media/mojo/interfaces/mirror_service_remoting.mojom');
loadScript('media/mojo/interfaces/remoting_common.mojom');
loadScript('mojo/common/time.mojom');
loadScript('net/interfaces/ip_address.mojom');
loadScript('net/interfaces/ip_endpoint.mojom');
loadScript('url/mojo/origin.mojom');
loadScript('url/mojo/url.mojom');

// The following adapter classes preserve backward compatibility for the media
// router component extension.
// TODO(crbug.com/787128): Remove these adapters.

function assignFields(object, fields) {
  for(var field in fields) {
    if (object.hasOwnProperty(field))
      object[field] = fields[field];
  }
}

/**
 * Adapter for mediaRouter.mojom.DialMediaSink.
 * @constructor
 */
function DialMediaSinkAdapter(fields) {
  this.ip_address = null;
  this.model_name = null;
  this.app_url = null;

  assignFields(this, fields);
}

DialMediaSinkAdapter.fromNewVersion = function(other) {
  return new DialMediaSinkAdapter({
    'ip_address': IPAddressAdapter.fromNewVersion(other.ipAddress),
    'model_name': other.modelName,
    'app_url': other.appUrl,
  });
};

DialMediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.DialMediaSink({
    'ipAddress' : this.ip_address.toNewVersion(),
    'modelName' : this.model_name,
    'appUrl' : this.app_url,
  });
};

/**
 * Adapter for mediaRouter.mojom.CastMediaSink.
 * @constructor
 */
function CastMediaSinkAdapter(fields) {
  this.ip_endpoint = null;
  this.model_name = null;
  this.capabilities = 0;
  this.cast_channel_id = 0;

  assignFields(this, fields);
}

CastMediaSinkAdapter.fromNewVersion = function(other) {
  return new CastMediaSinkAdapter({
    'ip_endpoint': IPEndpointAdapter.fromNewVersion(other.ipEndpoint),
    'model_name': other.modelName,
    'capabilities': other.capabilities,
    'cast_channel_id': other.castChannelId,
  });
};

CastMediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.CastMediaSink({
    'ipEndpoint': this.ip_endpoint.toNewVersion(),
    'modelName': this.model_name,
    'capabilities': this.capabilities,
    'castChannelId': this.cast_channel_id,
  });
};

/**
 * Adapter for mediaRouter.mojom.HangoutsMediaStatusExtraData.
 * @constructor
 */
function HangoutsMediaStatusExtraDataAdapter(fields) {
  this.local_present = false;

  assignFields(this, fields);
}

HangoutsMediaStatusExtraDataAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.HangoutsMediaStatusExtraData({
    'localPresent': this.local_present,
  });
};

/**
 * Adapter for net.interfaces.IPAddress.
 * @constructor
 */
function IPAddressAdapter(fields) {
  this.address_bytes = null;

  assignFields(this, fields);
}

IPAddressAdapter.fromNewVersion = function(other) {
  return new IPAddressAdapter({
    'address_bytes': other.addressBytes,
  });
};

IPAddressAdapter.prototype.toNewVersion = function() {
  return new net.interfaces.IPAddress({
    'addressBytes': this.address_bytes,
  });
};

/**
 * Adapter for net.interfaces.IPEndpoint.
 * @constructor
 */
function IPEndpointAdapter(fields) {
  this.address = null;
  this.port = 0;

  assignFields(this, fields);
}

IPEndpointAdapter.fromNewVersion = function(other) {
  return new IPEndpointAdapter({
    'address': IPAddressAdapter.fromNewVersion(other.address),
    'port': other.port,
  });
};

IPEndpointAdapter.prototype.toNewVersion = function() {
  return new net.interfaces.IPEndpoint({
    'address': this.address.toNewVersion(),
    'port': this.port,
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaStatus.
 * @constructor
 */
function MediaStatusAdapter(fields) {
  this.title = null;
  this.description = null;
  this.can_play_pause = false;
  this.can_mute = false;
  this.can_set_volume = false;
  this.can_seek = false;
  this.is_muted = false;
  this.play_state = 0;
  this.volume = 0;
  this.duration = null;
  this.current_time = null;
  this.hangouts_extra_data = null;

  assignFields(this, fields);
}

MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState;

MediaStatusAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.MediaStatus({
    'title': this.title,
    'description': this.description,
    'canPlayPause': this.can_play_pause,
    'canMute': this.can_mute,
    'canSetVolume': this.can_set_volume,
    'canSeek': this.can_seek,
    'isMuted': this.is_muted,
    'playState': this.play_state,
    'volume': this.volume,
    'duration': this.duration,
    'currentTime': this.current_time,
    'hangoutsExtraData':
        this.hangouts_extra_data && this.hangouts_extra_data.toNewVersion(),
  });
};

/**
 * Adapter for media.mojom.RemotingSinkMetadata.
 * @constructor
 */
function RemotingSinkMetadataAdapter(fields) {
  this.features = null;
  this.audio_capabilities = null;
  this.video_capabilities = null;
  this.friendly_name = null;

  assignFields(this, fields);
}

RemotingSinkMetadataAdapter.fromNewVersion = function(other) {
  return new RemotingSinkMetadataAdapter({
    'features': other.features,
    'audio_capabilities': other.audioCapabilities,
    'video_capabilities': other.videoCapabilities,
    'friendly_name': other.friendlyName,
  });
};

RemotingSinkMetadataAdapter.prototype.toNewVersion = function() {
  return new media.mojom.RemotingSinkMetadata({
    'features': this.features,
    'audioCapabilities': this.audio_capabilities,
    'videoCapabilities': this.video_capabilities,
    'friendlyName': this.friendly_name,
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaSink.
 * @constructor
 */
function MediaSinkAdapter(fields) {
  this.sink_id = null;
  this.name = null;
  this.description = null;
  this.domain = null;
  this.icon_type = 0;
  this.extra_data = null;

  assignFields(this, fields);
}

MediaSinkAdapter.fromNewVersion = function(other) {
  return new MediaSinkAdapter({
    'sink_id': other.sinkId,
    'name': other.name,
    'description': other.description,
    'domain': other.domain,
    'icon_type': other.iconType,
    'extra_data': other.extraData &&
        MediaSinkExtraDataAdapter.fromNewVersion(other.extraData),
  });
};

MediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.MediaSink({
    'sinkId': this.sink_id,
    'name': this.name,
    'description': this.description,
    'domain': this.domain,
    'iconType': this.icon_type,
    'extraData': this.extra_data && this.extra_data.toNewVersion(),
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaSinkExtraData.
 * @constructor
 */
function MediaSinkExtraDataAdapter(value) {
  this.$data = null;
  this.$tag = undefined;

  if (value == undefined) {
    return;
  }

  var keys = Object.keys(value);
  if (keys.length == 0) {
    return;
  }

  if (keys.length > 1) {
    throw new TypeError('You may set only one member on a union.');
  }

  var fields = [
    'dial_media_sink',
    'cast_media_sink',
  ];

  if (fields.indexOf(keys[0]) < 0) {
    throw new ReferenceError(keys[0] +
        ' is not a MediaSinkExtraDataAdapter member.');
  }

  this[keys[0]] = value[keys[0]];
}

MediaSinkExtraDataAdapter.Tags = {
  dial_media_sink: 0,
  cast_media_sink: 1,
};

Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', {
  get: function() {
    if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
      throw new ReferenceError(
          'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.');
    }
    return this.$data;
  },

  set: function(value) {
    this.$tag = MediaSinkExtraDataAdapter.Tags.dial_media_sink;
    this.$data = value;
  }
});

Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', {
  get: function() {
    if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) {
      throw new ReferenceError(
          'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.');
    }
    return this.$data;
  },

  set: function(value) {
    this.$tag = MediaSinkExtraDataAdapter.Tags.cast_media_sink;
    this.$data = value;
  }
});

MediaSinkExtraDataAdapter.fromNewVersion = function(other) {
  if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) {
    return new MediaSinkExtraDataAdapter({
      'dial_media_sink':
          DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink),
    });
  } else {
    return new MediaSinkExtraDataAdapter({
      'cast_media_sink':
          CastMediaSinkAdapter.fromNewVersion(other.castMediaSink),
    });
  }
};

MediaSinkExtraDataAdapter.prototype.toNewVersion = function() {
  if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
    return new mediaRouter.mojom.MediaSinkExtraData({
      'dialMediaSink': this.dial_media_sink.toNewVersion(),
    });
  } else {
    return new mediaRouter.mojom.MediaSinkExtraData({
      'castMediaSink': this.cast_media_sink.toNewVersion(),
    });
  }
};

/**
 * Adapter for media.mojom.MirrorServiceRemoterPtr.
 * @constructor
 */
function MirrorServiceRemoterPtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MirrorServiceRemoterAdapter,
                                             handleOrPtrInfo);
}

MirrorServiceRemoterPtrAdapter.prototype =
    Object.create(media.mojom.MirrorServiceRemoterPtr.prototype);
MirrorServiceRemoterPtrAdapter.prototype.constructor =
    MirrorServiceRemoterPtrAdapter;

MirrorServiceRemoterPtrAdapter.prototype.startDataStreams = function() {
  return MirrorServiceRemoterProxy.prototype.startDataStreams
      .apply(this.ptr.getProxy(), arguments).then(function(response) {
    return Promise.resolve({
      'audio_stream_id': response.audioStreamId,
      'video_stream_id': response.videoStreamId,
    });
  });
};

/**
 * Adapter for media.mojom.MirrorServiceRemoter.stubclass.
 * @constructor
 */
function MirrorServiceRemoterStubAdapter(delegate) {
  this.delegate_ = delegate;
}

MirrorServiceRemoterStubAdapter.prototype = Object.create(
    media.mojom.MirrorServiceRemoter.stubClass.prototype);
MirrorServiceRemoterStubAdapter.prototype.constructor =
    MirrorServiceRemoterStubAdapter;

MirrorServiceRemoterStubAdapter.prototype.startDataStreams =
    function(hasAudio, hasVideo) {
  return this.delegate_ && this.delegate_.startDataStreams &&
      this.delegate_.startDataStreams(hasAudio, hasVideo).then(
          function(response) {
            return {
              'audioStreamId': response.audio_stream_id,
              'videoStreamId': response.video_stream_id,
            };
          });
};

/**
 * Adapter for media.mojom.MirrorServiceRemoter.
 */
var MirrorServiceRemoterAdapter = {
    name: 'media::mojom::MirrorServiceRemoter',
    kVersion: 0,
    ptrClass: MirrorServiceRemoterPtrAdapter,
    proxyClass: media.mojom.MirrorServiceRemoter.proxyClass,
    stubClass: MirrorServiceRemoterStubAdapter,
    validateRequest: media.mojom.MirrorServiceRemoter.validateRequest,
    validateResponse: media.mojom.MirrorServiceRemoter.validateResponse,
};

/**
 * Adapter for media.mojom.MirrorServiceRemotingSourcePtr.
 * @constructor
 */
function MirrorServiceRemotingSourcePtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MirrorServiceRemotingSourceAdapter,
                                             handleOrPtrInfo);
}

MirrorServiceRemotingSourcePtrAdapter.prototype =
    Object.create(media.mojom.MirrorServiceRemotingSourcePtr.prototype);
MirrorServiceRemotingSourcePtrAdapter.prototype.constructor =
    MirrorServiceRemotingSourcePtrAdapter;

MirrorServiceRemotingSourcePtrAdapter.prototype.onSinkAvailable =
    function(metadata) {
  return this.ptr.getProxy().onSinkAvailable(metadata.toNewVersion());
};

/**
 * Adapter for media.mojom.MirrorServiceRemotingSource.
 */
var MirrorServiceRemotingSourceAdapter = {
    name: 'media::mojom::MirrorServiceRemotingSource',
    kVersion: 0,
    ptrClass: MirrorServiceRemotingSourcePtrAdapter,
    proxyClass: media.mojom.MirrorServiceRemotingSource.proxyClass,
    stubClass: null,
    validateRequest: media.mojom.MirrorServiceRemotingSource.validateRequest,
    validateResponse: null,
};

/**
 * Adapter for mediaRouter.mojom.MediaStatusObserver.
 * @constructor
 */
function MediaStatusObserverPtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MediaStatusObserverAdapter,
                                             handleOrPtrInfo);
}

MediaStatusObserverPtrAdapter.prototype =
    Object.create(mediaRouter.mojom.MediaStatusObserverPtr.prototype);
MediaStatusObserverPtrAdapter.prototype.constructor =
    MediaStatusObserverPtrAdapter;

MediaStatusObserverPtrAdapter.prototype.onMediaStatusUpdated =
    function(status) {
  return this.ptr.getProxy().onMediaStatusUpdated(status.toNewVersion());
};

/**
 * Adapter for mediaRouter.mojom.MediaStatusObserver.
 */
var MediaStatusObserverAdapter = {
  name: 'mediaRouter::mojom::MediaStatusObserver',
  kVersion: 0,
  ptrClass: MediaStatusObserverPtrAdapter,
  proxyClass: mediaRouter.mojom.MediaStatusObserver.proxyClass,
  stubClass: null,
  validateRequest: mediaRouter.mojom.MediaStatusObserver.validateRequest,
  validateResponse: null,
};

/**
 * Converts a media sink to a MediaSink Mojo object.
 * @param {!MediaSink} sink A media sink.
 * @return {!mediaRouter.mojom.MediaSink} A Mojo MediaSink object.
 */
function sinkToMojo_(sink) {
  return new mediaRouter.mojom.MediaSink({
    'name': sink.friendlyName,
    'description': sink.description,
    'domain': sink.domain,
    'sinkId': sink.id,
    'iconType': sinkIconTypeToMojo(sink.iconType),
    'provider_id': mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
  });
}

/**
 * Converts a media sink's icon type to a MediaSink.IconType Mojo object.
 * @param {!MediaSink.IconType} type A media sink's icon type.
 * @return {!mediaRouter.mojom.MediaSink.IconType} A Mojo MediaSink.IconType
 *     object.
 */
function sinkIconTypeToMojo(type) {
  switch (type) {
    case 'cast':
      return mediaRouter.mojom.SinkIconType.CAST;
    case 'cast_audio_group':
      return mediaRouter.mojom.SinkIconType.CAST_AUDIO_GROUP;
    case 'cast_audio':
      return mediaRouter.mojom.SinkIconType.CAST_AUDIO;
    case 'meeting':
      return mediaRouter.mojom.SinkIconType.MEETING;
    case 'hangout':
      return mediaRouter.mojom.SinkIconType.HANGOUT;
    case 'education':
      return mediaRouter.mojom.SinkIconType.EDUCATION;
    case 'generic':
      return mediaRouter.mojom.SinkIconType.GENERIC;
    default:
      console.error('Unknown sink icon type : ' + type);
      return mediaRouter.mojom.SinkIconType.GENERIC;
  }
}

/**
 * Returns a Mojo MediaRoute object given a MediaRoute and a
 * media sink name.
 * @param {!MediaRoute} route
 * @return {!mediaRouter.mojom.MediaRoute}
 */
function routeToMojo_(route) {
  return new mediaRouter.mojom.MediaRoute({
    'mediaRouteId': route.id,
    'mediaSource': route.mediaSource,
    'mediaSinkId': route.sinkId,
    'description': route.description,
    'iconUrl': route.iconUrl,
    'isLocal': route.isLocal,
    'customControllerPath': route.customControllerPath || '',
    'forDisplay': route.forDisplay,
    'isIncognito': route.offTheRecord,
    'isLocalPresentation': route.isOffscreenPresentation,
    'supportsMediaRouteController': route.supportsMediaRouteController,
    'controllerType': route.controllerType,
    // Begin newly added properties, followed by the milestone they were
    // added.  The guard should be safe to remove N+2 milestones later.
    'presentationId': route.presentationId || ''  // M64
  });
}

/**
 * Converts a route message to a RouteMessage Mojo object.
 * @param {!RouteMessage} message
 * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object.
 */
function messageToMojo_(message) {
  if ("string" == typeof message.message) {
    return new mediaRouter.mojom.RouteMessage({
      'type': mediaRouter.mojom.RouteMessage.Type.TEXT,
      'message': message.message,
    });
  } else {
    return new mediaRouter.mojom.RouteMessage({
      'type': mediaRouter.mojom.RouteMessage.Type.BINARY,
      'data': message.message,
    });
  }
}

/**
 * Converts presentation connection state to Mojo enum value.
 * @param {!string} state
 * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionState}
 */
function presentationConnectionStateToMojo_(state) {
  var PresentationConnectionState =
      mediaRouter.mojom.MediaRouter.PresentationConnectionState;
  switch (state) {
    case 'connecting':
      return PresentationConnectionState.CONNECTING;
    case 'connected':
      return PresentationConnectionState.CONNECTED;
    case 'closed':
      return PresentationConnectionState.CLOSED;
    case 'terminated':
      return PresentationConnectionState.TERMINATED;
    default:
      console.error('Unknown presentation connection state: ' + state);
      return PresentationConnectionState.TERMINATED;
  }
}

/**
 * Converts presentation connection close reason to Mojo enum value.
 * @param {!string} reason
 * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason}
 */
function presentationConnectionCloseReasonToMojo_(reason) {
  var PresentationConnectionCloseReason =
      mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason;
  switch (reason) {
    case 'error':
      return PresentationConnectionCloseReason.CONNECTION_ERROR;
    case 'closed':
      return PresentationConnectionCloseReason.CLOSED;
    case 'went_away':
      return PresentationConnectionCloseReason.WENT_AWAY;
    default:
      console.error('Unknown presentation connection close reason : ' +
          reason);
      return PresentationConnectionCloseReason.CONNECTION_ERROR;
  }
}

/**
 * Parses the given route request Error object and converts it to the
 * corresponding result code.
 * @param {!Error} error
 * @return {!mediaRouter.mojom.RouteRequestResultCode}
 */
function getRouteRequestResultCode_(error) {
  return error.errorCode ? error.errorCode :
    mediaRouter.mojom.RouteRequestResultCode.UNKNOWN_ERROR;
}

/**
 * Creates and returns a successful route response from given route.
 * @param {!MediaRoute} route
 * @return {!Object}
 */
function toSuccessRouteResponse_(route) {
  return {
      route: routeToMojo_(route),
      resultCode: mediaRouter.mojom.RouteRequestResultCode.OK
  };
}

/**
 * Creates and returns a error route response from given Error object.
 * @param {!Error} error
 * @return {!Object}
 */
function toErrorRouteResponse_(error) {
  return {
      errorText: error.message,
      resultCode: getRouteRequestResultCode_(error)
  };
}

/**
 * Creates a new MediaRouter.
 * Converts a route struct to its Mojo form.
 * @param {!mediaRouter.mojom.MediaRouterPtr} service
 * @constructor
 */
function MediaRouter(service) {
  /**
   * The Mojo service proxy. Allows extension code to call methods that reside
   * in the browser.
   * @type {!mediaRouter.mojom.MediaRouterPtr}
   */
  this.service_ = service;

  /**
   * The provider manager service delegate. Its methods are called by the
   * browser-resident Mojo service.
   * @type {!MediaRouter}
   */
  this.mrpm_ = new MediaRouteProvider(this);

  /**
   * Handle to a KeepAlive service object, which prevents the extension from
   * being suspended as long as it remains in scope.
   * @type {boolean}
   */
  this.keepAlive_ = null;

  /**
   * The bindings to bind the service delegate to the Mojo interface.
   * Object must remain in scope for the lifetime of the connection to
   * prevent the connection from closing automatically.
   * @type {!mojo.Binding}
   */
  this.mediaRouteProviderBinding_ = new mojo.Binding(
      mediaRouter.mojom.MediaRouteProvider, this.mrpm_);
}

/**
 * Returns definitions of Mojo core and generated Mojom classes that can be
 * used directly by the component.
 * @return {!Object}
 * TODO(imcheng): We should export these along with MediaRouter. This requires
 * us to modify the component to handle multiple exports. When that logic is
 * baked in for a couple of milestones, we should be able to remove this
 * method.
 * TODO(imcheng): We should stop exporting mojo bindings classes that the
 * Media Router extension doesn't directly use, such as
 * mojo.AssociatedInterfacePtrInfo, mojo.InterfacePtrController and
 * mojo.interfaceControl.
 */
MediaRouter.prototype.getMojoExports = function() {
  return {
    AssociatedInterfacePtrInfo: mojo.AssociatedInterfacePtrInfo,
    Binding: mojo.Binding,
    DialMediaSink: DialMediaSinkAdapter,
    CastMediaSink: CastMediaSinkAdapter,
    HangoutsMediaRouteController:
        mediaRouter.mojom.HangoutsMediaRouteController,
    HangoutsMediaStatusExtraData: HangoutsMediaStatusExtraDataAdapter,
    IPAddress: IPAddressAdapter,
    IPEndpoint: IPEndpointAdapter,
    InterfacePtrController: mojo.InterfacePtrController,
    InterfacePtrInfo: mojo.InterfacePtrInfo,
    InterfaceRequest: mojo.InterfaceRequest,
    MediaController: mediaRouter.mojom.MediaController,
    MediaStatus: MediaStatusAdapter,
    MediaStatusObserverPtr: mediaRouter.mojom.MediaStatusObserverPtr,
    MirrorServiceRemoter: MirrorServiceRemoterAdapter,
    MirrorServiceRemoterPtr: MirrorServiceRemoterPtrAdapter,
    MirrorServiceRemotingSourcePtr: MirrorServiceRemotingSourcePtrAdapter,
    RemotingStopReason: media.mojom.RemotingStopReason,
    RemotingStartFailReason: media.mojom.RemotingStartFailReason,
    RemotingSinkFeature: media.mojom.RemotingSinkFeature,
    RemotingSinkAudioCapability:
        media.mojom.RemotingSinkAudioCapability,
    RemotingSinkVideoCapability:
        media.mojom.RemotingSinkVideoCapability,
    RemotingSinkMetadata: RemotingSinkMetadataAdapter,
    RouteControllerType: mediaRouter.mojom.RouteControllerType,
    Origin: url.mojom.Origin,
    Sink: MediaSinkAdapter,
    SinkExtraData: MediaSinkExtraDataAdapter,
    TimeDelta: mojo.common.mojom.TimeDelta,
    Url: url.mojom.Url,
    interfaceControl: mojo.interfaceControl,
    makeRequest: mojo.makeRequest,
  };
};

/**
 * Registers the Media Router Provider Manager with the Media Router.
 * @return {!Promise<Object>} Instance ID and config for the Media Router.
 */
MediaRouter.prototype.start = function() {
  return this.service_.registerMediaRouteProvider(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
      this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then(
          function(response) {
            return {
              'enable_dial_discovery': response.enableDialDiscovery,
              'enable_cast_discovery': response.enableCastDiscovery,
            };
          });
}

/**
 * Sets the service delegate methods.
 * @param {Object} handlers
 */
MediaRouter.prototype.setHandlers = function(handlers) {
  this.mrpm_.setHandlers(handlers);
}

/**
 * The keep alive status.
 * @return {boolean}
 */
MediaRouter.prototype.getKeepAlive = function() {
  return this.keepAlive_ != null;
};

/**
 * Called by the provider manager when a sink list for a given source is
 * updated.
 * @param {!string} sourceUrn
 * @param {!Array<!MediaSink>} sinks
 * @param {!Array<!url.mojom.Origin>} origins
 */
MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) {
  this.service_.onSinksReceived(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, sourceUrn,
      sinks.map(sinkToMojo_), origins);
};

/**
 * Called by the provider manager when a sink is found to notify the MR of the
 * sink's ID. The actual sink will be returned through the normal sink list
 * update process, so this helps the MR identify the search result in the
 * list.
 * @param {string} pseudoSinkId  ID of the pseudo sink that started the
 *     search.
 * @param {string} sinkId ID of the newly-found sink.
 */
MediaRouter.prototype.onSearchSinkIdReceived = function(
    pseudoSinkId, sinkId) {
  this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId);
};

/**
 * Called by the provider manager to keep the extension from suspending
 * if it enters a state where suspension is undesirable (e.g. there is an
 * active MediaRoute.)
 * If keepAlive is true, the extension is kept alive.
 * If keepAlive is false, the extension is allowed to suspend.
 * @param {boolean} keepAlive
 */
MediaRouter.prototype.setKeepAlive = function(keepAlive) {
  if (keepAlive === false && this.keepAlive_) {
    this.keepAlive_.ptr.reset();
    this.keepAlive_ = null;
  } else if (keepAlive === true && !this.keepAlive_) {
    this.keepAlive_ = new extensions.KeepAlivePtr;
    Mojo.bindInterface(extensions.KeepAlive.name,
                       mojo.makeRequest(this.keepAlive_).handle);
  }
};

/**
 * Called by the provider manager to send an issue from a media route
 * provider to the Media Router, to show the user.
 * @param {!Object} issue The issue object.
 */
MediaRouter.prototype.onIssue = function(issue) {
  function issueSeverityToMojo_(severity) {
    switch (severity) {
      case 'fatal':
        return mediaRouter.mojom.Issue.Severity.FATAL;
      case 'warning':
        return mediaRouter.mojom.Issue.Severity.WARNING;
      case 'notification':
        return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
      default:
        console.error('Unknown issue severity: ' + severity);
        return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
    }
  }

  function issueActionToMojo_(action) {
    switch (action) {
      case 'dismiss':
        return mediaRouter.mojom.Issue.ActionType.DISMISS;
      case 'learn_more':
        return mediaRouter.mojom.Issue.ActionType.LEARN_MORE;
      default:
        console.error('Unknown issue action type : ' + action);
        return mediaRouter.mojom.Issue.ActionType.OK;
    }
  }

  var secondaryActions = (issue.secondaryActions || []).map(issueActionToMojo_);
  this.service_.onIssue(new mediaRouter.mojom.Issue({
    'routeId': issue.routeId || '',
    'severity': issueSeverityToMojo_(issue.severity),
    'title': issue.title,
    'message': issue.message || '',
    'defaultAction': issueActionToMojo_(issue.defaultAction),
    'secondaryActions': secondaryActions,
    'helpPageId': issue.helpPageId,
    'isBlocking': issue.isBlocking
  }));
};

/**
 * Called by the provider manager when the set of active routes
 * has been updated.
 * @param {!Array<MediaRoute>} routes The active set of media routes.
 * @param {string=} sourceUrn The sourceUrn associated with this route
 *     query.
 * @param {Array<string>=} joinableRouteIds The active set of joinable
 *     media routes.
 */
MediaRouter.prototype.onRoutesUpdated = function(
    routes, sourceUrn = '', joinableRouteIds = []) {
  this.service_.onRoutesUpdated(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
      routes.map(routeToMojo_), sourceUrn, joinableRouteIds);
};

/**
 * Called by the provider manager when sink availability has been updated.
 * @param {!mediaRouter.mojom.MediaRouter.SinkAvailability} availability
 *     The new sink availability.
 */
MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) {
  this.service_.onSinkAvailabilityUpdated(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, availability);
};

/**
 * Called by the provider manager when the state of a presentation connected
 * to a route has changed.
 * @param {string} routeId
 * @param {string} state
 */
MediaRouter.prototype.onPresentationConnectionStateChanged =
    function(routeId, state) {
  this.service_.onPresentationConnectionStateChanged(
      routeId, presentationConnectionStateToMojo_(state));
};

/**
 * Called by the provider manager when the state of a presentation connected
 * to a route has closed.
 * @param {string} routeId
 * @param {string} reason
 * @param {string} message
 */
MediaRouter.prototype.onPresentationConnectionClosed =
    function(routeId, reason, message) {
  this.service_.onPresentationConnectionClosed(
      routeId, presentationConnectionCloseReasonToMojo_(reason), message);
};

/**
 * @param {string} routeId
 * @param {!Array<!RouteMessage>} mesages
 */
MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) {
  this.service_.onRouteMessagesReceived(
      routeId, messages.map(messageToMojo_));
};

/**
 * @param {number} tabId
 * @param {!media.mojom.MirrorServiceRemoterPtr} remoter
 * @param {!mojo.InterfaceRequest} remotingSource
 */
MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter,
    remotingSource) {
  this.service_.onMediaRemoterCreated(
      tabId,
      new media.mojom.MirrorServiceRemoterPtr(remoter.ptr.passInterface()),
      remotingSource);
}

/**
 * Object containing callbacks set by the provider manager.
 *
 * @constructor
 * @struct
 */
function MediaRouterHandlers() {
  /**
   * @type {function(!string, !string, !string, !string, !number)}
   */
  this.createRoute = null;

  /**
   * @type {function(!string, !string, !string, !number)}
   */
  this.joinRoute = null;

  /**
   * @type {function(string): Promise}
   */
  this.terminateRoute = null;

  /**
   * @type {function(string)}
   */
  this.startObservingMediaSinks = null;

  /**
   * @type {function(string)}
   */
  this.stopObservingMediaSinks = null;

  /**
   * @type {function(string, string): Promise}
   */
  this.sendRouteMessage = null;

  /**
   * @type {function(string, Uint8Array): Promise}
   */
  this.sendRouteBinaryMessage = null;

  /**
   * @type {function(string)}
   */
  this.startListeningForRouteMessages = null;

  /**
   * @type {function(string)}
   */
  this.stopListeningForRouteMessages = null;

  /**
   * @type {function(string)}
   */
  this.detachRoute = null;

  /**
   * @type {function()}
   */
  this.startObservingMediaRoutes = null;

  /**
   * @type {function()}
   */
  this.stopObservingMediaRoutes = null;

  /**
   * @type {function()}
   */
  this.connectRouteByRouteId = null;

  /**
   * @type {function()}
   */
  this.enableMdnsDiscovery = null;

  /**
   * @type {function()}
   */
  this.updateMediaSinks = null;

  /**
   * @type {function(string, string, !SinkSearchCriteria): string}
   */
  this.searchSinks = null;

  /**
   * @type {function()}
   */
  this.provideSinks = null;

  /**
   * @type {function(string, !mojo.InterfaceRequest,
   *            !mediaRouter.mojom.MediaStatusObserverPtr): !Promise<void>}
   */
  this.createMediaRouteController = null;
};

/**
 * Routes calls from Media Router to the provider manager extension.
 * Registered with the MediaRouter stub.
 * @param {!MediaRouter} MediaRouter proxy to call into the
 * Media Router mojo interface.
 * @constructor
 */
function MediaRouteProvider(mediaRouter) {
  /**
   * Object containing JS callbacks into Provider Manager code.
   * @type {!MediaRouterHandlers}
   */
  this.handlers_ = new MediaRouterHandlers();

  /**
   * Proxy class to the browser's Media Router Mojo service.
   * @type {!MediaRouter}
   */
  this.mediaRouter_ = mediaRouter;
}

/*
 * Sets the callback handler used to invoke methods in the provider manager.
 *
 * @param {!MediaRouterHandlers} handlers
 */
MediaRouteProvider.prototype.setHandlers = function(handlers) {
  this.handlers_ = handlers;
  var requiredHandlers = [
    'stopObservingMediaRoutes',
    'startObservingMediaRoutes',
    'sendRouteMessage',
    'sendRouteBinaryMessage',
    'startListeningForRouteMessages',
    'stopListeningForRouteMessages',
    'detachRoute',
    'terminateRoute',
    'joinRoute',
    'createRoute',
    'stopObservingMediaSinks',
    'startObservingMediaRoutes',
    'connectRouteByRouteId',
    'enableMdnsDiscovery',
    'updateMediaSinks',
    'searchSinks',
    'provideSinks',
    'createMediaRouteController',
    'onBeforeInvokeHandler'
  ];
  requiredHandlers.forEach(function(nextHandler) {
    if (handlers[nextHandler] === undefined) {
      console.error(nextHandler + ' handler not registered.');
    }
  });
}

/**
 * Starts querying for sinks capable of displaying the media source
 * designated by |sourceUrn|.  Results are returned by calling
 * OnSinksReceived.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.startObservingMediaSinks =
    function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startObservingMediaSinks(sourceUrn);
};

/**
 * Stops querying for sinks capable of displaying |sourceUrn|.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.stopObservingMediaSinks =
    function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopObservingMediaSinks(sourceUrn);
};

/**
 * Requests that |sinkId| render the media referenced by |sourceUrn|. If the
 * request is from the Presentation API, then origin and tabId will
 * be populated.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} sinkId Media sink ID.
 * @param {!string} presentationId Presentation ID from the site
 *     requesting presentation. TODO(mfoltz): Remove.
 * @param {!url.mojom.Origin} origin Origin of site requesting presentation.
 * @param {!number} tabId ID of tab requesting presentation.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.createRoute =
    function(sourceUrn, sinkId, presentationId, origin, tabId,
             timeout, incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.createRoute(
      sourceUrn, sinkId, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Handles a request via the Presentation API to join an existing route given
 * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for
 * validating same-origin/tab scope.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} presentationId Presentation ID to join.
 * @param {!url.mojom.Origin} origin Origin of site requesting join.
 * @param {!number} tabId ID of tab requesting join.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.joinRoute =
    function(sourceUrn, presentationId, origin, tabId, timeout,
             incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.joinRoute(
      sourceUrn, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Handles a request via the Presentation API to join an existing route given
 * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for
 * validating same-origin/tab scope.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} routeId Route ID to join.
 * @param {!string} presentationId Presentation ID to join.
 * @param {!url.mojom.Origin} origin Origin of site requesting join.
 * @param {!number} tabId ID of tab requesting join.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.connectRouteByRouteId =
    function(sourceUrn, routeId, presentationId, origin, tabId,
             timeout, incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.connectRouteByRouteId(
      sourceUrn, routeId, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Terminates the route specified by |routeId|.
 * @param {!string} routeId
 * @return {!Promise<!Object>} A Promise resolving to an object describing
 *    the result of the terminate operation, or rejecting with an error
 *    message and code if the operation failed.
 */
MediaRouteProvider.prototype.terminateRoute = function(routeId) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.terminateRoute(routeId).then(
      () => ({resultCode: mediaRouter.mojom.RouteRequestResultCode.OK}),
      (err) => toErrorRouteResponse_(err));
};

/**
 * Posts a message to the route designated by |routeId|.
 * @param {!string} routeId
 * @param {!string} message
 * @return {!Promise.<boolean>} Resolved with true if the message was sent,
 *    or false on failure.
 */
MediaRouteProvider.prototype.sendRouteMessage = function(
  routeId, message) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.sendRouteMessage(routeId, message)
      .then(function() {
        return {'sent': true};
      }, function() {
        return {'sent': false};
      });
};

/**
 * Sends a binary message to the route designated by |routeId|.
 * @param {!string} routeId
 * @param {!Array<number>} data
 * @return {!Promise.<boolean>} Resolved with true if the data was sent,
 *    or false on failure.
 */
MediaRouteProvider.prototype.sendRouteBinaryMessage = function(
  routeId, data) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data))
      .then(function() {
        return {'sent': true};
      }, function() {
        return {'sent': false};
      });
};

/**
 * Listen for messages from a route.
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.startListeningForRouteMessages = function(
    routeId) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startListeningForRouteMessages(routeId);
};

/**
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.stopListeningForRouteMessages = function(
    routeId) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopListeningForRouteMessages(routeId);
};

/**
 * Indicates that the presentation connection that was connected to |routeId|
 * is no longer connected to it.
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.detachRoute = function(
    routeId) {
  this.handlers_.detachRoute(routeId);
};

/**
 * Requests that the provider manager start sending information about active
 * media routes to the Media Router.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startObservingMediaRoutes(sourceUrn);
};

/**
 * Requests that the provider manager stop sending information about active
 * media routes to the Media Router.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopObservingMediaRoutes(sourceUrn);
};

/**
 * Enables mDNS device discovery.
 */
MediaRouteProvider.prototype.enableMdnsDiscovery = function() {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.enableMdnsDiscovery();
};

/**
 * Requests that the provider manager update media sinks.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.updateMediaSinks(sourceUrn);
};

/**
 * Requests that the provider manager search its providers for a sink matching
 * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found
 * that can be used immediately for route creation, its ID is returned.
 * Otherwise the empty string is returned.
 *
 * @param {string} sinkId Sink ID of the pseudo sink generating the request.
 * @param {string} sourceUrn Media source to be used with the sink.
 * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route
 *     providers.
 * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the
 *     sink ID of the sink found by the search that can be used for route
 *     creation, or the empty string if no route can be immediately created.
 */
MediaRouteProvider.prototype.searchSinks = function(
    sinkId, sourceUrn, searchCriteria) {
  this.handlers_.onBeforeInvokeHandler();
 return this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria).then(
      sinkId => {
        return { 'sinkId': sinkId };
      },
      () => {
        return { 'sinkId': '' };
      });
};

/**
 * Notifies the provider manager that MediaRouter has discovered a list of
 * sinks.
 * @param {string} providerName
 * @param {!Array<!mediaRouter.mojom.MediaSink>} sinks
 */
MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.provideSinks(providerName,
                              sinks.map(MediaSinkAdapter.fromNewVersion));
};

/**
 * Creates a controller for the given route and binds the given
 * InterfaceRequest to it, and registers an observer for media status updates
 * for the route.
 * @param {string} routeId
 * @param {!mojo.InterfaceRequest} controllerRequest
 * @param {!mediaRouter.mojom.MediaStatusObserverPtr} observer
 * @return {!Promise<!{success: boolean}>} Resolves to true if a controller
 *     is created. Resolves to false if a controller cannot be created, or if
 *     the controller is already bound.
 */
MediaRouteProvider.prototype.createMediaRouteController = function(
    routeId, controllerRequest, observer) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.createMediaRouteController(
      routeId, controllerRequest,
      new MediaStatusObserverPtrAdapter(observer.ptr.passInterface())).then(
          () => ({success: true}), e => ({success: false}));
};

var ptr = new mediaRouter.mojom.MediaRouterPtr;
Mojo.bindInterface(mediaRouter.mojom.MediaRouter.name,
                   mojo.makeRequest(ptr).handle);
exports.$set('returnValue', new MediaRouter(ptr));
