DO NOT MERGE: ApfTest: tag tests with @SmallTest or @MediumTest
am: 5d2654124e  -s ours

Change-Id: I8cfbe35c719dc2f135ec695f346c555fb45dfa58
diff --git a/cmds/uiautomator/library/Android.mk b/cmds/uiautomator/library/Android.mk
index d65b0833..af2e25a 100644
--- a/cmds/uiautomator/library/Android.mk
+++ b/cmds/uiautomator/library/Android.mk
@@ -18,7 +18,7 @@
 
 uiautomator.core_src_files := $(call all-java-files-under, core-src) \
 	$(call all-java-files-under, testrunner-src)
-uiautomator.core_java_libraries := android.test.runner core-junit
+uiautomator.core_java_libraries := android.test.runner junit
 
 uiautomator_internal_api_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_api.txt
 uiautomator_internal_removed_api_file := \
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 43c8c81..0afb546 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2592,8 +2592,7 @@
 
         /**
          * Called if no network is found in the given timeout time.  If no timeout is given,
-         * this will not be called. The associated {@link NetworkRequest} will have already
-         * been removed and released, as if {@link #unregisterNetworkCallback} had been called.
+         * this will not be called.
          * @hide
          */
         public void onUnavailable() {}
@@ -2666,26 +2665,6 @@
     /** @hide */
     public static final int CALLBACK_RESUMED             = BASE + 12;
 
-    /** @hide */
-    public static String getCallbackName(int whichCallback) {
-        switch (whichCallback) {
-            case CALLBACK_PRECHECK:     return "CALLBACK_PRECHECK";
-            case CALLBACK_AVAILABLE:    return "CALLBACK_AVAILABLE";
-            case CALLBACK_LOSING:       return "CALLBACK_LOSING";
-            case CALLBACK_LOST:         return "CALLBACK_LOST";
-            case CALLBACK_UNAVAIL:      return "CALLBACK_UNAVAIL";
-            case CALLBACK_CAP_CHANGED:  return "CALLBACK_CAP_CHANGED";
-            case CALLBACK_IP_CHANGED:   return "CALLBACK_IP_CHANGED";
-            case CALLBACK_RELEASED:     return "CALLBACK_RELEASED";
-            case CALLBACK_EXIT:         return "CALLBACK_EXIT";
-            case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
-            case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
-            case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
-            default:
-                return Integer.toString(whichCallback);
-        }
-    }
-
     private class CallbackHandler extends Handler {
         private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
         private final AtomicInteger mRefCount;
@@ -2852,7 +2831,7 @@
     private final static int REQUEST = 2;
 
     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
-            NetworkCallback networkCallback, int timeoutMs, int action,
+            NetworkCallback networkCallback, int timeoutSec, int action,
             int legacyType) {
         if (networkCallback == null) {
             throw new IllegalArgumentException("null NetworkCallback");
@@ -2868,7 +2847,7 @@
                             new Messenger(sCallbackHandler), new Binder());
                 } else {
                     networkCallback.networkRequest = mService.requestNetwork(need,
-                            new Messenger(sCallbackHandler), timeoutMs, new Binder(), legacyType);
+                            new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
                 }
                 if (networkCallback.networkRequest != null) {
                     sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 59cbf6e..542a0a7 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -56,17 +56,26 @@
     void disableScoring();
 
     /**
-     * Register a network subsystem for scoring.
+     * Register a cache to receive scoring updates.
      *
      * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
      * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
      * @throws SecurityException if the caller is not the system.
-     * @throws IllegalArgumentException if a score cache is already registed for this type.
      * @hide
      */
     void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
 
     /**
+     * Unregister a cache to receive scoring updates.
+     *
+     * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
+     * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
+     * @throws SecurityException if the caller is not the system.
+     * @hide
+     */
+    void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
+
+    /**
      * Request a recommendation for the best network to connect to
      * taking into account the inputs from the {@link RecommendationRequest}.
      *
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c301fe3..af21cef 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -279,6 +279,24 @@
     }
 
     /**
+     * Unregister a network score cache.
+     *
+     * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
+     * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
+     * @throws SecurityException if the caller does not hold the
+     *         {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+     * @throws IllegalArgumentException if a score cache is already registered for this type.
+     * @hide
+     */
+    public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+        try {
+            mService.unregisterNetworkScoreCache(networkType, scoreCache);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Request a recommendation for which network to connect to.
      *
      * @param request a {@link RecommendationRequest} instance containing additional
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1a8ba74..1350bfa 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7646,6 +7646,8 @@
 
         /**
          * Value to specify if Wi-Fi Wakeup feature is enabled.
+         *
+         * Type: int (0 for false, 1 for true)
          * @hide
          */
         @SystemApi
@@ -7654,6 +7656,8 @@
         /**
          * Value to specify if network recommendations from
          * {@link com.android.server.NetworkScoreService} are enabled.
+         *
+         * Type: int (0 for false, 1 for true)
          * @hide
          */
         @SystemApi
@@ -8024,45 +8028,11 @@
         public static final String PAC_CHANGE_DELAY = "pac_change_delay";
 
         /**
-         * Don't attempt to detect captive portals.
-         *
-         * @hide
-         */
-        public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
-        /**
-         * When detecting a captive portal, display a notification that
-         * prompts the user to sign in.
-         *
-         * @hide
-         */
-        public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
-        /**
-         * When detecting a captive portal, immediately disconnect from the
-         * network and do not reconnect to that network in the future.
-         *
-         * @hide
-         */
-        public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
-        /**
-         * What to do when connecting a network that presents a captive portal.
-         * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
-         *
-         * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
-         * @hide
-         */
-        public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
-        /**
          * Setting to turn off captive portal detection. Feature is enabled by
          * default and the setting needs to be set to 0 to disable it.
          *
-         * @deprecated use CAPTIVE_PORTAL_MODE_IGNORE to disable captive portal detection
          * @hide
          */
-        @Deprecated
         public static final String
                 CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
 
diff --git a/core/java/com/android/internal/os/TransferPipe.java b/core/java/com/android/internal/os/TransferPipe.java
index e76b395..f904150 100644
--- a/core/java/com/android/internal/os/TransferPipe.java
+++ b/core/java/com/android/internal/os/TransferPipe.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import java.io.Closeable;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -32,13 +33,13 @@
 /**
  * Helper for transferring data through a pipe from a client app.
  */
-public final class TransferPipe implements Runnable {
+public final class TransferPipe implements Runnable, Closeable {
     static final String TAG = "TransferPipe";
     static final boolean DEBUG = false;
 
     static final long DEFAULT_TIMEOUT = 5000;  // 5 seconds
 
-    final Thread mThread;;
+    final Thread mThread;
     final ParcelFileDescriptor[] mFds;
 
     FileDescriptor mOutFd;
@@ -54,8 +55,13 @@
     }
 
     public TransferPipe() throws IOException {
+        this(null);
+    }
+
+    public TransferPipe(String bufferPrefix) throws IOException {
         mThread = new Thread(this, "TransferPipe");
         mFds = ParcelFileDescriptor.createPipe();
+        mBufferPrefix = bufferPrefix;
     }
 
     ParcelFileDescriptor getReadFd() {
@@ -70,6 +76,11 @@
         mBufferPrefix = prefix;
     }
 
+    public static void dumpAsync(IBinder binder, FileDescriptor out, String[] args)
+            throws IOException, RemoteException {
+        goDump(binder, out, args);
+    }
+
     static void go(Caller caller, IInterface iface, FileDescriptor out,
             String prefix, String[] args) throws IOException, RemoteException {
         go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
@@ -86,12 +97,9 @@
             return;
         }
 
-        TransferPipe tp = new TransferPipe();
-        try {
+        try (TransferPipe tp = new TransferPipe()) {
             caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
             tp.go(out, timeout);
-        } finally {
-            tp.kill();
         }
     }
 
@@ -111,12 +119,9 @@
             return;
         }
 
-        TransferPipe tp = new TransferPipe();
-        try {
+        try (TransferPipe tp = new TransferPipe()) {
             binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
             tp.go(out, timeout);
-        } finally {
-            tp.kill();
         }
     }
 
@@ -173,6 +178,11 @@
         }
     }
 
+    @Override
+    public void close() {
+        kill();
+    }
+
     public void kill() {
         synchronized (this) {
             closeFd(0);
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
index 981be11..6d1ebb4 100644
--- a/core/tests/utiltests/Android.mk
+++ b/core/tests/utiltests/Android.mk
@@ -14,7 +14,6 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
-    frameworks-base-testutils \
     mockito-target
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index fe5d8ca..0011002 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -27,3 +27,15 @@
 LOCAL_MODULE := legacy-test
 
 include $(BUILD_JAVA_LIBRARY)
+
+ifeq ($(HOST_OS),linux)
+# Build the legacy-performance-test-hostdex library
+# =================================================
+# This contains the android.test.PerformanceTestCase class only
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../core/java/android/test/PerformanceTestCase.java
+LOCAL_MODULE := legacy-performance-test-hostdex
+
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+endif  # HOST_OS == linux
diff --git a/location/java/android/location/IFusedProvider.aidl b/location/java/android/location/IFusedProvider.aidl
index 8870d2a..e86ad1a 100644
--- a/location/java/android/location/IFusedProvider.aidl
+++ b/location/java/android/location/IFusedProvider.aidl
@@ -22,11 +22,11 @@
  * Interface definition for Location providers that require FLP services.
  * @hide
  */
-interface IFusedProvider {
+oneway interface IFusedProvider {
     /**
      * Provides access to a FusedLocationHardware instance needed for the provider to work.
      *
      * @param instance      The FusedLocationHardware available for the provider to use.
      */
     void onFusedLocationHardwareChange(in IFusedLocationHardware instance);
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ca9a229..30edd9f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1813,14 +1813,11 @@
     private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
         final String iface = newLp.getInterfaceName();
         final int mtu = newLp.getMtu();
-        if (oldLp == null && mtu == 0) {
-            // Silently ignore unset MTU value.
-            return;
-        }
         if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
             if (VDBG) log("identical MTU - not setting");
             return;
         }
+
         if (LinkProperties.isValidMtu(mtu, newLp.hasGlobalIPv6Address()) == false) {
             if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
             return;
@@ -2266,19 +2263,11 @@
                     synchronized (mNetworkForNetId) {
                         nai = mNetworkForNetId.get(netId);
                     }
-                    // If captive portal status has changed, update capabilities or disconnect.
+                    // If captive portal status has changed, update capabilities.
                     if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
                         final int oldScore = nai.getCurrentScore();
                         nai.lastCaptivePortalDetected = visible;
                         nai.everCaptivePortalDetected |= visible;
-                        if (nai.lastCaptivePortalDetected &&
-                            Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
-                            if (DBG) log("Avoiding captive portal network: " + nai.name());
-                            nai.asyncChannel.sendMessage(
-                                    NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
-                            teardownUnneededNetwork(nai);
-                            break;
-                        }
                         updateCapabilities(oldScore, nai, nai.networkCapabilities);
                     }
                     if (!visible) {
@@ -2299,12 +2288,6 @@
             return true;
         }
 
-        private int getCaptivePortalMode() {
-            return Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.CAPTIVE_PORTAL_MODE,
-                    Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
-        }
-
         private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
             switch (msg.what) {
                 default:
@@ -2614,28 +2597,14 @@
                 "request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED);
     }
 
-    private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
-        if (mNetworkRequests.get(nri.request) != null && mNetworkForRequestId.get(
-                nri.request.requestId) == null) {
-            handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_UNAVAIL);
-        }
-    }
-
     private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
         final NetworkRequestInfo nri = getNriForAppRequest(
                 request, callingUid, "release NetworkRequest");
-        if (nri != null) {
-            handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_RELEASED);
-        }
-    }
+        if (nri == null) return;
 
-    private void handleRemoveNetworkRequest(final NetworkRequestInfo nri, final int whichCallback) {
-        final String logCallbackType = ConnectivityManager.getCallbackName(whichCallback);
-        if (VDBG || (DBG && nri.request.isRequest())) {
-            log("releasing " + nri.request + " (" + logCallbackType + ")");
-        }
+        if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
         nri.unlinkDeathRecipient();
-        mNetworkRequests.remove(nri.request);
+        mNetworkRequests.remove(request);
         synchronized (mUidToNetworkRequestCount) {
             int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
             if (requests < 1) {
@@ -2729,7 +2698,7 @@
                 }
             }
         }
-        callCallbackForRequest(nri, null, whichCallback, 0);
+        callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
     }
 
     @Override
@@ -2966,11 +2935,6 @@
                     handleRegisterNetworkRequestWithIntent(msg);
                     break;
                 }
-                case EVENT_TIMEOUT_NETWORK_REQUEST: {
-                    NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
-                    handleTimedOutNetworkRequest(nri);
-                    break;
-                }
                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
                     break;
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index df1b6f5..3ad264d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -25,6 +25,7 @@
 import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethod;
@@ -4030,9 +4031,9 @@
         if (client != null) {
             pw.flush();
             try {
-                client.client.asBinder().dump(fd, args);
-            } catch (RemoteException e) {
-                p.println("Input method client dead: " + e);
+                TransferPipe.dumpAsync(client.client.asBinder(), fd, args);
+            } catch (IOException | RemoteException e) {
+                p.println("Failed to dump input method client: " + e);
             }
         } else {
             p.println("No input method client.");
@@ -4046,9 +4047,9 @@
             p.println(" ");
             pw.flush();
             try {
-                focusedWindowClient.client.asBinder().dump(fd, args);
-            } catch (RemoteException e) {
-                p.println("Input method client in focused window dead: " + e);
+                TransferPipe.dumpAsync(focusedWindowClient.client.asBinder(), fd, args);
+            } catch (IOException | RemoteException e) {
+                p.println("Failed to dump input method client in focused window: " + e);
             }
         }
 
@@ -4056,9 +4057,9 @@
         if (method != null) {
             pw.flush();
             try {
-                method.asBinder().dump(fd, args);
-            } catch (RemoteException e) {
-                p.println("Input method service dead: " + e);
+                TransferPipe.dumpAsync(method.asBinder(), fd, args);
+            } catch (IOException | RemoteException e) {
+                p.println("Failed to dump input method service: " + e);
             }
         } else {
             p.println("No input method service.");
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 4e969be..6412e01 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -36,25 +36,29 @@
 import android.net.wifi.WifiConfiguration;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.TransferPipe;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Backing service for {@link android.net.NetworkScoreManager}.
@@ -66,7 +70,8 @@
 
     private final Context mContext;
     private final NetworkScorerAppManager mNetworkScorerAppManager;
-    private final Map<Integer, INetworkScoreCache> mScoreCaches;
+    @GuardedBy("mScoreCaches")
+    private final Map<Integer, RemoteCallbackList<INetworkScoreCache>> mScoreCaches;
     /** Lock used to update mPackageMonitor when scorer package changes occur. */
     private final Object mPackageMonitorLock = new Object[0];
 
@@ -164,7 +169,7 @@
     NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager) {
         mContext = context;
         mNetworkScorerAppManager = networkScoreAppManager;
-        mScoreCaches = new HashMap<>();
+        mScoreCaches = new ArrayMap<>();
         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
         // TODO: Need to update when we support per-user scorers. http://b/23422763
         mContext.registerReceiverAsUser(
@@ -274,7 +279,7 @@
         }
 
         // Separate networks by type.
-        Map<Integer, List<ScoredNetwork>> networksByType = new HashMap<>();
+        Map<Integer, List<ScoredNetwork>> networksByType = new ArrayMap<>();
         for (ScoredNetwork network : networks) {
             List<ScoredNetwork> networkList = networksByType.get(network.networkKey.type);
             if (networkList == null) {
@@ -285,19 +290,32 @@
         }
 
         // Pass the scores of each type down to the appropriate network scorer.
-        for (Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
-            INetworkScoreCache scoreCache = mScoreCaches.get(entry.getKey());
-            if (scoreCache != null) {
-                try {
-                    scoreCache.updateScores(entry.getValue());
-                } catch (RemoteException e) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+        for (final Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
+            final RemoteCallbackList<INetworkScoreCache> callbackList;
+            final boolean isEmpty;
+            synchronized (mScoreCaches) {
+                callbackList = mScoreCaches.get(entry.getKey());
+                isEmpty = callbackList == null || callbackList.getRegisteredCallbackCount() == 0;
+            }
+            if (isEmpty) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "No scorer registered for type " + entry.getKey() + ", discarding");
+                }
+                continue;
+            }
+
+            sendCallback(new Consumer<INetworkScoreCache>() {
+                @Override
+                public void accept(INetworkScoreCache networkScoreCache) {
+                    try {
+                        networkScoreCache.updateScores(entry.getValue());
+                    } catch (RemoteException e) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+                        }
                     }
                 }
-            } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.v(TAG, "No scorer registered for type " + entry.getKey() + ", discarding");
-            }
+            }, Collections.singleton(callbackList));
         }
 
         return true;
@@ -392,28 +410,52 @@
 
     /** Clear scores. Callers are responsible for checking permissions as appropriate. */
     private void clearInternal() {
-        Set<INetworkScoreCache> cachesToClear = getScoreCaches();
-
-        for (INetworkScoreCache scoreCache : cachesToClear) {
-            try {
-                scoreCache.clearScores();
-            } catch (RemoteException e) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Unable to clear scores", e);
+        sendCallback(new Consumer<INetworkScoreCache>() {
+            @Override
+            public void accept(INetworkScoreCache networkScoreCache) {
+                try {
+                    networkScoreCache.clearScores();
+                } catch (RemoteException e) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "Unable to clear scores", e);
+                    }
                 }
             }
-        }
+        }, getScoreCacheLists());
     }
 
     @Override
     public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
         mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
         synchronized (mScoreCaches) {
-            if (mScoreCaches.containsKey(networkType)) {
-                throw new IllegalArgumentException(
-                        "Score cache already registered for type " + networkType);
+            RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+            if (callbackList == null) {
+                callbackList = new RemoteCallbackList<>();
+                mScoreCaches.put(networkType, callbackList);
             }
-            mScoreCaches.put(networkType, scoreCache);
+            if (!callbackList.register(scoreCache)) {
+                if (callbackList.getRegisteredCallbackCount() == 0) {
+                    mScoreCaches.remove(networkType);
+                }
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "Unable to register NetworkScoreCache for type " + networkType);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+        mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+        synchronized (mScoreCaches) {
+            RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+            if (callbackList == null || !callbackList.unregister(scoreCache)) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "Unable to unregister NetworkScoreCache for type " + networkType);
+                }
+            } else if (callbackList.getRegisteredCallbackCount() == 0) {
+                mScoreCaches.remove(networkType);
+            }
         }
     }
 
@@ -428,7 +470,7 @@
     }
 
     @Override
-    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+    protected void dump(final FileDescriptor fd, final PrintWriter writer, final String[] args) {
         mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
         NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer();
         if (currentScorer == null) {
@@ -437,16 +479,17 @@
         }
         writer.println("Current scorer: " + currentScorer.mPackageName);
 
-        for (INetworkScoreCache scoreCache : getScoreCaches()) {
-            try {
-                scoreCache.asBinder().dump(fd, args);
-            } catch (RemoteException e) {
-                writer.println("Unable to dump score cache");
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Unable to dump score cache", e);
+        sendCallback(new Consumer<INetworkScoreCache>() {
+            @Override
+            public void accept(INetworkScoreCache networkScoreCache) {
+                try {
+                  TransferPipe.dumpAsync(networkScoreCache.asBinder(), fd, args);
+                } catch (IOException | RemoteException e) {
+                  writer.println("Failed to dump score cache: " + e);
                 }
             }
-        }
+        }, getScoreCacheLists());
+
         if (mServiceConnection != null) {
             mServiceConnection.dump(fd, writer, args);
         } else {
@@ -456,14 +499,30 @@
     }
 
     /**
-     * Returns a set of all score caches that are currently active.
+     * Returns a {@link Collection} of all {@link RemoteCallbackList}s that are currently active.
      *
      * <p>May be used to perform an action on all score caches without potentially strange behavior
      * if a new scorer is registered during that action's execution.
      */
-    private Set<INetworkScoreCache> getScoreCaches() {
+    private Collection<RemoteCallbackList<INetworkScoreCache>> getScoreCacheLists() {
         synchronized (mScoreCaches) {
-            return new HashSet<>(mScoreCaches.values());
+            return new ArrayList<>(mScoreCaches.values());
+        }
+    }
+
+    private void sendCallback(Consumer<INetworkScoreCache> consumer,
+            Collection<RemoteCallbackList<INetworkScoreCache>> remoteCallbackLists) {
+        for (RemoteCallbackList<INetworkScoreCache> callbackList : remoteCallbackLists) {
+            synchronized (callbackList) { // Ensure only one active broadcast per RemoteCallbackList
+                final int count = callbackList.beginBroadcast();
+                try {
+                    for (int i = 0; i < count; i++) {
+                        consumer.accept(callbackList.getBroadcastItem(i));
+                    }
+                } finally {
+                    callbackList.finishBroadcast();
+                }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index c73d1dd..6eb89fa 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -211,9 +211,7 @@
     private final NetworkRequest mDefaultRequest;
     private final IpConnectivityLog mMetricsLog;
 
-    @VisibleForTesting
-    protected boolean mIsCaptivePortalCheckEnabled;
-
+    private boolean mIsCaptivePortalCheckEnabled;
     private boolean mUseHttps;
 
     // Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
@@ -267,8 +265,7 @@
         setInitialState(mDefaultState);
 
         mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CAPTIVE_PORTAL_MODE, Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT)
-                != Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE;
+                Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1;
         mUseHttps = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
 
@@ -635,10 +632,7 @@
 
     @VisibleForTesting
     protected CaptivePortalProbeResult isCaptivePortal() {
-        if (!mIsCaptivePortalCheckEnabled) {
-            validationLog("Validation disabled.");
-            return new CaptivePortalProbeResult(204);
-        }
+        if (!mIsCaptivePortalCheckEnabled) return new CaptivePortalProbeResult(204);
 
         URL pacUrl = null, httpsUrl = null, httpUrl = null, fallbackUrl = null;
 
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6d96a10..0beb227 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -71,7 +71,6 @@
 import com.android.internal.util.StateMachine;
 import com.android.server.connectivity.tethering.IControlsTethering;
 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
-import com.android.server.connectivity.tethering.IPv6TetheringInterfaceServices;
 import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -1940,8 +1939,7 @@
     private void trackNewTetherableInterface(String iface, int interfaceType) {
         TetherState tetherState;
         tetherState = new TetherState(new TetherInterfaceStateMachine(iface, mLooper,
-                interfaceType, mNMService, mStatsService, this,
-                new IPv6TetheringInterfaceServices(iface, mNMService)));
+                interfaceType, mNMService, mStatsService, this));
         mTetherStates.put(iface, tetherState);
         tetherState.mStateMachine.start();
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
index dec2f77..c2c1a8c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
@@ -45,7 +45,7 @@
 /**
  * @hide
  */
-public class IPv6TetheringInterfaceServices {
+class IPv6TetheringInterfaceServices {
     private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName();
     private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
     private static final int RFC7421_IP_PREFIX_LENGTH = 64;
@@ -59,7 +59,7 @@
     private RouterAdvertisementDaemon mRaDaemon;
     private RaParams mLastRaParams;
 
-    public IPv6TetheringInterfaceServices(String ifname, INetworkManagementService nms) {
+    IPv6TetheringInterfaceServices(String ifname, INetworkManagementService nms) {
         mIfName = ifname;
         mNMService = nms;
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 37221a9..6ca4e27 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -94,14 +94,14 @@
 
     public TetherInterfaceStateMachine(String ifaceName, Looper looper, int interfaceType,
                     INetworkManagementService nMService, INetworkStatsService statsService,
-                    IControlsTethering tetherController, IPv6TetheringInterfaceServices ipv6Svc) {
+                    IControlsTethering tetherController) {
         super(ifaceName, looper);
         mNMService = nMService;
         mStatsService = statsService;
         mTetherController = tetherController;
         mIfaceName = ifaceName;
         mInterfaceType = interfaceType;
-        mIPv6TetherSvc = ipv6Svc;
+        mIPv6TetherSvc = new IPv6TetheringInterfaceServices(mIfaceName, mNMService);
         mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
 
         mInitialState = new InitialState();
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 5eb06ed..b44087c 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -17,6 +17,7 @@
 package com.android.server.location;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
 
 import android.content.Context;
@@ -30,6 +31,7 @@
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ILocationProvider;
 import com.android.internal.location.ProviderRequest;
+import com.android.internal.os.TransferPipe;
 import com.android.server.LocationManagerService;
 import com.android.server.ServiceWatcher;
 
@@ -230,14 +232,9 @@
         pw.flush();
 
         try {
-            service.asBinder().dump(fd, args);
-        } catch (RemoteException e) {
-            pw.println("service down (RemoteException)");
-            Log.w(TAG, e);
-        } catch (Exception e) {
-            pw.println("service down (Exception)");
-            // never let remote service crash system server
-            Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
+            TransferPipe.dumpAsync(service.asBinder(), fd, args);
+        } catch (IOException | RemoteException e) {
+            pw.println("Failed to dump location provider: " + e);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 68b465a..07d98bc 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -32,7 +32,10 @@
 import android.os.UserHandle;
 import android.util.TimedRemoteCaller;
 
+import com.android.internal.os.TransferPipe;
+
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -85,13 +88,11 @@
                     .append((mRemoteInstance != null) ? "true" : "false").println();
 
             pw.flush();
-
             try {
-                getRemoteInstanceLazy().asBinder().dump(fd, new String[] { prefix });
-            } catch (TimeoutException te) {
-                /* ignore */
-            } catch (RemoteException re) {
-                /* ignore */
+                TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
+                        new String[] { prefix });
+            } catch (IOException | TimeoutException | RemoteException e) {
+                pw.println("Failed to dump remote instance: " + e);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index d8f6b80..bff68d8 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -204,35 +204,70 @@
                 outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries);
     }
 
-    public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
-        return mInstaller.mergeProfiles(uid, pkgName);
+    public boolean mergeProfiles(int uid, String packageName) throws InstallerException {
+        checkLock();
+        try {
+            return mInstalld.mergeProfiles(uid, packageName);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
-    public boolean dumpProfiles(String gid, String packageName, String codePaths)
+    public boolean dumpProfiles(int uid, String packageName, String codePaths)
             throws InstallerException {
-        return mInstaller.dumpProfiles(gid, packageName, codePaths);
+        checkLock();
+        try {
+            return mInstalld.dumpProfiles(uid, packageName, codePaths);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void idmap(String targetApkPath, String overlayApkPath, int uid)
             throws InstallerException {
-        mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid);
+        checkLock();
+        try {
+            mInstalld.idmap(targetApkPath, overlayApkPath, uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void rmdex(String codePath, String instructionSet) throws InstallerException {
         assertValidInstructionSet(instructionSet);
-        mInstaller.execute("rmdex", codePath, instructionSet);
+        checkLock();
+        try {
+            mInstalld.rmdex(codePath, instructionSet);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void rmPackageDir(String packageDir) throws InstallerException {
-        mInstaller.execute("rmpackagedir", packageDir);
+        checkLock();
+        try {
+            mInstalld.rmPackageDir(packageDir);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
-    public void clearAppProfiles(String pkgName) throws InstallerException {
-        mInstaller.execute("clear_app_profiles", pkgName);
+    public void clearAppProfiles(String packageName) throws InstallerException {
+        checkLock();
+        try {
+            mInstalld.clearAppProfiles(packageName);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
-    public void destroyAppProfiles(String pkgName) throws InstallerException {
-        mInstaller.execute("destroy_app_profiles", pkgName);
+    public void destroyAppProfiles(String packageName) throws InstallerException {
+        checkLock();
+        try {
+            mInstalld.destroyAppProfiles(packageName);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void createUserData(String uuid, int userId, int userSerial, int flags)
@@ -256,11 +291,21 @@
 
     public void markBootComplete(String instructionSet) throws InstallerException {
         assertValidInstructionSet(instructionSet);
-        mInstaller.execute("markbootcomplete", instructionSet);
+        checkLock();
+        try {
+            mInstalld.markBootComplete(instructionSet);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void freeCache(String uuid, long freeStorageSize) throws InstallerException {
-        mInstaller.execute("freecache", uuid, freeStorageSize);
+        checkLock();
+        try {
+            mInstalld.freeCache(uuid, freeStorageSize);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     /**
@@ -268,29 +313,54 @@
      * directory to the real location for backward compatibility. Note that no
      * such symlink is created for 64 bit shared libraries.
      */
-    public void linkNativeLibraryDirectory(String uuid, String dataPath, String nativeLibPath32,
+    public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32,
             int userId) throws InstallerException {
-        mInstaller.execute("linklib", uuid, dataPath, nativeLibPath32, userId);
+        checkLock();
+        try {
+            mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void createOatDir(String oatDir, String dexInstructionSet)
             throws InstallerException {
-        mInstaller.execute("createoatdir", oatDir, dexInstructionSet);
+        checkLock();
+        try {
+            mInstalld.createOatDir(oatDir, dexInstructionSet);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void linkFile(String relativePath, String fromBase, String toBase)
             throws InstallerException {
-        mInstaller.execute("linkfile", relativePath, fromBase, toBase);
+        checkLock();
+        try {
+            mInstalld.linkFile(relativePath, fromBase, toBase);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void moveAb(String apkPath, String instructionSet, String outputPath)
             throws InstallerException {
-        mInstaller.execute("move_ab", apkPath, instructionSet, outputPath);
+        checkLock();
+        try {
+            mInstalld.moveAb(apkPath, instructionSet, outputPath);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     public void deleteOdex(String apkPath, String instructionSet, String outputPath)
             throws InstallerException {
-        mInstaller.execute("delete_odex", apkPath, instructionSet, outputPath);
+        checkLock();
+        try {
+            mInstalld.deleteOdex(apkPath, instructionSet, outputPath);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new InstallerException(e.getMessage());
+        }
     }
 
     private static void assertValidInstructionSet(String instructionSet)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 56a0173..9102fee 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7530,9 +7530,8 @@
             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
             try {
                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
-                String gid = Integer.toString(sharedGid);
                 String codePaths = TextUtils.join(";", allCodePaths);
-                mInstaller.dumpProfiles(gid, packageName, codePaths);
+                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
             } catch (InstallerException e) {
                 Slog.w(TAG, "Failed to dump profiles", e);
             }
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index a8356dc..4c75452 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -283,20 +283,14 @@
         mReceiveThread.start();
     }
 
-    // Returns seconds since device boot.
+    // Returns seconds since Unix Epoch.
+    // TODO: use SystemClock.elapsedRealtime() instead
     private static long curTime() {
-        return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
-    }
-
-    public static class InvalidRaException extends Exception {
-        public InvalidRaException(String m) {
-            super(m);
-        }
+        return System.currentTimeMillis() / DateUtils.SECOND_IN_MILLIS;
     }
 
     // A class to hold information about an RA.
-    @VisibleForTesting
-    class Ra {
+    private class Ra {
         // From RFC4861:
         private static final int ICMP6_RA_HEADER_LEN = 16;
         private static final int ICMP6_RA_CHECKSUM_OFFSET =
@@ -368,7 +362,7 @@
             } catch (UnsupportedOperationException e) {
                 // array() failed. Cannot happen, mPacket is array-backed and read-write.
                 return "???";
-            } catch (ClassCastException|UnknownHostException e) {
+            } catch (ClassCastException | UnknownHostException e) {
                 // Cannot happen.
                 return "???";
             }
@@ -378,16 +372,16 @@
         // TODO: Make this static once RA is its own class.
         private void prefixOptionToString(StringBuffer sb, int offset) {
             String prefix = IPv6AddresstoString(offset + 16);
-            int length = getUint8(mPacket, offset + 2);
-            long valid = getUint32(mPacket, offset + 4);
-            long preferred = getUint32(mPacket, offset + 8);
+            int length = uint8(mPacket.get(offset + 2));
+            long valid = mPacket.getInt(offset + 4);
+            long preferred = mPacket.getInt(offset + 8);
             sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
         }
 
         private void rdnssOptionToString(StringBuffer sb, int offset) {
-            int optLen = getUint8(mPacket, offset + 1) * 8;
+            int optLen = uint8(mPacket.get(offset + 1)) * 8;
             if (optLen < 24) return;  // Malformed or empty.
-            long lifetime = getUint32(mPacket, offset + 4);
+            long lifetime = uint32(mPacket.getInt(offset + 4));
             int numServers = (optLen - 8) / 16;
             sb.append("DNS ").append(lifetime).append("s");
             for (int server = 0; server < numServers; server++) {
@@ -401,7 +395,7 @@
                 sb.append(String.format("RA %s -> %s %ds ",
                         IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
                         IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
-                        getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
+                        uint16(mPacket.getShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET))));
                 for (int i: mPrefixOptionOffsets) {
                     prefixOptionToString(sb, i);
                 }
@@ -409,7 +403,7 @@
                     rdnssOptionToString(sb, i);
                 }
                 return sb.toString();
-            } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
+            } catch (BufferUnderflowException | IndexOutOfBoundsException e) {
                 return "<Malformed RA>";
             }
         }
@@ -442,20 +436,16 @@
         // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
         // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
         // specifications.
-        Ra(byte[] packet, int length) throws InvalidRaException {
-            if (length < ICMP6_RA_OPTION_OFFSET) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
+        Ra(byte[] packet, int length) {
             mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
             mLastSeen = curTime();
 
             // Sanity check packet in case a packet arrives before we attach RA filter
             // to our packet socket. b/29586253
             if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
-                    getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
-                    getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMP6_ROUTER_ADVERTISEMENT) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
+                    uint8(mPacket.get(IPV6_NEXT_HEADER_OFFSET)) != IPPROTO_ICMPV6 ||
+                    uint8(mPacket.get(ICMP6_TYPE_OFFSET)) != ICMP6_ROUTER_ADVERTISEMENT) {
+                throw new IllegalArgumentException("Not an ICMP6 router advertisement");
             }
 
 
@@ -476,8 +466,8 @@
             mPacket.position(ICMP6_RA_OPTION_OFFSET);
             while (mPacket.hasRemaining()) {
                 final int position = mPacket.position();
-                final int optionType = getUint8(mPacket, position);
-                final int optionLength = getUint8(mPacket, position + 1) * 8;
+                final int optionType = uint8(mPacket.get(position));
+                final int optionLength = uint8(mPacket.get(position + 1)) * 8;
                 long lifetime;
                 switch (optionType) {
                     case ICMP6_PREFIX_OPTION_TYPE:
@@ -521,7 +511,7 @@
                         break;
                 }
                 if (optionLength <= 0) {
-                    throw new InvalidRaException(String.format(
+                    throw new IllegalArgumentException(String.format(
                         "Invalid option length opt=%d len=%d", optionType, optionLength));
                 }
                 mPacket.position(position + optionLength);
@@ -562,10 +552,10 @@
                 final long optionLifetime;
                 switch (lifetimeLength) {
                     case 2:
-                        optionLifetime = getUint16(byteBuffer, offset);
+                        optionLifetime = uint16(byteBuffer.getShort(offset));
                         break;
                     case 4:
-                        optionLifetime = getUint32(byteBuffer, offset);
+                        optionLifetime = uint32(byteBuffer.getInt(offset));
                         break;
                     default:
                         throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
@@ -935,8 +925,8 @@
             // Execution will reach the end of the program if no filters match, which will pass the
             // packet to the AP.
             program = gen.generate();
-        } catch (IllegalInstructionException|IllegalStateException e) {
-            Log.e(TAG, "Failed to generate APF program.", e);
+        } catch (IllegalInstructionException e) {
+            Log.e(TAG, "Program failed to generate: ", e);
             return;
         }
         mLastTimeInstalledProgram = curTime();
@@ -982,8 +972,7 @@
      * if the current APF program should be updated.
      * @return a ProcessRaResult enum describing what action was performed.
      */
-    @VisibleForTesting
-    synchronized ProcessRaResult processRa(byte[] packet, int length) {
+    private synchronized ProcessRaResult processRa(byte[] packet, int length) {
         if (VDBG) hexDump("Read packet = ", packet, length);
 
         // Have we seen this RA before?
@@ -1022,7 +1011,7 @@
         try {
             ra = new Ra(packet, length);
         } catch (Exception e) {
-            Log.e(TAG, "Error parsing RA", e);
+            Log.e(TAG, "Error parsing RA: " + e);
             return ProcessRaResult.PARSE_ERROR;
         }
         // Ignore 0 lifetime RAs.
@@ -1161,11 +1150,7 @@
         return i & 0xffffffffL;
     }
 
-    private static int getUint8(ByteBuffer buffer, int position) {
-        return uint8(buffer.get(position));
-    }
-
-    private static int getUint16(ByteBuffer buffer, int position) {
+    private static long getUint16(ByteBuffer buffer, int position) {
         return uint16(buffer.getShort(position));
     }
 
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index a883e28..a6bb40c 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -50,9 +50,9 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -163,7 +163,8 @@
     private Map<InetAddress, Short> mIpWatchList = new HashMap<>();
     @GuardedBy("mLock")
     private int mIpWatchListVersion;
-    private volatile boolean mRunning;
+    @GuardedBy("mLock")
+    private boolean mRunning;
     // Time in milliseconds of the last forced probe request.
     private volatile long mLastProbeTimeMs;
 
@@ -245,7 +246,7 @@
     }
 
     public void stop() {
-        mRunning = false;
+        synchronized (mLock) { mRunning = false; }
         clearLinkProperties();
         mNetlinkSocketObserver.clearNetlinkSocket();
     }
@@ -280,6 +281,12 @@
         }
     }
 
+    private boolean stillRunning() {
+        synchronized (mLock) {
+            return mRunning;
+        }
+    }
+
     private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
         for (RouteInfo route : routes) {
             if (!route.hasGateway() && route.matches(ip)) {
@@ -383,12 +390,12 @@
     }
 
     public void probeAll() {
-        final List<InetAddress> ipProbeList;
+        Set<InetAddress> ipProbeList = new HashSet<InetAddress>();
         synchronized (mLock) {
-            ipProbeList = new ArrayList<>(mIpWatchList.keySet());
+            ipProbeList.addAll(mIpWatchList.keySet());
         }
 
-        if (!ipProbeList.isEmpty() && mRunning) {
+        if (!ipProbeList.isEmpty() && stillRunning()) {
             // Keep the CPU awake long enough to allow all ARP/ND
             // probes a reasonable chance at success. See b/23197666.
             //
@@ -399,7 +406,7 @@
         }
 
         for (InetAddress target : ipProbeList) {
-            if (!mRunning) {
+            if (!stillRunning()) {
                 break;
             }
             final int returnValue = probeNeighbor(mInterfaceIndex, target);
@@ -444,21 +451,21 @@
         @Override
         public void run() {
             if (VDBG) { Log.d(TAG, "Starting observing thread."); }
-            mRunning = true;
+            synchronized (mLock) { mRunning = true; }
 
             try {
                 setupNetlinkSocket();
             } catch (ErrnoException | SocketException e) {
                 Log.e(TAG, "Failed to suitably initialize a netlink socket", e);
-                mRunning = false;
+                synchronized (mLock) { mRunning = false; }
             }
 
-            while (mRunning) {
-                final ByteBuffer byteBuffer;
+            ByteBuffer byteBuffer;
+            while (stillRunning()) {
                 try {
                     byteBuffer = recvKernelReply();
                 } catch (ErrnoException e) {
-                    if (mRunning) { Log.w(TAG, "ErrnoException: ", e); }
+                    if (stillRunning()) { Log.w(TAG, "ErrnoException: ", e); }
                     break;
                 }
                 final long whenMs = SystemClock.elapsedRealtime();
@@ -470,7 +477,7 @@
 
             clearNetlinkSocket();
 
-            mRunning = false; // Not a no-op when ErrnoException happened.
+            synchronized (mLock) { mRunning = false; }
             if (VDBG) { Log.d(TAG, "Finishing observing thread."); }
         }
 
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index 07b26e8..6b919df 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -43,9 +43,12 @@
 import android.util.Slog;
 import android.util.TimedRemoteCaller;
 
+import com.android.internal.os.TransferPipe;
+
 import libcore.io.IoUtils;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.List;
@@ -572,13 +575,11 @@
                     .append((mRemoteInstance != null) ? "true" : "false").println();
 
             pw.flush();
-
             try {
-                getRemoteInstanceLazy().asBinder().dump(fd, new String[]{prefix});
-            } catch (TimeoutException te) {
-                /* ignore */
-            } catch (RemoteException re) {
-                /* ignore */
+                TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
+                        new String[] { prefix });
+            } catch (IOException | TimeoutException | RemoteException e) {
+                pw.println("Failed to dump remote instance: " + e);
             }
         }
     }
diff --git a/tests/net/jni/UidRangeTest.cpp b/services/tests/servicestests/jni/UidRangeTest.cpp
similarity index 100%
rename from tests/net/jni/UidRangeTest.cpp
rename to services/tests/servicestests/jni/UidRangeTest.cpp
diff --git a/tests/net/jni/UidRangeTest.h b/services/tests/servicestests/jni/UidRangeTest.h
similarity index 100%
rename from tests/net/jni/UidRangeTest.h
rename to services/tests/servicestests/jni/UidRangeTest.h
diff --git a/tests/net/jni/apf_jni.cpp b/services/tests/servicestests/jni/apf_jni.cpp
similarity index 100%
rename from tests/net/jni/apf_jni.cpp
rename to services/tests/servicestests/jni/apf_jni.cpp
diff --git a/tests/net/res/raw/apf.pcap b/services/tests/servicestests/res/raw/apf.pcap
similarity index 100%
rename from tests/net/res/raw/apf.pcap
rename to services/tests/servicestests/res/raw/apf.pcap
Binary files differ
diff --git a/tests/net/java/android/net/ConnectivityMetricsLoggerTest.java b/services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
similarity index 100%
rename from tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
rename to services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
diff --git a/tests/net/java/android/net/UidRangeTest.java b/services/tests/servicestests/src/android/net/UidRangeTest.java
similarity index 98%
rename from tests/net/java/android/net/UidRangeTest.java
rename to services/tests/servicestests/src/android/net/UidRangeTest.java
index 0a56e1b..221fe0f 100644
--- a/tests/net/java/android/net/UidRangeTest.java
+++ b/services/tests/servicestests/src/android/net/UidRangeTest.java
@@ -26,7 +26,7 @@
 public class UidRangeTest extends TestCase {
 
     static {
-        System.loadLibrary("frameworksnettestsjni");
+        System.loadLibrary("servicestestsjni");
     }
 
     private static native byte[] readAndWriteNative(byte[] inParcel);
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/services/tests/servicestests/src/android/net/apf/ApfTest.java
similarity index 96%
rename from tests/net/java/android/net/apf/ApfTest.java
rename to services/tests/servicestests/src/android/net/apf/ApfTest.java
index 81f66a5..f7c61d1 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/services/tests/servicestests/src/android/net/apf/ApfTest.java
@@ -16,6 +16,10 @@
 
 package android.net.apf;
 
+import static android.system.OsConstants.*;
+
+import com.android.frameworks.servicestests.R;
+
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkUtils;
@@ -32,12 +36,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import static android.system.OsConstants.*;
-
-import com.android.frameworks.tests.net.R;
-import com.android.internal.util.HexDump;
+import android.test.suitebuilder.annotation.LargeTest;
 
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -55,7 +54,6 @@
 import java.net.NetworkInterface;
 import java.nio.ByteBuffer;
 import java.util.List;
-import java.util.Random;
 
 import libcore.io.IoUtils;
 import libcore.io.Streams;
@@ -76,7 +74,7 @@
         super.setUp();
         MockitoAnnotations.initMocks(this);
         // Load up native shared library containing APF interpreter exposed via JNI.
-        System.loadLibrary("frameworksnettestsjni");
+        System.loadLibrary("servicestestsjni");
     }
 
     // Expected return codes from APF interpreter.
@@ -155,7 +153,7 @@
      * generating bytecode for that program and running it through the
      * interpreter to verify it functions correctly.
      */
-    @MediumTest
+    @LargeTest
     public void testApfInstructions() throws IllegalInstructionException {
         // Empty program should pass because having the program counter reach the
         // location immediately after the program indicates the packet should be
@@ -563,7 +561,7 @@
      * Generate some BPF programs, translate them to APF, then run APF and BPF programs
      * over packet traces and verify both programs filter out the same packets.
      */
-    @MediumTest
+    @LargeTest
     public void testApfAgainstBpf() throws Exception {
         String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
                 "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
@@ -721,7 +719,7 @@
     private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
-    @MediumTest
+    @LargeTest
     public void testApfFilterIPv4() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -776,7 +774,7 @@
         apfFilter.shutdown();
     }
 
-    @MediumTest
+    @LargeTest
     public void testApfFilterIPv6() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -802,7 +800,7 @@
         apfFilter.shutdown();
     }
 
-    @MediumTest
+    @LargeTest
     public void testApfFilterMulticast() throws Exception {
         final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
         final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -912,7 +910,7 @@
         assertDrop(program, garpReply());
     }
 
-    @MediumTest
+    @LargeTest
     public void testApfFilterArp() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -1031,7 +1029,7 @@
         ipManagerCallback.assertNoProgramUpdate();
     }
 
-    @MediumTest
+    @LargeTest
     public void testApfFilterRa() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);
@@ -1148,41 +1146,6 @@
         buffer.position(original);
     }
 
-    @SmallTest
-    public void testRaParsing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpManagerCallback cb = new MockIpManagerCallback();
-        TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.new Ra(packet, packet.length);
-            } catch (ApfFilter.InvalidRaException e) {
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    @SmallTest
-    public void testRaProcessing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpManagerCallback cb = new MockIpManagerCallback();
-        TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.processRa(packet, packet.length);
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
     /**
      * Call the APF interpreter the run {@code program} on {@code packet} pretending the
      * filter was installed {@code filter_age} seconds ago.
@@ -1204,7 +1167,6 @@
     private native static boolean compareBpfApf(String filter, String pcap_filename,
             byte[] apf_program);
 
-    @SmallTest
     public void testBytesToInt() {
         assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR));
         assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS));
diff --git a/tests/net/java/android/net/apf/Bpf2Apf.java b/services/tests/servicestests/src/android/net/apf/Bpf2Apf.java
similarity index 100%
rename from tests/net/java/android/net/apf/Bpf2Apf.java
rename to services/tests/servicestests/src/android/net/apf/Bpf2Apf.java
diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
similarity index 100%
rename from tests/net/java/android/net/dhcp/DhcpPacketTest.java
rename to services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
rename to services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/NetlinkSocketTest.java
rename to services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
rename to services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/services/tests/servicestests/src/android/net/util/IpUtilsTest.java
similarity index 100%
rename from tests/net/java/android/net/util/IpUtilsTest.java
rename to services/tests/servicestests/src/android/net/util/IpUtilsTest.java
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
similarity index 98%
rename from tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
rename to services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
index 8ca849b..808f4dd 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
+++ b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.util.test;
+package com.android.internal.util;
 
 import android.net.Uri;
 import android.os.Bundle;
diff --git a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
similarity index 97%
rename from core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
rename to services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
index f2be109..05de0a5 100644
--- a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
+++ b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.util.test;
+package com.android.internal.util;
 
 import android.content.ContentResolver;
 import android.database.ContentObserver;
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
similarity index 89%
rename from tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
rename to services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
index 27b7419..13657ab 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
+++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.util.test;
+package com.android.server;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -25,12 +25,13 @@
 import android.os.Handler;
 import android.os.UserHandle;
 
-import java.util.ArrayList;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.AbstractFuture;
+
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -41,17 +42,9 @@
 public class BroadcastInterceptingContext extends ContextWrapper {
     private static final String TAG = "WatchingContext";
 
-    private final List<BroadcastInterceptor> mInterceptors = new ArrayList<>();
+    private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList();
 
-    public abstract class FutureIntent extends FutureTask<Intent> {
-        public FutureIntent() {
-            super(
-                () -> { throw new IllegalStateException("Cannot happen"); }
-            );
-        }
-    }
-
-    public class BroadcastInterceptor extends FutureIntent {
+    public class BroadcastInterceptor extends AbstractFuture<Intent> {
         private final BroadcastReceiver mReceiver;
         private final IntentFilter mFilter;
 
@@ -89,11 +82,11 @@
         super(base);
     }
 
-    public FutureIntent nextBroadcastIntent(String action) {
+    public Future<Intent> nextBroadcastIntent(String action) {
         return nextBroadcastIntent(new IntentFilter(action));
     }
 
-    public FutureIntent nextBroadcastIntent(IntentFilter filter) {
+    public Future<Intent> nextBroadcastIntent(IntentFilter filter) {
         final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter);
         synchronized (mInterceptors) {
             mInterceptors.add(interceptor);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
similarity index 94%
rename from tests/net/java/com/android/server/ConnectivityServiceTest.java
rename to services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 885e8a7..4af1cf1 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -68,16 +68,14 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.AndroidTestCase;
-import android.test.FlakyTest;
 import android.test.mock.MockContentResolver;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.LogPrinter;
 
+import com.android.internal.util.FakeSettingsProvider;
 import com.android.internal.util.WakeupMessage;
-import com.android.internal.util.test.BroadcastInterceptingContext;
-import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
 import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
@@ -217,20 +215,8 @@
             mService.waitForIdle();
             assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
         }
-    }
-
-    @FlakyTest(tolerance = 3)
-    public void testNotWaitingForIdleCausesRaceConditions() {
-        // Bring up a network that we can use to send messages to ConnectivityService.
-        ConditionVariable cv = waitForConnectivityBroadcasts(1);
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.connect(false);
-        waitFor(cv);
-        Network n = mWiFiNetworkAgent.getNetwork();
-        assertNotNull(n);
 
         // Ensure that not calling waitForIdle causes a race condition.
-        final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
         for (int i = 0; i < attempts; i++) {
             mWiFiNetworkAgent.setSignalStrength(i);
             if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
@@ -250,7 +236,6 @@
         private final IdleableHandlerThread mHandlerThread;
         private final ConditionVariable mDisconnected = new ConditionVariable();
         private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
-        private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
         private int mScore;
         private NetworkAgent mNetworkAgent;
         private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
@@ -306,11 +291,6 @@
                     mRedirectUrl = redirectUrl;
                     mNetworkStatusReceived.open();
                 }
-
-                @Override
-                protected void preventAutomaticReconnect() {
-                    mPreventReconnectReceived.open();
-                }
             };
             // Waits for the NetworkAgent to be registered, which includes the creation of the
             // NetworkMonitor.
@@ -395,6 +375,11 @@
             mWrappedNetworkMonitor.gen204ProbeResult = 200;
             mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
             connect(false);
+            waitFor(new Criteria() { public boolean get() {
+                NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork());
+                return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} });
+            mWrappedNetworkMonitor.gen204ProbeResult = 500;
+            mWrappedNetworkMonitor.gen204ProbeRedirectUrl = null;
         }
 
         public void disconnect() {
@@ -406,10 +391,6 @@
             return new Network(mNetworkAgent.netId);
         }
 
-        public ConditionVariable getPreventReconnectReceived() {
-            return mPreventReconnectReceived;
-        }
-
         public ConditionVariable getDisconnectedCV() {
             return mDisconnected;
         }
@@ -616,7 +597,6 @@
 
         @Override
         protected CaptivePortalProbeResult isCaptivePortal() {
-            if (!mIsCaptivePortalCheckEnabled) { return new CaptivePortalProbeResult(204); }
             return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl, null);
         }
     }
@@ -763,9 +743,6 @@
         mService.systemReady();
         mCm = new WrappedConnectivityManager(getContext(), mService);
         mCm.bindProcessToNetwork(null);
-
-        // Ensure that the default setting for Captive Portals is used for most tests
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
     }
 
     public void tearDown() throws Exception {
@@ -1100,8 +1077,7 @@
         NETWORK_CAPABILITIES,
         LINK_PROPERTIES,
         LOSING,
-        LOST,
-        UNAVAILABLE
+        LOST
     }
 
     /**
@@ -1142,11 +1118,6 @@
         }
 
         @Override
-        public void onUnavailable() {
-            setLastCallback(CallbackState.UNAVAILABLE, null, null);
-        }
-
-        @Override
         public void onLosing(Network network, int maxMsToLive) {
             setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
         }
@@ -1733,47 +1704,6 @@
         validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
     }
 
-    @LargeTest
-    public void testAvoidOrIgnoreCaptivePortals() {
-        final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
-        final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
-                .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
-        mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
-
-        final TestNetworkCallback validatedCallback = new TestNetworkCallback();
-        final NetworkRequest validatedRequest = new NetworkRequest.Builder()
-                .addCapability(NET_CAPABILITY_VALIDATED).build();
-        mCm.registerNetworkCallback(validatedRequest, validatedCallback);
-
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID);
-        // Bring up a network with a captive portal.
-        // Expect it to fail to connect and not result in any callbacks.
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        String firstRedirectUrl = "http://example.com/firstPath";
-
-        ConditionVariable disconnectCv = mWiFiNetworkAgent.getDisconnectedCV();
-        ConditionVariable avoidCv = mWiFiNetworkAgent.getPreventReconnectReceived();
-        mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
-        waitFor(disconnectCv);
-        waitFor(avoidCv);
-
-        assertNoCallbacks(captivePortalCallback, validatedCallback);
-
-        // Now test ignore mode.
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
-
-        // Bring up a network with a captive portal.
-        // Since we're ignoring captive portals, the network will validate.
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        String secondRedirectUrl = "http://example.com/secondPath";
-        mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
-
-        // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
-        validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        // But there should be no CaptivePortal callback.
-        captivePortalCallback.assertNoCallback();
-    }
-
     @SmallTest
     public void testInvalidNetworkSpecifier() {
         boolean execptionCalled = true;
@@ -1914,11 +1844,6 @@
         mCm.unregisterNetworkCallback(cellNetworkCallback);
     }
 
-    private void setCaptivePortalMode(int mode) {
-        ContentResolver cr = mServiceContext.getContentResolver();
-        Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
-    }
-
     private void setMobileDataAlwaysOn(boolean enable) {
         ContentResolver cr = mServiceContext.getContentResolver();
         Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
@@ -2296,79 +2221,6 @@
         mCm.unregisterNetworkCallback(defaultCallback);
     }
 
-    /**
-     * Validate that a satisfied network request does not trigger onUnavailable() once the
-     * time-out period expires.
-     */
-    @SmallTest
-    public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI).build();
-        final TestNetworkCallback networkCallback = new TestNetworkCallback();
-        mCm.requestNetwork(nr, networkCallback, 10);
-
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.connect(false);
-        networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-
-        // pass timeout and validate that UNAVAILABLE is not called
-        try {
-            Thread.sleep(15);
-        } catch (InterruptedException e) {
-        }
-        networkCallback.assertNoCallback();
-    }
-
-    /**
-     * Validate that when a time-out is specified for a network request the onUnavailable()
-     * callback is called when time-out expires. Then validate that if network request is
-     * (somehow) satisfied - the callback isn't called later.
-     */
-    @SmallTest
-    public void testTimedoutNetworkRequest() {
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI).build();
-        final TestNetworkCallback networkCallback = new TestNetworkCallback();
-        mCm.requestNetwork(nr, networkCallback, 10);
-
-        // pass timeout and validate that UNAVAILABLE is called
-        networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
-
-        // create a network satisfying request - validate that request not triggered
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.connect(false);
-        networkCallback.assertNoCallback();
-    }
-
-    /**
-     * Validate that when a network request is unregistered (cancelled) the time-out for that
-     * request doesn't trigger the onUnavailable() callback.
-     */
-    @SmallTest
-    public void testTimedoutAfterUnregisteredNetworkRequest() {
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI).build();
-        final TestNetworkCallback networkCallback = new TestNetworkCallback();
-        mCm.requestNetwork(nr, networkCallback, 10);
-
-        // remove request
-        mCm.unregisterNetworkCallback(networkCallback);
-
-        // pass timeout and validate that no callbacks
-        // Note: doesn't validate that nothing called from CS since even if called the CM already
-        // unregisters the callback and won't pass it through!
-        try {
-            Thread.sleep(15);
-        } catch (InterruptedException e) {
-        }
-        networkCallback.assertNoCallback();
-
-        // create a network satisfying request - validate that request not triggered
-        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.connect(false);
-        networkCallback.assertNoCallback();
-    }
-
     private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
 
         public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index f841bf9..0d5daa5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -24,7 +24,6 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import com.android.server.net.BaseNetworkObserver;
-import com.android.internal.util.test.BroadcastInterceptingContext;
 
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 8d36ac9..541be3d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -78,7 +78,6 @@
 import android.text.format.Time;
 import android.util.TrustedTime;
 
-import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.google.common.util.concurrent.AbstractFuture;
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
new file mode 100644
index 0000000..0139671
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.Manifest.permission;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.INetworkScoreCache;
+import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
+import android.net.NetworkScorerAppManager;
+import android.net.NetworkScorerAppManager.NetworkScorerAppData;
+import android.net.ScoredNetwork;
+import android.net.WifiKey;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.R;
+import com.android.server.devicepolicy.MockUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link NetworkScoreService}.
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class NetworkScoreServiceTest {
+    private static final ScoredNetwork SCORED_NETWORK =
+            new ScoredNetwork(new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
+                    null /* rssiCurve*/);
+    private static final NetworkScorerAppData PREV_SCORER = new NetworkScorerAppData(
+            "prevPackageName", 0, "prevScorerName", null /* configurationActivityClassName */,
+            "prevScoringServiceClass");
+    private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData(
+            "newPackageName", 1, "newScorerName", null /* configurationActivityClassName */,
+            "newScoringServiceClass");
+
+    @Mock private PackageManager mPackageManager;
+    @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
+    @Mock private Context mContext;
+    @Mock private Resources mResources;
+    @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
+    @Mock private IBinder mIBinder, mIBinder2;
+    @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
+
+    private ContentResolver mContentResolver;
+    private NetworkScoreService mNetworkScoreService;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
+        when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
+        mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getResources()).thenReturn(mResources);
+        mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager);
+    }
+
+    @Test
+    public void testSystemReady_networkScorerProvisioned() throws Exception {
+        Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 1);
+
+        mNetworkScoreService.systemReady();
+
+        verify(mNetworkScorerAppManager, never()).setActiveScorer(anyString());
+    }
+
+    @Test
+    public void testSystemReady_networkScorerNotProvisioned_defaultScorer() throws Exception {
+        Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 0);
+
+        when(mResources.getString(R.string.config_defaultNetworkScorerPackageName))
+                .thenReturn(NEW_SCORER.mPackageName);
+
+        mNetworkScoreService.systemReady();
+
+        verify(mNetworkScorerAppManager).setActiveScorer(NEW_SCORER.mPackageName);
+        assertEquals(1,
+                Settings.Global.getInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED));
+
+    }
+
+    @Test
+    public void testSystemReady_networkScorerNotProvisioned_noDefaultScorer() throws Exception {
+        Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 0);
+
+        when(mResources.getString(R.string.config_defaultNetworkScorerPackageName))
+                .thenReturn(null);
+
+        mNetworkScoreService.systemReady();
+
+        verify(mNetworkScorerAppManager, never()).setActiveScorer(anyString());
+        assertEquals(1,
+                Settings.Global.getInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED));
+    }
+
+    @Test
+    public void testSystemRunning() {
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
+
+        mNetworkScoreService.systemRunning();
+
+        verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+                new ComponentName(NEW_SCORER.mPackageName, NEW_SCORER.mScoringServiceClassName))),
+                any(ServiceConnection.class),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(UserHandle.SYSTEM));
+    }
+
+    @Test
+    public void testUpdateScores_notActiveScorer() {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+
+        try {
+            mNetworkScoreService.updateScores(new ScoredNetwork[0]);
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testUpdateScores_oneRegisteredCache() throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+        verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture());
+
+        assertEquals(1, mScoredNetworkCaptor.getValue().size());
+        assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0));
+    }
+
+    @Test
+    public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
+
+        // updateScores should update both caches
+        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+        verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class));
+        verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class));
+
+        mNetworkScoreService.unregisterNetworkScoreCache(
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
+
+        // updateScores should only update the first cache since the 2nd has been unregistered
+        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+        verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class));
+
+        mNetworkScoreService.unregisterNetworkScoreCache(
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        // updateScores should not update any caches since they are both unregistered
+        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+        verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
+    }
+
+    @Test
+    public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+            .thenReturn(PackageManager.PERMISSION_DENIED);
+        try {
+            mNetworkScoreService.clearScores();
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+            .thenReturn(PackageManager.PERMISSION_DENIED);
+
+        mNetworkScoreService.clearScores();
+    }
+
+    @Test
+    public void testClearScores_activeScorer() throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.clearScores();
+
+        verify(mNetworkScoreCache).clearScores();
+    }
+
+    @Test
+    public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
+            throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.clearScores();
+
+        verify(mNetworkScoreCache).clearScores();
+    }
+
+    @Test
+    public void testSetActiveScorer_noScoreNetworksPermission() {
+        doThrow(new SecurityException()).when(mContext)
+                .enforceCallingOrSelfPermission(eq(permission.SCORE_NETWORKS), anyString());
+
+        try {
+            mNetworkScoreService.setActiveScorer(null);
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testSetActiveScorer_failure() throws RemoteException {
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER);
+        when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(false);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
+
+        assertFalse(success);
+        verify(mNetworkScoreCache).clearScores();
+        verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+                new ComponentName(PREV_SCORER.mPackageName, PREV_SCORER.mScoringServiceClassName))),
+                any(ServiceConnection.class),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(UserHandle.SYSTEM));
+    }
+
+    @Test
+    public void testSetActiveScorer_success() throws RemoteException {
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, NEW_SCORER);
+        when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(true);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
+
+        assertTrue(success);
+        verify(mNetworkScoreCache).clearScores();
+        verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+                new ComponentName(NEW_SCORER.mPackageName, NEW_SCORER.mScoringServiceClassName))),
+                any(ServiceConnection.class),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(UserHandle.SYSTEM));
+        verify(mContext, times(2)).sendBroadcastAsUser(
+                MockUtils.checkIntentAction(NetworkScoreManager.ACTION_SCORER_CHANGED),
+                eq(UserHandle.SYSTEM));
+    }
+
+    @Test
+    public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+
+        try {
+            mNetworkScoreService.disableScoring();
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+
+    }
+
+    @Test
+    public void testDisableScoring_activeScorer() throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
+        when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        mNetworkScoreService.disableScoring();
+
+        verify(mNetworkScoreCache).clearScores();
+        verify(mContext).sendBroadcastAsUser(
+                MockUtils.checkIntent(new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED)
+                        .setPackage(PREV_SCORER.mPackageName)),
+                eq(UserHandle.SYSTEM));
+        verify(mContext, never()).bindServiceAsUser(any(Intent.class),
+                any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+    }
+
+    @Test
+    public void testDisableScoring_notActiveScorer_hasBroadcastNetworkPermission()
+            throws RemoteException {
+        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
+        when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+        mNetworkScoreService.disableScoring();
+
+        verify(mNetworkScoreCache).clearScores();
+        verify(mContext).sendBroadcastAsUser(
+                MockUtils.checkIntent(new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED)
+                        .setPackage(PREV_SCORER.mPackageName)),
+                eq(UserHandle.SYSTEM));
+        verify(mContext, never()).bindServiceAsUser(any(Intent.class),
+                any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+    }
+
+    @Test
+    public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+
+        try {
+            mNetworkScoreService.registerNetworkScoreCache(
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+
+        try {
+            mNetworkScoreService.unregisterNetworkScoreCache(
+                    NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testDump_noDumpPermission() {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                eq(permission.DUMP), anyString());
+
+        try {
+            mNetworkScoreService.dump(
+                    new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
+            fail("SecurityException expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testDump_doesNotCrash() {
+        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
+        StringWriter stringWriter = new StringWriter();
+
+        mNetworkScoreService.dump(
+                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
+
+        assertFalse(stringWriter.toString().isEmpty());
+    }
+}
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
diff --git a/tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
diff --git a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java b/services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
rename to services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/TetheringTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/VpnTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
similarity index 97%
rename from tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index 9f7261d..a30b362 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -59,14 +59,13 @@
     @Mock private INetworkStatsService mStatsService;
     @Mock private IControlsTethering mTetherHelper;
     @Mock private InterfaceConfiguration mInterfaceConfiguration;
-    @Mock private IPv6TetheringInterfaceServices mIPv6TetheringInterfaceServices;
 
     private final TestLooper mLooper = new TestLooper();
     private TetherInterfaceStateMachine mTestedSm;
 
     private void initStateMachine(int interfaceType) throws Exception {
         mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), interfaceType,
-                mNMService, mStatsService, mTetherHelper, mIPv6TetheringInterfaceServices);
+                mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         // Starting the state machine always puts us in a consistent state and notifies
         // the test of the world that we've changed from an unknown to available state.
@@ -92,8 +91,7 @@
     @Test
     public void startsOutAvailable() {
         mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
-                ConnectivityManager.TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper,
-                mIPv6TetheringInterfaceServices);
+                ConnectivityManager.TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         mLooper.dispatchAll();
         verify(mTetherHelper).notifyInterfaceStateChange(
@@ -276,4 +274,4 @@
                 upstreamIface);
         mLooper.dispatchAll();
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 58db192..3806da6 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -82,6 +82,21 @@
         return Mockito.argThat(m);
     }
 
+    public static Intent checkIntent(final Intent intent) {
+        final Matcher<Intent> m = new BaseMatcher<Intent>() {
+            @Override
+            public boolean matches(Object item) {
+                if (item == null) return false;
+                return intent.filterEquals((Intent) item);
+            }
+            @Override
+            public void describeTo(Description description) {
+                description.appendText(intent.toString());
+            }
+        };
+        return Mockito.argThat(m);
+    }
+
     public static Bundle checkUserRestrictions(String... keys) {
         final Bundle expected = DpmTestUtils.newRestrictions(Preconditions.checkNotNull(keys));
         final Matcher<Bundle> m = new BaseMatcher<Bundle>() {
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
index 4b69eb3..94c6711 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
@@ -88,7 +88,7 @@
 import android.util.TrustedTime;
 
 import com.android.internal.net.VpnInfo;
-import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.BroadcastInterceptingContext;
 import com.android.server.net.NetworkStatsService;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 68bde35..a317994 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit framework
+LOCAL_JAVA_LIBRARIES := core-oj core-libart junit framework
 LOCAL_STATIC_JAVA_LIBRARIES := junit-runner
 
 LOCAL_MODULE:= android.test.runner
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
deleted file mode 100644
index 8aa27a9..0000000
--- a/tests/net/Android.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-#########################################################################
-# Build FrameworksNetTests package
-#########################################################################
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    frameworks-base-testutils \
-    framework-protos \
-    android-support-test \
-    mockito-target-minus-junit4 \
-    platform-test-annotations \
-    services.core \
-    services.net
-
-LOCAL_JAVA_LIBRARIES := \
-    android.test.runner
-
-LOCAL_PACKAGE_NAME := FrameworksNetTests
-
-LOCAL_CERTIFICATE := platform
-
-# These are not normally accessible from apps so they must be explicitly included.
-LOCAL_JNI_SHARED_LIBRARIES := libframeworksnettestsjni \
-    libbacktrace \
-    libbase \
-    libbinder \
-    libc++ \
-    libcutils \
-    liblog \
-    liblzma \
-    libnativehelper \
-    libnetdaidl \
-    libui \
-    libunwind \
-    libutils
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-include $(BUILD_PACKAGE)
-
-#########################################################################
-# Build JNI Shared Library
-#########################################################################
-
-LOCAL_PATH:= $(LOCAL_PATH)/jni
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_CFLAGS := -Wall -Wextra -Werror
-
-LOCAL_C_INCLUDES := \
-  libpcap \
-  hardware/google/apf
-
-LOCAL_SRC_FILES := $(call all-cpp-files-under)
-
-LOCAL_SHARED_LIBRARIES := \
-  libbinder \
-  liblog \
-  libcutils \
-  libnativehelper \
-  libnetdaidl
-
-LOCAL_STATIC_LIBRARIES := \
-  libpcap \
-  libapf
-
-LOCAL_MODULE := libframeworksnettestsjni
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
deleted file mode 100644
index e069dd0..0000000
--- a/tests/net/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.frameworks.tests.net">
-
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
-    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
-    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
-    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
-    <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
-    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
-    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
-    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.frameworks.tests.net"
-        android:label="Frameworks Networking Tests" />
-</manifest>
diff --git a/tests/utils/testutils/Android.mk b/tests/utils/testutils/Android.mk
index acbe4bc..d53167f 100644
--- a/tests/utils/testutils/Android.mk
+++ b/tests/utils/testutils/Android.mk
@@ -27,6 +27,4 @@
     android-support-test \
     mockito-target
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 69e9fcd..43e6246 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -746,50 +746,6 @@
     @SystemApi
     public int numAssociation;
 
-    /**
-     * @hide
-     * Number of time user disabled WiFi while associated to this configuration with Low RSSI.
-     */
-    public int numUserTriggeredWifiDisableLowRSSI;
-
-    /**
-     * @hide
-     * Number of time user disabled WiFi while associated to this configuration with Bad RSSI.
-     */
-    public int numUserTriggeredWifiDisableBadRSSI;
-
-    /**
-     * @hide
-     * Number of time user disabled WiFi while associated to this configuration
-     * and RSSI was not HIGH.
-     */
-    public int numUserTriggeredWifiDisableNotHighRSSI;
-
-    /**
-     * @hide
-     * Number of ticks associated to this configuration with Low RSSI.
-     */
-    public int numTicksAtLowRSSI;
-
-    /**
-     * @hide
-     * Number of ticks associated to this configuration with Bad RSSI.
-     */
-    public int numTicksAtBadRSSI;
-
-    /**
-     * @hide
-     * Number of ticks associated to this configuration
-     * and RSSI was not HIGH.
-     */
-    public int numTicksAtNotHighRSSI;
-    /**
-     * @hide
-     * Number of time user (WifiManager) triggered association to this configuration.
-     * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps
-     */
-    public int numUserTriggeredJoinAttempts;
-
     /** @hide
      * Boost given to RSSI on a home network for the purpose of calculating the score
      * This adds stickiness to home networks, as defined by:
@@ -1630,16 +1586,6 @@
                 sbuf.append('\n');
             }
         }
-        sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI);
-        sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI);
-        sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI);
-        sbuf.append('\n');
-        sbuf.append("ticksLow: ").append(this.numTicksAtLowRSSI);
-        sbuf.append(" ticksBad: ").append(this.numTicksAtBadRSSI);
-        sbuf.append(" ticksNotHigh: ").append(this.numTicksAtNotHighRSSI);
-        sbuf.append('\n');
-        sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts);
-        sbuf.append('\n');
 
         return sbuf.toString();
     }
@@ -1946,13 +1892,6 @@
             numScorerOverride = source.numScorerOverride;
             numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
             numAssociation = source.numAssociation;
-            numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI;
-            numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI;
-            numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI;
-            numTicksAtLowRSSI = source.numTicksAtLowRSSI;
-            numTicksAtBadRSSI = source.numTicksAtBadRSSI;
-            numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
-            numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
             userApproved = source.userApproved;
             numNoInternetAccessReports = source.numNoInternetAccessReports;
             noInternetAccessExpected = source.noInternetAccessExpected;
@@ -2018,13 +1957,6 @@
         dest.writeInt(numScorerOverride);
         dest.writeInt(numScorerOverrideAndSwitchedNetwork);
         dest.writeInt(numAssociation);
-        dest.writeInt(numUserTriggeredWifiDisableLowRSSI);
-        dest.writeInt(numUserTriggeredWifiDisableBadRSSI);
-        dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI);
-        dest.writeInt(numTicksAtLowRSSI);
-        dest.writeInt(numTicksAtBadRSSI);
-        dest.writeInt(numTicksAtNotHighRSSI);
-        dest.writeInt(numUserTriggeredJoinAttempts);
         dest.writeInt(userApproved);
         dest.writeInt(numNoInternetAccessReports);
         dest.writeInt(noInternetAccessExpected ? 1 : 0);
@@ -2090,13 +2022,6 @@
                 config.numScorerOverride = in.readInt();
                 config.numScorerOverrideAndSwitchedNetwork = in.readInt();
                 config.numAssociation = in.readInt();
-                config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
-                config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
-                config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
-                config.numTicksAtLowRSSI = in.readInt();
-                config.numTicksAtBadRSSI = in.readInt();
-                config.numTicksAtNotHighRSSI = in.readInt();
-                config.numUserTriggeredJoinAttempts = in.readInt();
                 config.userApproved = in.readInt();
                 config.numNoInternetAccessReports = in.readInt();
                 config.noInternetAccessExpected = in.readInt() != 0;
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
new file mode 100644
index 0000000..5f949747
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 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 android.net.wifi;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiConfiguration}.
+ */
+public class WifiConfigurationTest {
+
+    @Before
+    public void setUp() {
+    }
+
+    /**
+     * Check that parcel marshalling/unmarshalling works
+     *
+     * Create and populate a WifiConfiguration.
+     * Marshall and unmashall it, and expect to recover a copy of the original.
+     * Marshall the resulting object, and expect the bytes to match the
+     * first marshall result.
+     */
+    @Test
+    public void testWifiConfigurationParcel() {
+        String cookie = "C O.o |<IE";
+        WifiConfiguration config = new WifiConfiguration();
+        config.setPasspointManagementObjectTree(cookie);
+        Parcel parcelW = Parcel.obtain();
+        config.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        WifiConfiguration reconfig = WifiConfiguration.CREATOR.createFromParcel(parcelR);
+
+        // lacking a useful config.equals, check one field near the end.
+        assertEquals(cookie, reconfig.getMoTree());
+
+        Parcel parcelWW = Parcel.obtain();
+        reconfig.writeToParcel(parcelWW, 0);
+        byte[] rebytes = parcelWW.marshall();
+        parcelWW.recycle();
+
+        assertArrayEquals(bytes, rebytes);
+    }
+}