• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2018 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 {RawQueryResult, TraceProcessor} from './protos';
16import {TimeSpan} from './time';
17
18/**
19 * Abstract interface of a trace proccessor.
20 * This class is wrapper for multiple proto services defined in:
21 * //protos/perfetto/trace_processor/*
22 * For each service ("FooService") Engine will have abstract getter
23 * ("fooService") which returns a protobufjs rpc.Service object for
24 * the given service.
25 *
26 * Engine also defines helpers for the most common service methods
27 * (e.g. query).
28 */
29export abstract class Engine {
30  abstract readonly id: string;
31  private _numCpus?: number;
32
33  /**
34   * Push trace data into the engine. The engine is supposed to automatically
35   * figure out the type of the trace (JSON vs Protobuf).
36   */
37  abstract parse(data: Uint8Array): void;
38
39  /**
40   * Notify the engine no more data is coming.
41   */
42  abstract notifyEof(): void;
43
44  /*
45   * The RCP interface to call service methods defined in trace_processor.proto.
46   */
47  abstract get rpc(): TraceProcessor;
48
49  /**
50   * Shorthand for sending a SQL query to the engine.
51   * Exactly the same as engine.rpc.rawQuery({rawQuery});
52   */
53  query(sqlQuery: string): Promise<RawQueryResult> {
54    const timeQueuedNs = Math.floor(performance.now() * 1e6);
55    return this.rpc.rawQuery({sqlQuery, timeQueuedNs});
56  }
57
58  async queryOneRow(query: string): Promise<number[]> {
59    const result = await this.query(query);
60    const res: number[] = [];
61    result.columns.map(c => res.push(+c.longValues![0]));
62    return res;
63  }
64
65  // TODO(hjd): When streaming must invalidate this somehow.
66  async getNumberOfCpus(): Promise<number> {
67    if (!this._numCpus) {
68      const result = await this.query(
69          'select count(distinct(cpu)) as cpuCount from sched;');
70      this._numCpus = +result.columns[0].longValues![0];
71    }
72    return this._numCpus;
73  }
74
75  // TODO: This should live in code that's more specific to chrome, instead of
76  // in engine.
77  async getNumberOfProcesses(): Promise<number> {
78    const result = await this.query('select count(*) from process;');
79    return +result.columns[0].longValues![0];
80  }
81
82  async getTraceTimeBounds(): Promise<TimeSpan> {
83    const query = `select start_ts, end_ts from trace_bounds`;
84    const res = (await this.queryOneRow(query));
85    return new TimeSpan(res[0] / 1e9, res[1] / 1e9);
86  }
87}
88