xref: /aosp_15_r20/external/perfetto/ui/src/chrome_extension/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {binaryDecode} from '../base/string_utils';
16import {ChromeTracingController} from './chrome_tracing_controller';
17
18let chromeTraceController: ChromeTracingController | undefined = undefined;
19
20enableOnlyOnPerfettoHost();
21
22// Listen for messages from the perfetto ui.
23// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
24if (globalThis.chrome) {
25  chrome.runtime.onConnectExternal.addListener((port) => {
26    chromeTraceController = new ChromeTracingController(port);
27    port.onMessage.addListener(onUIMessage);
28  });
29}
30
31function onUIMessage(
32  message: {method: string; requestData: string},
33  port: chrome.runtime.Port,
34) {
35  if (message.method === 'ExtensionVersion') {
36    port.postMessage({version: chrome.runtime.getManifest().version});
37    return;
38  }
39  console.assert(chromeTraceController !== undefined);
40  if (!chromeTraceController) return;
41  // ChromeExtensionConsumerPort sends the request data as string because
42  // chrome.runtime.port doesn't support ArrayBuffers.
43  const requestDataArray: Uint8Array = message.requestData
44    ? binaryDecode(message.requestData)
45    : new Uint8Array();
46  chromeTraceController.handleCommand(message.method, requestDataArray);
47}
48
49function enableOnlyOnPerfettoHost() {
50  function enableOnHostWithSuffix(suffix: string) {
51    return {
52      conditions: [
53        new chrome.declarativeContent.PageStateMatcher({
54          pageUrl: {hostSuffix: suffix},
55        }),
56      ],
57      actions: [new chrome.declarativeContent.ShowPageAction()],
58    };
59  }
60  chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
61    chrome.declarativeContent.onPageChanged.addRules([
62      enableOnHostWithSuffix('localhost'),
63      enableOnHostWithSuffix('127.0.0.1'),
64      enableOnHostWithSuffix('.perfetto.dev'),
65      enableOnHostWithSuffix('.storage.googleapis.com'),
66    ]);
67  });
68}
69