diff --git a/Android.mk b/Android.mk
index a7cb362..c4f222e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -398,6 +398,7 @@
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
 	core/java/com/android/internal/car/ICarServiceHelper.aidl \
 	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
+	core/java/com/android/internal/net/INetworkWatchlistManager.aidl \
 	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6989db6..4efc2c7 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -81,6 +81,7 @@
 import android.net.IpSecManager;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkScoreManager;
+import android.net.NetworkWatchlistManager;
 import android.net.lowpan.ILowpanManager;
 import android.net.lowpan.LowpanManager;
 import android.net.nsd.INsdManager;
@@ -150,6 +151,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.app.ISoundTriggerService;
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.net.INetworkWatchlistManager;
 import com.android.internal.os.IDropBoxManagerService;
 import com.android.internal.policy.PhoneLayoutInflater;
 
@@ -862,6 +864,17 @@
                 return new ShortcutManager(ctx, IShortcutService.Stub.asInterface(b));
             }});
 
+        registerService(Context.NETWORK_WATCHLIST_SERVICE, NetworkWatchlistManager.class,
+                new CachedServiceFetcher<NetworkWatchlistManager>() {
+                    @Override
+                    public NetworkWatchlistManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder b =
+                                ServiceManager.getServiceOrThrow(Context.NETWORK_WATCHLIST_SERVICE);
+                        return new NetworkWatchlistManager(ctx,
+                                INetworkWatchlistManager.Stub.asInterface(b));
+                    }});
+
         registerService(Context.SYSTEM_HEALTH_SERVICE, SystemHealthManager.class,
                 new CachedServiceFetcher<SystemHealthManager>() {
             @Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c165fb3..01ad3ad 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3413,6 +3413,8 @@
     public static final String NETWORK_STATS_SERVICE = "netstats";
     /** {@hide} */
     public static final String NETWORK_POLICY_SERVICE = "netpolicy";
+    /** {@hide} */
+    public static final String NETWORK_WATCHLIST_SERVICE = "network_watchlist";
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
diff --git a/core/java/android/net/IIpConnectivityMetrics.aidl b/core/java/android/net/IIpConnectivityMetrics.aidl
index 6f07b31..aeaf09d 100644
--- a/core/java/android/net/IIpConnectivityMetrics.aidl
+++ b/core/java/android/net/IIpConnectivityMetrics.aidl
@@ -30,11 +30,11 @@
     int logEvent(in ConnectivityMetricsEvent event);
 
     /**
-     * At most one callback can be registered (by DevicePolicyManager).
+     * Callback can be registered by DevicePolicyManager or NetworkWatchlistService only.
      * @return status {@code true} if registering/unregistering of the callback was successful,
      *         {@code false} otherwise (might happen if IIpConnectivityMetrics is not available,
      *         if it happens make sure you call it when the service is up in the caller)
      */
-    boolean registerNetdEventCallback(in INetdEventCallback callback);
-    boolean unregisterNetdEventCallback();
+    boolean addNetdEventCallback(in int callerType, in INetdEventCallback callback);
+    boolean removeNetdEventCallback(in int callerType);
 }
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
index 49436be..1fd9423 100644
--- a/core/java/android/net/INetdEventCallback.aidl
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -19,6 +19,10 @@
 /** {@hide} */
 oneway interface INetdEventCallback {
 
+    // Possible addNetdEventCallback callers.
+    const int CALLBACK_CALLER_DEVICE_POLICY = 0;
+    const int CALLBACK_CALLER_NETWORK_WATCHLIST = 1;
+
     /**
      * Reports a single DNS lookup function call.
      * This method must not block or perform long-running operations.
diff --git a/core/java/android/net/NetworkWatchlistManager.java b/core/java/android/net/NetworkWatchlistManager.java
new file mode 100644
index 0000000..42e43c8
--- /dev/null
+++ b/core/java/android/net/NetworkWatchlistManager.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.internal.net.INetworkWatchlistManager;
+import com.android.internal.util.Preconditions;
+
+/**
+ * Class that manage network watchlist in system.
+ * @hide
+ */
+@SystemService(Context.NETWORK_WATCHLIST_SERVICE)
+public class NetworkWatchlistManager {
+
+    private static final String TAG = "NetworkWatchlistManager";
+    private static final String SHARED_MEMORY_TAG = "NETWORK_WATCHLIST_SHARED_MEMORY";
+
+    private final Context mContext;
+    private final INetworkWatchlistManager mNetworkWatchlistManager;
+
+    /**
+     * @hide
+     */
+    public NetworkWatchlistManager(Context context, INetworkWatchlistManager manager) {
+        mContext = context;
+        mNetworkWatchlistManager = manager;
+    }
+
+    /**
+     * @hide
+     */
+    public NetworkWatchlistManager(Context context) {
+        mContext = Preconditions.checkNotNull(context, "missing context");
+        mNetworkWatchlistManager = (INetworkWatchlistManager)
+                INetworkWatchlistManager.Stub.asInterface(
+                        ServiceManager.getService(Context.NETWORK_WATCHLIST_SERVICE));
+    }
+
+    /**
+     * Report network watchlist records if necessary.
+     *
+     * Watchlist report process will run summarize records into a single report, then the
+     * report will be processed by differential privacy framework and store it on disk.
+     *
+     * @hide
+     */
+    public void reportWatchlistIfNecessary() {
+        try {
+            mNetworkWatchlistManager.reportWatchlistIfNecessary();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Cannot report records", e);
+            e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0a20c43..69c2180 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8513,6 +8513,13 @@
        public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
                "network_metered_multipath_preference";
 
+        /**
+         * Network watchlist last report time.
+         * @hide
+         */
+        public static final String NETWORK_WATCHLIST_LAST_REPORT_TIME =
+                "network_watchlist_last_report_time";
+
        /**
         * The thresholds of the wifi throughput badging (SD, HD etc.) as a comma-delimited list of
         * colon-delimited key-value pairs. The key is the badging enum value defined in
diff --git a/core/java/com/android/internal/net/INetworkWatchlistManager.aidl b/core/java/com/android/internal/net/INetworkWatchlistManager.aidl
new file mode 100644
index 0000000..7e88369
--- /dev/null
+++ b/core/java/com/android/internal/net/INetworkWatchlistManager.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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.internal.net;
+
+import android.os.SharedMemory;
+
+/** {@hide} */
+interface INetworkWatchlistManager {
+    boolean startWatchlistLogging();
+    boolean stopWatchlistLogging();
+    void reportWatchlistIfNecessary();
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 49de135..b8d3a57 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3944,6 +3944,10 @@
         <service android:name="com.android.server.timezone.TimeZoneUpdateIdler"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
+
+        <service android:name="com.android.server.net.watchlist.ReportWatchlistJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
     </application>
 
 </manifest>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 1002939..d36ed63 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -26,7 +26,6 @@
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -264,6 +263,7 @@
                     Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE,
                     Settings.Global.NETWORK_AVOID_BAD_WIFI,
                     Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE,
+                    Settings.Global.NETWORK_WATCHLIST_LAST_REPORT_TIME,
                     Settings.Global.NETWORK_PREFERENCE,
                     Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE,
                     Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS,
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index 5cc390a..f427819 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -23,8 +23,6 @@
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.Binder;
-import android.os.IBinder;
-import android.os.Parcelable;
 import android.os.Process;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -322,22 +320,22 @@
         }
 
         @Override
-        public boolean registerNetdEventCallback(INetdEventCallback callback) {
+        public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
             enforceNetdEventListeningPermission();
             if (mNetdListener == null) {
                 return false;
             }
-            return mNetdListener.registerNetdEventCallback(callback);
+            return mNetdListener.addNetdEventCallback(callerType, callback);
         }
 
         @Override
-        public boolean unregisterNetdEventCallback() {
+        public boolean removeNetdEventCallback(int callerType) {
             enforceNetdEventListeningPermission();
             if (mNetdListener == null) {
                 // if the service is null, we aren't registered anyway
                 return true;
             }
-            return mNetdListener.unregisterNetdEventCallback();
+            return mNetdListener.removeNetdEventCallback(callerType);
         }
     };
 
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 61b11e1..af138b93 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -98,21 +98,55 @@
     @GuardedBy("this")
     private final TokenBucket mConnectTb =
             new TokenBucket(CONNECT_LATENCY_FILL_RATE, CONNECT_LATENCY_BURST_LIMIT);
-    // Callback should only be registered/unregistered when logging is being enabled/disabled in DPM
-    // by the device owner. It's DevicePolicyManager's responsibility to ensure that.
-    @GuardedBy("this")
-    private INetdEventCallback mNetdEventCallback;
 
-    public synchronized boolean registerNetdEventCallback(INetdEventCallback callback) {
-        mNetdEventCallback = callback;
+
+    /**
+     * There are only 2 possible callbacks.
+     *
+     * mNetdEventCallbackList[CALLBACK_CALLER_DEVICE_POLICY].
+     * Callback registered/unregistered when logging is being enabled/disabled in DPM
+     * by the device owner. It's DevicePolicyManager's responsibility to ensure that.
+     *
+     * mNetdEventCallbackList[CALLBACK_CALLER_NETWORK_WATCHLIST]
+     * Callback registered/unregistered by NetworkWatchlistService.
+     */
+    @GuardedBy("this")
+    private static final int[] ALLOWED_CALLBACK_TYPES = {
+        INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY,
+        INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST
+    };
+
+    @GuardedBy("this")
+    private INetdEventCallback[] mNetdEventCallbackList =
+            new INetdEventCallback[ALLOWED_CALLBACK_TYPES.length];
+
+    public synchronized boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
+        if (!isValidCallerType(callerType)) {
+            Log.e(TAG, "Invalid caller type: " + callerType);
+            return false;
+        }
+        mNetdEventCallbackList[callerType] = callback;
         return true;
     }
 
-    public synchronized boolean unregisterNetdEventCallback() {
-        mNetdEventCallback = null;
+    public synchronized boolean removeNetdEventCallback(int callerType) {
+        if (!isValidCallerType(callerType)) {
+            Log.e(TAG, "Invalid caller type: " + callerType);
+            return false;
+        }
+        mNetdEventCallbackList[callerType] = null;
         return true;
     }
 
+    private static boolean isValidCallerType(int callerType) {
+        for (int i = 0; i < ALLOWED_CALLBACK_TYPES.length; i++) {
+            if (callerType == ALLOWED_CALLBACK_TYPES[i]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     public NetdEventListenerService(Context context) {
         this(context.getSystemService(ConnectivityManager.class));
     }
@@ -169,8 +203,10 @@
         long timestamp = System.currentTimeMillis();
         getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs);
 
-        if (mNetdEventCallback != null) {
-            mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
+        for (INetdEventCallback callback : mNetdEventCallbackList) {
+            if (callback != null) {
+                callback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
+            }
         }
     }
 
@@ -184,8 +220,14 @@
         long timestamp = System.currentTimeMillis();
         getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr);
 
-        if (mNetdEventCallback != null) {
-            mNetdEventCallback.onConnectEvent(ipAddr, port, timestamp, uid);
+        for (INetdEventCallback callback : mNetdEventCallbackList) {
+            if (callback != null) {
+                // TODO(rickywai): Remove this checking to collect ip in watchlist.
+                if (callback ==
+                        mNetdEventCallbackList[INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY]) {
+                    callback.onConnectEvent(ipAddr, port, timestamp, uid);
+                }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/net/watchlist/DigestUtils.java b/services/core/java/com/android/server/net/watchlist/DigestUtils.java
new file mode 100644
index 0000000..57becb0
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/DigestUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Utils for calculating digests.
+ */
+public class DigestUtils {
+
+    private static final int FILE_READ_BUFFER_SIZE = 16 * 1024;
+
+    private DigestUtils() {}
+
+    /** @return SHA256 hash of the provided file */
+    public static byte[] getSha256Hash(File apkFile) throws IOException, NoSuchAlgorithmException {
+        try (InputStream stream = new FileInputStream(apkFile)) {
+            return getSha256Hash(stream);
+        }
+    }
+
+    /** @return SHA256 hash of data read from the provided input stream */
+    public static byte[] getSha256Hash(InputStream stream)
+            throws IOException, NoSuchAlgorithmException {
+        MessageDigest digester = MessageDigest.getInstance("SHA256");
+
+        int bytesRead;
+        byte[] buf = new byte[FILE_READ_BUFFER_SIZE];
+        while ((bytesRead = stream.read(buf)) >= 0) {
+            digester.update(buf, 0, bytesRead);
+        }
+        return digester.digest();
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/net/watchlist/HarmfulDigests.java b/services/core/java/com/android/server/net/watchlist/HarmfulDigests.java
new file mode 100644
index 0000000..27c22ce
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/HarmfulDigests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import com.android.internal.util.HexDump;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Helper class to store all harmful digests in memory.
+ * TODO: Optimize memory usage using byte array with binary search.
+ */
+class HarmfulDigests {
+
+    private final Set<String> mDigestSet;
+
+    HarmfulDigests(List<byte[]> digests) {
+        final HashSet<String> tmpDigestSet = new HashSet<>();
+        final int size = digests.size();
+        for (int i = 0; i < size; i++) {
+            tmpDigestSet.add(HexDump.toHexString(digests.get(i)));
+        }
+        mDigestSet = Collections.unmodifiableSet(tmpDigestSet);
+    }
+
+    public boolean contains(byte[] digest) {
+        return mDigestSet.contains(HexDump.toHexString(digest));
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        for (String digest : mDigestSet) {
+            pw.println(digest);
+        }
+        pw.println("");
+    }
+}
diff --git a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistService.java b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistService.java
new file mode 100644
index 0000000..171703a
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistService.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
+import android.net.NetworkWatchlistManager;
+import android.net.metrics.IpConnectivityLog;
+import android.os.Binder;
+import android.os.Process;
+import android.os.SharedMemory;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.net.INetworkWatchlistManager;
+import com.android.server.ServiceThread;
+import com.android.server.SystemService;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Implementation of network watchlist service.
+ */
+public class NetworkWatchlistService extends INetworkWatchlistManager.Stub {
+
+    private static final String TAG = NetworkWatchlistService.class.getSimpleName();
+    static final boolean DEBUG = false;
+
+    private static final String PROPERTY_NETWORK_WATCHLIST_ENABLED =
+            "ro.network_watchlist_enabled";
+
+    private static final int MAX_NUM_OF_WATCHLIST_DIGESTS = 10000;
+
+    public static class Lifecycle extends SystemService {
+        private NetworkWatchlistService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            if (!SystemProperties.getBoolean(PROPERTY_NETWORK_WATCHLIST_ENABLED, false)) {
+                // Watchlist service is disabled
+                return;
+            }
+            mService = new NetworkWatchlistService(getContext());
+            publishBinderService(Context.NETWORK_WATCHLIST_SERVICE, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (!SystemProperties.getBoolean(PROPERTY_NETWORK_WATCHLIST_ENABLED, false)) {
+                // Watchlist service is disabled
+                return;
+            }
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                try {
+                    mService.initIpConnectivityMetrics();
+                    mService.startWatchlistLogging();
+                } catch (RemoteException e) {
+                    // Should not happen
+                }
+                ReportWatchlistJobService.schedule(getContext());
+            }
+        }
+    }
+
+    private volatile boolean mIsLoggingEnabled = false;
+    private final Object mLoggingSwitchLock = new Object();
+
+    private final WatchlistSettings mSettings;
+    private final Context mContext;
+
+    // Separate thread to handle expensive watchlist logging work.
+    private final ServiceThread mHandlerThread;
+
+    @VisibleForTesting
+    IIpConnectivityMetrics mIpConnectivityMetrics;
+    @VisibleForTesting
+    WatchlistLoggingHandler mNetworkWatchlistHandler;
+
+    public NetworkWatchlistService(Context context) {
+        mContext = context;
+        mSettings = WatchlistSettings.getInstance();
+        mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+                        /* allowIo */ false);
+        mHandlerThread.start();
+        mNetworkWatchlistHandler = new WatchlistLoggingHandler(mContext,
+                mHandlerThread.getLooper());
+        mNetworkWatchlistHandler.reportWatchlistIfNecessary();
+    }
+
+    // For testing only
+    @VisibleForTesting
+    NetworkWatchlistService(Context context, ServiceThread handlerThread,
+            WatchlistLoggingHandler handler, IIpConnectivityMetrics ipConnectivityMetrics) {
+        mContext = context;
+        mSettings = WatchlistSettings.getInstance();
+        mHandlerThread = handlerThread;
+        mNetworkWatchlistHandler = handler;
+        mIpConnectivityMetrics = ipConnectivityMetrics;
+    }
+
+    private void initIpConnectivityMetrics() {
+        mIpConnectivityMetrics = (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface(
+                ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
+    }
+
+    private final INetdEventCallback mNetdEventCallback = new INetdEventCallback.Stub() {
+        @Override
+        public void onDnsEvent(String hostname, String[] ipAddresses, int ipAddressesCount,
+                long timestamp, int uid) {
+            if (!mIsLoggingEnabled) {
+                return;
+            }
+            mNetworkWatchlistHandler.asyncNetworkEvent(hostname, ipAddresses, uid);
+        }
+
+        @Override
+        public void onConnectEvent(String ipAddr, int port, long timestamp, int uid) {
+            if (!mIsLoggingEnabled) {
+                return;
+            }
+            mNetworkWatchlistHandler.asyncNetworkEvent(null, new String[]{ipAddr}, uid);
+        }
+    };
+
+    @VisibleForTesting
+    protected boolean startWatchlistLoggingImpl() throws RemoteException {
+        if (DEBUG) {
+            Slog.i(TAG, "Starting watchlist logging.");
+        }
+        synchronized (mLoggingSwitchLock) {
+            if (mIsLoggingEnabled) {
+                Slog.w(TAG, "Watchlist logging is already running");
+                return true;
+            }
+            try {
+                if (mIpConnectivityMetrics.addNetdEventCallback(
+                        INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST, mNetdEventCallback)) {
+                    mIsLoggingEnabled = true;
+                    return true;
+                } else {
+                    return false;
+                }
+            } catch (RemoteException re) {
+                // Should not happen
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public boolean startWatchlistLogging() throws RemoteException {
+        enforceWatchlistLoggingPermission();
+        return startWatchlistLoggingImpl();
+    }
+
+    @VisibleForTesting
+    protected boolean stopWatchlistLoggingImpl() {
+        if (DEBUG) {
+            Slog.i(TAG, "Stopping watchlist logging");
+        }
+        synchronized (mLoggingSwitchLock) {
+            if (!mIsLoggingEnabled) {
+                Slog.w(TAG, "Watchlist logging is not running");
+                return true;
+            }
+            // stop the logging regardless of whether we fail to unregister listener
+            mIsLoggingEnabled = false;
+
+            try {
+                return mIpConnectivityMetrics.removeNetdEventCallback(
+                        INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST);
+            } catch (RemoteException re) {
+                // Should not happen
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public boolean stopWatchlistLogging() throws RemoteException {
+        enforceWatchlistLoggingPermission();
+        return stopWatchlistLoggingImpl();
+    }
+
+    private void enforceWatchlistLoggingPermission() {
+        final int uid = Binder.getCallingUid();
+        if (uid != Process.SYSTEM_UID) {
+            throw new SecurityException(String.format("Uid %d has no permission to change watchlist"
+                    + " setting.", uid));
+        }
+    }
+
+    /**
+     * Set a new network watchlist.
+     * This method should be called by ConfigUpdater only.
+     *
+     * @return True if network watchlist is updated.
+     */
+    public boolean setNetworkSecurityWatchlist(List<byte[]> domainsCrc32Digests,
+            List<byte[]> domainsSha256Digests,
+            List<byte[]> ipAddressesCrc32Digests,
+            List<byte[]> ipAddressesSha256Digests) {
+        Slog.i(TAG, "Setting network watchlist");
+        if (domainsCrc32Digests == null || domainsSha256Digests == null
+                || ipAddressesCrc32Digests == null || ipAddressesSha256Digests == null) {
+            Slog.e(TAG, "Parameters cannot be null");
+            return false;
+        }
+        if (domainsCrc32Digests.size() != domainsSha256Digests.size()
+                || ipAddressesCrc32Digests.size() != ipAddressesSha256Digests.size()) {
+            Slog.e(TAG, "Must need to have the same number of CRC32 and SHA256 digests");
+            return false;
+        }
+        if (domainsSha256Digests.size() + ipAddressesSha256Digests.size()
+                > MAX_NUM_OF_WATCHLIST_DIGESTS) {
+            Slog.e(TAG, "Total watchlist size cannot exceed " + MAX_NUM_OF_WATCHLIST_DIGESTS);
+            return false;
+        }
+        mSettings.writeSettingsToDisk(domainsCrc32Digests, domainsSha256Digests,
+                ipAddressesCrc32Digests, ipAddressesSha256Digests);
+        Slog.i(TAG, "Set network watchlist: Success");
+        return true;
+    }
+
+    @Override
+    public void reportWatchlistIfNecessary() {
+        // Allow any apps to trigger report event, as we won't run it if it's too early.
+        mNetworkWatchlistHandler.reportWatchlistIfNecessary();
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        mSettings.dump(fd, pw, args);
+    }
+
+}
diff --git a/services/core/java/com/android/server/net/watchlist/ReportWatchlistJobService.java b/services/core/java/com/android/server/net/watchlist/ReportWatchlistJobService.java
new file mode 100644
index 0000000..dfeb1b2
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/ReportWatchlistJobService.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.NetworkWatchlistManager;
+import android.util.Slog;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A job that periodically report watchlist records.
+ */
+public class ReportWatchlistJobService extends JobService {
+
+    private static final boolean DEBUG = NetworkWatchlistService.DEBUG;
+    private static final String TAG = "WatchlistJobService";
+
+    // Unique job id used in system service, other jobs should not use the same value.
+    public static final int REPORT_WATCHLIST_RECORDS_JOB_ID = 0xd7689;
+    public static final long REPORT_WATCHLIST_RECORDS_PERIOD_MILLIS =
+            TimeUnit.HOURS.toMillis(12);
+
+    @Override
+    public boolean onStartJob(final JobParameters jobParameters) {
+        if (jobParameters.getJobId() != REPORT_WATCHLIST_RECORDS_JOB_ID) {
+            return false;
+        }
+        if (DEBUG) Slog.d(TAG, "Start scheduled job.");
+        new NetworkWatchlistManager(this).reportWatchlistIfNecessary();
+        jobFinished(jobParameters, false);
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters jobParameters) {
+        return true; // Reschedule when possible.
+    }
+
+    /**
+     * Schedule the {@link ReportWatchlistJobService} to run periodically.
+     */
+    public static void schedule(Context context) {
+        if (DEBUG) Slog.d(TAG, "Scheduling records aggregator task");
+        final JobScheduler scheduler =
+                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        scheduler.schedule(new JobInfo.Builder(REPORT_WATCHLIST_RECORDS_JOB_ID,
+                new ComponentName(context, ReportWatchlistJobService.class))
+                //.setOverrideDeadline(45 * 1000) // Schedule job soon, for testing.
+                .setPeriodic(REPORT_WATCHLIST_RECORDS_PERIOD_MILLIS)
+                .setRequiresDeviceIdle(true)
+                .setRequiresBatteryNotLow(true)
+                .setPersisted(false)
+                .build());
+    }
+
+}
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java b/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java
new file mode 100644
index 0000000..2247558
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.DropBoxManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A Handler class for network watchlist logging on a background thread.
+ */
+class WatchlistLoggingHandler extends Handler {
+
+    private static final String TAG = WatchlistLoggingHandler.class.getSimpleName();
+    private static final boolean DEBUG = NetworkWatchlistService.DEBUG;
+
+    @VisibleForTesting
+    static final int LOG_WATCHLIST_EVENT_MSG = 1;
+    @VisibleForTesting
+    static final int REPORT_RECORDS_IF_NECESSARY_MSG = 2;
+
+    private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
+    private static final String DROPBOX_TAG = "network_watchlist_report";
+
+    private final Context mContext;
+    private final ContentResolver mResolver;
+    private final PackageManager mPm;
+    private final WatchlistReportDbHelper mDbHelper;
+    private final WatchlistSettings mSettings;
+    // A cache for uid and apk digest mapping.
+    // As uid won't be reused until reboot, it's safe to assume uid is unique per signature and app.
+    // TODO: Use more efficient data structure.
+    private final HashMap<Integer, byte[]> mCachedUidDigestMap = new HashMap<>();
+
+    private interface WatchlistEventKeys {
+        String HOST = "host";
+        String IP_ADDRESSES = "ipAddresses";
+        String UID = "uid";
+        String TIMESTAMP = "timestamp";
+    }
+
+    WatchlistLoggingHandler(Context context, Looper looper) {
+        super(looper);
+        mContext = context;
+        mPm = mContext.getPackageManager();
+        mResolver = mContext.getContentResolver();
+        mDbHelper = WatchlistReportDbHelper.getInstance(context);
+        mSettings = WatchlistSettings.getInstance();
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case LOG_WATCHLIST_EVENT_MSG: {
+                final Bundle data = msg.getData();
+                handleNetworkEvent(
+                        data.getString(WatchlistEventKeys.HOST),
+                        data.getStringArray(WatchlistEventKeys.IP_ADDRESSES),
+                        data.getInt(WatchlistEventKeys.UID),
+                        data.getLong(WatchlistEventKeys.TIMESTAMP)
+                );
+                break;
+            }
+            case REPORT_RECORDS_IF_NECESSARY_MSG:
+                tryAggregateRecords();
+                break;
+            default: {
+                Slog.d(TAG, "WatchlistLoggingHandler received an unknown of message.");
+                break;
+            }
+        }
+    }
+
+    /**
+     * Report network watchlist records if we collected enough data.
+     */
+    public void reportWatchlistIfNecessary() {
+        final Message msg = obtainMessage(REPORT_RECORDS_IF_NECESSARY_MSG);
+        sendMessage(msg);
+    }
+
+    /**
+     * Insert network traffic event to watchlist async queue processor.
+     */
+    public void asyncNetworkEvent(String host, String[] ipAddresses, int uid) {
+        final Message msg = obtainMessage(LOG_WATCHLIST_EVENT_MSG);
+        final Bundle bundle = new Bundle();
+        bundle.putString(WatchlistEventKeys.HOST, host);
+        bundle.putStringArray(WatchlistEventKeys.IP_ADDRESSES, ipAddresses);
+        bundle.putInt(WatchlistEventKeys.UID, uid);
+        bundle.putLong(WatchlistEventKeys.TIMESTAMP, System.currentTimeMillis());
+        msg.setData(bundle);
+        sendMessage(msg);
+    }
+
+    private void handleNetworkEvent(String hostname, String[] ipAddresses,
+            int uid, long timestamp) {
+        if (DEBUG) {
+            Slog.i(TAG, "handleNetworkEvent with host: " + hostname + ", uid: " + uid);
+        }
+        final String cncDomain = searchAllSubDomainsInWatchlist(hostname);
+        if (cncDomain != null) {
+            insertRecord(getDigestFromUid(uid), cncDomain, timestamp);
+        } else {
+            final String cncIp = searchIpInWatchlist(ipAddresses);
+            if (cncIp != null) {
+                insertRecord(getDigestFromUid(uid), cncIp, timestamp);
+            }
+        }
+    }
+
+    private boolean insertRecord(byte[] digest, String cncHost, long timestamp) {
+        final boolean result = mDbHelper.insertNewRecord(digest, cncHost, timestamp);
+        tryAggregateRecords();
+        return result;
+    }
+
+    private boolean shouldReportNetworkWatchlist() {
+        final long lastReportTime = Settings.Global.getLong(mResolver,
+                Settings.Global.NETWORK_WATCHLIST_LAST_REPORT_TIME, 0L);
+        final long currentTimestamp = System.currentTimeMillis();
+        if (currentTimestamp < lastReportTime) {
+            Slog.i(TAG, "Last report time is larger than current time, reset report");
+            mDbHelper.cleanup();
+            return false;
+        }
+        return currentTimestamp >= lastReportTime + ONE_DAY_MS;
+    }
+
+    private void tryAggregateRecords() {
+        if (shouldReportNetworkWatchlist()) {
+            Slog.i(TAG, "Start aggregating watchlist records.");
+            final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
+            if (dbox != null && !dbox.isTagEnabled(DROPBOX_TAG)) {
+                final WatchlistReportDbHelper.AggregatedResult aggregatedResult =
+                        mDbHelper.getAggregatedRecords();
+                final byte[] encodedResult = encodeAggregatedResult(aggregatedResult);
+                if (encodedResult != null) {
+                    addEncodedReportToDropBox(encodedResult);
+                }
+            }
+            mDbHelper.cleanup();
+            Settings.Global.putLong(mResolver, Settings.Global.NETWORK_WATCHLIST_LAST_REPORT_TIME,
+                    System.currentTimeMillis());
+        } else {
+            Slog.i(TAG, "No need to aggregate record yet.");
+        }
+    }
+
+    private byte[] encodeAggregatedResult(
+            WatchlistReportDbHelper.AggregatedResult aggregatedResult) {
+        // TODO: Encode results using differential privacy.
+        return null;
+    }
+
+    private void addEncodedReportToDropBox(byte[] encodedReport) {
+        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
+        dbox.addData(DROPBOX_TAG, encodedReport, 0);
+    }
+
+    /**
+     * Get app digest from app uid.
+     */
+    private byte[] getDigestFromUid(int uid) {
+        final byte[] cachedDigest = mCachedUidDigestMap.get(uid);
+        if (cachedDigest != null) {
+            return cachedDigest;
+        }
+        final String[] packageNames = mPm.getPackagesForUid(uid);
+        final int userId = UserHandle.getUserId(uid);
+        if (!ArrayUtils.isEmpty(packageNames)) {
+            for (String packageName : packageNames) {
+                try {
+                    final String apkPath = mPm.getPackageInfoAsUser(packageName,
+                            PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId)
+                            .applicationInfo.publicSourceDir;
+                    if (TextUtils.isEmpty(apkPath)) {
+                        Slog.w(TAG, "Cannot find apkPath for " + packageName);
+                        continue;
+                    }
+                    final byte[] digest = DigestUtils.getSha256Hash(new File(apkPath));
+                    mCachedUidDigestMap.put(uid, digest);
+                    return digest;
+                } catch (NameNotFoundException | NoSuchAlgorithmException | IOException e) {
+                    Slog.e(TAG, "Should not happen", e);
+                    return null;
+                }
+            }
+        } else {
+            Slog.e(TAG, "Should not happen");
+        }
+        return null;
+    }
+
+    /**
+     * Search if any ip addresses are in watchlist.
+     *
+     * @param ipAddresses Ip address that you want to search in watchlist.
+     * @return Ip address that exists in watchlist, null if it does not match anything.
+     */
+    private String searchIpInWatchlist(String[] ipAddresses) {
+        for (String ipAddress : ipAddresses) {
+            if (isIpInWatchlist(ipAddress)) {
+                return ipAddress;
+            }
+        }
+        return null;
+    }
+
+    /** Search if the ip is in watchlist */
+    private boolean isIpInWatchlist(String ipAddr) {
+        if (ipAddr == null) {
+            return false;
+        }
+        return mSettings.containsIp(ipAddr);
+    }
+
+    /** Search if the host is in watchlist */
+    private boolean isHostInWatchlist(String host) {
+        if (host == null) {
+            return false;
+        }
+        return mSettings.containsDomain(host);
+    }
+
+    /**
+     * Search if any sub-domain in host is in watchlist.
+     *
+     * @param host Host that we want to search.
+     * @return Domain that exists in watchlist, null if it does not match anything.
+     */
+    private String searchAllSubDomainsInWatchlist(String host) {
+        if (host == null) {
+            return null;
+        }
+        final String[] subDomains = getAllSubDomains(host);
+        for (String subDomain : subDomains) {
+            if (isHostInWatchlist(subDomain)) {
+                return subDomain;
+            }
+        }
+        return null;
+    }
+
+    /** Get all sub-domains in a host */
+    @VisibleForTesting
+    static String[] getAllSubDomains(String host) {
+        if (host == null) {
+            return null;
+        }
+        final ArrayList<String> subDomainList = new ArrayList<>();
+        subDomainList.add(host);
+        int index = host.indexOf(".");
+        while (index != -1) {
+            host = host.substring(index + 1);
+            if (!TextUtils.isEmpty(host)) {
+                subDomainList.add(host);
+            }
+            index = host.indexOf(".");
+        }
+        return subDomainList.toArray(new String[0]);
+    }
+}
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java b/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java
new file mode 100644
index 0000000..f48463f
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Pair;
+
+import com.android.internal.util.HexDump;
+
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Helper class to process watchlist read / save watchlist reports.
+ */
+class WatchlistReportDbHelper extends SQLiteOpenHelper {
+
+    private static final String TAG = "WatchlistReportDbHelper";
+
+    private static final String NAME = "watchlist_report.db";
+    private static final int VERSION = 2;
+
+    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
+
+    private static class WhiteListReportContract {
+        private static final String TABLE = "records";
+        private static final String APP_DIGEST = "app_digest";
+        private static final String CNC_DOMAIN = "cnc_domain";
+        private static final String TIMESTAMP = "timestamp";
+    }
+
+    private static final String CREATE_TABLE_MODEL = "CREATE TABLE "
+            + WhiteListReportContract.TABLE + "("
+            + WhiteListReportContract.APP_DIGEST + " BLOB,"
+            + WhiteListReportContract.CNC_DOMAIN + " TEXT,"
+            + WhiteListReportContract.TIMESTAMP + " INTEGER DEFAULT 0" + " )";
+
+    private static final int INDEX_DIGEST = 0;
+    private static final int INDEX_CNC_DOMAIN = 1;
+    private static final int INDEX_TIMESTAMP = 2;
+
+    private static final String[] DIGEST_DOMAIN_PROJECTION =
+            new String[] {
+                    WhiteListReportContract.APP_DIGEST,
+                    WhiteListReportContract.CNC_DOMAIN
+            };
+
+    private static WatchlistReportDbHelper sInstance;
+
+    /**
+     * Aggregated watchlist records.
+     */
+    public static class AggregatedResult {
+        // A list of digests that visited c&c domain or ip before.
+        Set<String> appDigestList;
+
+        // The c&c domain or ip visited before.
+        String cncDomainVisited;
+
+        // A list of app digests and c&c domain visited.
+        HashMap<String, String> appDigestCNCList;
+    }
+
+    private WatchlistReportDbHelper(Context context) {
+        super(context, WatchlistSettings.getSystemWatchlistFile(NAME).getAbsolutePath(),
+                null, VERSION);
+        // Memory optimization - close idle connections after 30s of inactivity
+        setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+    }
+
+    public static synchronized WatchlistReportDbHelper getInstance(Context context) {
+        if (sInstance != null) {
+            return sInstance;
+        }
+        sInstance = new WatchlistReportDbHelper(context);
+        return sInstance;
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        db.execSQL(CREATE_TABLE_MODEL);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        // TODO: For now, drop older tables and recreate new ones.
+        db.execSQL("DROP TABLE IF EXISTS " + WhiteListReportContract.TABLE);
+        onCreate(db);
+    }
+
+    /**
+     * Insert new watchlist record.
+     *
+     * @param appDigest The digest of an app.
+     * @param cncDomain C&C domain that app visited.
+     * @return True if success.
+     */
+    public boolean insertNewRecord(byte[] appDigest, String cncDomain,
+            long timestamp) {
+        final SQLiteDatabase db = getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        values.put(WhiteListReportContract.APP_DIGEST, appDigest);
+        values.put(WhiteListReportContract.CNC_DOMAIN, cncDomain);
+        values.put(WhiteListReportContract.TIMESTAMP, timestamp);
+        return db.insert(WhiteListReportContract.TABLE, null, values) != -1;
+    }
+
+    /**
+     * Aggregate the records in database, and return a rappor encoded result.
+     */
+    public AggregatedResult getAggregatedRecords() {
+        final long twoDaysBefore = getTwoDaysBeforeTimestamp();
+        final long yesterday = getYesterdayTimestamp();
+        final String selectStatement = WhiteListReportContract.TIMESTAMP + " >= ? AND " +
+                WhiteListReportContract.TIMESTAMP + " <= ?";
+
+        final SQLiteDatabase db = getReadableDatabase();
+        Cursor c = null;
+        try {
+            c = db.query(true /* distinct */,
+                    WhiteListReportContract.TABLE, DIGEST_DOMAIN_PROJECTION, selectStatement,
+                    new String[]{"" + twoDaysBefore, "" + yesterday}, null, null,
+                    null, null);
+            if (c == null || c.getCount() == 0) {
+                return null;
+            }
+            final AggregatedResult result = new AggregatedResult();
+            result.cncDomainVisited = null;
+            // After aggregation, each digest maximum will have only 1 record.
+            result.appDigestList = new HashSet<>();
+            result.appDigestCNCList = new HashMap<>();
+            while (c.moveToNext()) {
+                // We use hex string here as byte[] cannot be a key in HashMap.
+                String digestHexStr = HexDump.toHexString(c.getBlob(INDEX_DIGEST));
+                String cncDomain = c.getString(INDEX_CNC_DOMAIN);
+
+                result.appDigestList.add(digestHexStr);
+                if (result.cncDomainVisited != null) {
+                    result.cncDomainVisited = cncDomain;
+                }
+                result.appDigestCNCList.put(digestHexStr, cncDomain);
+            }
+            return result;
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+    }
+
+    /**
+     * Remove all the records before yesterday.
+     *
+     * @return True if success.
+     */
+    public boolean cleanup() {
+        final SQLiteDatabase db = getWritableDatabase();
+        final long twoDaysBefore = getTwoDaysBeforeTimestamp();
+        final String clause = WhiteListReportContract.TIMESTAMP + "< " + twoDaysBefore;
+        return db.delete(WhiteListReportContract.TABLE, clause, null) != 0;
+    }
+
+    static long getTwoDaysBeforeTimestamp() {
+        return getMidnightTimestamp(2);
+    }
+
+    static long getYesterdayTimestamp() {
+        return getMidnightTimestamp(1);
+    }
+
+    static long getMidnightTimestamp(int daysBefore) {
+        java.util.Calendar date = new GregorianCalendar();
+        // reset hour, minutes, seconds and millis
+        date.set(java.util.Calendar.HOUR_OF_DAY, 0);
+        date.set(java.util.Calendar.MINUTE, 0);
+        date.set(java.util.Calendar.SECOND, 0);
+        date.set(java.util.Calendar.MILLISECOND, 0);
+        date.add(java.util.Calendar.DAY_OF_MONTH, -daysBefore);
+        return date.getTimeInMillis();
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
new file mode 100644
index 0000000..c50f0d5
--- /dev/null
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.HexDump;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.CRC32;
+
+/**
+ * A util class to do watchlist settings operations, like setting watchlist, query if a domain
+ * exists in watchlist.
+ */
+class WatchlistSettings {
+    private static final String TAG = "WatchlistSettings";
+
+    // Settings xml will be stored in /data/system/network_watchlist/watchlist_settings.xml
+    static final String SYSTEM_WATCHLIST_DIR = "network_watchlist";
+
+    private static final String WATCHLIST_XML_FILE = "watchlist_settings.xml";
+
+    private static class XmlTags {
+        private static final String WATCHLIST_SETTINGS = "watchlist-settings";
+        private static final String SHA256_DOMAIN = "sha256-domain";
+        private static final String CRC32_DOMAIN = "crc32-domain";
+        private static final String SHA256_IP = "sha256-ip";
+        private static final String CRC32_IP = "crc32-ip";
+        private static final String HASH = "hash";
+    }
+
+    private static WatchlistSettings sInstance = new WatchlistSettings();
+    private final AtomicFile mXmlFile;
+    private final Object mLock = new Object();
+    private HarmfulDigests mCrc32DomainDigests = new HarmfulDigests(new ArrayList<>());
+    private HarmfulDigests mSha256DomainDigests = new HarmfulDigests(new ArrayList<>());
+    private HarmfulDigests mCrc32IpDigests = new HarmfulDigests(new ArrayList<>());
+    private HarmfulDigests mSha256IpDigests = new HarmfulDigests(new ArrayList<>());
+
+    public static synchronized WatchlistSettings getInstance() {
+        return sInstance;
+    }
+
+    private WatchlistSettings() {
+        this(getSystemWatchlistFile(WATCHLIST_XML_FILE));
+    }
+
+    @VisibleForTesting
+    protected WatchlistSettings(File xmlFile) {
+        mXmlFile = new AtomicFile(xmlFile);
+        readSettingsLocked();
+    }
+
+    static File getSystemWatchlistFile(String filename) {
+        final File dataSystemDir = Environment.getDataSystemDirectory();
+        final File systemWatchlistDir = new File(dataSystemDir, SYSTEM_WATCHLIST_DIR);
+        systemWatchlistDir.mkdirs();
+        return new File(systemWatchlistDir, filename);
+    }
+
+    private void readSettingsLocked() {
+        synchronized (mLock) {
+            FileInputStream stream;
+            try {
+                stream = mXmlFile.openRead();
+            } catch (FileNotFoundException e) {
+                Log.i(TAG, "No watchlist settings: " + mXmlFile.getBaseFile().getAbsolutePath());
+                return;
+            }
+
+            final List<byte[]> crc32DomainList = new ArrayList<>();
+            final List<byte[]> sha256DomainList = new ArrayList<>();
+            final List<byte[]> crc32IpList = new ArrayList<>();
+            final List<byte[]> sha256IpList = new ArrayList<>();
+
+            try {
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(stream, StandardCharsets.UTF_8.name());
+                parser.nextTag();
+                parser.require(XmlPullParser.START_TAG, null, XmlTags.WATCHLIST_SETTINGS);
+                while (parser.nextTag() == XmlPullParser.START_TAG) {
+                    String tagName = parser.getName();
+                    switch (tagName) {
+                        case XmlTags.CRC32_DOMAIN:
+                            parseHash(parser, tagName, crc32DomainList);
+                            break;
+                        case XmlTags.CRC32_IP:
+                            parseHash(parser, tagName, crc32IpList);
+                            break;
+                        case XmlTags.SHA256_DOMAIN:
+                            parseHash(parser, tagName, sha256DomainList);
+                            break;
+                        case XmlTags.SHA256_IP:
+                            parseHash(parser, tagName, sha256IpList);
+                            break;
+                        default:
+                            Log.w(TAG, "Unknown element: " + parser.getName());
+                            XmlUtils.skipCurrentTag(parser);
+                    }
+                }
+                parser.require(XmlPullParser.END_TAG, null, XmlTags.WATCHLIST_SETTINGS);
+                writeSettingsToMemory(crc32DomainList, sha256DomainList, crc32IpList, sha256IpList);
+            } catch (IllegalStateException | NullPointerException | NumberFormatException |
+                    XmlPullParserException | IOException | IndexOutOfBoundsException e) {
+                Log.w(TAG, "Failed parsing " + e);
+            } finally {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private void parseHash(XmlPullParser parser, String tagName, List<byte[]> hashSet)
+            throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, null, tagName);
+        while (parser.nextTag() == XmlPullParser.START_TAG) {
+            parser.require(XmlPullParser.START_TAG, null, XmlTags.HASH);
+            byte[] hash = HexDump.hexStringToByteArray(parser.nextText());
+            parser.require(XmlPullParser.END_TAG, null, XmlTags.HASH);
+            hashSet.add(hash);
+        }
+        parser.require(XmlPullParser.END_TAG, null, tagName);
+    }
+
+    /**
+     * Write network watchlist settings to disk.
+     * Adb should not use it, should use writeSettingsToMemory directly instead.
+     */
+    public void writeSettingsToDisk(List<byte[]> newCrc32DomainList,
+            List<byte[]> newSha256DomainList,
+            List<byte[]> newCrc32IpList,
+            List<byte[]> newSha256IpList) {
+        synchronized (mLock) {
+            FileOutputStream stream;
+            try {
+                stream = mXmlFile.startWrite();
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to write display settings: " + e);
+                return;
+            }
+
+            try {
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(stream, StandardCharsets.UTF_8.name());
+                out.startDocument(null, true);
+                out.startTag(null, XmlTags.WATCHLIST_SETTINGS);
+
+                writeHashSetToXml(out, XmlTags.SHA256_DOMAIN, newSha256DomainList);
+                writeHashSetToXml(out, XmlTags.SHA256_IP, newSha256IpList);
+                writeHashSetToXml(out, XmlTags.CRC32_DOMAIN, newCrc32DomainList);
+                writeHashSetToXml(out, XmlTags.CRC32_IP, newCrc32IpList);
+
+                out.endTag(null, XmlTags.WATCHLIST_SETTINGS);
+                out.endDocument();
+                mXmlFile.finishWrite(stream);
+                writeSettingsToMemory(newCrc32DomainList, newSha256DomainList, newCrc32IpList,
+                        newSha256IpList);
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to write display settings, restoring backup.", e);
+                mXmlFile.failWrite(stream);
+            }
+        }
+    }
+
+    /**
+     * Write network watchlist settings to memory.
+     */
+    public void writeSettingsToMemory(List<byte[]> newCrc32DomainList,
+            List<byte[]> newSha256DomainList,
+            List<byte[]> newCrc32IpList,
+            List<byte[]> newSha256IpList) {
+        synchronized (mLock) {
+            mCrc32DomainDigests = new HarmfulDigests(newCrc32DomainList);
+            mCrc32IpDigests = new HarmfulDigests(newCrc32IpList);
+            mSha256DomainDigests = new HarmfulDigests(newSha256DomainList);
+            mSha256IpDigests = new HarmfulDigests(newSha256IpList);
+        }
+    }
+
+    private static void writeHashSetToXml(XmlSerializer out, String tagName, List<byte[]> hashSet)
+            throws IOException {
+        out.startTag(null, tagName);
+        for (byte[] hash : hashSet) {
+            out.startTag(null, XmlTags.HASH);
+            out.text(HexDump.toHexString(hash));
+            out.endTag(null, XmlTags.HASH);
+        }
+        out.endTag(null, tagName);
+    }
+
+    public boolean containsDomain(String domain) {
+        // First it does a quick CRC32 check.
+        final byte[] crc32 = getCrc32(domain);
+        if (!mCrc32DomainDigests.contains(crc32)) {
+            return false;
+        }
+        // Now we do a slow SHA256 check.
+        final byte[] sha256 = getSha256(domain);
+        return mSha256DomainDigests.contains(sha256);
+    }
+
+    public boolean containsIp(String ip) {
+        // First it does a quick CRC32 check.
+        final byte[] crc32 = getCrc32(ip);
+        if (!mCrc32IpDigests.contains(crc32)) {
+            return false;
+        }
+        // Now we do a slow SHA256 check.
+        final byte[] sha256 = getSha256(ip);
+        return mSha256IpDigests.contains(sha256);
+    }
+
+
+    /** Get CRC32 of a string */
+    private byte[] getCrc32(String str) {
+        final CRC32 crc = new CRC32();
+        crc.update(str.getBytes());
+        final long tmp = crc.getValue();
+        return new byte[]{(byte)(tmp >> 24 & 255), (byte)(tmp >> 16 & 255),
+                (byte)(tmp >> 8 & 255), (byte)(tmp & 255)};
+    }
+
+    /** Get SHA256 of a string */
+    private byte[] getSha256(String str) {
+        MessageDigest messageDigest;
+        try {
+            messageDigest = MessageDigest.getInstance("SHA256");
+        } catch (NoSuchAlgorithmException e) {
+            /* can't happen */
+            return null;
+        }
+        messageDigest.update(str.getBytes());
+        return messageDigest.digest();
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Domain CRC32 digest list:");
+        mCrc32DomainDigests.dump(fd, pw, args);
+        pw.println("Domain SHA256 digest list:");
+        mSha256DomainDigests.dump(fd, pw, args);
+        pw.println("Ip CRC32 digest list:");
+        mCrc32IpDigests.dump(fd, pw, args);
+        pw.println("Ip SHA256 digest list:");
+        mSha256IpDigests.dump(fd, pw, args);
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
index 0085931..0aaf32c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
@@ -107,7 +107,8 @@
             return false;
         }
         try {
-           if (mIpConnectivityMetrics.registerNetdEventCallback(mNetdEventCallback)) {
+           if (mIpConnectivityMetrics.addNetdEventCallback(
+                   INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY, mNetdEventCallback)) {
                 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
                         /* allowIo */ false);
                 mHandlerThread.start();
@@ -138,7 +139,8 @@
                 // logging is forcefully disabled even if unregistering fails
                 return true;
             }
-            return mIpConnectivityMetrics.unregisterNetdEventCallback();
+            return mIpConnectivityMetrics.removeNetdEventCallback(
+                    INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY);
         } catch (RemoteException re) {
             Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re);
             return true;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f8bcb73..e2e491a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -83,6 +83,7 @@
 import com.android.server.media.projection.MediaProjectionManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
+import com.android.server.net.watchlist.NetworkWatchlistService;
 import com.android.server.notification.NotificationManagerService;
 import com.android.server.oemlock.OemLockService;
 import com.android.server.om.OverlayManagerService;
@@ -884,6 +885,10 @@
             mSystemServiceManager.startService(IpConnectivityMetrics.class);
             traceEnd();
 
+            traceBeginAndSlog("NetworkWatchlistService");
+            mSystemServiceManager.startService(NetworkWatchlistService.Lifecycle.class);
+            traceEnd();
+
             traceBeginAndSlog("PinnerService");
             mSystemServiceManager.startService(PinnerService.class);
             traceEnd();
diff --git a/services/tests/servicestests/assets/NetworkWatchlistTest/watchlist_settings_test1.xml b/services/tests/servicestests/assets/NetworkWatchlistTest/watchlist_settings_test1.xml
new file mode 100644
index 0000000..bb97e94
--- /dev/null
+++ b/services/tests/servicestests/assets/NetworkWatchlistTest/watchlist_settings_test1.xml
@@ -0,0 +1,27 @@
+<?xml version='1.0'?>
+<watchlist-settings>
+    <sha256-domain>
+        <!-- test-cc-domain.com -->
+        <hash>8E7DCD2AEB4F364358242BB3F403263E61E3B4AECE4E2500FF28BF32E52FF0F1</hash>
+        <!-- test-cc-match-sha256-only.com -->
+        <hash>F0905DA7549614957B449034C281EF7BDEFDBC2B6E050AD1E78D6DE18FBD0D5F</hash>
+    </sha256-domain>
+    <sha256-ip>
+        <!-- 127.0.0.2 -->
+        <hash>1EDD62868F2767A1FFF68DF0A4CB3C23448E45100715768DB9310B5E719536A1</hash>
+        <!-- 127.0.0.3, match in sha256 only -->
+        <hash>18DD41C9F2E8E4879A1575FB780514EF33CF6E1F66578C4AE7CCA31F49B9F2ED</hash>
+    </sha256-ip>
+    <crc32-domain>
+        <!-- test-cc-domain.com -->
+        <hash>6C67059D</hash>
+        <!-- test-cc-match-crc32-only.com -->
+        <hash>3DC775F8</hash>
+    </crc32-domain>
+    <crc32-ip>
+        <!-- 127.0.0.2 -->
+        <hash>4EBEB612</hash>
+        <!-- 127.0.0.4, match in crc32 only -->
+        <hash>A7DD1327</hash>
+    </crc32-ip>
+</watchlist-settings>
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 9d23fe9..6de3395 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3193,7 +3193,7 @@
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
         getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
-        when(getServices().iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
+        when(getServices().iipConnectivityMetrics.addNetdEventCallback(anyInt(), anyObject()))
                 .thenReturn(true);
 
         // No logs were retrieved so far.
diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/HarmfulDigestsTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/HarmfulDigestsTests.java
new file mode 100644
index 0000000..a34f95e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/watchlist/HarmfulDigestsTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.HexDump;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * runtest frameworks-services -c com.android.server.net.watchlist.HarmfulDigestsTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class HarmfulDigestsTests {
+
+    private static final byte[] TEST_DIGEST_1 = HexDump.hexStringToByteArray("AAAAAA");
+    private static final byte[] TEST_DIGEST_2 = HexDump.hexStringToByteArray("BBBBBB");
+    private static final byte[] TEST_DIGEST_3 = HexDump.hexStringToByteArray("AAAABB");
+    private static final byte[] TEST_DIGEST_4 = HexDump.hexStringToByteArray("BBBBAA");
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void testHarmfulDigests_setAndContains() throws Exception {
+        HarmfulDigests harmfulDigests = new HarmfulDigests(
+                Arrays.asList(new byte[][] {TEST_DIGEST_1}));
+        assertTrue(harmfulDigests.contains(TEST_DIGEST_1));
+        assertFalse(harmfulDigests.contains(TEST_DIGEST_2));
+        assertFalse(harmfulDigests.contains(TEST_DIGEST_3));
+        assertFalse(harmfulDigests.contains(TEST_DIGEST_4));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/NetworkWatchlistServiceTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/NetworkWatchlistServiceTests.java
new file mode 100644
index 0000000..ccd3cdd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/watchlist/NetworkWatchlistServiceTests.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.ConnectivityMetricsEvent;
+import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.ServiceThread;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * runtest frameworks-services -c com.android.server.net.watchlist.NetworkWatchlistServiceTests
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class NetworkWatchlistServiceTests {
+
+    private static final long NETWOR_EVENT_TIMEOUT_SEC = 1;
+    private static final String TEST_HOST = "testhost.com";
+    private static final String TEST_IP = "7.6.8.9";
+    private static final String[] TEST_IPS =
+            new String[] {"1.2.3.4", "4.6.8.9", "2001:0db8:0001:0000:0000:0ab9:C0A8:0102"};
+
+    private static class TestHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case WatchlistLoggingHandler.LOG_WATCHLIST_EVENT_MSG:
+                    onLogEvent();
+                    break;
+                case WatchlistLoggingHandler.REPORT_RECORDS_IF_NECESSARY_MSG:
+                    onAggregateEvent();
+                    break;
+                default:
+                    fail("Unexpected message: " + msg.what);
+            }
+        }
+
+        public void onLogEvent() {}
+        public void onAggregateEvent() {}
+    }
+
+    private static class TestIIpConnectivityMetrics implements IIpConnectivityMetrics {
+
+        int counter = 0;
+        INetdEventCallback callback = null;
+
+        @Override
+        public IBinder asBinder() {
+            return null;
+        }
+
+        @Override
+        public int logEvent(ConnectivityMetricsEvent connectivityMetricsEvent)
+                    throws RemoteException {
+            return 0;
+        }
+
+        @Override
+        public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
+            counter++;
+            this.callback = callback;
+            return true;
+        }
+
+        @Override
+        public boolean removeNetdEventCallback(int callerType) {
+            counter--;
+            return true;
+        }
+    };
+
+    ServiceThread mHandlerThread;
+    WatchlistLoggingHandler mWatchlistHandler;
+    NetworkWatchlistService mWatchlistService;
+
+    @Before
+    public void setUp() {
+        mHandlerThread = new ServiceThread("NetworkWatchlistServiceTests",
+                Process.THREAD_PRIORITY_BACKGROUND, /* allowIo */ false);
+        mHandlerThread.start();
+        mWatchlistHandler = new WatchlistLoggingHandler(InstrumentationRegistry.getContext(),
+                mHandlerThread.getLooper());
+        mWatchlistService = new NetworkWatchlistService(InstrumentationRegistry.getContext(),
+                mHandlerThread, mWatchlistHandler, null);
+    }
+
+    @After
+    public void tearDown() {
+        mHandlerThread.quitSafely();
+    }
+
+    @Test
+    public void testStartStopWatchlistLogging() throws Exception {
+        TestIIpConnectivityMetrics connectivityMetrics = new TestIIpConnectivityMetrics() {
+            @Override
+            public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
+                super.addNetdEventCallback(callerType, callback);
+                assertEquals(callerType, INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST);
+                return true;
+            }
+
+            @Override
+            public boolean removeNetdEventCallback(int callerType) {
+                super.removeNetdEventCallback(callerType);
+                assertEquals(callerType, INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST);
+                return true;
+            }
+        };
+        assertEquals(connectivityMetrics.counter, 0);
+        mWatchlistService.mIpConnectivityMetrics = connectivityMetrics;
+        assertTrue(mWatchlistService.startWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 1);
+        assertTrue(mWatchlistService.startWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 1);
+        assertTrue(mWatchlistService.stopWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 0);
+        assertTrue(mWatchlistService.stopWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 0);
+        assertTrue(mWatchlistService.startWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 1);
+        assertTrue(mWatchlistService.stopWatchlistLoggingImpl());
+        assertEquals(connectivityMetrics.counter, 0);
+    }
+
+    @Test
+    public void testNetworkEvents() throws Exception {
+        TestIIpConnectivityMetrics connectivityMetrics = new TestIIpConnectivityMetrics();
+        mWatchlistService.mIpConnectivityMetrics = connectivityMetrics;
+        assertTrue(mWatchlistService.startWatchlistLoggingImpl());
+
+        // Test DNS events
+        final CountDownLatch testDnsLatch = new CountDownLatch(1);
+        final Object[] dnsParams = new Object[3];
+        final WatchlistLoggingHandler testDnsHandler =
+                new WatchlistLoggingHandler(InstrumentationRegistry.getContext(),
+                        mHandlerThread.getLooper()) {
+                    @Override
+                    public void asyncNetworkEvent(String host, String[] ipAddresses, int uid) {
+                        dnsParams[0] = host;
+                        dnsParams[1] = ipAddresses;
+                        dnsParams[2] = uid;
+                        testDnsLatch.countDown();
+                    }
+                };
+        mWatchlistService.mNetworkWatchlistHandler = testDnsHandler;
+        connectivityMetrics.callback.onDnsEvent(TEST_HOST, TEST_IPS, TEST_IPS.length, 123L, 456);
+        if (!testDnsLatch.await(NETWOR_EVENT_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for network event");
+        }
+        assertEquals(TEST_HOST, dnsParams[0]);
+        for (int i = 0; i < TEST_IPS.length; i++) {
+            assertEquals(TEST_IPS[i], ((String[])dnsParams[1])[i]);
+        }
+        assertEquals(456, dnsParams[2]);
+
+        // Test connect events
+        final CountDownLatch testConnectLatch = new CountDownLatch(1);
+        final Object[] connectParams = new Object[3];
+        final WatchlistLoggingHandler testConnectHandler =
+                new WatchlistLoggingHandler(InstrumentationRegistry.getContext(),
+                        mHandlerThread.getLooper()) {
+                    @Override
+                    public void asyncNetworkEvent(String host, String[] ipAddresses, int uid) {
+                        connectParams[0] = host;
+                        connectParams[1] = ipAddresses;
+                        connectParams[2] = uid;
+                        testConnectLatch.countDown();
+                    }
+                };
+        mWatchlistService.mNetworkWatchlistHandler = testConnectHandler;
+        connectivityMetrics.callback.onConnectEvent(TEST_IP, 80, 123L, 456);
+        if (!testConnectLatch.await(NETWOR_EVENT_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for network event");
+        }
+        assertNull(connectParams[0]);
+        assertEquals(1, ((String[]) connectParams[1]).length);
+        assertEquals(TEST_IP, ((String[]) connectParams[1])[0]);
+        assertEquals(456, connectParams[2]);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistLoggingHandlerTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistLoggingHandlerTests.java
new file mode 100644
index 0000000..e356b13
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistLoggingHandlerTests.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * runtest frameworks-services -c com.android.server.net.watchlist.WatchlistLoggingHandlerTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WatchlistLoggingHandlerTests {
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void testWatchlistLoggingHandler_getAllSubDomains() throws Exception {
+        String[] subDomains = WatchlistLoggingHandler.getAllSubDomains("abc.def.gh.i.jkl.mm");
+        assertTrue(Arrays.equals(subDomains, new String[] {"abc.def.gh.i.jkl.mm",
+                "def.gh.i.jkl.mm", "gh.i.jkl.mm", "i.jkl.mm", "jkl.mm", "mm"}));
+        subDomains = WatchlistLoggingHandler.getAllSubDomains(null);
+        assertNull(subDomains);
+        subDomains = WatchlistLoggingHandler.getAllSubDomains("jkl.mm");
+        assertTrue(Arrays.equals(subDomains, new String[] {"jkl.mm", "mm"}));
+        subDomains = WatchlistLoggingHandler.getAllSubDomains("abc");
+        assertTrue(Arrays.equals(subDomains, new String[] {"abc"}));
+        subDomains = WatchlistLoggingHandler.getAllSubDomains("jkl.mm.");
+        assertTrue(Arrays.equals(subDomains, new String[] {"jkl.mm.", "mm."}));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistSettingsTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistSettingsTests.java
new file mode 100644
index 0000000..f3cb980
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistSettingsTests.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2017 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.net.watchlist;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.HexDump;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+/**
+ * runtest frameworks-services -c com.android.server.net.watchlist.WatchlistSettingsTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WatchlistSettingsTests {
+
+    private static final String TEST_XML_1 = "NetworkWatchlistTest/watchlist_settings_test1.xml";
+    private static final String TEST_CC_DOMAIN = "test-cc-domain.com";
+    private static final String TEST_CC_IP = "127.0.0.2";
+    private static final String TEST_NOT_EXIST_CC_DOMAIN = "test-not-exist-cc-domain.com";
+    private static final String TEST_NOT_EXIST_CC_IP = "1.2.3.4";
+    private static final String TEST_SHA256_ONLY_DOMAIN = "test-cc-match-sha256-only.com";
+    private static final String TEST_SHA256_ONLY_IP = "127.0.0.3";
+    private static final String TEST_CRC32_ONLY_DOMAIN = "test-cc-match-crc32-only.com";
+    private static final String TEST_CRC32_ONLY_IP = "127.0.0.4";
+
+    private static final String TEST_NEW_CC_DOMAIN = "test-new-cc-domain.com";
+    private static final byte[] TEST_NEW_CC_DOMAIN_SHA256 = HexDump.hexStringToByteArray(
+            "B86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB43");
+    private static final byte[] TEST_NEW_CC_DOMAIN_CRC32 = HexDump.hexStringToByteArray("76795BD3");
+
+    private static final String TEST_NEW_CC_IP = "1.1.1.2";
+    private static final byte[] TEST_NEW_CC_IP_SHA256 = HexDump.hexStringToByteArray(
+            "721BAB5E313CF0CC76B10F9592F18B9D1B8996497501A3306A55B3AE9F1CC87C");
+    private static final byte[] TEST_NEW_CC_IP_CRC32 = HexDump.hexStringToByteArray("940B8BEE");
+
+    private Context mContext;
+    private File mTestXmlFile;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mTestXmlFile =  new File(mContext.getFilesDir(), "test_watchlist_settings.xml");
+        mTestXmlFile.delete();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTestXmlFile.delete();
+    }
+
+    @Test
+    public void testWatchlistSettings_parsing() throws Exception {
+        copyWatchlistSettingsXml(mContext, TEST_XML_1, mTestXmlFile);
+        WatchlistSettings settings = new WatchlistSettings(mTestXmlFile);
+        assertTrue(settings.containsDomain(TEST_CC_DOMAIN));
+        assertTrue(settings.containsIp(TEST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_NOT_EXIST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NOT_EXIST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_SHA256_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_SHA256_ONLY_IP));
+        assertFalse(settings.containsDomain(TEST_CRC32_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CRC32_ONLY_IP));
+    }
+
+    @Test
+    public void testWatchlistSettings_writeSettingsToDisk() throws Exception {
+        copyWatchlistSettingsXml(mContext, TEST_XML_1, mTestXmlFile);
+        WatchlistSettings settings = new WatchlistSettings(mTestXmlFile);
+        settings.writeSettingsToDisk(Arrays.asList(TEST_NEW_CC_DOMAIN_CRC32),
+                Arrays.asList(TEST_NEW_CC_DOMAIN_SHA256), Arrays.asList(TEST_NEW_CC_IP_CRC32),
+                Arrays.asList(TEST_NEW_CC_IP_SHA256));
+        // Ensure old watchlist is not in memory
+        assertFalse(settings.containsDomain(TEST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_NOT_EXIST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NOT_EXIST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_SHA256_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_SHA256_ONLY_IP));
+        assertFalse(settings.containsDomain(TEST_CRC32_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CRC32_ONLY_IP));
+        // Ensure new watchlist is in memory
+        assertTrue(settings.containsDomain(TEST_NEW_CC_DOMAIN));
+        assertTrue(settings.containsIp(TEST_NEW_CC_IP));
+        // Reload settings from disk and test again
+        settings = new WatchlistSettings(mTestXmlFile);
+        // Ensure old watchlist is not in memory
+        assertFalse(settings.containsDomain(TEST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_NOT_EXIST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NOT_EXIST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_SHA256_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_SHA256_ONLY_IP));
+        assertFalse(settings.containsDomain(TEST_CRC32_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CRC32_ONLY_IP));
+        // Ensure new watchlist is in memory
+        assertTrue(settings.containsDomain(TEST_NEW_CC_DOMAIN));
+        assertTrue(settings.containsIp(TEST_NEW_CC_IP));
+    }
+
+    @Test
+    public void testWatchlistSettings_writeSettingsToMemory() throws Exception {
+        copyWatchlistSettingsXml(mContext, TEST_XML_1, mTestXmlFile);
+        WatchlistSettings settings = new WatchlistSettings(mTestXmlFile);
+        settings.writeSettingsToMemory(Arrays.asList(TEST_NEW_CC_DOMAIN_CRC32),
+                Arrays.asList(TEST_NEW_CC_DOMAIN_SHA256), Arrays.asList(TEST_NEW_CC_IP_CRC32),
+                Arrays.asList(TEST_NEW_CC_IP_SHA256));
+        // Ensure old watchlist is not in memory
+        assertFalse(settings.containsDomain(TEST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_NOT_EXIST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NOT_EXIST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_SHA256_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_SHA256_ONLY_IP));
+        assertFalse(settings.containsDomain(TEST_CRC32_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CRC32_ONLY_IP));
+        // Ensure new watchlist is in memory
+        assertTrue(settings.containsDomain(TEST_NEW_CC_DOMAIN));
+        assertTrue(settings.containsIp(TEST_NEW_CC_IP));
+        // Reload settings from disk and test again
+        settings = new WatchlistSettings(mTestXmlFile);
+        // Ensure old watchlist is in memory
+        assertTrue(settings.containsDomain(TEST_CC_DOMAIN));
+        assertTrue(settings.containsIp(TEST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_NOT_EXIST_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NOT_EXIST_CC_IP));
+        assertFalse(settings.containsDomain(TEST_SHA256_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_SHA256_ONLY_IP));
+        assertFalse(settings.containsDomain(TEST_CRC32_ONLY_DOMAIN));
+        assertFalse(settings.containsIp(TEST_CRC32_ONLY_IP));
+        // Ensure new watchlist is not in memory
+        assertFalse(settings.containsDomain(TEST_NEW_CC_DOMAIN));
+        assertFalse(settings.containsIp(TEST_NEW_CC_IP));;
+    }
+
+    private static void copyWatchlistSettingsXml(Context context, String xmlAsset, File outFile)
+            throws IOException {
+        writeToFile(outFile, readAsset(context, xmlAsset));
+
+    }
+
+    private static String readAsset(Context context, String assetPath) throws IOException {
+        final StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = new BufferedReader(
+                new InputStreamReader(
+                        context.getResources().getAssets().open(assetPath)))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                sb.append(line);
+                sb.append(System.lineSeparator());
+            }
+        }
+        return sb.toString();
+    }
+
+    private static void writeToFile(File path, String content)
+            throws IOException {
+        path.getParentFile().mkdirs();
+
+        try (FileWriter writer = new FileWriter(path)) {
+            writer.write(content);
+        }
+    }
+}
