Search in sources :

Example 1 with StringElement

use of org.acra.model.StringElement in project acra by ACRA.

the class LogCatCollector method collectLogCat.

/**
     * Executes the logcat command with arguments taken from
     * {@link ReportsCrashes#logcatArguments()}
     *
     * @param bufferName The name of the buffer to be read: "main" (default), "radio" or "events".
     * @return A {@link String} containing the latest lines of the output.
     * Default is 100 lines, use "-t", "300" in
     * {@link ReportsCrashes#logcatArguments()} if you want 300 lines.
     * You should be aware that increasing this value causes a longer
     * report generation time and a bigger footprint on the device data
     * plan consumption.
     */
private Element collectLogCat(@Nullable String bufferName) {
    final int myPid = android.os.Process.myPid();
    final String myPidStr = config.logcatFilterByPid() && myPid > 0 ? Integer.toString(myPid) + "):" : null;
    final List<String> commandLine = new ArrayList<String>();
    commandLine.add("logcat");
    if (bufferName != null) {
        commandLine.add("-b");
        commandLine.add(bufferName);
    }
    final int tailCount;
    final List<String> logcatArgumentsList = config.logcatArguments();
    final int tailIndex = logcatArgumentsList.indexOf("-t");
    if (tailIndex > -1 && tailIndex < logcatArgumentsList.size()) {
        tailCount = Integer.parseInt(logcatArgumentsList.get(tailIndex + 1));
    } else {
        tailCount = -1;
    }
    Element logcat;
    commandLine.addAll(logcatArgumentsList);
    try {
        final Process process = new ProcessBuilder().command(commandLine).redirectErrorStream(true).start();
        if (ACRA.DEV_LOGGING)
            ACRA.log.d(LOG_TAG, "Retrieving logcat output...");
        logcat = new StringElement(streamToString(process.getInputStream(), new Predicate<String>() {

            @Override
            public boolean apply(String s) {
                return myPidStr == null || s.contains(myPidStr);
            }
        }, tailCount));
        process.destroy();
    } catch (IOException e) {
        ACRA.log.e(LOG_TAG, "LogCatCollector.collectLogCat could not retrieve data.", e);
        logcat = ACRAConstants.NOT_AVAILABLE;
    }
    return logcat;
}
Also used : StringElement(org.acra.model.StringElement) Element(org.acra.model.Element) StringElement(org.acra.model.StringElement) ArrayList(java.util.ArrayList) IOException(java.io.IOException)

Example 2 with StringElement

use of org.acra.model.StringElement in project acra by ACRA.

the class ReportConverter method legacyLoad.

/**
     * Loads properties from the specified InputStream. The properties are of
     * the form <code>key=value</code>, one property per line. It may be not
     * encode as 'ISO-8859-1'.The {@code Properties} file is interpreted
     * according to the following rules:
     * <ul>
     * <li>Empty lines are ignored.</li>
     * <li>Lines starting with either a "#" or a "!" are comment lines and are
     * ignored.</li>
     * <li>A backslash at the end of the line escapes the following newline
     * character ("\r", "\n", "\r\n"). If there's a whitespace after the
     * backslash it will just escape that whitespace instead of concatenating
     * the lines. This does not apply to comment lines.</li>
     * <li>A property line consists of the key, the space between the key and
     * the value, and the value. The key goes up to the first whitespace, "=" or
     * ":" that is not escaped. The space between the key and the value contains
     * either one whitespace, one "=" or one ":" and any number of additional
     * whitespaces before and after that character. The value starts with the
     * first character after the space between the key and the value.</li>
     * <li>Following escape sequences are recognized: "\ ", "\\", "\r", "\n",
     * "\!", "\#", "\t", "\b", "\f", and "&#92;uXXXX" (unicode character).</li>
     * </ul>
     *
     * @param reader Reader from which to read the properties of this CrashReportData.
     * @return CrashReportData read from the supplied Reader.
     * @throws java.io.IOException if the properties could not be read.
     * @since 1.6
     */
@NonNull
private synchronized CrashReportData legacyLoad(@NonNull Reader reader) throws IOException {
    int mode = NONE, unicode = 0, count = 0;
    char nextChar;
    char[] buf = new char[40];
    int offset = 0, keyLength = -1, intVal;
    boolean firstChar = true;
    final CrashReportData crashData = new CrashReportData();
    final BufferedReader br = new BufferedReader(reader, ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES);
    try {
        while (true) {
            intVal = br.read();
            if (intVal == -1) {
                break;
            }
            nextChar = (char) intVal;
            if (offset == buf.length) {
                final char[] newBuf = new char[buf.length * 2];
                System.arraycopy(buf, 0, newBuf, 0, offset);
                buf = newBuf;
            }
            if (mode == UNICODE) {
                final int digit = Character.digit(nextChar, 16);
                if (digit >= 0) {
                    unicode = (unicode << 4) + digit;
                    if (++count < 4) {
                        continue;
                    }
                } else if (count <= 4) {
                    // luni.09=Invalid Unicode sequence: illegal character
                    throw new IllegalArgumentException("luni.09");
                }
                mode = NONE;
                buf[offset++] = (char) unicode;
                if (nextChar != '\n' && nextChar != '…') {
                    continue;
                }
            }
            if (mode == SLASH) {
                mode = NONE;
                switch(nextChar) {
                    case '\r':
                        // Look for a following \n
                        mode = CONTINUE;
                        continue;
                    case '…':
                    case '\n':
                        // Ignore whitespace on the next line
                        mode = IGNORE;
                        continue;
                    case 'b':
                        nextChar = '\b';
                        break;
                    case 'f':
                        nextChar = '\f';
                        break;
                    case 'n':
                        nextChar = '\n';
                        break;
                    case 'r':
                        nextChar = '\r';
                        break;
                    case 't':
                        nextChar = '\t';
                        break;
                    case 'u':
                        mode = UNICODE;
                        unicode = count = 0;
                        continue;
                }
            } else {
                switch(nextChar) {
                    case '#':
                    case '!':
                        if (firstChar) {
                            while (true) {
                                intVal = br.read();
                                if (intVal == -1) {
                                    break;
                                }
                                // & 0xff
                                nextChar = (char) intVal;
                                // required
                                if (nextChar == '\r' || nextChar == '\n' || nextChar == '…') {
                                    break;
                                }
                            }
                            continue;
                        }
                        break;
                    case '\n':
                        if (mode == CONTINUE) {
                            // Part of a \r\n sequence
                            // Ignore whitespace on the next line
                            mode = IGNORE;
                            continue;
                        }
                    // fall into the next case
                    case '…':
                    case '\r':
                        mode = NONE;
                        firstChar = true;
                        if (offset > 0 || (offset == 0 && keyLength == 0)) {
                            if (keyLength == -1) {
                                keyLength = offset;
                            }
                            final String temp = new String(buf, 0, offset);
                            final String elementString = temp.substring(keyLength);
                            Element element;
                            try {
                                element = new ComplexElement(elementString);
                            } catch (JSONException e1) {
                                try {
                                    element = new NumberElement(Double.valueOf(elementString));
                                } catch (NumberFormatException e2) {
                                    if (elementString.equals("true")) {
                                        element = new BooleanElement(true);
                                    } else if (elementString.equals("false")) {
                                        element = new BooleanElement(false);
                                    } else {
                                        element = new StringElement(elementString);
                                    }
                                }
                            }
                            crashData.put(Enum.valueOf(ReportField.class, temp.substring(0, keyLength)), element);
                        }
                        keyLength = -1;
                        offset = 0;
                        continue;
                    case '\\':
                        if (mode == KEY_DONE) {
                            keyLength = offset;
                        }
                        mode = SLASH;
                        continue;
                    case ':':
                    case '=':
                        if (keyLength == -1) {
                            // if parsing the key
                            mode = NONE;
                            keyLength = offset;
                            continue;
                        }
                        break;
                }
                if (Character.isWhitespace(nextChar)) {
                    if (mode == CONTINUE) {
                        mode = IGNORE;
                    }
                    // if key length == 0 or value length == 0
                    if (offset == 0 || offset == keyLength || mode == IGNORE) {
                        continue;
                    }
                    if (keyLength == -1) {
                        // if parsing the key
                        mode = KEY_DONE;
                        continue;
                    }
                }
                if (mode == IGNORE || mode == CONTINUE) {
                    mode = NONE;
                }
            }
            firstChar = false;
            if (mode == KEY_DONE) {
                keyLength = offset;
                mode = NONE;
            }
            buf[offset++] = nextChar;
        }
        if (mode == UNICODE && count <= 4) {
            // luni.08=Invalid Unicode sequence: expected format \\uxxxx
            throw new IllegalArgumentException("luni.08");
        }
        if (keyLength == -1 && offset > 0) {
            keyLength = offset;
        }
        if (keyLength >= 0) {
            final String temp = new String(buf, 0, offset);
            final ReportField key = Enum.valueOf(ReportField.class, temp.substring(0, keyLength));
            String value = temp.substring(keyLength);
            if (mode == SLASH) {
                value += "";
            }
            Element element;
            try {
                element = new ComplexElement(value);
            } catch (JSONException e1) {
                try {
                    element = new NumberElement(Double.valueOf(value));
                } catch (NumberFormatException e2) {
                    if (value.equals("true")) {
                        element = new BooleanElement(true);
                    } else if (value.equals("false")) {
                        element = new BooleanElement(false);
                    } else {
                        element = new StringElement(value);
                    }
                }
            }
            crashData.put(key, element);
        }
        IOUtils.safeClose(reader);
        return crashData;
    } finally {
        IOUtils.safeClose(br);
    }
}
Also used : StringElement(org.acra.model.StringElement) Element(org.acra.model.Element) StringElement(org.acra.model.StringElement) ComplexElement(org.acra.model.ComplexElement) BooleanElement(org.acra.model.BooleanElement) NumberElement(org.acra.model.NumberElement) NumberElement(org.acra.model.NumberElement) JSONException(org.json.JSONException) BooleanElement(org.acra.model.BooleanElement) CrashReportData(org.acra.collector.CrashReportData) ReportField(org.acra.ReportField) BufferedReader(java.io.BufferedReader) ComplexElement(org.acra.model.ComplexElement) NonNull(android.support.annotation.NonNull)

Aggregations

Element (org.acra.model.Element)2 StringElement (org.acra.model.StringElement)2 NonNull (android.support.annotation.NonNull)1 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 ReportField (org.acra.ReportField)1 CrashReportData (org.acra.collector.CrashReportData)1 BooleanElement (org.acra.model.BooleanElement)1 ComplexElement (org.acra.model.ComplexElement)1 NumberElement (org.acra.model.NumberElement)1 JSONException (org.json.JSONException)1