chromium/chrome/test/data/geolocation/two_watches.html

<html>
 <head>
  <script src="../result_queue.js"></script>
  <script>
    var position_1 = 0;
    var position_2 = 0;
    var watch_1_id = 0;
    var watch_2_id = 0;
    var last_error = 0;
    var expected_final_position_latitude = 0;
    var expected_final_position_longitude = 0;
    var first_position_received = false;
    var position_updated = false;

    const resultQueue = new ResultQueue();
    const geopositionUpdates = resultQueue;

    // The permission request is not considered complete until both of the
    // watches have been set.
    function possiblyNotifyFirstPositionReceived() {
      if (position_1 == 0 || position_2 == 0 || first_position_received)
        return;
      first_position_received = true;
      if (position_1.coords.latitude != position_2.coords.latitude ||
          position_1.coords.longitude != position_2.coords.longitude) {
        last_error = "TEST FAIL: watches received different locations. " +
                      " Watch 1 (" + watch_1_id + ") got " + position_1 +
                      " Watch 2 (" + watch_2_id + ") got " + position_2;
        resultQueue.push(last_error);
        return;
      }
      resultQueue.push('request-callback-success');
    }

    // This will be triggered twice:
    //  1. When the permission request is approved, it will receive an initial
    //     value. At this point, the callback does not directly notify success
    //     because success won't be complete until both callbacks are invoked.
    //  2. When a new geolocation value is supplied.
    function geoSuccessCallback1(position) {
      position_1 = position;
      if (!first_position_received) {
        possiblyNotifyFirstPositionReceived();
        return;
      }
      if (position.coords.latitude == expected_final_position_latitude &&
          position.coords.longitude == expected_final_position_longitude) {
        position_updated = true;
        resultQueue.push('geoposition-updated');
      }
    }

    // This callback will be triggered once, when the permission request is 
    // approved. After that, it unregisters itself.
    function geoSuccessCallback2(position) {
      navigator.geolocation.clearWatch(watch_2_id);
      position_2 = position;
      if (!first_position_received) {
        possiblyNotifyFirstPositionReceived();
        return;
      }
      if (position.coords.latitude == expected_final_position_latitude ||
          position.coords.longitude == expected_final_position_longitude) {
        last_error = "TEST FAIL: watch 2 received the final position";
      }
    }

    function geoErrorCallback(error) {
      last_error = error;
      resultQueue.push('request-callback-error');
    }
    function geoStartWithAsyncResponse() {
      watch_1_id = navigator.geolocation.watchPosition(
          geoSuccessCallback1, geoErrorCallback,
          {maximumAge:600000, timeout:100000, enableHighAccuracy:false});
      watch_2_id = navigator.geolocation.watchPosition(
          geoSuccessCallback2, geoErrorCallback,
          {maximumAge:600000, timeout:100000, enableHighAccuracy:true});

      return resultQueue.pop();
    }
    function geoGetLastPositionLatitude() {
      return "" + position_1.coords.latitude;
    }
    function geoGetLastPositionLongitude() {
      return "" + position_1.coords.longitude;
    }
    function geoGetLastError() {
      return "" + (last_error ? last_error : 0);
    }
    function geoSetFinalPosition(latitude, longitude) {
      expected_final_position_latitude = latitude;
      expected_final_position_longitude = longitude;
      return 'ok';
    }
  </script>
 </head>
 <body>
 <input type="button" value="manual" onclick="geoStart()"/>
 </body>
</html>