# Deep linking to the Perfetto UI

This document describes how to open traces hosted on external servers with the
Perfetto UI. This can help integrating the Perfetto UI with custom dashboards
and implement _'Open with Perfetto UI'_-like features.

## Using window.open and postMessage

The supported way of doing this is to _inject_ the trace as an ArrayBuffer
via `window.open('https://ui.perfetto.dev')` and `postMessage()`.
In order to do this you need some minimal JavaScript code running on some
hosting infrastructure you control which can access the trace file. In most
cases this is some dashboard which you want to deep-link to the Perfetto UI.

#### Open ui.perfetto.dev via window.open

The source dashboard, the one that knows how to locate a trace and deal with
ACL checking / oauth authentication and the like, creates a new tab by doing

```js
var handle = window.open('https://ui.perfetto.dev');
```

The window handle allows bidirectional communication using `postMessage()`
between the source dashboard and the Perfetto UI.

#### Wait for the UI to be ready via PING/PONG

Wait for the UI to be ready. The `window.open()` message channel is not
buffered. If you send a message before the opened page has registered an
`onmessage` listener the messagge will be dropped on the floor.
In order to avoid this race, you can use a very basic PING/PONG protocol: keep
sending a 'PING' message until the opened window replies with a 'PONG'.
When this happens, that is the signal that the Perfetto UI is ready to open
traces.

#### Post a message the following JavaScript object

```js
  {
    'perfetto': {
      buffer: ArrayBuffer;
      title: string;
      fileName?: string;  // Optional
      url?: string;       // Optional
    }
  }
```

`buffer` is the ArrayBuffer with the actual trace file content. This is
typically something that you obtain by doing a `fetch()` on your backend
storage.

`title` is the human friendly trace title that will be shown in the
sidebar. This can help people to disambiguate traces from several tabs.

`fileName` will be used if the user clicks on "Download". A generic name will
be used if omitted.

`url` is used if the user clicks on the "Share" link in the sidebar. This should
print to a URL owned by you that would cause your dashboard to re-open the
current trace, by re-kicking-off the window.open() process herein described.
If omitted traces won't be shareable.

### Code samples

See [this example caller](https://gistcdn.rawgit.org/primiano/e164868b617844ef8fa4770eb3b323b9/1d9aa2bf52cf903709ea7dd4d583fd2d07d7a255/open_with_perfetto_ui.html),
for which the code is in
[this GitHub gist](https://gist.github.com/primiano/e164868b617844ef8fa4770eb3b323b9).

Googlers: take a look at the
[existing examples in the internal codesearch](http://go/perfetto-ui-deeplink-cs)

### Common pitfalls

Many browsers sometimes block window.open() requests prompting the user to allow
popups for the site. This usually happens if:

- The window.open() is NOT initiated by a user gesture.
- Too much time is passed from the user gesture to the window.open()

If the trace file is big enough, the fetch() might take long time and pass the
user gesture threshold. This can be detected by observing that the window.open()
returned `null`. When this happens the best option is to show another clickable
element and bind the fetched trace ArrayBuffer to the new onclick handler, like
the code in the example above does.

Some browser can have a variable time threshold for the user gesture timeout
which depends on the website engagement score (how much the user has visited
the page that does the window.open() before). It's quite common when testing
this code to see a popup blocker the first time the new feature is used and
then not see it again.

### Where does the posted trace go?

The Perfetto UI is client-only and doesn't require any server-side interaction.
Traces pushed via postMessage() are kept only in the browser memory/cache and
are not sent to any server.

## Why can't I just pass a URL?

_"Why you don't let me just pass a URL to the Perfetto UI (e.g. ui.perfetto.dev?url=...) and you deal with all this?"_

The answer to this is manifold and boils down to security.

#### Cross origin requests blocking

If ui.perfetto.dev had to do a `fetch('https://yourwebsite.com/trace')` that
would be a cross-origin request. Browsers disallow by default cross-origin
fetch requests.
In order for this to work, the web server that hosts yourwebsite.com would have
to expose a custom HTTP response header
 (`Access-Control-Allow-Origin: https://ui.perfetto.dev`) to allow the fetch.
In most cases customizing the HTTP response headers is outside of dashboard's
owners control.

You can learn more about CORS at
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

#### Content Security Policy

Perfetto UI uses a strict Content Security Policy which disallows foreign
fetches and subresources, as a security mitigation about common attacks.
Even assuming that CORS headers are properly set and your trace files are
publicly accessible, fetching the trace from the Perfetto UI would require
allow-listing your origin in our CSP policy. This is not scalable.

You can learn more about CSP at
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

#### Dealing with OAuth2 or other authentication mechanisms

Even ignoring CORS, the Perfetto UI would have to deal with OAuth2 or other
authentication mechanisms to fetch the trace file. Even if all the dashboards
out there used OAuth2, that would still mean that Perfetto UI would have to know
about all the possible OAuth2 scopes, one for each dashboard. This is not
scalable.

## Source links

The source code that deals with the postMessage() in the Perfetto UI is
[`post_message_handler.ts`](/ui/src/frontend/post_message_handler.ts)
