blob: 89124ea58f8c1f21c705113e9686a2c97a45e447 [file] [log] [blame]
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {Actions} from '../common/actions';
import {globals} from './globals';
const VALID_ORIGINS = [
'https://chrometto.googleplex.com',
'https://uma.googleplex.com',
];
// The message handler supports loading traces from an ArrayBuffer.
// There is no other requirement than sending the ArrayBuffer as the |data|
// property. However, since this will happen across different origins, it is not
// possible for the source website to inspect whether the message handler is
// ready, so the message handler always replies to a 'PING' message with 'PONG',
// which indicates it is ready to receive a trace.
export function postMessageHandler(messageEvent: MessageEvent) {
if (!VALID_ORIGINS.includes(messageEvent.origin)) {
throw new Error('Invalid origin for postMessage: ' + messageEvent.origin);
}
if (document.readyState !== 'complete') {
console.error('Not ready.');
return;
}
if (messageEvent.source === null) {
throw new Error('Incoming message has no source');
}
if (!('data' in messageEvent)) {
throw new Error('Incoming message has no data property');
}
if (messageEvent.data === 'PING') {
// Cross-origin messaging means we can't read |messageEvent.source|, but
// it still needs to be of the correct type to be able to invoke the
// correct version of postMessage(...).
const windowSource = messageEvent.source as Window;
windowSource.postMessage('PONG', messageEvent.origin);
return;
}
if (!(messageEvent.data instanceof ArrayBuffer)) {
throw new Error('Incoming message data is not an ArrayBuffer');
}
const buffer = messageEvent.data;
if (buffer.byteLength === 0) {
throw new Error('Incoming message trace buffer is empty');
}
// For external traces, we need to disable other features such as downloading
// and sharing a trace.
globals.frontendLocalState.localOnlyMode = true;
globals.dispatch(Actions.openTraceFromBuffer({buffer}));
}