<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCPeerConnection.prototype.iceConnectionState</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
  'use strict';

  // Test is based on the following editor draft:
  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

  /*
    4.3.2.  Interface Definition
      interface RTCPeerConnection : EventTarget {
        ...
        readonly  attribute RTCIceConnectionState  iceConnectionState;
                  attribute EventHandler           oniceconnectionstatechange;
      };

    4.4.4 RTCIceConnectionState Enum
      enum RTCIceConnectionState {
        "new",
        "checking",
        "connected",
        "completed",
        "failed",
        "disconnected",
        "closed"
      };

    5.6.  RTCIceTransport Interface
      interface RTCIceTransport {
        readonly attribute RTCIceTransportState state;
                 attribute EventHandler         onstatechange;

        ...
      };

      enum RTCIceTransportState {
        "new",
        "checking",
        "connected",
        "completed",
        "failed",
        "disconnected",
        "closed"
      };
   */

  /*
    4.4.4 RTCIceConnectionState Enum
      new
        Any of the RTCIceTransports are in the new state and none of them
        are in the checking, failed or disconnected state, or all
        RTCIceTransport s are in the closed state.
   */
  test(t => {
    const pc = new RTCPeerConnection();
    assert_equals(pc.iceConnectionState, 'new');
  }, 'Initial iceConnectionState should be new');

  test(t => {
    const pc = new RTCPeerConnection();
    pc.close();
    assert_equals(pc.iceConnectionState, 'closed');
  }, 'Closing the connection should set iceConnectionState to closed');

  /*
    4.4.4 RTCIceConnectionState Enum
      checking
        Any of the RTCIceTransport s are in the checking state and none of
        them are in the failed or disconnected state.

      connected
        All RTCIceTransport s are in the connected, completed or closed state
        and at least one of them is in the connected state.

      completed
        All RTCIceTransport s are in the completed or closed state and at least
        one of them is in the completed state.

      checking
        The RTCIceTransport has received at least one remote candidate and
        is checking candidate pairs and has either not yet found a connection
        or consent checks [RFC7675] have failed on all previously successful
        candidate pairs. In addition to checking, it may also still be gathering.

    5.6.  enum RTCIceTransportState
      connected
        The RTCIceTransport has found a usable connection, but is still
        checking other candidate pairs to see if there is a better connection.
        It may also still be gathering and/or waiting for additional remote
        candidates. If consent checks [RFC7675] fail on the connection in use,
        and there are no other successful candidate pairs available, then the
        state transitions to "checking" (if there are candidate pairs remaining
        to be checked) or "disconnected" (if there are no candidate pairs to
        check, but the peer is still gathering and/or waiting for additional
        remote candidates).

      completed
        The RTCIceTransport has finished gathering, received an indication that
        there are no more remote candidates, finished checking all candidate
        pairs and found a connection. If consent checks [RFC7675] subsequently
        fail on all successful candidate pairs, the state transitions to "failed".
   */
  async_test(t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

    let had_checking = false;

    const onIceConnectionStateChange = t.step_func(() => {
      const {iceConnectionState} = pc1;
      if (iceConnectionState === 'checking') {
        had_checking = true;
      } else if (iceConnectionState === 'connected' ||
                 iceConnectionState === 'completed') {
        assert_true(had_checking, 'state should pass checking before' +
                                  ' reaching connected or completed');
        t.done();
      } else if (iceConnectionState === 'failed') {
        assert_unreached("ICE should not fail");
      }
    });

    pc1.createDataChannel('test');

    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
  }, 'connection with one data channel should eventually have connected or ' +
     'completed connection state');

async_test(t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();

    t.add_cleanup(() => pc2.close());

    const onIceConnectionStateChange = t.step_func(() => {
      const { iceConnectionState } = pc1;

      if(iceConnectionState === 'checking') {
        const iceTransport = pc1.sctp.transport.iceTransport;

        assert_equals(iceTransport.state, 'checking',
          'Expect ICE transport to be in checking state when' +
          ' iceConnectionState is checking');

      } else if(iceConnectionState === 'connected') {
        const iceTransport = pc1.sctp.transport.iceTransport;

        assert_equals(iceTransport.state, 'connected',
          'Expect ICE transport to be in connected state when' +
          ' iceConnectionState is connected');
        t.done();
      } else if(iceConnectionState === 'completed') {
        const iceTransport = pc1.sctp.transport.iceTransport;

        assert_equals(iceTransport.state, 'completed',
          'Expect ICE transport to be in connected state when' +
          ' iceConnectionState is completed');
        t.done();
      } else if (iceConnectionState === 'failed') {
        assert_unreached("ICE should not fail");
      }
    });

    pc1.createDataChannel('test');

    assert_equals(pc1.oniceconnectionstatechange, null,
      'Expect connection to have iceconnectionstatechange event');

    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
  }, 'connection with one data channel should eventually ' +
     'have connected connection state');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    stream.getTracks().forEach(track => pc1.addTrack(track, stream));

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
    await listenToIceConnected(pc1);
  }, 'connection with audio track should eventually ' +
     'have connected connection state');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

    const stream = await getNoiseStream({audio: true, video:true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    stream.getTracks().forEach(track => pc1.addTrack(track, stream));

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
    await listenToIceConnected(pc1);
  }, 'connection with audio and video tracks should eventually ' +
     'have connected connection state');

  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());

    caller.addTransceiver('audio', {direction:'recvonly'});
    const stream = await getNoiseStream({audio:true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    callee.addTrack(track, stream);
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);

    assert_equals(caller.getTransceivers().length, 1);
    const [transceiver] = caller.getTransceivers();
    assert_equals(transceiver.currentDirection, 'recvonly');

    await listenToIceConnected(caller);
  }, 'ICE can connect in a recvonly usecase');

  /*
    TODO
    4.4.4 RTCIceConnectionState Enum
      failed
        Any of the RTCIceTransport s are in the failed state.

      disconnected
        Any of the RTCIceTransport s are in the disconnected state and none of
        them are in the failed state.

      closed
        The RTCPeerConnection object's [[ isClosed]] slot is true.

    5.6.  enum RTCIceTransportState
      new
        The RTCIceTransport is gathering candidates and/or waiting for
        remote candidates to be supplied, and has not yet started checking.

      failed
        The RTCIceTransport has finished gathering, received an indication that
        there are no more remote candidates, finished checking all candidate pairs,
        and all pairs have either failed connectivity checks or have lost consent.

      disconnected
        The ICE Agent has determined that connectivity is currently lost for this
        RTCIceTransport . This is more aggressive than failed, and may trigger
        intermittently (and resolve itself without action) on a flaky network.
        The way this state is determined is implementation dependent.

        Examples include:
          Losing the network interface for the connection in use.
          Repeatedly failing to receive a response to STUN requests.

        Alternatively, the RTCIceTransport has finished checking all existing
        candidates pairs and failed to find a connection (or consent checks
        [RFC7675] once successful, have now failed), but it is still gathering
        and/or waiting for additional remote candidates.

      closed
        The RTCIceTransport has shut down and is no longer responding to STUN requests.
  */

for (let bundle_policy of ['balanced', 'max-bundle', 'max-compat']) {


    promise_test(async t => {
      const caller = new RTCPeerConnection({bundlePolicy: bundle_policy});
      t.add_cleanup(() => caller.close());
      const stream = await getNoiseStream(
          {audio: true, video:true});
      t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
      const [track1, track2] = stream.getTracks();
      const sender1 = caller.addTrack(track1);
      const sender2 = caller.addTrack(track2);
      caller.createDataChannel('datachannel');
      const callee = new RTCPeerConnection();
      t.add_cleanup(() => callee.close());
      exchangeIceCandidates(caller, callee);
      const offer = await caller.createOffer();
      await caller.setLocalDescription(offer);
      const [caller_transceiver1, caller_transceiver2] = caller.getTransceivers();
      assert_equals(sender1.transport, caller_transceiver1.sender.transport);
      await callee.setRemoteDescription(offer);
      const [callee_transceiver1, callee_transceiver2] = callee.getTransceivers();
      const answer = await callee.createAnswer();
      await callee.setLocalDescription(answer);
      await caller.setRemoteDescription(answer);
      // At this point, we should have a single ICE transport, and it
      // should eventually get to the "connected" state.
      await waitForState(caller_transceiver1.receiver.transport.iceTransport,
                         'connected');
      // The PeerConnection's iceConnectionState should therefore be 'connected'
      assert_equals(caller.iceConnectionState, 'connected',
                    'PC.iceConnectionState:');
    }, 'iceConnectionState changes at the right time, with bundle policy ' +
                 bundle_policy);
}

promise_test(async t => {
  const pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc2.close());
  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
  pc1.candidateBuffer = [];
  pc2.onicecandidate = e => {
    // Don't add candidate if candidate buffer is already used
    if (pc1.candidateBuffer) {
      pc1.candidateBuffer.push(e.candidate)
    }
  };
  pc1.iceStates = [pc1.iceConnectionState];
  pc2.iceStates = [pc2.iceConnectionState];
  pc1.oniceconnectionstatechange = () => {
    pc1.iceStates.push(pc1.iceConnectionState);
  };
  pc2.oniceconnectionstatechange = () => {
    pc2.iceStates.push(pc2.iceConnectionState);
  };

  const localStream = await getNoiseStream({audio: true, video: true});
  const localStream2 = await getNoiseStream({audio: true, video: true});
  const remoteStream = await getNoiseStream({audio: true, video: true});
  for (const stream of [localStream, localStream2, remoteStream]) {
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
  }
  localStream.getTracks().forEach(t => pc1.addTrack(t, localStream));
  localStream2.getTracks().forEach(t => pc1.addTrack(t, localStream2));
  remoteStream.getTracks().forEach(t => pc2.addTrack(t, remoteStream));
  const offer = await pc1.createOffer();
  await pc2.setRemoteDescription(offer);
  await pc1.setLocalDescription(offer);
  const answer = await pc2.createAnswer();
  await pc2.setLocalDescription(answer);
  await pc1.setRemoteDescription(answer);
  pc1.candidateBuffer.forEach(c => pc1.addIceCandidate(c));
  delete pc1.candidateBuffer;
  await listenToIceConnected(pc1);
  await listenToIceConnected(pc2);
  // While we're waiting for pc2, pc1 may or may not have transitioned
  // to "completed" state, so allow for both cases.
  if (pc1.iceStates.length == 3) {
    assert_array_equals(pc1.iceStates, ['new', 'checking', 'connected']);
  } else {
    assert_array_equals(pc1.iceStates, ['new', 'checking', 'connected',
                                        'completed']);
  }
  assert_array_equals(pc2.iceStates, ['new', 'checking', 'connected']);
}, 'Responder ICE connection state behaves as expected');

/*
  Test case for step 11 of PeerConnection.close().
  ...
  11. Set connection's ICE connection state to "closed". This does not invoke
      the "update the ICE connection state" procedure, and does not fire any
      event.
  ...
*/
promise_test(async t => {
  const pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  const pc2 = new RTCPeerConnection();
  const stream = await getNoiseStream({ audio: true });
  t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));

  stream.getTracks().forEach(track => pc1.addTrack(track, stream));
  exchangeIceCandidates(pc1, pc2);
  exchangeOfferAnswer(pc1, pc2);
  await listenToIceConnected(pc2);

  pc2.oniceconnectionstatechange = t.unreached_func();
  pc2.close();
  assert_equals(pc2.iceConnectionState, 'closed');
  await new Promise(r => t.step_timeout(r, 100));
}, 'Closing a PeerConnection should not fire iceconnectionstatechange event');

</script>
