Merge "Speculatively fix windows build and unblock autoroller"
diff --git a/ui/src/assets/perfetto.scss b/ui/src/assets/perfetto.scss
index cac3d75..8ef1161 100644
--- a/ui/src/assets/perfetto.scss
+++ b/ui/src/assets/perfetto.scss
@@ -312,6 +312,19 @@
height: 25px;
}
+header.overview {
+ display: flex;
+ justify-content: space-between;
+}
+
+.query-error {
+ user-select: text;
+}
+
+span.code {
+ user-select: text;
+}
+
.text-column {
font-size: 115%;
// 2-3 alphabets per line is comfortable for reading.
diff --git a/ui/src/frontend/clipboard.ts b/ui/src/frontend/clipboard.ts
new file mode 100644
index 0000000..28d70be
--- /dev/null
+++ b/ui/src/frontend/clipboard.ts
@@ -0,0 +1,23 @@
+// 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.
+
+export async function copyToClipboard(text: string): Promise<void> {
+ try {
+ // TODO(hjd): Fix typescript type for navigator.
+ // tslint:disable-next-line no-any
+ await(navigator as any).clipboard.writeText(text);
+ } catch (err) {
+ console.error(`Failed to copy "${text}" to clipboard: ${err}`);
+ }
+}
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index 79d8417..21e295e 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -14,21 +14,12 @@
import * as m from 'mithril';
+import {copyToClipboard} from './clipboard';
import {createPage} from './pages';
const RECORD_COMMAND_LINE =
'echo CgYIgKAGIAESIwohCgxsaW51eC5mdHJhY2UQAKIGDhIFc2NoZWQSBWlucHV0GJBOMh0KFnBlcmZldHRvLnRyYWNlZF9wcm9iZXMQgCAYBEAASAA= | base64 --decode | adb shell "perfetto -c - -o /data/misc/perfetto-traces/trace" && adb pull /data/misc/perfetto-traces/trace /tmp/trace';
-async function copyToClipboard(text: string): Promise<void> {
- try {
- // TODO(hjd): Fix typescript type for navigator.
- // tslint:disable-next-line no-any
- await(navigator as any).clipboard.writeText(text);
- } catch (err) {
- console.error(`Failed to copy "${text}" to clipboard: ${err}`);
- }
-}
-
interface CodeSampleAttrs {
text: string;
}
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index adca962..d89bd5d 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -17,6 +17,7 @@
import {QueryResponse} from '../common/queries';
import {TimeSpan} from '../common/time';
+import {copyToClipboard} from './clipboard';
import {FlameGraphPanel} from './flame_graph_panel';
import {globals} from './globals';
import {HeaderPanel} from './header_panel';
@@ -54,8 +55,27 @@
return m(
'div',
m('header.overview',
- `Query result - ${Math.round(resp.durationMs)} ms`,
- m('span.code', resp.query)),
+ m('span',
+ `Query result - ${Math.round(resp.durationMs)} ms`,
+ m('span.code', resp.query)),
+ resp.error ? null :
+ m('button',
+ {
+ onclick: () => {
+ const lines: string[][] = [];
+ lines.push(resp.columns);
+ for (const row of resp.rows) {
+ const line = [];
+ for (const col of resp.columns) {
+ line.push(row[col].toString());
+ }
+ lines.push(line);
+ }
+ copyToClipboard(
+ lines.map(line => line.join('\t')).join('\n'));
+ },
+ },
+ 'Copy as .tsv')),
resp.error ?
m('.query-error', `SQL error: ${resp.error}`) :
m('table.query-table', m('thead', header), m('tbody', rows)));