diff --git a/framework/src/android/net/NetworkAgentConfig.java b/framework/src/android/net/NetworkAgentConfig.java
index b28c006..0d2b620 100644
--- a/framework/src/android/net/NetworkAgentConfig.java
+++ b/framework/src/android/net/NetworkAgentConfig.java
@@ -24,6 +24,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.modules.utils.build.SdkLevel;
+
 import java.util.Objects;
 
 /**
@@ -473,6 +475,9 @@
         @NonNull
         @SystemApi(client = MODULE_LIBRARIES)
         public Builder setLocalRoutesExcludedForVpn(boolean excludeLocalRoutes) {
+            if (!SdkLevel.isAtLeastT()) {
+                throw new UnsupportedOperationException("Method is not supported");
+            }
             mConfig.excludeLocalRouteVpn = excludeLocalRoutes;
             return this;
         }
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/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
index ce955fd..b06c8aa 100644
--- a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
+++ b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
@@ -29,7 +29,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
-import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -94,11 +93,7 @@
             @NonNull final TelephonyManager t) {
         mContext = c;
         mTelephonyManager = t;
-        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) {
-            mTelephonyManagerShim = new TelephonyManagerShimImpl(mTelephonyManager);
-        } else {
-            mTelephonyManagerShim = null;
-        }
+        mTelephonyManagerShim = TelephonyManagerShimImpl.newInstance(mTelephonyManager);
         mThread = new HandlerThread(TAG);
         mThread.start();
         mHandler = new Handler(mThread.getLooper()) {};
@@ -192,36 +187,30 @@
 
     private void addCarrierPrivilegesListener(int logicalSlotIndex, Executor executor,
             CarrierPrivilegesListenerShim listener) {
-        if (mTelephonyManagerShim  == null) {
-            return;
-        }
         try {
             mTelephonyManagerShim.addCarrierPrivilegesListener(
                     logicalSlotIndex, executor, listener);
         } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
+            // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
             Log.e(TAG, "addCarrierPrivilegesListener API is not available");
         }
     }
 
     private void removeCarrierPrivilegesListener(CarrierPrivilegesListenerShim listener) {
-        if (mTelephonyManagerShim  == null) {
-            return;
-        }
         try {
             mTelephonyManagerShim.removeCarrierPrivilegesListener(listener);
         } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
+            // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
             Log.e(TAG, "removeCarrierPrivilegesListener API is not available");
         }
     }
 
     private String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
-        if (mTelephonyManagerShim  == null) {
-            return null;
-        }
         try {
             return mTelephonyManagerShim.getCarrierServicePackageNameForLogicalSlot(
                     logicalSlotIndex);
         } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
+            // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
             Log.e(TAG, "getCarrierServicePackageNameForLogicalSlot API is not available");
         }
         return null;
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index 2885ba7..62b3add 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -127,9 +127,17 @@
     @GuardedBy("this")
     private final Set<Integer> mUidsAllowedOnRestrictedNetworks = new ArraySet<>();
 
+    // Store PackageManager for each user.
+    // Keys are users, Values are PackageManagers which get from each user.
     @GuardedBy("this")
     private final Map<UserHandle, PackageManager> mUsersPackageManager = new ArrayMap<>();
 
+    // Store appIds traffic permissions for each user.
+    // Keys are users, Values are SparseArrays where each entry maps an appId to the permissions
+    // that appId has within that user.
+    @GuardedBy("this")
+    private final Map<UserHandle, SparseIntArray> mUsersTrafficPermissions = new ArrayMap<>();
+
     private static final int SYSTEM_APPID = SYSTEM_UID;
 
     private static final int MAX_PERMISSION_UPDATE_LOGS = 40;
@@ -292,14 +300,24 @@
         sendUidsNetworkPermission(uids, true /* add */);
     }
 
-    private void updateAppIdsTrafficPermission(final SparseIntArray appIds,
-            final SparseIntArray extraAppIds) {
-        for (int i = 0; i < extraAppIds.size(); i++) {
-            final int appId = extraAppIds.keyAt(i);
-            final int permission = extraAppIds.valueAt(i);
-            appIds.put(appId, appIds.get(appId) | permission);
+    /**
+     * Calculates permissions for appIds.
+     * Maps each appId to the union of all traffic permissions that the appId has in all users.
+     *
+     * @return The appIds traffic permissions.
+     */
+    private synchronized SparseIntArray makeAppIdsTrafficPermForAllUsers() {
+        final SparseIntArray appIds = new SparseIntArray();
+        // Check appIds permissions from each user.
+        for (UserHandle user : mUsersTrafficPermissions.keySet()) {
+            final SparseIntArray userAppIds = mUsersTrafficPermissions.get(user);
+            for (int i = 0; i < userAppIds.size(); i++) {
+                final int appId = userAppIds.keyAt(i);
+                final int permission = userAppIds.valueAt(i);
+                appIds.put(appId, appIds.get(appId) | permission);
+            }
         }
-        sendAppIdsTrafficPermission(appIds);
+        return appIds;
     }
 
     private SparseIntArray getSystemTrafficPerm() {
@@ -363,6 +381,10 @@
         // mUidsAllowedOnRestrictedNetworks.
         updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext));
 
+        // Read system traffic permissions when a user removed and put them to USER_ALL because they
+        // are not specific to any particular user.
+        mUsersTrafficPermissions.put(UserHandle.ALL, getSystemTrafficPerm());
+
         final List<UserHandle> usrs = mUserManager.getUserHandles(true /* excludeDying */);
         // Update netd permissions for all users.
         for (UserHandle user : usrs) {
@@ -487,9 +509,16 @@
         final SparseIntArray uids = makeUidsNetworkPerm(apps);
         updateUidsNetworkPermission(uids);
 
-        // App ids traffic permission
-        final SparseIntArray appIds = makeAppIdsTrafficPerm(apps);
-        updateAppIdsTrafficPermission(appIds, getSystemTrafficPerm());
+        // Add new user appIds permissions.
+        final SparseIntArray addedUserAppIds = makeAppIdsTrafficPerm(apps);
+        mUsersTrafficPermissions.put(user, addedUserAppIds);
+        // Generate appIds from all users and send result to netd.
+        final SparseIntArray appIds = makeAppIdsTrafficPermForAllUsers();
+        sendAppIdsTrafficPermission(appIds);
+
+        // Log user added
+        mPermissionUpdateLogs.log("New user(" + user.getIdentifier() + ") added: nPerm uids="
+                + uids + ", tPerm appIds=" + addedUserAppIds);
     }
 
     /**
@@ -502,6 +531,7 @@
     public synchronized void onUserRemoved(@NonNull UserHandle user) {
         mUsers.remove(user);
 
+        // Remove uids network permissions that belongs to the user.
         final SparseIntArray removedUids = new SparseIntArray();
         final SparseIntArray allUids = mUidToNetworkPerm.clone();
         for (int i = 0; i < allUids.size(); i++) {
@@ -512,6 +542,27 @@
             }
         }
         sendUidsNetworkPermission(removedUids, false /* add */);
+
+        // Remove appIds traffic permission that belongs to the user
+        final SparseIntArray removedUserAppIds = mUsersTrafficPermissions.remove(user);
+        // Generate appIds from left users.
+        final SparseIntArray appIds = makeAppIdsTrafficPermForAllUsers();
+        // Clear permission on those appIds belong to this user only, set the permission to
+        // PERMISSION_UNINSTALLED.
+        if (removedUserAppIds != null) {
+            for (int i = 0; i < removedUserAppIds.size(); i++) {
+                final int appId = removedUserAppIds.keyAt(i);
+                // Need to clear permission if the removed appId is not found in the array.
+                if (appIds.indexOfKey(appId) < 0) {
+                    appIds.put(appId, PERMISSION_UNINSTALLED);
+                }
+            }
+        }
+        sendAppIdsTrafficPermission(appIds);
+
+        // Log user removed
+        mPermissionUpdateLogs.log("User(" + user.getIdentifier() + ") removed: nPerm uids="
+                + removedUids + ", tPerm appIds=" + removedUserAppIds);
     }
 
     /**
@@ -598,6 +649,39 @@
         }
     }
 
+    private synchronized void updateAppIdTrafficPermission(int uid) {
+        final int appId = UserHandle.getAppId(uid);
+        final int uidTrafficPerm = getTrafficPermissionForUid(uid);
+        final SparseIntArray userTrafficPerms =
+                mUsersTrafficPermissions.get(UserHandle.getUserHandleForUid(uid));
+        if (userTrafficPerms == null) {
+            Log.wtf(TAG, "Can't get user traffic permission from uid=" + uid);
+            return;
+        }
+        // Do not put PERMISSION_UNINSTALLED into the array. If no package left on the uid
+        // (PERMISSION_UNINSTALLED), remove the appId from the array. Otherwise, update the latest
+        // permission to the appId.
+        if (uidTrafficPerm == PERMISSION_UNINSTALLED) {
+            userTrafficPerms.delete(appId);
+        } else {
+            userTrafficPerms.put(appId, uidTrafficPerm);
+        }
+    }
+
+    private synchronized int getAppIdTrafficPermission(int appId) {
+        int permission = PERMISSION_NONE;
+        boolean installed = false;
+        for (UserHandle user : mUsersTrafficPermissions.keySet()) {
+            final SparseIntArray userApps = mUsersTrafficPermissions.get(user);
+            final int appIdx = userApps.indexOfKey(appId);
+            if (appIdx >= 0) {
+                permission |= userApps.valueAt(appIdx);
+                installed = true;
+            }
+        }
+        return installed ? permission : PERMISSION_UNINSTALLED;
+    }
+
     /**
      * Called when a package is added.
      *
@@ -607,9 +691,12 @@
      * @hide
      */
     public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
+        // Update uid permission.
+        updateAppIdTrafficPermission(uid);
+        // Get the appId permission from all users then send the latest permission to netd.
         final int appId = UserHandle.getAppId(uid);
-        final int trafficPerm = getTrafficPermissionForUid(uid);
-        sendPackagePermissionsForAppId(appId, trafficPerm);
+        final int appIdTrafficPerm = getAppIdTrafficPermission(appId);
+        sendPackagePermissionsForAppId(appId, appIdTrafficPerm);
 
         final int currentPermission = mUidToNetworkPerm.get(uid, PERMISSION_NONE);
         final int permission = highestPermissionForUid(uid, currentPermission, packageName);
@@ -633,10 +720,12 @@
         // package can bypass VPN.
         updateVpnUid(uid, true /* add */);
         mAllApps.add(appId);
+
+        // Log package added.
         mPermissionUpdateLogs.log("Package add: name=" + packageName + ", uid=" + uid
                 + ", nPerm=(" + permissionToString(permission) + "/"
                 + permissionToString(currentPermission) + ")"
-                + ", tPerm=" + permissionToString(trafficPerm));
+                + ", tPerm=" + permissionToString(appIdTrafficPerm));
     }
 
     private int highestUidNetworkPermission(int uid) {
@@ -664,9 +753,12 @@
      * @hide
      */
     public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
+        // Update uid permission.
+        updateAppIdTrafficPermission(uid);
+        // Get the appId permission from all users then send the latest permission to netd.
         final int appId = UserHandle.getAppId(uid);
-        final int trafficPerm = getTrafficPermissionForUid(uid);
-        sendPackagePermissionsForAppId(appId, trafficPerm);
+        final int appIdTrafficPerm = getAppIdTrafficPermission(appId);
+        sendPackagePermissionsForAppId(appId, appIdTrafficPerm);
 
         // If the newly-removed package falls within some VPN's uid range, update Netd with it.
         // This needs to happen before the mUidToNetworkPerm update below, since
@@ -680,10 +772,13 @@
 
         final int currentPermission = mUidToNetworkPerm.get(uid, PERMISSION_NONE);
         final int permission = highestUidNetworkPermission(uid);
+
+        // Log package removed.
         mPermissionUpdateLogs.log("Package remove: name=" + packageName + ", uid=" + uid
                 + ", nPerm=(" + permissionToString(permission) + "/"
                 + permissionToString(currentPermission) + ")"
-                + ", tPerm=" + permissionToString(trafficPerm));
+                + ", tPerm=" + permissionToString(appIdTrafficPerm));
+
         if (permission != currentPermission) {
             final SparseIntArray apps = new SparseIntArray();
             int sdkSandboxUid = -1;
diff --git a/tests/common/AndroidTest_Coverage.xml b/tests/common/AndroidTest_Coverage.xml
index 7c8e710..d4898b2 100644
--- a/tests/common/AndroidTest_Coverage.xml
+++ b/tests/common/AndroidTest_Coverage.xml
@@ -18,6 +18,8 @@
     </target_preparer>
 
     <option name="test-tag" value="ConnectivityCoverageTests" />
+    <!-- Tethering/Connectivity is a SDK 30+ module -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
     <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.connectivity.tests.coverage" />
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index d40bc9f..9055861 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -590,6 +590,7 @@
     }
 
     @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+    @AppModeFull(reason = "Cannot get installed packages in instant app mode")
     @Test
     public void testGetRedactedLinkPropertiesForPackage() throws Exception {
         final String groundedPkg = findPackageByPermissions(
@@ -675,6 +676,7 @@
     }
 
     @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+    @AppModeFull(reason = "Cannot get installed packages in instant app mode")
     @Test
     public void testGetRedactedNetworkCapabilitiesForPackage() throws Exception {
         final String groundedPkg = findPackageByPermissions(
diff --git a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
index 2737258..30e0015 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -17,7 +17,9 @@
 
 import android.Manifest.permission.MANAGE_TEST_NETWORKS
 import android.Manifest.permission.NETWORK_SETTINGS
+import android.net.InetAddresses
 import android.net.IpConfiguration
+import android.net.MacAddress
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
 import android.platform.test.annotations.AppModeFull
@@ -32,6 +34,7 @@
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import android.content.Context
 import org.junit.runner.RunWith
 import kotlin.test.assertNull
 import kotlin.test.fail
@@ -46,10 +49,15 @@
 import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_CLIENT
 import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_NONE
 import com.android.networkstack.apishim.EthernetManagerShimImpl
+import com.android.testutils.RouterAdvertisementResponder
+import com.android.testutils.TapPacketReader
+import com.android.testutils.waitForIdle
+import java.net.Inet6Address
 import java.util.concurrent.Executor
 import kotlin.test.assertFalse
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
+import java.net.NetworkInterface
 
 private const val TIMEOUT_MS = 1000L
 private const val NO_CALLBACK_TIMEOUT_MS = 200L
@@ -66,9 +74,40 @@
     private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
     private val em by lazy { EthernetManagerShimImpl.newInstance(context) }
 
-    private val createdIfaces = ArrayList<TestNetworkInterface>()
+    private val createdIfaces = ArrayList<EthernetTestInterface>()
     private val addedListeners = ArrayList<InterfaceStateListener>()
 
+    private class EthernetTestInterface(
+        context: Context,
+        private val handler: Handler
+    ) {
+        private val tapInterface: TestNetworkInterface
+        private val packetReader: TapPacketReader
+        private val raResponder: RouterAdvertisementResponder
+        val interfaceName get() = tapInterface.interfaceName
+
+        init {
+            tapInterface = runAsShell(MANAGE_TEST_NETWORKS) {
+                val tnm = context.getSystemService(TestNetworkManager::class.java)
+                tnm.createTapInterface(false /* bringUp */)
+            }
+            val mtu = NetworkInterface.getByName(tapInterface.interfaceName).getMTU()
+            packetReader = TapPacketReader(handler, tapInterface.fileDescriptor.fileDescriptor, mtu)
+            raResponder = RouterAdvertisementResponder(packetReader)
+            raResponder.addRouterEntry(MacAddress.fromString("01:23:45:67:89:ab"),
+                    InetAddresses.parseNumericAddress("fe80::abcd") as Inet6Address)
+
+            packetReader.startAsyncForTest()
+            raResponder.start()
+        }
+
+        fun destroy() {
+            raResponder.stop()
+            handler.post({ packetReader.stop() })
+            handler.waitForIdle(TIMEOUT_MS)
+        }
+    }
+
     private open class EthernetStateListener private constructor(
         private val history: ArrayTrackRecord<CallbackEntry>
     ) : InterfaceStateListener,
@@ -101,7 +140,7 @@
             return event as T
         }
 
-        fun expectCallback(iface: TestNetworkInterface, state: Int, role: Int) {
+        fun expectCallback(iface: EthernetTestInterface, state: Int, role: Int) {
             expectCallback(InterfaceStateChanged(iface.interfaceName, state, role,
                 if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null))
         }
@@ -116,23 +155,55 @@
         }
     }
 
+    @Before
+    fun setUp() {
+        setIncludeTestInterfaces(true)
+    }
+
+    @After
+    fun tearDown() {
+        setIncludeTestInterfaces(false)
+        for (iface in createdIfaces) {
+            iface.destroy()
+        }
+        for (listener in addedListeners) {
+            em.removeInterfaceStateListener(listener)
+        }
+    }
+
+    private fun addInterfaceStateListener(executor: Executor, listener: InterfaceStateListener) {
+        em.addInterfaceStateListener(executor, listener)
+        addedListeners.add(listener)
+    }
+
+    private fun createInterface(): EthernetTestInterface {
+        return EthernetTestInterface(context, Handler(Looper.getMainLooper()))
+    }
+
+    private fun setIncludeTestInterfaces(value: Boolean) {
+        runAsShell(NETWORK_SETTINGS) {
+            em.setIncludeTestInterfaces(value)
+        }
+    }
+
+    private fun removeInterface(iface: EthernetTestInterface) {
+        iface.destroy()
+        createdIfaces.remove(iface)
+    }
+
     @Test
     public fun testCallbacks() {
         val executor = HandlerExecutor(Handler(Looper.getMainLooper()))
 
         // If an interface exists when the callback is registered, it is reported on registration.
-        val iface = runAsShell(MANAGE_TEST_NETWORKS) {
-            createInterface()
-        }
+        val iface = createInterface()
         val listener = EthernetStateListener()
         addInterfaceStateListener(executor, listener)
         listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
 
         // If an interface appears, existing callbacks see it.
         // TODO: fix the up/up/down/up callbacks and only send down/up.
-        val iface2 = runAsShell(MANAGE_TEST_NETWORKS) {
-            createInterface()
-        }
+        val iface2 = createInterface()
         listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
         listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
         listener.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
@@ -149,66 +220,25 @@
         listener.assertNoCallback()
     }
 
-    @Before
-    fun setUp() {
-        runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) {
-            em.setIncludeTestInterfaces(true)
-        }
-    }
-
-    @After
-    fun tearDown() {
-        runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) {
-            em.setIncludeTestInterfaces(false)
-            for (iface in createdIfaces) {
-                if (iface.fileDescriptor.fileDescriptor.valid()) iface.fileDescriptor.close()
-            }
-            for (listener in addedListeners) {
-                em.removeInterfaceStateListener(listener)
-            }
-        }
-    }
-
-    private fun addInterfaceStateListener(executor: Executor, listener: InterfaceStateListener) {
-        em.addInterfaceStateListener(executor, listener)
-        addedListeners.add(listener)
-    }
-
-    private fun createInterface(): TestNetworkInterface {
-        val tnm = context.getSystemService(TestNetworkManager::class.java)
-        return tnm.createTapInterface(false /* bringUp */).also { createdIfaces.add(it) }
-    }
-
-    private fun removeInterface(iface: TestNetworkInterface) {
-        iface.fileDescriptor.close()
-        createdIfaces.remove(iface)
-    }
-
-    private fun doTestGetInterfaceList() {
-        em.setIncludeTestInterfaces(true)
+    @Test
+    public fun testGetInterfaceList() {
+        setIncludeTestInterfaces(true)
 
         // Create two test interfaces and check the return list contains the interface names.
         val iface1 = createInterface()
         val iface2 = createInterface()
         var ifaces = em.getInterfaceList()
         assertTrue(ifaces.size > 0)
-        assertTrue(ifaces.contains(iface1.getInterfaceName()))
-        assertTrue(ifaces.contains(iface2.getInterfaceName()))
+        assertTrue(ifaces.contains(iface1.interfaceName))
+        assertTrue(ifaces.contains(iface2.interfaceName))
 
         // Remove one existing test interface and check the return list doesn't contain the
         // removed interface name.
         removeInterface(iface1)
         ifaces = em.getInterfaceList()
-        assertFalse(ifaces.contains(iface1.getInterfaceName()))
-        assertTrue(ifaces.contains(iface2.getInterfaceName()))
+        assertFalse(ifaces.contains(iface1.interfaceName))
+        assertTrue(ifaces.contains(iface2.interfaceName))
 
         removeInterface(iface2)
     }
-
-    @Test
-    public fun testGetInterfaceList() {
-        runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) {
-            doTestGetInterfaceList()
-        }
-    }
 }
diff --git a/tests/native/Android.bp b/tests/native/Android.bp
index 9c286d8..a8d908a 100644
--- a/tests/native/Android.bp
+++ b/tests/native/Android.bp
@@ -9,8 +9,8 @@
         "mts-tethering",
         "vts",
     ],
+    test_config_template: "AndroidTestTemplate.xml",
     min_sdk_version: "31",
-    require_root: true,
     tidy: false,
     srcs: [
         "connectivity_native_test.cpp",
@@ -30,5 +30,4 @@
         "libutils",
     ],
     compile_multilib: "first",
-    defaults: ["connectivity-mainline-presubmit-cc-defaults"],
 }
diff --git a/tests/native/AndroidTestTemplate.xml b/tests/native/AndroidTestTemplate.xml
new file mode 100644
index 0000000..44e35a9
--- /dev/null
+++ b/tests/native/AndroidTestTemplate.xml
@@ -0,0 +1,30 @@
+<!-- Copyright (C) 2022 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.
+-->
+<configuration description="Configuration for connectivity {MODULE} tests">
+    <option name="test-suite-tag" value="mts" />
+    <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
+    <!-- The tested code is only part of a SDK 30+ module (Tethering) -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="{MODULE}" />
+    </test>
+</configuration>
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 4c63cba..545f7b9 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());
-    }
-}
diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
index 6b379e8..fb821c3 100644
--- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -117,23 +117,32 @@
 public class PermissionMonitorTest {
     private static final int MOCK_USER_ID1 = 0;
     private static final int MOCK_USER_ID2 = 1;
+    private static final int MOCK_USER_ID3 = 2;
     private static final UserHandle MOCK_USER1 = UserHandle.of(MOCK_USER_ID1);
     private static final UserHandle MOCK_USER2 = UserHandle.of(MOCK_USER_ID2);
+    private static final UserHandle MOCK_USER3 = UserHandle.of(MOCK_USER_ID3);
     private static final int MOCK_APPID1 = 10001;
     private static final int MOCK_APPID2 = 10086;
+    private static final int MOCK_APPID3 = 10110;
     private static final int SYSTEM_APPID1 = 1100;
     private static final int SYSTEM_APPID2 = 1108;
     private static final int VPN_APPID = 10002;
     private static final int MOCK_UID11 = MOCK_USER1.getUid(MOCK_APPID1);
     private static final int MOCK_UID12 = MOCK_USER1.getUid(MOCK_APPID2);
+    private static final int MOCK_UID13 = MOCK_USER1.getUid(MOCK_APPID3);
     private static final int SYSTEM_APP_UID11 = MOCK_USER1.getUid(SYSTEM_APPID1);
     private static final int VPN_UID = MOCK_USER1.getUid(VPN_APPID);
     private static final int MOCK_UID21 = MOCK_USER2.getUid(MOCK_APPID1);
     private static final int MOCK_UID22 = MOCK_USER2.getUid(MOCK_APPID2);
+    private static final int MOCK_UID23 = MOCK_USER2.getUid(MOCK_APPID3);
     private static final int SYSTEM_APP_UID21 = MOCK_USER2.getUid(SYSTEM_APPID1);
+    private static final int MOCK_UID31 = MOCK_USER3.getUid(MOCK_APPID1);
+    private static final int MOCK_UID32 = MOCK_USER3.getUid(MOCK_APPID2);
+    private static final int MOCK_UID33 = MOCK_USER3.getUid(MOCK_APPID3);
     private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
     private static final String MOCK_PACKAGE1 = "appName1";
     private static final String MOCK_PACKAGE2 = "appName2";
+    private static final String MOCK_PACKAGE3 = "appName3";
     private static final String SYSTEM_PACKAGE1 = "sysName1";
     private static final String SYSTEM_PACKAGE2 = "sysName2";
     private static final String PARTITION_SYSTEM = "system";
@@ -191,6 +200,7 @@
         mBpfMapMonitor = new BpfMapMonitor(mBpfNetMaps);
 
         doReturn(List.of()).when(mPackageManager).getInstalledPackagesAsUser(anyInt(), anyInt());
+        mPermissionMonitor.onUserAdded(MOCK_USER1);
     }
 
     private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion,
@@ -283,6 +293,18 @@
         mPermissionMonitor.onPackageAdded(packageName, uid);
     }
 
+    private void removePackage(String packageName, int uid) {
+        final String[] oldPackages = mPackageManager.getPackagesForUid(uid);
+        // If the package isn't existed, no need to remove it.
+        if (!CollectionUtils.contains(oldPackages, packageName)) return;
+
+        // Remove the package if this uid is shared with other packages.
+        final String[] newPackages = Arrays.stream(oldPackages).filter(e -> !e.equals(packageName))
+                .toArray(String[]::new);
+        doReturn(newPackages).when(mPackageManager).getPackagesForUid(eq(uid));
+        mPermissionMonitor.onPackageRemoved(packageName, uid);
+    }
+
     @Test
     public void testHasPermission() {
         PackageInfo app = systemPackageInfoWithPermissions();
@@ -791,6 +813,7 @@
                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11);
+        doReturn(List.of(MOCK_USER1, MOCK_USER2)).when(mUserManager).getUserHandles(eq(true));
 
         mPermissionMonitor.startMonitoring();
         final Set<UidRange> vpnRange = Set.of(UidRange.createForUser(MOCK_USER1),
@@ -881,7 +904,7 @@
         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
 
-        // Install another package with the same uid and no permissions should not cause the app id
+        // Install another package with the same uid and no permissions should not cause the appId
         // to lose permissions.
         addPackage(MOCK_PACKAGE2, MOCK_UID11);
         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
@@ -1249,4 +1272,211 @@
         assertTrue(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_NETWORK));
         assertFalse(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_SYSTEM));
     }
+
+    private void prepareMultiUserPackages() {
+        // MOCK_USER1 has installed 3 packages
+        // mockApp1 has no permission and share MOCK_APPID1.
+        // mockApp2 has INTERNET permission and share MOCK_APPID2.
+        // mockApp3 has UPDATE_DEVICE_STATS permission and share MOCK_APPID3.
+        final List<PackageInfo> pkgs1 = List.of(
+                buildPackageInfo("mockApp1", MOCK_UID11),
+                buildPackageInfo("mockApp2", MOCK_UID12, INTERNET),
+                buildPackageInfo("mockApp3", MOCK_UID13, UPDATE_DEVICE_STATS));
+
+        // MOCK_USER2 has installed 2 packages
+        // mockApp4 has UPDATE_DEVICE_STATS permission and share MOCK_APPID1.
+        // mockApp5 has INTERNET permission and share MOCK_APPID2.
+        final List<PackageInfo> pkgs2 = List.of(
+                buildPackageInfo("mockApp4", MOCK_UID21, UPDATE_DEVICE_STATS),
+                buildPackageInfo("mockApp5", MOCK_UID23, INTERNET));
+
+        // MOCK_USER3 has installed 1 packages
+        // mockApp6 has UPDATE_DEVICE_STATS permission and share MOCK_APPID2.
+        final List<PackageInfo> pkgs3 = List.of(
+                buildPackageInfo("mockApp6", MOCK_UID32, UPDATE_DEVICE_STATS));
+
+        doReturn(pkgs1).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
+                eq(MOCK_USER_ID1));
+        doReturn(pkgs2).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
+                eq(MOCK_USER_ID2));
+        doReturn(pkgs3).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
+                eq(MOCK_USER_ID3));
+    }
+
+    private void addUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm,
+            int appId2Perm, int appId3Perm) {
+        mPermissionMonitor.onUserAdded(user);
+        mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1);
+        mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2);
+        mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3);
+    }
+
+    private void removeUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm,
+            int appId2Perm, int appId3Perm) {
+        mPermissionMonitor.onUserRemoved(user);
+        mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1);
+        mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2);
+        mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3);
+    }
+
+    @Test
+    public void testAppIdsTrafficPermission_UserAddedRemoved() {
+        prepareMultiUserPackages();
+
+        // Add MOCK_USER1 and verify the permissions with each appIds.
+        addUserAndVerifyAppIdsPermissions(MOCK_USER1, PERMISSION_NONE, PERMISSION_INTERNET,
+                PERMISSION_UPDATE_DEVICE_STATS);
+
+        // Add MOCK_USER2 and verify the permissions upgrade on MOCK_APPID1 & MOCK_APPID3.
+        addUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_UPDATE_DEVICE_STATS,
+                PERMISSION_INTERNET, PERMISSION_TRAFFIC_ALL);
+
+        // Add MOCK_USER3 and verify the permissions upgrade on MOCK_APPID2.
+        addUserAndVerifyAppIdsPermissions(MOCK_USER3, PERMISSION_UPDATE_DEVICE_STATS,
+                PERMISSION_TRAFFIC_ALL, PERMISSION_TRAFFIC_ALL);
+
+        // Remove MOCK_USER2 and verify the permissions downgrade on MOCK_APPID1 & MOCK_APPID3.
+        removeUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_NONE, PERMISSION_TRAFFIC_ALL,
+                PERMISSION_UPDATE_DEVICE_STATS);
+
+        // Remove MOCK_USER1 and verify the permissions downgrade on all appIds.
+        removeUserAndVerifyAppIdsPermissions(MOCK_USER1, PERMISSION_UNINSTALLED,
+                PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_UNINSTALLED);
+
+        // Add MOCK_USER2 back and verify the permissions upgrade on MOCK_APPID1 & MOCK_APPID3.
+        addUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_UPDATE_DEVICE_STATS,
+                PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_INTERNET);
+
+        // Remove MOCK_USER3 and verify the permissions downgrade on MOCK_APPID2.
+        removeUserAndVerifyAppIdsPermissions(MOCK_USER3, PERMISSION_UPDATE_DEVICE_STATS,
+                PERMISSION_UNINSTALLED, PERMISSION_INTERNET);
+    }
+
+    @Test
+    public void testAppIdsTrafficPermission_Multiuser_PackageAdded() throws Exception {
+        // Add two users with empty package list.
+        mPermissionMonitor.onUserAdded(MOCK_USER1);
+        mPermissionMonitor.onUserAdded(MOCK_USER2);
+
+        final int[] netdPermissions = {PERMISSION_NONE, PERMISSION_INTERNET,
+                PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_TRAFFIC_ALL};
+        final String[][] grantPermissions = {new String[]{}, new String[]{INTERNET},
+                new String[]{UPDATE_DEVICE_STATS}, new String[]{INTERNET, UPDATE_DEVICE_STATS}};
+
+        // Verify that the permission combination is expected when same appId package is installed
+        // on another user. List the expected permissions below.
+        // NONE                + NONE                = NONE
+        // NONE                + INTERNET            = INTERNET
+        // NONE                + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
+        // NONE                + ALL                 = ALL
+        // INTERNET            + NONE                = INTERNET
+        // INTERNET            + INTERNET            = INTERNET
+        // INTERNET            + UPDATE_DEVICE_STATS = ALL
+        // INTERNET            + ALL                 = ALL
+        // UPDATE_DEVICE_STATS + NONE                = UPDATE_DEVICE_STATS
+        // UPDATE_DEVICE_STATS + INTERNET            = ALL
+        // UPDATE_DEVICE_STATS + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
+        // UPDATE_DEVICE_STATS + ALL                 = ALL
+        // ALL                 + NONE                = ALL
+        // ALL                 + INTERNET            = ALL
+        // ALL                 + UPDATE_DEVICE_STATS = ALL
+        // ALL                 + ALL                 = ALL
+        for (int i = 0, num = 0; i < netdPermissions.length; i++) {
+            final int current = netdPermissions[i];
+            final String[] user1Perm = grantPermissions[i];
+            for (int j = 0; j < netdPermissions.length; j++) {
+                final int appId = MOCK_APPID1 + num;
+                final int added = netdPermissions[j];
+                final String[] user2Perm = grantPermissions[j];
+                // Add package on MOCK_USER1 and verify the permission is same as package granted.
+                addPackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId), user1Perm);
+                mBpfMapMonitor.expectTrafficPerm(current, appId);
+
+                // Add package which share the same appId on MOCK_USER2, and verify the permission
+                // has combined.
+                addPackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId), user2Perm);
+                mBpfMapMonitor.expectTrafficPerm((current | added), appId);
+                num++;
+            }
+        }
+    }
+
+    private void verifyAppIdPermissionsAfterPackageRemoved(int appId, int expectedPerm,
+            String[] user1Perm, String[] user2Perm) throws Exception {
+        // Add package on MOCK_USER1 and verify the permission is same as package granted.
+        addPackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId), user1Perm);
+        mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
+
+        // Add two packages which share the same appId and don't declare permission on
+        // MOCK_USER2. Verify the permission has no change.
+        addPackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId));
+        addPackage(MOCK_PACKAGE3, MOCK_USER2.getUid(appId), user2Perm);
+        mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
+
+        // Remove one packages from MOCK_USER2. Verify the permission has no change too.
+        removePackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId));
+        mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
+
+        // Remove last packages from MOCK_USER2. Verify the permission has still no change.
+        removePackage(MOCK_PACKAGE3, MOCK_USER2.getUid(appId));
+        mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
+    }
+
+    @Test
+    public void testAppIdsTrafficPermission_Multiuser_PackageRemoved() throws Exception {
+        // Add two users with empty package list.
+        mPermissionMonitor.onUserAdded(MOCK_USER1);
+        mPermissionMonitor.onUserAdded(MOCK_USER2);
+
+        int appId = MOCK_APPID1;
+        // Verify that the permission combination is expected when same appId package is removed on
+        // another user. List the expected permissions below.
+        /***** NONE *****/
+        // NONE + NONE = NONE
+        verifyAppIdPermissionsAfterPackageRemoved(
+                appId++, PERMISSION_NONE, new String[]{}, new String[]{});
+
+        /***** INTERNET *****/
+        // INTERNET + NONE = INTERNET
+        verifyAppIdPermissionsAfterPackageRemoved(
+                appId++, PERMISSION_INTERNET, new String[]{INTERNET}, new String[]{});
+
+        // INTERNET + INTERNET = INTERNET
+        verifyAppIdPermissionsAfterPackageRemoved(
+                appId++, PERMISSION_INTERNET, new String[]{INTERNET}, new String[]{INTERNET});
+
+        /***** UPDATE_DEVICE_STATS *****/
+        // UPDATE_DEVICE_STATS + NONE = UPDATE_DEVICE_STATS
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_UPDATE_DEVICE_STATS,
+                new String[]{UPDATE_DEVICE_STATS}, new String[]{});
+
+        // UPDATE_DEVICE_STATS + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_UPDATE_DEVICE_STATS,
+                new String[]{UPDATE_DEVICE_STATS}, new String[]{UPDATE_DEVICE_STATS});
+
+        /***** ALL *****/
+        // ALL + NONE = ALL
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
+                new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{});
+
+        // ALL + INTERNET = ALL
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
+                new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{INTERNET});
+
+        // ALL + UPDATE_DEVICE_STATS = ALL
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
+                new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{UPDATE_DEVICE_STATS});
+
+        // ALL + ALL = ALL
+        verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
+                new String[]{INTERNET, UPDATE_DEVICE_STATS},
+                new String[]{INTERNET, UPDATE_DEVICE_STATS});
+
+        /***** UNINSTALL *****/
+        // UNINSTALL + UNINSTALL = UNINSTALL
+        verifyAppIdPermissionsAfterPackageRemoved(
+                appId, PERMISSION_NONE, new String[]{}, new String[]{});
+        removePackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId));
+        mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, appId);
+    }
 }
