| // Copyright (C) 2018 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 * as m from 'mithril'; |
| |
| import {assertExists} from '../base/logging'; |
| import {Actions} from '../common/actions'; |
| import {HttpRpcEngine, RPC_URL} from '../common/http_rpc_engine'; |
| import {StatusResult} from '../common/protos'; |
| import * as version from '../gen/perfetto_version'; |
| import {perfetto} from '../gen/protos'; |
| |
| import {globals} from './globals'; |
| import {showModal} from './modal'; |
| |
| const CURRENT_API_VERSION = perfetto.protos.TraceProcessorApiVersion |
| .TRACE_PROCESSOR_CURRENT_API_VERSION; |
| |
| const PROMPT = `Trace Processor Native Accelerator detected on ${RPC_URL} with: |
| $loadedTraceName |
| |
| YES, use loaded trace: |
| Will load from the current state of Trace Processor. If you did run |
| trace_processor_shell --httpd file.pftrace this is likely what you want. |
| |
| YES, but reset state: |
| Use this if you want to open another trace but still use the |
| accelerator. This is the equivalent of killing and restarting |
| trace_processor_shell --httpd. |
| |
| NO, Use builtin WASM: |
| Will not use the accelerator in this tab. |
| |
| Using the native accelerator has some minor caveats: |
| - Only one tab can be using the accelerator. |
| - Sharing, downloading and conversion-to-legacy aren't supported. |
| - You may encounter UI errors if the Trace Processor version you are using is |
| too old. Get the latest version from get.perfetto.dev/trace_processor. |
| `; |
| |
| |
| const MSG_TOO_OLD = `The Trace Processor instance on ${RPC_URL} is too old. |
| |
| This UI requires TraceProcessor features that are not present in the |
| Trace Processor native accelerator you are currently running. |
| If you continue, this is almost surely going to cause UI failures. |
| |
| Please update your local Trace Processor binary: |
| |
| curl -LO https://get.perfetto.dev/trace_processor |
| chmod +x ./trace_processor |
| ./trace_processor --httpd |
| |
| UI version: ${version.VERSION} |
| TraceProcessor RPC API required: ${CURRENT_API_VERSION} or higher |
| |
| TraceProcessor version: $tpVersion |
| RPC API: $tpApi |
| `; |
| |
| let forceUseOldVersion = false; |
| |
| // Try to connect to the external Trace Processor HTTP RPC accelerator (if |
| // available, often it isn't). If connected it will populate the |
| // |httpRpcState| in the frontend local state. In turn that will show the UI |
| // chip in the sidebar. trace_controller.ts will repeat this check before |
| // trying to load a new trace. We do this ahead of time just to have a |
| // consistent UX (i.e. so that the user can tell if the RPC is working without |
| // having to open a trace). |
| export async function CheckHttpRpcConnection(): Promise<void> { |
| const state = await HttpRpcEngine.checkConnection(); |
| globals.frontendLocalState.setHttpRpcState(state); |
| if (!state.connected) return; |
| const tpStatus = assertExists(state.status); |
| |
| if (tpStatus.apiVersion < CURRENT_API_VERSION) { |
| await showDialogTraceProcessorTooOld(tpStatus); |
| if (!forceUseOldVersion) return; |
| } |
| |
| if (tpStatus.loadedTraceName) { |
| // If a trace is already loaded in the trace processor (e.g., the user |
| // launched trace_processor_shell -D trace_file.pftrace), prompt the user to |
| // initialize the UI with the already-loaded trace. |
| return showDialogToUsePreloadedTrace(tpStatus); |
| } |
| } |
| |
| async function showDialogTraceProcessorTooOld(tpStatus: StatusResult) { |
| return showModal({ |
| title: 'Your Trace Processor binary is outdated', |
| content: |
| m('.modal-pre', |
| MSG_TOO_OLD.replace('$tpVersion', tpStatus.humanReadableVersion) |
| .replace('$tpApi', `${tpStatus.apiVersion}`)), |
| buttons: [ |
| { |
| text: 'Use builtin Wasm', |
| primary: true, |
| id: 'tp_old_wasm', |
| action: () => { |
| globals.dispatch( |
| Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'})); |
| } |
| }, |
| { |
| text: 'Use old version regardless (might crash)', |
| primary: false, |
| id: 'tp_old_cont', |
| action: () => { |
| forceUseOldVersion = true; |
| } |
| }, |
| ], |
| }); |
| } |
| |
| async function showDialogToUsePreloadedTrace(tpStatus: StatusResult) { |
| return showModal({ |
| title: 'Use Trace Processor Native Acceleration?', |
| content: |
| m('.modal-pre', |
| PROMPT.replace('$loadedTraceName', tpStatus.loadedTraceName)), |
| buttons: [ |
| { |
| text: 'YES, use loaded trace', |
| primary: true, |
| id: 'rpc_load', |
| action: () => { |
| globals.dispatch(Actions.openTraceFromHttpRpc({})); |
| } |
| }, |
| { |
| text: 'YES, but reset state', |
| primary: false, |
| id: 'rpc_reset', |
| action: () => {} |
| }, |
| { |
| text: 'NO, Use builtin Wasm', |
| primary: false, |
| id: 'rpc_force_wasm', |
| action: () => { |
| globals.dispatch( |
| Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'})); |
| } |
| }, |
| ], |
| }); |
| } |