perfetto-ui: Load ctrace files in legacy UI

Only works for files that are small enough for the old UI to handle.
Tested with a 15MB .ctrace file that loaded correctly.

Bug:133847449
Change-Id: I36c08811f76d93fcf4badd62bf245956ea400ee8
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 7cd529c..9a35e81 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -126,6 +126,11 @@
       "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.17.tgz",
       "integrity": "sha512-3N3FRd/rA1v5glXjb90YdYUa+sOB7WrkU2rAhKZnF4TKD86Cym9swtulGuH0p9nxo7fP5woRNa8b0oFTpCO1bg=="
     },
+    "@types/pako": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
+      "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
+    },
     "@types/puppeteer": {
       "version": "1.12.4",
       "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-1.12.4.tgz",
@@ -5470,6 +5475,11 @@
       "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
       "dev": true
     },
+    "pako": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
+      "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw=="
+    },
     "parse-glob": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
diff --git a/ui/package.json b/ui/package.json
index 3e613c5..69b26b1 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -11,12 +11,14 @@
   "author": "Perfetto Team",
   "license": "Apache-2.0",
   "dependencies": {
-    "@types/mithril": "^1.1.16",
-    "@types/uuid": "^3.4.4",
     "@types/color-convert": "^1.9.0",
+    "@types/mithril": "^1.1.16",
+    "@types/pako": "^1.0.1",
+    "@types/uuid": "^3.4.4",
     "color-convert": "^2.0.0",
     "immer": "^1.12.1",
     "mithril": "^1.1.6",
+    "pako": "^1.0.10",
     "protobufjs": "^6.8.8",
     "uuid": "^3.3.2"
   },
diff --git a/ui/src/frontend/legacy_trace_viewer.ts b/ui/src/frontend/legacy_trace_viewer.ts
index 7c85ed8..4dafe4c 100644
--- a/ui/src/frontend/legacy_trace_viewer.ts
+++ b/ui/src/frontend/legacy_trace_viewer.ts
@@ -12,7 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+import {inflate} from 'pako';
+
 import {assertTrue} from '../base/logging';
+
 import {globals} from './globals';
 
 export function isLegacyTrace(fileName: string): boolean {
@@ -36,13 +39,15 @@
   reader.onerror = err => {
     console.error(err);
   };
-  if (file.name.endsWith('.gz') || file.name.endsWith('.zip')) {
+  if (file.name.endsWith('.gz') || file.name.endsWith('.zip') ||
+      file.name.endsWith('.ctrace')) {
     reader.readAsArrayBuffer(file);
   } else {
     reader.readAsText(file);
   }
 }
 
+
 export function openBufferWithLegacyTraceViewer(
     name: string, data: ArrayBuffer|string, size: number) {
   if (data instanceof ArrayBuffer) {
@@ -50,7 +55,15 @@
     if (size !== data.byteLength) {
       data = data.slice(0, size);
     }
+
+    // Handle .ctrace files.
+    const enc = new TextDecoder('utf-8');
+    const header = enc.decode(data.slice(0, 7));
+    if (header === 'TRACE:\n') {
+      data = inflate(new Uint8Array(data.slice(7, size)), {to: 'string'});
+    }
   }
+
   document.body.style.transition =
       'filter 1s ease, transform 1s cubic-bezier(0.985, 0.005, 1.000, 0.225)';
   document.body.style.filter = 'grayscale(1) blur(10px) opacity(0)';