aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java169
1 files changed, 169 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java
new file mode 100644
index 000000000..2548edc23
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/systrace/SystraceOutputParser.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+package com.android.ide.eclipse.ddms.systrace;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+
+/** {@link SystraceOutputParser} receives the output of atrace command run on the device,
+ * parses it and generates html based on the trace */
+public class SystraceOutputParser {
+ private static final String TRACE_START = "TRACE:\n"; //$NON-NLS-1$
+
+ private final boolean mUncompress;
+ private final String mJs;
+ private final String mCss;
+ private final String mHtmlPrefix;
+ private final String mHtmlSuffix;
+
+ private byte[] mAtraceOutput;
+ private int mAtraceLength;
+ private int mSystraceIndex = -1;
+
+ /**
+ * Constructs a atrace output parser.
+ * @param compressedStream Is the input stream compressed using zlib?
+ * @param systraceJs systrace javascript content
+ * @param systraceCss systrace css content
+ */
+ public SystraceOutputParser(boolean compressedStream, String systraceJs, String systraceCss,
+ String htmlPrefix, String htmlSuffix) {
+ mUncompress = compressedStream;
+ mJs = systraceJs;
+ mCss = systraceCss;
+ mHtmlPrefix = htmlPrefix;
+ mHtmlSuffix = htmlSuffix;
+ }
+
+ /**
+ * Parses the atrace output for systrace content.
+ * @param atraceOutput output bytes from atrace
+ */
+ public void parse(byte[] atraceOutput) {
+ mAtraceOutput = atraceOutput;
+ mAtraceLength = atraceOutput.length;
+
+ removeCrLf();
+
+ // locate the trace start marker within the first hundred bytes
+ String header = new String(mAtraceOutput, 0, Math.min(100, mAtraceLength));
+ mSystraceIndex = locateSystraceData(header);
+
+ if (mSystraceIndex < 0) {
+ throw new RuntimeException("Unable to find trace start marker 'TRACE:':\n" + header);
+ }
+ }
+
+ /** Replaces \r\n with \n in {@link #mAtraceOutput}. */
+ private void removeCrLf() {
+ int dst = 0;
+ for (int src = 0; src < mAtraceLength - 1; src++, dst++) {
+ byte copy;
+ if (mAtraceOutput[src] == '\r' && mAtraceOutput[src + 1] == '\n') {
+ copy = '\n';
+ src++;
+ } else {
+ copy = mAtraceOutput[src];
+ }
+ mAtraceOutput[dst] = copy;
+ }
+
+ mAtraceLength = dst;
+ }
+
+ private int locateSystraceData(String header) {
+ int index = header.indexOf(TRACE_START);
+ if (index < 0) {
+ return -1;
+ } else {
+ return index + TRACE_START.length();
+ }
+ }
+
+ public String getSystraceHtml() {
+ if (mSystraceIndex < 0) {
+ return "";
+ }
+
+ String trace = "";
+ if (mUncompress) {
+ Inflater decompressor = new Inflater();
+ decompressor.setInput(mAtraceOutput, mSystraceIndex, mAtraceLength - mSystraceIndex);
+
+ byte[] buf = new byte[4096];
+ int n;
+ StringBuilder sb = new StringBuilder(1000);
+ try {
+ while ((n = decompressor.inflate(buf)) > 0) {
+ sb.append(new String(buf, 0, n));
+ }
+ } catch (DataFormatException e) {
+ throw new RuntimeException(e);
+ }
+ decompressor.end();
+
+ trace = sb.toString();
+ } else {
+ trace = new String(mAtraceOutput, mSystraceIndex, mAtraceLength - mSystraceIndex);
+ }
+
+ // each line should end with the characters \n\ followed by a newline
+ String html_out = trace.replaceAll("\n", "\\\\n\\\\\n");
+ String header = String.format(mHtmlPrefix, mCss, mJs, "");
+ String footer = mHtmlSuffix;
+ return header + html_out + footer;
+ }
+
+ public static String getJs(File assetsFolder) {
+ try {
+ return String.format("<script language=\"javascript\">%s</script>",
+ Files.toString(new File(assetsFolder, "script.js"), Charsets.UTF_8));
+ } catch (IOException e) {
+ return "";
+ }
+ }
+
+ public static String getCss(File assetsFolder) {
+ try {
+ return String.format("<style type=\"text/css\">%s</style>",
+ Files.toString(new File(assetsFolder, "style.css"), Charsets.UTF_8));
+ } catch (IOException e) {
+ return "";
+ }
+ }
+
+ public static String getHtmlPrefix(File assetsFolder) {
+ return getHtmlTemplate(assetsFolder, "prefix.html");
+ }
+
+ public static String getHtmlSuffix(File assetsFolder) {
+ return getHtmlTemplate(assetsFolder, "suffix.html");
+ }
+
+ private static String getHtmlTemplate(File assetsFolder, String htmlFileName) {
+ try {
+ return Files.toString(new File(assetsFolder, htmlFileName), Charsets.UTF_8);
+ } catch (IOException e) {
+ return "";
+ }
+ }
+}