diff --git a/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java b/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java
deleted file mode 100644
index 0cf9dcd..0000000
--- a/service-t/src/com/android/server/INativeDaemonConnectorCallbacks.java
+++ /dev/null
@@ -1,25 +0,0 @@
-
-/*
- * Copyright (C) 2007 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.server;
-
-interface INativeDaemonConnectorCallbacks {
-
-    void onDaemonConnected();
-    boolean onCheckHoldWakeLock(int code);
-    boolean onEvent(int code, String raw, String[] cooked);
-}
diff --git a/service-t/src/com/android/server/NativeDaemonConnector.java b/service-t/src/com/android/server/NativeDaemonConnector.java
deleted file mode 100644
index ec8d779..0000000
--- a/service-t/src/com/android/server/NativeDaemonConnector.java
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (C) 2007 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.server;
-
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Objects;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Generic connector class for interfacing with a native daemon which uses the
- * {@code libsysutils} FrameworkListener protocol.
- */
-final class NativeDaemonConnector implements Runnable, Handler.Callback {
-    private final static boolean VDBG = false;
-
-    private final String TAG;
-
-    private String mSocket;
-    private OutputStream mOutputStream;
-    private LocalLog mLocalLog;
-
-    private volatile boolean mDebug = false;
-    private volatile Object mWarnIfHeld;
-
-    private final ResponseQueue mResponseQueue;
-
-    private final PowerManager.WakeLock mWakeLock;
-
-    private final Looper mLooper;
-
-    private INativeDaemonConnectorCallbacks mCallbacks;
-    private Handler mCallbackHandler;
-
-    private AtomicInteger mSequenceNumber;
-
-    private static final long DEFAULT_TIMEOUT = 1 * 60 * 1000; /* 1 minute */
-    private static final long WARN_EXECUTE_DELAY_MS = 500; /* .5 sec */
-
-    /** Lock held whenever communicating with native daemon. */
-    private final Object mDaemonLock = new Object();
-
-    private final int BUFFER_SIZE = 4096;
-
-    NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
-            int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
-        mCallbacks = callbacks;
-        mSocket = socket;
-        mResponseQueue = new ResponseQueue(responseQueueSize);
-        mWakeLock = wl;
-        if (mWakeLock != null) {
-            mWakeLock.setReferenceCounted(true);
-        }
-        mSequenceNumber = new AtomicInteger(0);
-        TAG = logTag != null ? logTag : "NativeDaemonConnector";
-        mLocalLog = new LocalLog(maxLogSize);
-        final HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mLooper = thread.getLooper();
-    }
-
-    /**
-     * Enable Set debugging mode, which causes messages to also be written to both
-     * {@link Log} in addition to internal log.
-     */
-    public void setDebug(boolean debug) {
-        mDebug = debug;
-    }
-
-    /**
-     * Like SystemClock.uptimeMillis, except truncated to an int so it will fit in a message arg.
-     * Inaccurate across 49.7 days of uptime, but only used for debugging.
-     */
-    private int uptimeMillisInt() {
-        return (int) SystemClock.uptimeMillis() & Integer.MAX_VALUE;
-    }
-
-    /**
-     * Yell loudly if someone tries making future {@link #execute(Command)}
-     * calls while holding a lock on the given object.
-     */
-    public void setWarnIfHeld(Object warnIfHeld) {
-        if (mWarnIfHeld != null) {
-            throw new IllegalStateException("warnIfHeld is already set.");
-        }
-        mWarnIfHeld = Objects.requireNonNull(warnIfHeld);
-    }
-
-    @Override
-    public void run() {
-        mCallbackHandler = new Handler(mLooper, this);
-
-        while (true) {
-            try {
-                listenToSocket();
-            } catch (Exception e) {
-                loge("Error in NativeDaemonConnector: " + e);
-                SystemClock.sleep(5000);
-            }
-        }
-    }
-
-    @Override
-    public boolean handleMessage(Message msg) {
-        final String event = (String) msg.obj;
-        final int start = uptimeMillisInt();
-        final int sent = msg.arg1;
-        try {
-            if (!mCallbacks.onEvent(msg.what, event, NativeDaemonEvent.unescapeArgs(event))) {
-                log(String.format("Unhandled event '%s'", event));
-            }
-        } catch (Exception e) {
-            loge("Error handling '" + event + "': " + e);
-        } finally {
-            if (mCallbacks.onCheckHoldWakeLock(msg.what) && mWakeLock != null) {
-                mWakeLock.release();
-            }
-            final int end = uptimeMillisInt();
-            if (start > sent && start - sent > WARN_EXECUTE_DELAY_MS) {
-                loge(String.format("NDC event {%s} processed too late: %dms", event, start - sent));
-            }
-            if (end > start && end - start > WARN_EXECUTE_DELAY_MS) {
-                loge(String.format("NDC event {%s} took too long: %dms", event, end - start));
-            }
-        }
-        return true;
-    }
-
-    private LocalSocketAddress determineSocketAddress() {
-        // If we're testing, set up a socket in a namespace that's accessible to test code.
-        // In order to ensure that unprivileged apps aren't able to impersonate native daemons on
-        // production devices, even if said native daemons ill-advisedly pick a socket name that
-        // starts with __test__, only allow this on debug builds.
-        if (mSocket.startsWith("__test__") && Build.isDebuggable()) {
-            return new LocalSocketAddress(mSocket);
-        } else {
-            return new LocalSocketAddress(mSocket, LocalSocketAddress.Namespace.RESERVED);
-        }
-    }
-
-    private void listenToSocket() throws IOException {
-        LocalSocket socket = null;
-
-        try {
-            socket = new LocalSocket();
-            LocalSocketAddress address = determineSocketAddress();
-
-            socket.connect(address);
-
-            InputStream inputStream = socket.getInputStream();
-            synchronized (mDaemonLock) {
-                mOutputStream = socket.getOutputStream();
-            }
-
-            mCallbacks.onDaemonConnected();
-
-            FileDescriptor[] fdList = null;
-            byte[] buffer = new byte[BUFFER_SIZE];
-            int start = 0;
-
-            while (true) {
-                int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
-                if (count < 0) {
-                    loge("got " + count + " reading with start = " + start);
-                    break;
-                }
-                fdList = socket.getAncillaryFileDescriptors();
-
-                // Add our starting point to the count and reset the start.
-                count += start;
-                start = 0;
-
-                for (int i = 0; i < count; i++) {
-                    if (buffer[i] == 0) {
-                        // Note - do not log this raw message since it may contain
-                        // sensitive data
-                        final String rawEvent = new String(
-                                buffer, start, i - start, StandardCharsets.UTF_8);
-
-                        boolean releaseWl = false;
-                        try {
-                            final NativeDaemonEvent event =
-                                    NativeDaemonEvent.parseRawEvent(rawEvent, fdList);
-
-                            log("RCV <- {" + event + "}");
-
-                            if (event.isClassUnsolicited()) {
-                                // TODO: migrate to sending NativeDaemonEvent instances
-                                if (mCallbacks.onCheckHoldWakeLock(event.getCode())
-                                        && mWakeLock != null) {
-                                    mWakeLock.acquire();
-                                    releaseWl = true;
-                                }
-                                Message msg = mCallbackHandler.obtainMessage(
-                                        event.getCode(), uptimeMillisInt(), 0, event.getRawEvent());
-                                if (mCallbackHandler.sendMessage(msg)) {
-                                    releaseWl = false;
-                                }
-                            } else {
-                                mResponseQueue.add(event.getCmdNumber(), event);
-                            }
-                        } catch (IllegalArgumentException e) {
-                            log("Problem parsing message " + e);
-                        } finally {
-                            if (releaseWl) {
-                                mWakeLock.release();
-                            }
-                        }
-
-                        start = i + 1;
-                    }
-                }
-
-                if (start == 0) {
-                    log("RCV incomplete");
-                }
-
-                // We should end at the amount we read. If not, compact then
-                // buffer and read again.
-                if (start != count) {
-                    final int remaining = BUFFER_SIZE - start;
-                    System.arraycopy(buffer, start, buffer, 0, remaining);
-                    start = remaining;
-                } else {
-                    start = 0;
-                }
-            }
-        } catch (IOException ex) {
-            loge("Communications error: " + ex);
-            throw ex;
-        } finally {
-            synchronized (mDaemonLock) {
-                if (mOutputStream != null) {
-                    try {
-                        loge("closing stream for " + mSocket);
-                        mOutputStream.close();
-                    } catch (IOException e) {
-                        loge("Failed closing output stream: " + e);
-                    }
-                    mOutputStream = null;
-                }
-            }
-
-            try {
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (IOException ex) {
-                loge("Failed closing socket: " + ex);
-            }
-        }
-    }
-
-    /**
-     * Wrapper around argument that indicates it's sensitive and shouldn't be
-     * logged.
-     */
-    public static class SensitiveArg {
-        private final Object mArg;
-
-        public SensitiveArg(Object arg) {
-            mArg = arg;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(mArg);
-        }
-    }
-
-    /**
-     * Make command for daemon, escaping arguments as needed.
-     */
-    @VisibleForTesting
-    static void makeCommand(StringBuilder rawBuilder, StringBuilder logBuilder, int sequenceNumber,
-            String cmd, Object... args) {
-        if (cmd.indexOf('\0') >= 0) {
-            throw new IllegalArgumentException("Unexpected command: " + cmd);
-        }
-        if (cmd.indexOf(' ') >= 0) {
-            throw new IllegalArgumentException("Arguments must be separate from command");
-        }
-
-        rawBuilder.append(sequenceNumber).append(' ').append(cmd);
-        logBuilder.append(sequenceNumber).append(' ').append(cmd);
-        for (Object arg : args) {
-            final String argString = String.valueOf(arg);
-            if (argString.indexOf('\0') >= 0) {
-                throw new IllegalArgumentException("Unexpected argument: " + arg);
-            }
-
-            rawBuilder.append(' ');
-            logBuilder.append(' ');
-
-            appendEscaped(rawBuilder, argString);
-            if (arg instanceof SensitiveArg) {
-                logBuilder.append("[scrubbed]");
-            } else {
-                appendEscaped(logBuilder, argString);
-            }
-        }
-
-        rawBuilder.append('\0');
-    }
-
-    /**
-     * Method that waits until all asychronous notifications sent by the native daemon have
-     * been processed. This method must not be called on the notification thread or an
-     * exception will be thrown.
-     */
-    public void waitForCallbacks() {
-        if (Thread.currentThread() == mLooper.getThread()) {
-            throw new IllegalStateException("Must not call this method on callback thread");
-        }
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        mCallbackHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                latch.countDown();
-            }
-        });
-        try {
-            latch.await();
-        } catch (InterruptedException e) {
-            Log.wtf(TAG, "Interrupted while waiting for unsolicited response handling", e);
-        }
-    }
-
-    /**
-     * Issue the given command to the native daemon and return a single expected
-     * response.
-     *
-     * @throws NativeDaemonConnectorException when problem communicating with
-     *             native daemon, or if the response matches
-     *             {@link NativeDaemonEvent#isClassClientError()} or
-     *             {@link NativeDaemonEvent#isClassServerError()}.
-     */
-    public NativeDaemonEvent execute(Command cmd) throws NativeDaemonConnectorException {
-        return execute(cmd.mCmd, cmd.mArguments.toArray());
-    }
-
-    /**
-     * Issue the given command to the native daemon and return a single expected
-     * response. Any arguments must be separated from base command so they can
-     * be properly escaped.
-     *
-     * @throws NativeDaemonConnectorException when problem communicating with
-     *             native daemon, or if the response matches
-     *             {@link NativeDaemonEvent#isClassClientError()} or
-     *             {@link NativeDaemonEvent#isClassServerError()}.
-     */
-    public NativeDaemonEvent execute(String cmd, Object... args)
-            throws NativeDaemonConnectorException {
-        return execute(DEFAULT_TIMEOUT, cmd, args);
-    }
-
-    public NativeDaemonEvent execute(long timeoutMs, String cmd, Object... args)
-            throws NativeDaemonConnectorException {
-        final NativeDaemonEvent[] events = executeForList(timeoutMs, cmd, args);
-        if (events.length != 1) {
-            throw new NativeDaemonConnectorException(
-                    "Expected exactly one response, but received " + events.length);
-        }
-        return events[0];
-    }
-
-    /**
-     * Issue the given command to the native daemon and return any
-     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
-     * final terminal response.
-     *
-     * @throws NativeDaemonConnectorException when problem communicating with
-     *             native daemon, or if the response matches
-     *             {@link NativeDaemonEvent#isClassClientError()} or
-     *             {@link NativeDaemonEvent#isClassServerError()}.
-     */
-    public NativeDaemonEvent[] executeForList(Command cmd) throws NativeDaemonConnectorException {
-        return executeForList(cmd.mCmd, cmd.mArguments.toArray());
-    }
-
-    /**
-     * Issue the given command to the native daemon and return any
-     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
-     * final terminal response. Any arguments must be separated from base
-     * command so they can be properly escaped.
-     *
-     * @throws NativeDaemonConnectorException when problem communicating with
-     *             native daemon, or if the response matches
-     *             {@link NativeDaemonEvent#isClassClientError()} or
-     *             {@link NativeDaemonEvent#isClassServerError()}.
-     */
-    public NativeDaemonEvent[] executeForList(String cmd, Object... args)
-            throws NativeDaemonConnectorException {
-        return executeForList(DEFAULT_TIMEOUT, cmd, args);
-    }
-
-    /**
-     * Issue the given command to the native daemon and return any {@linke
-     * NativeDaemonEvent@isClassContinue()} responses, including the final
-     * terminal response. Note that the timeout does not count time in deep
-     * sleep. Any arguments must be separated from base command so they can be
-     * properly escaped.
-     *
-     * @throws NativeDaemonConnectorException when problem communicating with
-     *             native daemon, or if the response matches
-     *             {@link NativeDaemonEvent#isClassClientError()} or
-     *             {@link NativeDaemonEvent#isClassServerError()}.
-     */
-    public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args)
-            throws NativeDaemonConnectorException {
-        if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
-            Log.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
-                    + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable());
-        }
-
-        final long startTime = SystemClock.elapsedRealtime();
-
-        final ArrayList<NativeDaemonEvent> events = new ArrayList<>();
-
-        final StringBuilder rawBuilder = new StringBuilder();
-        final StringBuilder logBuilder = new StringBuilder();
-        final int sequenceNumber = mSequenceNumber.incrementAndGet();
-
-        makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);
-
-        final String rawCmd = rawBuilder.toString();
-        final String logCmd = logBuilder.toString();
-
-        log("SND -> {" + logCmd + "}");
-
-        synchronized (mDaemonLock) {
-            if (mOutputStream == null) {
-                throw new NativeDaemonConnectorException("missing output stream");
-            } else {
-                try {
-                    mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8));
-                } catch (IOException e) {
-                    throw new NativeDaemonConnectorException("problem sending command", e);
-                }
-            }
-        }
-
-        NativeDaemonEvent event = null;
-        do {
-            event = mResponseQueue.remove(sequenceNumber, timeoutMs, logCmd);
-            if (event == null) {
-                loge("timed-out waiting for response to " + logCmd);
-                throw new NativeDaemonTimeoutException(logCmd, event);
-            }
-            if (VDBG) log("RMV <- {" + event + "}");
-            events.add(event);
-        } while (event.isClassContinue());
-
-        final long endTime = SystemClock.elapsedRealtime();
-        if (endTime - startTime > WARN_EXECUTE_DELAY_MS) {
-            loge("NDC Command {" + logCmd + "} took too long (" + (endTime - startTime) + "ms)");
-        }
-
-        if (event.isClassClientError()) {
-            throw new NativeDaemonArgumentException(logCmd, event);
-        }
-        if (event.isClassServerError()) {
-            throw new NativeDaemonFailureException(logCmd, event);
-        }
-
-        return events.toArray(new NativeDaemonEvent[events.size()]);
-    }
-
-    /**
-     * Append the given argument to {@link StringBuilder}, escaping as needed,
-     * and surrounding with quotes when it contains spaces.
-     */
-    @VisibleForTesting
-    static void appendEscaped(StringBuilder builder, String arg) {
-        final boolean hasSpaces = arg.indexOf(' ') >= 0;
-        if (hasSpaces) {
-            builder.append('"');
-        }
-
-        final int length = arg.length();
-        for (int i = 0; i < length; i++) {
-            final char c = arg.charAt(i);
-
-            if (c == '"') {
-                builder.append("\\\"");
-            } else if (c == '\\') {
-                builder.append("\\\\");
-            } else {
-                builder.append(c);
-            }
-        }
-
-        if (hasSpaces) {
-            builder.append('"');
-        }
-    }
-
-    private static class NativeDaemonArgumentException extends NativeDaemonConnectorException {
-        public NativeDaemonArgumentException(String command, NativeDaemonEvent event) {
-            super(command, event);
-        }
-
-        @Override
-        public IllegalArgumentException rethrowAsParcelableException() {
-            throw new IllegalArgumentException(getMessage(), this);
-        }
-    }
-
-    private static class NativeDaemonFailureException extends NativeDaemonConnectorException {
-        public NativeDaemonFailureException(String command, NativeDaemonEvent event) {
-            super(command, event);
-        }
-    }
-
-    /**
-     * Command builder that handles argument list building. Any arguments must
-     * be separated from base command so they can be properly escaped.
-     */
-    public static class Command {
-        private String mCmd;
-        private ArrayList<Object> mArguments = new ArrayList<>();
-
-        public Command(String cmd, Object... args) {
-            mCmd = cmd;
-            for (Object arg : args) {
-                appendArg(arg);
-            }
-        }
-
-        public Command appendArg(Object arg) {
-            mArguments.add(arg);
-            return this;
-        }
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mLocalLog.dump(fd, pw, args);
-        pw.println();
-        mResponseQueue.dump(fd, pw, args);
-    }
-
-    private void log(String logstring) {
-        if (mDebug) Log.d(TAG, logstring);
-        mLocalLog.log(logstring);
-    }
-
-    private void loge(String logstring) {
-        Log.e(TAG, logstring);
-        mLocalLog.log(logstring);
-    }
-
-    private static class ResponseQueue {
-
-        private static class PendingCmd {
-            public final int cmdNum;
-            public final String logCmd;
-
-            public BlockingQueue<NativeDaemonEvent> responses =
-                    new ArrayBlockingQueue<NativeDaemonEvent>(10);
-
-            // The availableResponseCount member is used to track when we can remove this
-            // instance from the ResponseQueue.
-            // This is used under the protection of a sync of the mPendingCmds object.
-            // A positive value means we've had more writers retreive this object while
-            // a negative value means we've had more readers.  When we've had an equal number
-            // (it goes to zero) we can remove this object from the mPendingCmds list.
-            // Note that we may have more responses for this command (and more readers
-            // coming), but that would result in a new PendingCmd instance being created
-            // and added with the same cmdNum.
-            // Also note that when this goes to zero it just means a parity of readers and
-            // writers have retrieved this object - not that they are done using it.  The
-            // responses queue may well have more responses yet to be read or may get more
-            // responses added to it.  But all those readers/writers have retreived and
-            // hold references to this instance already so it can be removed from
-            // mPendingCmds queue.
-            public int availableResponseCount;
-
-            public PendingCmd(int cmdNum, String logCmd) {
-                this.cmdNum = cmdNum;
-                this.logCmd = logCmd;
-            }
-        }
-
-        private final LinkedList<PendingCmd> mPendingCmds;
-        private int mMaxCount;
-
-        ResponseQueue(int maxCount) {
-            mPendingCmds = new LinkedList<PendingCmd>();
-            mMaxCount = maxCount;
-        }
-
-        public void add(int cmdNum, NativeDaemonEvent response) {
-            PendingCmd found = null;
-            synchronized (mPendingCmds) {
-                for (PendingCmd pendingCmd : mPendingCmds) {
-                    if (pendingCmd.cmdNum == cmdNum) {
-                        found = pendingCmd;
-                        break;
-                    }
-                }
-                if (found == null) {
-                    // didn't find it - make sure our queue isn't too big before adding
-                    while (mPendingCmds.size() >= mMaxCount) {
-                        Log.e("NativeDaemonConnector.ResponseQueue",
-                                "more buffered than allowed: " + mPendingCmds.size() +
-                                " >= " + mMaxCount);
-                        // let any waiter timeout waiting for this
-                        PendingCmd pendingCmd = mPendingCmds.remove();
-                        Log.e("NativeDaemonConnector.ResponseQueue",
-                                "Removing request: " + pendingCmd.logCmd + " (" +
-                                pendingCmd.cmdNum + ")");
-                    }
-                    found = new PendingCmd(cmdNum, null);
-                    mPendingCmds.add(found);
-                }
-                found.availableResponseCount++;
-                // if a matching remove call has already retrieved this we can remove this
-                // instance from our list
-                if (found.availableResponseCount == 0) mPendingCmds.remove(found);
-            }
-            try {
-                found.responses.put(response);
-            } catch (InterruptedException e) { }
-        }
-
-        // note that the timeout does not count time in deep sleep.  If you don't want
-        // the device to sleep, hold a wakelock
-        public NativeDaemonEvent remove(int cmdNum, long timeoutMs, String logCmd) {
-            PendingCmd found = null;
-            synchronized (mPendingCmds) {
-                for (PendingCmd pendingCmd : mPendingCmds) {
-                    if (pendingCmd.cmdNum == cmdNum) {
-                        found = pendingCmd;
-                        break;
-                    }
-                }
-                if (found == null) {
-                    found = new PendingCmd(cmdNum, logCmd);
-                    mPendingCmds.add(found);
-                }
-                found.availableResponseCount--;
-                // if a matching add call has already retrieved this we can remove this
-                // instance from our list
-                if (found.availableResponseCount == 0) mPendingCmds.remove(found);
-            }
-            NativeDaemonEvent result = null;
-            try {
-                result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {}
-            if (result == null) {
-                Log.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response");
-            }
-            return result;
-        }
-
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            pw.println("Pending requests:");
-            synchronized (mPendingCmds) {
-                for (PendingCmd pendingCmd : mPendingCmds) {
-                    pw.println("  Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.logCmd);
-                }
-            }
-        }
-    }
-}
diff --git a/service-t/src/com/android/server/NativeDaemonConnectorException.java b/service-t/src/com/android/server/NativeDaemonConnectorException.java
deleted file mode 100644
index 4d8881c..0000000
--- a/service-t/src/com/android/server/NativeDaemonConnectorException.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2006 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.server;
-
-import android.os.Parcel;
-
-/**
- * An exception that indicates there was an error with a
- * {@link NativeDaemonConnector} operation.
- */
-public class NativeDaemonConnectorException extends Exception {
-    private String mCmd;
-    private NativeDaemonEvent mEvent;
-
-    public NativeDaemonConnectorException(String detailMessage) {
-        super(detailMessage);
-    }
-
-    public NativeDaemonConnectorException(String detailMessage, Throwable throwable) {
-        super(detailMessage, throwable);
-    }
-
-    public NativeDaemonConnectorException(String cmd, NativeDaemonEvent event) {
-        super("command '" + cmd + "' failed with '" + event + "'");
-        mCmd = cmd;
-        mEvent = event;
-    }
-
-    public int getCode() {
-        return mEvent != null ? mEvent.getCode() : -1;
-    }
-
-    public String getCmd() {
-        return mCmd;
-    }
-
-    /**
-     * Rethrow as a {@link RuntimeException} subclass that is handled by
-     * {@link Parcel#writeException(Exception)}.
-     */
-    public IllegalArgumentException rethrowAsParcelableException() {
-        throw new IllegalStateException(getMessage(), this);
-    }
-}
diff --git a/service-t/src/com/android/server/NativeDaemonEvent.java b/service-t/src/com/android/server/NativeDaemonEvent.java
deleted file mode 100644
index 5683694..0000000
--- a/service-t/src/com/android/server/NativeDaemonEvent.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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.server;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-
-/**
- * Parsed event from native side of {@link NativeDaemonConnector}.
- */
-public class NativeDaemonEvent {
-
-    // TODO: keep class ranges in sync with ResponseCode.h
-    // TODO: swap client and server error ranges to roughly mirror HTTP spec
-
-    private final int mCmdNumber;
-    private final int mCode;
-    private final String mMessage;
-    private final String mRawEvent;
-    private final String mLogMessage;
-    private String[] mParsed;
-    private FileDescriptor[] mFdList;
-
-    private NativeDaemonEvent(int cmdNumber, int code, String message,
-                              String rawEvent, String logMessage, FileDescriptor[] fdList) {
-        mCmdNumber = cmdNumber;
-        mCode = code;
-        mMessage = message;
-        mRawEvent = rawEvent;
-        mLogMessage = logMessage;
-        mParsed = null;
-        mFdList = fdList;
-    }
-
-    static public final String SENSITIVE_MARKER = "{{sensitive}}";
-
-    public int getCmdNumber() {
-        return mCmdNumber;
-    }
-
-    public int getCode() {
-        return mCode;
-    }
-
-    public String getMessage() {
-        return mMessage;
-    }
-
-    public FileDescriptor[] getFileDescriptors() {
-        return mFdList;
-    }
-
-    @Deprecated
-    public String getRawEvent() {
-        return mRawEvent;
-    }
-
-    @Override
-    public String toString() {
-        return mLogMessage;
-    }
-
-    /**
-     * Test if event represents a partial response which is continued in
-     * additional subsequent events.
-     */
-    public boolean isClassContinue() {
-        return mCode >= 100 && mCode < 200;
-    }
-
-    /**
-     * Test if event represents a command success.
-     */
-    public boolean isClassOk() {
-        return mCode >= 200 && mCode < 300;
-    }
-
-    /**
-     * Test if event represents a remote native daemon error.
-     */
-    public boolean isClassServerError() {
-        return mCode >= 400 && mCode < 500;
-    }
-
-    /**
-     * Test if event represents a command syntax or argument error.
-     */
-    public boolean isClassClientError() {
-        return mCode >= 500 && mCode < 600;
-    }
-
-    /**
-     * Test if event represents an unsolicited event from native daemon.
-     */
-    public boolean isClassUnsolicited() {
-        return isClassUnsolicited(mCode);
-    }
-
-    private static boolean isClassUnsolicited(int code) {
-        return code >= 600 && code < 700;
-    }
-
-    /**
-     * Verify this event matches the given code.
-     *
-     * @throws IllegalStateException if {@link #getCode()} doesn't match.
-     */
-    public void checkCode(int code) {
-        if (mCode != code) {
-            throw new IllegalStateException("Expected " + code + " but was: " + this);
-        }
-    }
-
-    /**
-     * Parse the given raw event into {@link NativeDaemonEvent} instance.
-     *
-     * @throws IllegalArgumentException when line doesn't match format expected
-     *             from native side.
-     */
-    public static NativeDaemonEvent parseRawEvent(String rawEvent, FileDescriptor[] fdList) {
-        final String[] parsed = rawEvent.split(" ");
-        if (parsed.length < 2) {
-            throw new IllegalArgumentException("Insufficient arguments");
-        }
-
-        int skiplength = 0;
-
-        final int code;
-        try {
-            code = Integer.parseInt(parsed[0]);
-            skiplength = parsed[0].length() + 1;
-        } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("problem parsing code", e);
-        }
-
-        int cmdNumber = -1;
-        if (isClassUnsolicited(code) == false) {
-            if (parsed.length < 3) {
-                throw new IllegalArgumentException("Insufficient arguemnts");
-            }
-            try {
-                cmdNumber = Integer.parseInt(parsed[1]);
-                skiplength += parsed[1].length() + 1;
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("problem parsing cmdNumber", e);
-            }
-        }
-
-        String logMessage = rawEvent;
-        if (parsed.length > 2 && parsed[2].equals(SENSITIVE_MARKER)) {
-            skiplength += parsed[2].length() + 1;
-            logMessage = parsed[0] + " " + parsed[1] + " {}";
-        }
-
-        final String message = rawEvent.substring(skiplength);
-
-        return new NativeDaemonEvent(cmdNumber, code, message, rawEvent, logMessage, fdList);
-    }
-
-    /**
-     * Filter the given {@link NativeDaemonEvent} list, returning
-     * {@link #getMessage()} for any events matching the requested code.
-     */
-    public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCode) {
-        final ArrayList<String> result = new ArrayList<>();
-        for (NativeDaemonEvent event : events) {
-            if (event.getCode() == matchCode) {
-                result.add(event.getMessage());
-            }
-        }
-        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) Log.e(LOGTAG, "parsing '" + rawEvent + "'");
-        if (rawEvent.charAt(current) == '\"') {
-            quoted = true;
-            current++;
-        }
-        while (current < length) {
-            // find the end of the word
-            char terminator = quoted ? '\"' : ' ';
-            wordEnd = current;
-            while (wordEnd < length && rawEvent.charAt(wordEnd) != terminator) {
-                if (rawEvent.charAt(wordEnd) == '\\') {
-                    // skip the escaped char
-                    ++wordEnd;
-                }
-                ++wordEnd;
-            }
-            if (wordEnd > length) 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 = word.replace("\\\\", "\\");
-            word = word.replace("\\\"", "\"");
-
-            if (DEBUG_ROUTINE) Log.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) {
-                Log.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) {
-                Log.e(LOGTAG, "next loop - current=" + current
-                        + ", length=" + length + ", quoted=" + quoted);
-            }
-        }
-        return parsed.toArray(new String[parsed.size()]);
-    }
-}
diff --git a/service-t/src/com/android/server/NativeDaemonTimeoutException.java b/service-t/src/com/android/server/NativeDaemonTimeoutException.java
deleted file mode 100644
index 658f7d6..0000000
--- a/service-t/src/com/android/server/NativeDaemonTimeoutException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.server;
-
-/**
- * An exception that indicates there was a timeout with a
- * {@link NativeDaemonConnector} operation.
- */
-public class NativeDaemonTimeoutException extends NativeDaemonConnectorException {
-    public NativeDaemonTimeoutException(String command, NativeDaemonEvent event) {
-        super(command, event);
-    }
-}
-
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index c27c973..bd925f3 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -76,7 +76,6 @@
         "java/com/android/server/IpSecServiceParameterizedTest.java",
         "java/com/android/server/IpSecServiceRefcountedResourceTest.java",
         "java/com/android/server/IpSecServiceTest.java",
-        "java/com/android/server/NativeDaemonConnectorTest.java",
         "java/com/android/server/NetworkManagementServiceTest.java",
         "java/com/android/server/NsdServiceTest.java",
         "java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java",
diff --git a/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java b/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
deleted file mode 100644
index e2253a2..0000000
--- a/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011 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.server;
-
-import static com.android.server.NativeDaemonConnector.appendEscaped;
-import static com.android.server.NativeDaemonConnector.makeCommand;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import com.android.server.NativeDaemonConnector.SensitiveArg;
-
-/**
- * Tests for {@link NativeDaemonConnector}.
- */
-@MediumTest
-public class NativeDaemonConnectorTest extends AndroidTestCase {
-    private static final String TAG = "NativeDaemonConnectorTest";
-
-    public void testArgumentNormal() throws Exception {
-        final StringBuilder builder = new StringBuilder();
-
-        builder.setLength(0);
-        appendEscaped(builder, "");
-        assertEquals("", builder.toString());
-
-        builder.setLength(0);
-        appendEscaped(builder, "foo");
-        assertEquals("foo", builder.toString());
-
-        builder.setLength(0);
-        appendEscaped(builder, "foo\"bar");
-        assertEquals("foo\\\"bar", builder.toString());
-
-        builder.setLength(0);
-        appendEscaped(builder, "foo\\bar\\\"baz");
-        assertEquals("foo\\\\bar\\\\\\\"baz", builder.toString());
-    }
-
-    public void testArgumentWithSpaces() throws Exception {
-        final StringBuilder builder = new StringBuilder();
-
-        builder.setLength(0);
-        appendEscaped(builder, "foo bar");
-        assertEquals("\"foo bar\"", builder.toString());
-
-        builder.setLength(0);
-        appendEscaped(builder, "foo\"bar\\baz foo");
-        assertEquals("\"foo\\\"bar\\\\baz foo\"", builder.toString());
-    }
-
-    public void testArgumentWithUtf() throws Exception {
-        final StringBuilder builder = new StringBuilder();
-
-        builder.setLength(0);
-        appendEscaped(builder, "caf\u00E9 c\u00F6ffee");
-        assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString());
-    }
-
-    public void testSensitiveArgs() throws Exception {
-        final StringBuilder rawBuilder = new StringBuilder();
-        final StringBuilder logBuilder = new StringBuilder();
-
-        rawBuilder.setLength(0);
-        logBuilder.setLength(0);
-        makeCommand(rawBuilder, logBuilder, 1, "foo", "bar", "baz");
-        assertEquals("1 foo bar baz\0", rawBuilder.toString());
-        assertEquals("1 foo bar baz", logBuilder.toString());
-
-        rawBuilder.setLength(0);
-        logBuilder.setLength(0);
-        makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("bar"), "baz");
-        assertEquals("1 foo bar baz\0", rawBuilder.toString());
-        assertEquals("1 foo [scrubbed] baz", logBuilder.toString());
-
-        rawBuilder.setLength(0);
-        logBuilder.setLength(0);
-        makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("foo bar"), "baz baz",
-                new SensitiveArg("wat"));
-        assertEquals("1 foo \"foo bar\" \"baz baz\" wat\0", rawBuilder.toString());
-        assertEquals("1 foo [scrubbed] \"baz baz\" [scrubbed]", logBuilder.toString());
-    }
-}
