Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c217f4cf authored by Robert Greenwalt's avatar Robert Greenwalt Committed by Android (Google) Code Review
Browse files

Merge "Allow quoted strings from NativeDaemonConnector"

parents 1313213a 2d34b4a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
    public boolean handleMessage(Message msg) {
        String event = (String) msg.obj;
        try {
            if (!mCallbacks.onEvent(msg.what, event, event.split(" "))) {
            if (!mCallbacks.onEvent(msg.what, event, NativeDaemonEvent.unescapeArgs(event))) {
                log(String.format("Unhandled event '%s'", event));
            }
        } catch (Exception e) {
+85 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server;

import android.util.Slog;
import com.google.android.collect.Lists;

import java.util.ArrayList;
@@ -32,12 +33,14 @@ public class NativeDaemonEvent {
    private final int mCode;
    private final String mMessage;
    private final String mRawEvent;
    private String[] mParsed;

    private NativeDaemonEvent(int cmdNumber, int code, String message, String rawEvent) {
        mCmdNumber = cmdNumber;
        mCode = code;
        mMessage = message;
        mRawEvent = rawEvent;
        mParsed = null;
    }

    public int getCmdNumber() {
@@ -166,4 +169,86 @@ public class NativeDaemonEvent {
        }
        return result.toArray(new String[result.size()]);
    }

    /**
     * Find the Nth field of the event.
     *
     * This ignores and code or cmdNum, the first return value is given for N=0.
     * Also understands "\"quoted\" multiword responses" and tries them as a single field
     */
    public String getField(int n) {
        if (mParsed == null) {
            mParsed = unescapeArgs(mRawEvent);
        }
        n += 2; // skip code and command#
        if (n > mParsed.length) return null;
            return mParsed[n];
        }

    public static String[] unescapeArgs(String rawEvent) {
        final boolean DEBUG_ROUTINE = false;
        final String LOGTAG = "unescapeArgs";
        final ArrayList<String> parsed = new ArrayList<String>();
        final int length = rawEvent.length();
        int current = 0;
        int wordEnd = -1;
        boolean quoted = false;

        if (DEBUG_ROUTINE) Slog.e(LOGTAG, "parsing '" + rawEvent + "'");
        if (rawEvent.charAt(current) == '\"') {
            quoted = true;
            current++;
        }
        while (current < length) {
            // find the end of the word
            if (quoted) {
                wordEnd = current;
                while ((wordEnd = rawEvent.indexOf('\"', wordEnd)) != -1) {
                    if (rawEvent.charAt(wordEnd - 1) != '\\') {
                        break;
                    } else {
                        wordEnd++; // skip this escaped quote and keep looking
                    }
                }
            } else {
                wordEnd = rawEvent.indexOf(' ', current);
            }
            // if we didn't find the end-o-word token, take the rest of the string
            if (wordEnd == -1) wordEnd = length;
            String word = rawEvent.substring(current, wordEnd);
            current += word.length();
            if (!quoted) {
                word = word.trim();
            } else {
                current++;  // skip the trailing quote
            }
            // unescape stuff within the word
            word.replace("\\\\", "\\");
            word.replace("\\\"", "\"");

            if (DEBUG_ROUTINE) Slog.e(LOGTAG, "found '" + word + "'");
            parsed.add(word);

            // find the beginning of the next word - either of these options
            int nextSpace = rawEvent.indexOf(' ', current);
            int nextQuote = rawEvent.indexOf(" \"", current);
            if (DEBUG_ROUTINE) {
                Slog.e(LOGTAG, "nextSpace=" + nextSpace + ", nextQuote=" + nextQuote);
            }
            if (nextQuote > -1 && nextQuote <= nextSpace) {
                quoted = true;
                current = nextQuote + 2;
            } else {
                quoted = false;
                if (nextSpace > -1) {
                    current = nextSpace + 1;
                }
            } // else we just start the next word after the current and read til the end
            if (DEBUG_ROUTINE) {
                Slog.e(LOGTAG, "next loop - current=" + current +
                        ", length=" + length + ", quoted=" + quoted);
            }
        }
        return parsed.toArray(new String[parsed.size()]);
    }
}