Revision 4e5f09f89e6f1976dd49a57ba46cd447c7e19a1e authored by Alex Moshchuk on 13 April 2018, 15:22:14 UTC, committed by Chromium WPT Sync on 13 April 2018, 15:22:14 UTC
Changes from original attempt at https://crrev.com/c/999182:
- fix flakiness in two additional ChromeOS login tests
- fix CSP WPT tests to not depend on ordering between iframe's onload
  and postMessage - see https://crbug.com/832319.

Previously, we sent the IPC to forward a cross-process postMessage
immediately.  This caused a behavioral difference from the
same-process case where the postMessage is always scheduled.  Namely,
in a scenario like this:

  frame.postMessage(...);
  doSomethingThatSendsIPCsToFrame(frame);

the IPCs from JS following the postMessage would've been ordered
incorrectly, causing |frame| to see their side effects after the
postMessage dispatch in the cross-process case, whereas they would be
seen before the postMessage dispatch in the same-process case.  One
example of this is frame.focus(), and another is a frame element
onload event (dispatched via FrameHostMsg_DispatchLoad) arriving after
a postMessage dispatched from an inline script while the frame was
still loading.

To resolve these ordering concerns, this CL changes cross-process
postMessage to do a PostTask on the sender side before sending the
message to the browser process.  This improves the current state of
the world, but does not yet achieve a perfect match for the IPC
ordering in the same-process case - see discussion on the bug.

Bug: 828529
Change-Id: I62a627c501526d09900be4f5bd2c899acf4d1e07
Reviewed-on: https://chromium-review.googlesource.com/999182
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#550284}
Reviewed-on: https://chromium-review.googlesource.com/1011287
Cr-Commit-Position: refs/heads/master@{#550621}
1 parent f90d3d6
Raw File
app-can-make-payment.js
self.addEventListener('canmakepayment', event => {
  if (event.methodData.length !== 1) {
    const msg = 'Expected exactly one method data.';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  const [method] = event.methodData;
  if (!method || method.supportedMethods.length !== 1) {
    const msg = 'Expected exactly one supported method name';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  if (method.data.defaultParameter !== 'defaultValue') {
    const msg = `Unexpected value for "defaultParameter": ${
      method.data.defaultParameter
    }`;
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  if ('defaultUnsupportedParameter' in method.data) {
    const msg = 'Unexpected "defaultUnsupportedParameter"';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  if (event.modifiers.length !== 1) {
    const msg = 'Expected exactly one modifier';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  const [modifier] = event.modifiers;

  if (!modifier || modifier.supportedMethods.length !== 1) {
    const msg = 'Expected exactly one supported method name in modifier';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  for (const member of [
    'additionalDisplayItems',
    'modifiedUnsupportedParameter',
    'total',
  ]) {
    if (member in modifier) {
      const msg = `Unexpected member "${member}" in modifier`;
      event.respondWith(Promise.reject(new Error(msg)));
      return;
    }
  }

  const [methodName] = method.supportedMethods;
  if (methodName === 'basic-card') {
    const msg =
      '"basic-card" payment method must never be checked in CanMakePaymentEvent';
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  const [modifierMethodName] = modifier.supportedMethods;
  if (modifierMethodName !== methodName) {
    const msg = `Unexpected modifier method name: "${modifierMethodName}". Expected "${methodName}".`;
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  if (modifier.data.modifiedParameter !== 'modifiedValue') {
    const msg = `Unexpected value for 'modifiedParameter': ${
      modifier.data.modifiedParameter
    }`;
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  const methodAsURL = new URL(methodName);
  if (event.topLevelOrigin !== methodAsURL.origin) {
    const msg = `Unexpected event.topLevelOrigin: "${
      event.topLevelOrigin
    }". Expected "${methodAsURL.origin}".`;
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  if (event.paymentRequestOrigin !== methodAsURL.origin) {
    const msg = `Unexpected iframe origin ${event.paymentRequestOrigin}`;
    event.respondWith(Promise.reject(new Error(msg)));
    return;
  }

  switch (methodAsURL.pathname.substr(1)) {
    case 'canMakePayment-true':
      event.respondWith(true);
      break;
    case 'canMakePayment-false':
      event.respondWith(false);
      break;
    case 'canMakePayment-promise-true':
      event.respondWith(Promise.resolve(true));
      break;
    case 'canMakePayment-promise-false':
      event.respondWith(Promise.resolve(false));
      break;
    case 'canMakePayment-custom-error':
      event.respondWith(Promise.reject(new Error('Custom error')));
      break;
    default:
      const msg = `Unrecognized payment method name "${methodName}".`;
      event.respondWith(Promise.reject(new Error(msg)));
      break;
  }
});
back to top