diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
deleted file mode 100644
index c9183f6..0000000
--- a/packages/CaptivePortalLogin/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-java_defaults {
-    name: "CaptivePortalLoginDefaults",
-    srcs: ["src/**/*.java"],
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-    static_libs: [
-        "android-support-v4",
-        "metrics-constants-protos",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifest.xml",
-}
-
-android_app {
-    name: "CaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative CaptivePortalLogin signed with the platform cert, to use
-// with InProcessNetworkStack.
-android_app {
-    name: "PlatformCaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "platform",
-    overrides: ["CaptivePortalLogin"],
-}
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
deleted file mode 100644
index 0a03425..0000000
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.captiveportallogin"
-    android:versionCode="11"
-    android:versionName="Q-initial">
-
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
-    <uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" />
-    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-
-    <application android:label="@string/app_name"
-                 android:icon="@drawable/app_icon"
-                 android:usesCleartextTraffic="true"
-                 android:supportsRtl="true" >
-        <activity
-            android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
-            android:label="@string/action_bar_label"
-            android:theme="@style/AppTheme"
-            android:configChanges="keyboardHidden|orientation|screenSize" >
-            <intent-filter>
-                <action android:name="android.net.conn.CAPTIVE_PORTAL"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/packages/CaptivePortalLogin/OWNERS b/packages/CaptivePortalLogin/OWNERS
deleted file mode 100644
index 5f3635e..0000000
--- a/packages/CaptivePortalLogin/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-set noparent
-
-lorenzo@google.com
-reminv@google.com
-baligh@google.com
-delphij@google.com
diff --git a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png b/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
deleted file mode 100644
index 08294ce..0000000
--- a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
+++ /dev/null
Binary files differ
diff --git a/packages/CaptivePortalLogin/res/drawable/app_icon.xml b/packages/CaptivePortalLogin/res/drawable/app_icon.xml
deleted file mode 100644
index 456ca83..0000000
--- a/packages/CaptivePortalLogin/res/drawable/app_icon.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-    Copyright (C) 2019 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.
--->
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background>
-        <color android:color="@*android:color/accent_device_default_light" />
-    </background>
-    <foreground>
-        <inset
-            android:drawable="@drawable/maybe_wifi"
-            android:inset="25%">
-        </inset>
-    </foreground>
-</adaptive-icon>
diff --git a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml b/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
deleted file mode 100644
index 207aade..0000000
--- a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2019 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="26.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M19.1,14l-3.4,0l0,-1.5c0,-1.8 0.8,-2.8 1.5,-3.4C18.1,8.3 19.200001,8 20.6,8c1.2,0 2.3,0.3 3.1,0.8l1.9,-2.3C25.1,6.1 20.299999,2.1 13,2.1S0.9,6.1 0.4,6.5L13,22l0,0l0,0l0,0l0,0l6.5,-8.1L19.1,14z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M19.5,17.799999c0,-0.8 0.1,-1.3 0.2,-1.6c0.2,-0.3 0.5,-0.7 1.1,-1.2c0.4,-0.4 0.7,-0.8 1,-1.1s0.4,-0.8 0.4,-1.2c0,-0.5 -0.1,-0.9 -0.4,-1.2c-0.3,-0.3 -0.7,-0.4 -1.2,-0.4c-0.4,0 -0.8,0.1 -1.1,0.3c-0.3,0.2 -0.4,0.6 -0.4,1.1l-1.9,0c0,-1 0.3,-1.7 1,-2.2c0.6,-0.5 1.5,-0.8 2.5,-0.8c1.1,0 2,0.3 2.6,0.8c0.6,0.5 0.9,1.3 0.9,2.3c0,0.7 -0.2,1.3 -0.6,1.8c-0.4,0.6 -0.9,1.1 -1.5,1.6c-0.3,0.3 -0.5,0.5 -0.6,0.7c-0.1,0.2 -0.1,0.6 -0.1,1L19.5,17.700001zM21.4,21l-1.9,0l0,-1.8l1.9,0L21.4,21z"/>
-</vector>
diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
deleted file mode 100644
index c292323..0000000
--- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity"
-    tools:ignore="MergeRootFrame" >
-
-    <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-      <FrameLayout
-          android:layout_width="match_parent"
-          android:layout_height="4dp" >
-
-        <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
-        <ProgressBar
-            android:id="@+id/progress_bar"
-            style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
-            android:indeterminate="false"
-            android:max="100"
-            android:progress="0"
-            android:layout_gravity="center"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-      </FrameLayout>
-
-      <android.support.v4.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_refresh"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-        <WebView
-              android:id="@+id/webview"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:layout_alignParentBottom="false"
-              android:layout_alignParentRight="false" />
-      </android.support.v4.widget.SwipeRefreshLayout>
-
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml b/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
deleted file mode 100644
index ce05e78..0000000
--- a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical" >
-
-    <!-- ssl error type -->
-    <TextView
-        android:id="@+id/ssl_error_type"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start"
-        android:text="SSL_UNKNOWN"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip"
-        android:layout_marginBottom="0dip"
-        android:layout_marginTop="24dip" />
-
-    <!-- Page info: -->
-    <TextView
-        android:id="@+id/page_info"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Title: -->
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Address: -->
-    <TextView
-        android:id="@+id/address_header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info_address"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <TextView
-        android:id="@+id/address"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <ScrollView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="4dip"
-        android:paddingEnd="4dip" >
-
-        <!-- certificate view: -->
-        <LinearLayout
-            android:id="@+id/certificate_layout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_marginBottom="16dip" >
-            <TextView
-                android:id="@+id/ssl_error_msg"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:layout_marginStart="20dip"
-                android:layout_marginEnd="20dip"
-                android:gravity="center_vertical"
-                android:layout_marginBottom="4dip"
-                android:layout_marginTop="16dip" />
-        </LinearLayout>
-
-    </ScrollView>
-
-</LinearLayout>
diff --git a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml b/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
deleted file mode 100644
index 1a88c5c..0000000
--- a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity" >
-    <item
-        android:id="@+id/action_do_not_use_network"
-        android:orderInCategory="100"
-        android:showAsAction="never"
-        android:title="@string/action_do_not_use_network"/>
-    <item
-        android:id="@+id/action_use_network"
-        android:orderInCategory="200"
-        android:showAsAction="never"
-        android:title="@string/action_use_network"/>
-
-</menu>
diff --git a/packages/CaptivePortalLogin/res/values-af/strings.xml b/packages/CaptivePortalLogin/res/values-af/strings.xml
deleted file mode 100644
index cf4dc82..0000000
--- a/packages/CaptivePortalLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortal-aanmelding"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gebruik hierdie netwerk nes dit is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Moenie hierdie netwerk gebruik nie"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Meld by netwerk aan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Meld aan by %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Gaan in elk geval deur blaaier voort"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Bladsy-inligting"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adres:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Sekuriteitswaarskuwing"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Bekyk sertifikaat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Hierdie sertifikaat is nie van \'n betroubare owerheid nie."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Die naam van die werf kom nie ooreen met die naam op die sertifikaat nie."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Hierdie sertifikaat het verval."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Hierdie sertifikaat is nog nie geldig nie."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Hierdie sertifikaat het \'n ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Hierdie sertifikaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Onbekende sertifikaatfout."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-am/strings.xml b/packages/CaptivePortalLogin/res/values-am/strings.xml
deleted file mode 100644
index cdcb5a5..0000000
--- a/packages/CaptivePortalLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ይህን አውታረ መረብ እንዳለ ተጠቀምበት"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ይህን አውታረ መረብ አትጠቀምበት"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ወደ %1$s ይግቡ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
-    <string name="ok" msgid="1509280796718850364">"እሺ"</string>
-    <string name="page_info" msgid="4048529256302257195">"የገፅ መረጃ"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"አድራሻ:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"የደህንነት ቅንብሮች"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"ምስክሮች ይመልከቱ"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"ይህ ምስክር ከታማኝ ቦታ አይደለም።"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"የጣቢያው ስም ከምስክር ወረቀቱ ስም ጋር አይዛመድም።"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"ይህ ምስክር ጊዜው አልፏል"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"ይህ ምስክር ገና ትክክል አይደለም።"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"ይህ ምስክር ትክክለኛ ቀን አለው።"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"ይህ ምስክር ትክክል ያልሆነ ነው።"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"ያልታወቀ የምስክር ስህተት።"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ar/strings.xml b/packages/CaptivePortalLogin/res/values-ar/strings.xml
deleted file mode 100644
index 799b8aa..0000000
--- a/packages/CaptivePortalLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"استخدام هذه الشبكة كما هي"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"عدم استخدام هذه الشبكة"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"تسجيل الدخول إلى الشبكة"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for action_bar_title (5645564790486983117) -->
-    <skip />
-    <string name="ssl_error_warning" msgid="6653188881418638872">"الشبكة التي تحاول الانضمام إليها بها مشكلات أمنية."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المنظمة المعروضة."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"المتابعة على أي حال عبر المتصفح"</string>
-    <string name="ok" msgid="1509280796718850364">"موافق"</string>
-    <string name="page_info" msgid="4048529256302257195">"معلومات الصفحة"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"العنوان:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"تحذير أمان"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"عرض الشهادة"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"هذه الشهادة ليست من جهة موثوق بها."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"لا يتطابق اسم الموقع مع الاسم على الشهادة."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"انتهت صلاحية هذه الشهادة."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"هذه الشهادة ليست صالحة بعد."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"تشتمل هذه الشهادة على تاريخ غير صالح."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"هذه الشهادة غير صالحة."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"حدث خطأ غير معروف بالشهادة."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-as/strings.xml b/packages/CaptivePortalLogin/res/values-as/strings.xml
deleted file mode 100644
index 94c3147..0000000
--- a/packages/CaptivePortalLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"এই নেটৱৰ্কটো এইদৰে ব্যৱহাৰ কৰক"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটৱৰ্কটো ব্যৱহাৰ নকৰিব"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$st ছাইন ইন কৰক"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপুনি সংযোগ কৰিবলৈ চেষ্টা কৰি থকা নেটৱৰ্কটোত সুৰক্ষাজনিত সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"তথাপি ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-az/strings.xml b/packages/CaptivePortalLogin/res/values-az/strings.xml
deleted file mode 100644
index 44b406d..0000000
--- a/packages/CaptivePortalLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu şəbəkəni olduğu kimi istifadə edin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu şəbəkəni istifadə etməyin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Şəbəkəyə daxil olun"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Daxil olun: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Hər bir halda brazuer ilə davam edin"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml b/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index f2a6e07..0000000
--- a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu takvu kakva je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavi me na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se u: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko pregledača"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-be/strings.xml b/packages/CaptivePortalLogin/res/values-be/strings.xml
deleted file mode 100644
index 09ed1de..0000000
--- a/packages/CaptivePortalLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Выкарыстоўваць гэтую сетку як ёсць"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не выкарыстоўваць гэту сетку"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увайсці ў сетку"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увайсці ў %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У сеткі, да якой вы спрабуеце далучыцца, ёсць праблемы з бяспекай."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усё роўна працягнуць праз браўзер"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
deleted file mode 100644
index 4dd8aa0..0000000
--- a/packages/CaptivePortalLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Директно използване на тази мрежа"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Вход в мрежата"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Влезте в/ъв %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например страницата за вход може да не принадлежи на показаната организация."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Продължаване през браузър въпреки това"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Данни за страницата"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Адрес:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Предупреждение относно защитата"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Преглед на сертификата"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Сертификатът не е от надежден орган."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Името на сайта не съответства на името в сертификата."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Сертификатът е изтекъл."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Сертификатът още не е валиден."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Този сертификат е с невалидна дата."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Този сертификат е невалиден."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Неизвестна грешка в сертификата."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bn/strings.xml b/packages/CaptivePortalLogin/res/values-bn/strings.xml
deleted file mode 100644
index fb703cf..0000000
--- a/packages/CaptivePortalLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে সাইন-ইন করুন"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s তে সাইন-ইন করুন"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগ-ইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sideinfo"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresse:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Sikkerhetsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Vis sertifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Sertifikatet er ikke fra en pålitelig myndighet."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Navnet på nettstedet samsvarer ikke med navnet på sertifikatet."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Sertifikatet er utløpt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Sertifikatet er ikke gyldig ennå."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Dette sertifikatet har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Dette sertifikatet er ugyldig."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Ukjent sertifikatfeil."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bs/strings.xml b/packages/CaptivePortalLogin/res/values-bs/strings.xml
deleted file mode 100644
index 10be0e5..0000000
--- a/packages/CaptivePortalLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Prijava na zaštitnom portalu"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu kakva jeste"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Naprimjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko preglednika"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
deleted file mode 100644
index a2c9ed8..0000000
--- a/packages/CaptivePortalLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Fes servir aquesta xarxa tal com està."</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia la sessió a la xarxa"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia la sessió a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La xarxa a què et vols connectar té problemes de seguretat."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua igualment mitjançant el navegador"</string>
-    <string name="ok" msgid="1509280796718850364">"D\'acord"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informació de la pàgina"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adreça:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Advertiment de seguretat"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Visualitza el certificat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Aquest certificat no és d\'una autoritat de confiança."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"El nom del lloc no coincideix amb el del certificat."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Aquest certificat ha caducat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Aquest certificat encara no és vàlid."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Aquest certificat té una data no vàlida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Aquest certificat no és vàlid."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Error de certificat desconegut."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-cs/strings.xml b/packages/CaptivePortalLogin/res/values-cs/strings.xml
deleted file mode 100644
index be649a5..0000000
--- a/packages/CaptivePortalLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použít tuto síť tak, jak je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Přihlásit se k síti"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Přihlaste se k síti %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Například přihlašovací stránka nemusí patřit do zobrazované organizace."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Přesto pokračovat prostřednictvím prohlížeče"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informace o stránce"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresa:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Upozornění zabezpečení"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Zobrazit certifikát"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Tento certifikát nepochází od důvěryhodné autority."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Název webu se neshoduje s názvem uvedeným v certifikátu."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Platnost certifikátu vypršela."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Tento certifikát ještě není platný."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Datum tohoto certifikátu není platné."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Neznámá chyba certifikátu."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-da/strings.xml b/packages/CaptivePortalLogin/res/values-da/strings.xml
deleted file mode 100644
index 8183105..0000000
--- a/packages/CaptivePortalLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Login til captive portal"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Brug dette netværk, som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Brug ikke dette netværk"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log ind på netværk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log ind på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsæt alligevel via browseren"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sideoplysninger"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresse:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Sikkerhedsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Vis certifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Dette certifikat stammer ikke fra en troværdig autoritet."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Navnet på websitet stemmer ikke overens med navnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Dette certifikat er udløbet."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Dette certifikat er endnu ikke gyldigt."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Dette certifikat har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Dette certifikat er ugyldigt."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Ukendt fejl i certifikatet."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
deleted file mode 100644
index 68862bf..0000000
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Dieses Netzwerk im Istzustand verwenden"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dieses Netzwerk nicht verwenden"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"In %1$s anmelden"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Seiteninfo"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresse:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Sicherheitswarnung"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Zertifikat ansehen"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Dieses Zertifikat wurde nicht von einer vertrauenswürdigen Stelle ausgegeben."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Name der Website stimmt nicht mit dem Namen auf dem Zertifikat überein."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Dieses Zertifikat ist abgelaufen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Dieses Zertifikat ist noch nicht gültig."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Dieses Zertifikat weist ein ungültiges Datum auf."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Dieses Zertifikat ist ungültig."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Unbekannter Zertifikatfehler"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-el/strings.xml b/packages/CaptivePortalLogin/res/values-el/strings.xml
deleted file mode 100644
index 16bf6e2..0000000
--- a/packages/CaptivePortalLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Χρήση αυτού του δικτύου ως έχει"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Να μη χρησιμοποιείται αυτό το δίκτυο"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Σύνδεση στο δίκτυο"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Συνδεθείτε στο %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Πληροφορίες σελίδας"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Διεύθυνση:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Προειδοποίηση ασφαλείας"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Προβολή πιστοποιητικού"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Αυτό το πιστοποιητικό δεν προέρχεται από αξιόπιστη αρχή."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Το όνομα του ιστότοπου δεν αντιστοιχεί με το όνομα στο πιστοποιητικό."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Αυτό το πιστοποιητικό έχει λήξει."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Αυτό το πιστοποιητικό δεν είναι έγκυρο ακόμα."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Αυτό το πιστοποιητικό δεν έχει έγκυρη ημερομηνία."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Αυτό το πιστοποιητικό δεν είναι έγκυρο."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Άγνωστο σφάλμα πιστοποιητικού."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index 2e8d1f0..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index 2e8d1f0..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml b/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index f940299..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Page info"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Address:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"View certificate"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Unknown certificate error."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index f940299..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Page info"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Address:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"View certificate"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Unknown certificate error."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml b/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index 6d29fd9..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎CaptivePortalLogin‎‏‎‎‏‎"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎Use this network as is‎‏‎‎‏‎"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎Do not use this network‎‏‎‎‏‎"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎Sign in to network‎‏‎‎‏‎"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎Sign in to %1$s‎‏‎‎‏‎"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎The network you’re trying to join has security issues.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎For example, the login page may not belong to the organization shown.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎Continue anyway via browser‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index c011664..0000000
--- a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta red como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No usar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Acceder a la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Acceder a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos desde el navegador"</string>
-    <string name="ok" msgid="1509280796718850364">"Aceptar"</string>
-    <string name="page_info" msgid="4048529256302257195">"Información de la página"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Dirección:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Ver certificado"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Este certificado no proviene de una autoridad confiable."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"El nombre del sitio no coincide con el nombre del certificado."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Este certificado ha expirado."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Error de certificado desconocido"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
deleted file mode 100644
index 65244e7..0000000
--- a/packages/CaptivePortalLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta red tal cual"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Iniciar sesión en la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas unirte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos a través del navegador"</string>
-    <string name="ok" msgid="1509280796718850364">"Aceptar"</string>
-    <string name="page_info" msgid="4048529256302257195">"Información de la página"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Dirección:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Ver certificado"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Este certificado no procede de una entidad de certificación de confianza."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"El nombre del sitio no coincide con el del certificado."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Este certificado ha caducado."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Error de certificado desconocido"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-et/strings.xml b/packages/CaptivePortalLogin/res/values-et/strings.xml
deleted file mode 100644
index e4c4c98..0000000
--- a/packages/CaptivePortalLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Kasuta seda võrku olemasoleval kujul"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ära kasuta seda võrku"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logi võrku sisse"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logige sisse: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jätka siiski brauseris"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Lehe teave"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Aadress:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Turvahoiatus"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Kuva sertifikaat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"See sertifikaat ei pärine usaldusväärselt asutuselt."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Saidi nimi ei vasta sertifikaadil olevale nimele."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"See sertifikaat on aegunud."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"See sertifikaat pole veel kehtiv."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Sellel sertifikaadil on kehtetu kuupäev."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"See sertifikaat on kehtetu."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Tundmatu sertifikaadiviga."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-eu/strings.xml b/packages/CaptivePortalLogin/res/values-eu/strings.xml
deleted file mode 100644
index 8925aac..0000000
--- a/packages/CaptivePortalLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s sarean"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jarraitu arakatzailearen bidez, halere"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fa/strings.xml b/packages/CaptivePortalLogin/res/values-fa/strings.xml
deleted file mode 100644
index 27b9b7f..0000000
--- a/packages/CaptivePortalLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"از این شبکه همانطور که هست استفاده شود"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"از این شبکه استفاده نشود"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ورود به سیستم شبکه"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏ورود به سیستم %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"در هر صورت از طریق مرورگر ادامه یابد"</string>
-    <string name="ok" msgid="1509280796718850364">"تأیید"</string>
-    <string name="page_info" msgid="4048529256302257195">"اطلاعات صفحه"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"آدرس:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"اخطار امنیتی"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"مشاهده گواهی"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"این گواهی از یک منبع مورد اطمینان صادر نشده است."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"نام سایت با نام موجود در گواهی مطابقت ندارد."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"این گواهی منقضی شده است."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"این گواهی هنوز معتبر نیست."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"تاریخ این گواهی نامعتبر است."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"این گواهی نامعتبر است."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"خطای ناشناخته در گواهی."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fi/strings.xml b/packages/CaptivePortalLogin/res/values-fi/strings.xml
deleted file mode 100644
index 8086fbf..0000000
--- a/packages/CaptivePortalLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Käytä tätä verkkoa sellaisenaan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Älä käytä tätä verkkoa"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Kirjaudu verkkoon"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Kirjaudu sisään kohteeseen %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Verkossa, johon yrität muodostaa yhteyttä, on turvallisuusongelmia."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jatka silti selaimen kautta."</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sivun tiedot"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Osoite:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Suojausvaroitus"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Näytä varmenne"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Varmenteen myöntäjä ei ole luotettava taho."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Sivuston nimi ei vastaa varmenteessa olevaa nimeä."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Varmenne ei ole enää voimassa."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Varmenne ei ole vielä voimassa."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Varmenteen päiväys ei kelpaa."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Varmenne on virheellinen."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Tuntematon varmennevirhe."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index a7525a5..0000000
--- a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Connectez-vous au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Connexion à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans un navigateur"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
deleted file mode 100644
index 39fc569..0000000
--- a/packages/CaptivePortalLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Se connecter au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Se connecter à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans le navigateur"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Infos sur la page"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresse :"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Avertissement de sécurité"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Afficher le certificat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Ce certificat provient d\'une autorité non approuvée."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Le nom du site ne correspond pas au nom indiqué dans le certificat."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Le certificat a expiré."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Ce certificat n\'est pas encore valide."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"La date de ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Erreur : Certificat inconnu."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml
deleted file mode 100644
index 6578285..0000000
--- a/packages/CaptivePortalLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede tal como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia sesión na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede á que tentas unirte ten problemas de seguranza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar igualmente co navegador"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gu/strings.xml b/packages/CaptivePortalLogin/res/values-gu/strings.xml
deleted file mode 100644
index c15eca4..0000000
--- a/packages/CaptivePortalLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"આ નેટવર્કનો જેમનો તેમ ઉપયોગ કરો"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"આ નેટવર્કનો ઉપયોગ કરશો નહીં"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sમાં સઇન ઇન કરો"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"તમે જોડાવાનો પ્રયાસ કરી રહ્યાં છો તે નેટવર્કમાં સુરક્ષા સમસ્યાઓ છે."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ દર્શાવેલ સંસ્થાનું હોઈ શકતું નથી."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"બ્રાઉઝર મારફતે કોઈપણ રીતે ચાલુ રાખો"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
deleted file mode 100644
index d924fff..0000000
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में साइन इन करें"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में साइन इन करें"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"आप जिस नेटवर्क में शामिल होने का प्रयास कर रहे हैं उसमें सुरक्षा समस्‍याएं हैं."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरण के लिए, हो सकता है कि लॉगिन पृष्‍ठ दिखाए गए संगठन से संबद्ध ना हो."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउज़र के द्वारा फिर जारी रखें"</string>
-    <string name="ok" msgid="1509280796718850364">"ठीक"</string>
-    <string name="page_info" msgid="4048529256302257195">"पृष्ठ जानकारी"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"पता:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"सुरक्षा चेतावनी"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"प्रमाणपत्र देखें"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"यह प्रमाणपत्र किसी विश्वस्त प्राधिकारी का नहीं है."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"साइट का नाम, प्रमाणपत्र के नाम से मिलान नहीं करता."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"इस प्रमाणपत्र की समय सीमा समाप्त हो गई है."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"यह प्रमाणपत्र अभी तक मान्य नहीं है."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"इस प्रमाणपत्र में एक अमान्‍य दिनांक है."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"यह प्रमाणपत्र अमान्य है."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"अज्ञात प्रमाणपत्र त्रुटि."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
deleted file mode 100644
index 11b1dd3..0000000
--- a/packages/CaptivePortalLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi putem preglednika"</string>
-    <string name="ok" msgid="1509280796718850364">"U redu"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informacije o stranici"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresa:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Upozorenje o sigurnosti"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Prikaži certifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Ovaj certifikat ne potječe iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Naziv web-lokacije ne podudara se s nazivom na certifikatu."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Ovaj je certifikat istekao."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Ovaj certifikat još nije važeći."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Ovaj certifikat ima nevažeći datum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Ovaj certifikat nije valjan."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Nepoznata pogreška certifikata."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
deleted file mode 100644
index 145e2ab..0000000
--- a/packages/CaptivePortalLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Hálózat használata jelen állapotában"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne használja ezt a hálózatot"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Bejelentkezés a hálózatba"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Bejelentkezés a következőbe: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Például lehet, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Folytatás ennek ellenére böngészőn keresztül"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Oldaladatok"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Cím:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Biztonsági figyelmeztetés"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Tanúsítvány megtekintése"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Ez a tanúsítvány nem hiteles tanúsítványkibocsátótól származik."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"A webhely neve nem egyezik a tanúsítványon lévő névvel."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"A tanúsítvány lejárt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"A tanúsítvány még nem érvényes."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"A tanúsítvány dátuma érvénytelen."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Ez a tanúsítvány érvénytelen."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Ismeretlen tanúsítványhiba."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hy/strings.xml b/packages/CaptivePortalLogin/res/values-hy/strings.xml
deleted file mode 100644
index a0ee862..0000000
--- a/packages/CaptivePortalLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Օգտագործել այս ցանցն ինչպես կա"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Մուտք գործել ցանց"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Մուտք գործել %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Շարունակել այնուամենայնիվ դիտարկիչի միջոցով"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
deleted file mode 100644
index e5b4eb4..0000000
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan jaringan ini sebagaimana adanya"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Masuk ke jaringan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, halaman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tetap lanjutkan melalui browser"</string>
-    <string name="ok" msgid="1509280796718850364">"Oke"</string>
-    <string name="page_info" msgid="4048529256302257195">"Info laman"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Alamat:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Peringatan sertifikat"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Lihat sertifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Sertifikat ini tidak berasal dari otoritas tepercaya."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Nama situs tidak cocok dengan nama pada sertifikat."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Sertifikat ini telah kedaluwarsa."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Sertifikat ini belum valid."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Tanggal sertifikat ini tidak valid."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Sertifikat ini tidak valid."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Kesalahan sertifikat tak dikenal."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-is/strings.xml b/packages/CaptivePortalLogin/res/values-is/strings.xml
deleted file mode 100644
index 8fde24b..0000000
--- a/packages/CaptivePortalLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Nota þetta net óbreytt"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ekki nota þetta net"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Skrá inn á net"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Skrá inn á %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Halda samt áfram í vafra"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-it/strings.xml b/packages/CaptivePortalLogin/res/values-it/strings.xml
deleted file mode 100644
index 2cc4038..0000000
--- a/packages/CaptivePortalLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizza questa rete così com\'è"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizzare questa rete"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Accedi alla rete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Accedi a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua comunque dal browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Info pagina"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Indirizzo:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Avviso di sicurezza"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Visualizza certificato"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Questo certificato non proviene da un\'autorità attendibile."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Il nome del sito non corrisponde al nome nel certificato."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Il certificato è scaduto."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Questo certificato non è ancora valido."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Questo certificato presenta una data non valida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Questo certificato non è valido."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Errore certificato sconosciuto."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-iw/strings.xml b/packages/CaptivePortalLogin/res/values-iw/strings.xml
deleted file mode 100644
index 527e692..0000000
--- a/packages/CaptivePortalLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"השתמש ברשת זו כפי שהיא"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"אל תשתמש ברשת זו"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"היכנס לרשת"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏כניסה אל %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"המשך בכל זאת באמצעות דפדפן"</string>
-    <string name="ok" msgid="1509280796718850364">"אישור"</string>
-    <string name="page_info" msgid="4048529256302257195">"פרטי דף"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"כתובת:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"אזהרת אבטחה"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"הצג אישור"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"אישור זה אינו מגיע מרשות אמינה."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"שם האתר לא תואם לשם באישור."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"פג תוקפו של אישור זה."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"אישור זה אינו חוקי עדיין."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"לאישור זה יש תאריך בלתי חוקי."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"אישור זה אינו חוקי."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"שגיאת אישור לא ידועה."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
deleted file mode 100644
index bcc8686..0000000
--- a/packages/CaptivePortalLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"このネットワークをそのまま使用する"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ネットワークにログイン"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s にログイン"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ブラウザから続行"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"ページ情報"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"アドレス:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"セキュリティ警告"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"証明書を表示"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"この証明書は信頼できる認証機関のものではありません。"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"サイト名と証明書上の名前が一致しません。"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"この証明書は有効期限切れです。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"この証明書はまだ有効ではありません。"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"この証明書の日付は無効です。"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"この証明書は無効です。"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"不明な証明書エラーです。"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ka/strings.xml b/packages/CaptivePortalLogin/res/values-ka/strings.xml
deleted file mode 100644
index 1ccff12..0000000
--- a/packages/CaptivePortalLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ამ ქსელის გამოყენება, როგორც არის"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ქსელში შესვლა"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-ში შესვლა"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ქსელს, რომელზედაც მიერთებას ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ბრაუზერში გაგრძელება"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kk/strings.xml b/packages/CaptivePortalLogin/res/values-kk/strings.xml
deleted file mode 100644
index a904dea..0000000
--- a/packages/CaptivePortalLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Осы желіні бар күйінде пайдалану"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Желіге кіру"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s жүйесіне кіру"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Қосылайын деп жатқан желіңіз қауіпсіз болуы мүмкін."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Бәрібір браузер арқылы жалғастыру"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-km/strings.xml b/packages/CaptivePortalLogin/res/values-km/strings.xml
deleted file mode 100644
index a0497f8..0000000
--- a/packages/CaptivePortalLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ចូលទៅបណ្ដាញ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ចូលទៅ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ឧបករណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករក"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kn/strings.xml b/packages/CaptivePortalLogin/res/values-kn/strings.xml
deleted file mode 100644
index 3084504..0000000
--- a/packages/CaptivePortalLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್ ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿರುವುದಿಲ್ಲ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ಹೇಗಾದರೂ ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
deleted file mode 100644
index 7a7f7e0..0000000
--- a/packages/CaptivePortalLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"현재 상태로 이 네트워크 사용"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"네트워크에 로그인"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s에 로그인"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"브라우저를 통해 계속하기"</string>
-    <string name="ok" msgid="1509280796718850364">"확인"</string>
-    <string name="page_info" msgid="4048529256302257195">"페이지 정보"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"주소:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"보안 경고"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"인증서 보기"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"신뢰할 수 있는 인증 기관에서 발급한 인증서가 아닙니다."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"사이트 이름이 인증서에 있는 것과 일치하지 않습니다."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"인증서가 만료되었습니다."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"인증서가 아직 유효하지 않습니다."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"인증서 날짜가 유효하지 않습니다."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"인증서가 잘못되었습니다."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"알 수 없는 인증서 오류입니다."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ky/strings.xml b/packages/CaptivePortalLogin/res/values-ky/strings.xml
deleted file mode 100644
index af81ce3..0000000
--- a/packages/CaptivePortalLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Тармакка кирүү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s каттоо эсебине кириңиз"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Баары бир серепчи аркылуу улантуу"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lo/strings.xml b/packages/CaptivePortalLogin/res/values-lo/strings.xml
deleted file mode 100644
index ee2b263..0000000
--- a/packages/CaptivePortalLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້​ຕາມ​ທີ່​ມັນ​ເປັນ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ບໍ່​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ເຂົ້າສູ່ລະບົບ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ເຄືອ​ຂ່າຍ​ທີ່​ທ່ານ​ກຳ​ລັງ​ເຂົ້າ​ຮ່ວມ​ມີ​ບັນ​ຫາ​ຄວາມ​ປອດ​ໄພ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ຕົວ​ຢ່າງ, ໜ້າ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ອາດ​ຈະ​ບໍ່​ເປັນ​ຂອງ​ອົງ​ການ​ທີ່​ສະ​ແດງ​ຂຶ້ນ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ແນວ​ໃດ​ກໍ່​ສືບ​ຕໍ່​ຜ່ານບ​ຣາວ​ເຊີ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
deleted file mode 100644
index 158f7ce..0000000
--- a/packages/CaptivePortalLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Naudoti šį tinklą tokį, koks yra"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prisijungti prie tinklo"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prisijungimas prie „%1$s“"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Kilo tinklo, prie kurio bandote prisijungti, problemų."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vis tiek tęsti naudojant naršyklę"</string>
-    <string name="ok" msgid="1509280796718850364">"Gerai"</string>
-    <string name="page_info" msgid="4048529256302257195">"Puslapio informacija"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresas:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Saugos įspėjimas"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Žiūrėti sertifikatą"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Šį sertifikatą išdavė nepatikima įstaiga."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Svetainės pavadinimas neatitinka sertifikate nurodyto pavadinimo."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Šio sertifikato galiojimo laikas baigėsi."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Šis sertifikatas dar negalioja."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Šio sertifikato data netinkama."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Šis sertifikatas netinkamas."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Nežinoma sertifikato klaida."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
deleted file mode 100644
index a42cb22..0000000
--- a/packages/CaptivePortalLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Pierakstīties tīklā"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Pierakstieties produktā %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Tīklam, kuram mēģināt pievienoties, ir drošības problēmas."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tik un tā turpināt, izmantojot pārlūkprogrammu"</string>
-    <string name="ok" msgid="1509280796718850364">"Labi"</string>
-    <string name="page_info" msgid="4048529256302257195">"Lapas informācija"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adrese:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Drošības brīdinājums"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Skatīt sertifikātu"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Šo sertifikātu nav izsniegusi uzticama iestāde."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Vietnes nosaukums neatbilst nosaukumam sertifikātā."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Šī sertifikāta derīguma termiņš ir beidzies."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Šis sertifikāts vēl nav derīgs."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Šī sertifikāta datums nav derīgs."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Šis sertifikāts nav derīgs."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Nezināma sertifikāta kļūda."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mk/strings.xml b/packages/CaptivePortalLogin/res/values-mk/strings.xml
deleted file mode 100644
index 2ae32c8..0000000
--- a/packages/CaptivePortalLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ја мрежата во оваа состојба"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Најавете се на мрежа"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Најавете се на %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страницата за најавување може да не припаѓа на организацијата што е прикажана."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Сепак продолжи преку прелистувач"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ml/strings.xml b/packages/CaptivePortalLogin/res/values-ml/strings.xml
deleted file mode 100644
index 79551f8..0000000
--- a/packages/CaptivePortalLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mn/strings.xml b/packages/CaptivePortalLogin/res/values-mn/strings.xml
deleted file mode 100644
index 67670915..0000000
--- a/packages/CaptivePortalLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Энэ сүлжээг ашиглана уу"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Сүлжээнд нэвтэрнэ үү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-д нэвтрэх"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Таны нэгдэх гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Жишээлбэл нэвтрэх хуудас нь харагдах байгууллагынх биш байж болзошгүй."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ямартаа ч хөтчөөр үргэлжлүүлэх"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mr/strings.xml b/packages/CaptivePortalLogin/res/values-mr/strings.xml
deleted file mode 100644
index fac0a08..0000000
--- a/packages/CaptivePortalLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"हे नेटवर्क जसेच्या तसे वापरा"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sमध्‍ये साइन इन करा"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये आपण सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणार्थ, लॉगिन पृष्‍ठ कदाचित दर्शविलेल्या संस्थेच्या मालकीचे नसावे."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउझरद्वारे तरीही सुरु ठेवा"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ms/strings.xml b/packages/CaptivePortalLogin/res/values-ms/strings.xml
deleted file mode 100644
index aaa51c8..0000000
--- a/packages/CaptivePortalLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan rangkaian ini"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan rangkaian ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log masuk ke rangkaian"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log masuk ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rangkaian yang anda cuba sertai mempunyai isu keselamatan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Teruskan juga melalui penyemak imbas"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Maklumat halaman"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Alamat:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Amaran keselamatan"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Lihat sijil"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Sijil ini bukan daripada pihak berkuasa yang dipercayai."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Nama tapak tidak sepadan dengan nama pada sijil."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Sijil ini telah tamat tempoh."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Sijil ini belum lagi sah."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Sijil ini mempunyai tarikh yang tidak sah."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Sijil ini tidak sah."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Ralat sijil tidak diketahui."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-my/strings.xml b/packages/CaptivePortalLogin/res/values-my/strings.xml
deleted file mode 100644
index 902834b..0000000
--- a/packages/CaptivePortalLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ဒီကွန်ရက်ကို လက်ရှိအတိုင်း သုံးရန်"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်သည် လုံခြုံရေးပြဿနာ ရှိနေသည်။"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ဥပမာ၊ ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှု မရှိနိုင်ပါ။"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ဘရောက်ဇာမှတစ်ဆင့် ဆက်လုပ်ရန်"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
deleted file mode 100644
index 29c23ed..0000000
--- a/packages/CaptivePortalLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bruk dette nettverket som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logg på nettverk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logg på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er for eksempel mulig at påloggingssiden kanskje ikke tilhører organisasjonen som vises."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsett likevel via nettleseren"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sideinfo"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresse:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Sikkerhetsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Vis sertifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Sertifikatet er ikke fra en pålitelig myndighet."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Navnet på nettstedet samsvarer ikke med navnet på sertifikatet."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Sertifikatet er utløpt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Sertifikatet er ikke gyldig ennå."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Dette sertifikatet har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Dette sertifikatet er ugyldig."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Ukjent sertifikatfeil."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ne/strings.xml b/packages/CaptivePortalLogin/res/values-ne/strings.xml
deleted file mode 100644
index 87a30c0..0000000
--- a/packages/CaptivePortalLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"यो सञ्जाल जस्तो छ प्रयोग गर्नुहोस्"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"यो सञ्जाल प्रयोग नगर्नुहोस्"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"सञ्जालमा साइन इन गर्नुहोस्"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s मा साइन इन गर्नुहोस्"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"तपाईँले सामेल हुन प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा मुद्दाहरू छन्।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
deleted file mode 100644
index 2cbca06..0000000
--- a/packages/CaptivePortalLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Dit netwerk in de huidige staat gebruiken"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inloggen bij netwerk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inloggen bij %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Het netwerk waarmee u verbinding probeert te maken, heeft beveiligingsproblemen."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Toch doorgaan via browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Pagina-informatie"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adres:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Beveiligingsmelding"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Certificaat weergeven"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Dit is geen certificaat van een vertrouwde autoriteit."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"De naam van deze site komt niet overeen met de naam op het certificaat."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Dit certificaat is verlopen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Dit certificaat is nog niet geldig."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Dit certificaat heeft een ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Dit certificaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Onbekende certificaatfout."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-or/strings.xml b/packages/CaptivePortalLogin/res/values-or/strings.xml
deleted file mode 100644
index 80074c3..0000000
--- a/packages/CaptivePortalLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ଏହି ନେଟ୍‌ୱର୍କ ଯେପରି ଅଛି, ସେହିପରି ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ଏହି ନେଟ୍‌ୱର୍କକୁ ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ଆପଣ ଯୋଗ ଦେବାକୁ ଚେଷ୍ଟା କରୁଥିବା ନେଟ୍‌ୱର୍କର ସୁରକ୍ଷା ସମସ୍ୟା ଅଛି।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍‍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ନହୋଇଥାଇପାରେ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ବ୍ରାଉଜର୍‍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pa/strings.xml b/packages/CaptivePortalLogin/res/values-pa/strings.xml
deleted file mode 100644
index 03e252f..0000000
--- a/packages/CaptivePortalLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ਇਸ ਨੈੱਟਵਰਕ ਨੂੰ ਉਵੇਂ ਵਰਤੋ ਜਿਵੇਂ ਇਹ ਹੈ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ਇਹ ਨੈੱਟਵਰਕ ਨਾ ਵਰਤੋ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਸ਼ਾਮਿਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੇ ਜਾ ਰਹੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
deleted file mode 100644
index 9ba066e..0000000
--- a/packages/CaptivePortalLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Używaj tej sieci tak jak jest"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Zaloguj się do sieci"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Zaloguj się w aplikacji %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Kontynuuj mimo to w przeglądarce"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informacje o stronie"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adres:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Ostrzeżenie zabezpieczeń"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Wyświetl certyfikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Certyfikat nie pochodzi od zaufanego urzędu."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Nazwa witryny nie pasuje do nazwy na certyfikacie."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Ten certyfikat wygasł."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Certyfikat nie jest jeszcze ważny."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Certyfikat ma nieprawidłową datę."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Certyfikat jest nieprawidłowy."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Nieznany błąd certyfikatu"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 3d1064c..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 5bef235..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Início de sessão na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sessão em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim através do navegador"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informações da página"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Endereço:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Ver certificado"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Este certificado não pertence a uma autoridade fidedigna."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"O nome do Web site não corresponde ao nome constante no certificado."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Este certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Este certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Este certificado tem uma data inválida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Este certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Erro: certificado desconhecido."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt/strings.xml b/packages/CaptivePortalLogin/res/values-pt/strings.xml
deleted file mode 100644
index ebe4148..0000000
--- a/packages/CaptivePortalLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informações da página"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Endereço:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Visualizar certificado"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Este certificado não é de uma autoridade confiável."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"O nome do site não corresponde ao nome no certificado."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Este certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Este certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Este certificado tem uma data inválida."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Este certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Erro de certificado desconhecido."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ro/strings.xml b/packages/CaptivePortalLogin/res/values-ro/strings.xml
deleted file mode 100644
index e2e4eac..0000000
--- a/packages/CaptivePortalLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizați această rețea în starea actuală"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nu utilizați această rețea"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Conectați-vă la rețea"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Conectați-vă la %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuați oricum prin browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informaţii pagină"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresă:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Avertisment de securitate"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Vizualizaţi certificatul"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Acest certificat nu provine de la o autoritate de încredere."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Numele acestui site nu se potriveşte cu numele de pe certificat."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Acest certificat a expirat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Acest certificat nu este încă valid."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Acest certificat are o dată nevalidă."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Acest certificat este nevalid."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Eroare de certificat necunoscută."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
deleted file mode 100644
index c0153e6..0000000
--- a/packages/CaptivePortalLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Использовать эту сеть"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Регистрация в сети"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Войти: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например, страница входа в аккаунт может быть фиктивной."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Игнорировать и открыть браузер"</string>
-    <string name="ok" msgid="1509280796718850364">"ОК"</string>
-    <string name="page_info" msgid="4048529256302257195">"Информация о странице"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Адрес:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Угроза безопасности"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Просмотреть сертификат"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Этот сертификат получен из ненадежных источников."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Название сайта не соответствует названию в сертификате."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Срок действия сертификата истек."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Сертификат еще не действителен."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Дата этого сертификата недействительна."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Этот сертификат недействителен."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Неизвестная ошибка сертификата."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-si/strings.xml b/packages/CaptivePortalLogin/res/values-si/strings.xml
deleted file mode 100644
index a307913..0000000
--- a/packages/CaptivePortalLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ජාලයට පුරනය වන්න"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s වෙත පුරන්න"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"කෙසේ වුවත් බ්‍රවුසරය හරහා ඉදිරියට යන්න"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sk/strings.xml b/packages/CaptivePortalLogin/res/values-sk/strings.xml
deleted file mode 100644
index 8ba24b1..0000000
--- a/packages/CaptivePortalLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použiť túto sieť tak, ako je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Túto sieť nepoužívať"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prihlásiť sa do siete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prihláste sa do služby %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Pokračovať pomocou prehliadača"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Informácie o stránke"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adresa:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Upozornenie zabezpečenia"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Zobraziť certifikát"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Tento certifikát nepochádza od dôveryhodnej autority."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Názov stránky sa nezhoduje s názvom uvedeným v certifikáte."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Platnosť certifikátu skončila."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Tento certifikát zatiaľ nie je platný."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Tento certifikát má neplatný dátum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Neznáma chyba certifikátu."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
deleted file mode 100644
index b7d9a8a..0000000
--- a/packages/CaptivePortalLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Uporabljajte to omrežje, »kakršno je«"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavite se v omrežje"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava v %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vseeno nadaljuj v brskalniku"</string>
-    <string name="ok" msgid="1509280796718850364">"V redu"</string>
-    <string name="page_info" msgid="4048529256302257195">"Podatki o strani"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Naslov:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Varnostno opozorilo"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Prikaži potrdilo"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Potrdila ni izdal zaupanja vreden overitelj."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Ime spletnega mesta se ne ujema z imenom na potrdilu."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Potrdilo je poteklo."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"To potrdilo še ni veljavno."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Potrdilo ima neveljaven datum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"To potrdilo ni veljavno."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Neznana napaka potrdila."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sq/strings.xml b/packages/CaptivePortalLogin/res/values-sq/strings.xml
deleted file mode 100644
index b06da6d..0000000
--- a/packages/CaptivePortalLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Përdore këtë rrjet siç është"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Mos e përdor këtë rrjet"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Identifikohu në rrjet"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Identifikohu në %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sr/strings.xml b/packages/CaptivePortalLogin/res/values-sr/strings.xml
deleted file mode 100644
index 967c8ba..0000000
--- a/packages/CaptivePortalLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ову мрежу такву каква је"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Пријави ме на мрежу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Пријавите се у: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ипак настави преко прегледача"</string>
-    <string name="ok" msgid="1509280796718850364">"Потврди"</string>
-    <string name="page_info" msgid="4048529256302257195">"Информације о страници"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Адреса:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Безбедносно упозорење"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Прикажи сертификат"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Овај сертификат не потиче од поузданог ауторитета."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Назив сајта се не подудара са називом на сертификату."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Овај сертификат је истекао."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Овај сертификат још увек није важећи."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Датум овог сертификата је неважећи."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Овај сертификат је неважећи."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Непозната грешка сертификата."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sv/strings.xml b/packages/CaptivePortalLogin/res/values-sv/strings.xml
deleted file mode 100644
index 75356f0..0000000
--- a/packages/CaptivePortalLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Använd det här nätverket som det är"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Använd inte det här nätverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logga in på nätverket"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logga in på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsätt ändå via webbläsaren"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sidinformation"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adress:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Säkerhetsvarning"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Visa certifikat"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Certifikatet kommer inte från en betrodd utfärdare."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Webbplatsens namn stämmer inte med namnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Certifikatet har upphört att gälla."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Certifikatet är inte giltigt än."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Det här certifikatet har ett ogiltigt datum."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Certifikatet är ogiltigt."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Okänt certifikatfel."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sw/strings.xml b/packages/CaptivePortalLogin/res/values-sw/strings.xml
deleted file mode 100644
index feb2dde..0000000
--- a/packages/CaptivePortalLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Tumia mtandao huu jinsi ulivyo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Usitumie mtandao huu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ingia katika mtandao"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ingia katika akaunti ya %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Endelea hata hivyo kupitia kivinjari"</string>
-    <string name="ok" msgid="1509280796718850364">"Sawa"</string>
-    <string name="page_info" msgid="4048529256302257195">"Maelezo ya ukurasa"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Anwani:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Ilani ya usalama"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Tazama cheti"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Cheti hiki hakijatoka kwa mamlaka inayoaminika."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Jina la tovuti halilingani na jina lililo katika cheti."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Cheti hiki kimepitwa na muda"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Cheti bado si halali."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Cheti hiki kina tarehe batili."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Hati hii ni batili."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Hitilafu isiyojulikana ya cheti."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ta/strings.xml b/packages/CaptivePortalLogin/res/values-ta/strings.xml
deleted file mode 100644
index 6a60ed7..0000000
--- a/packages/CaptivePortalLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s இல் உள்நுழைக"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"நீங்கள் சேர முயற்சிக்கும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"பரவாயில்லை, உலாவி வழியாகத் தொடரவும்"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-te/strings.xml b/packages/CaptivePortalLogin/res/values-te/strings.xml
deleted file mode 100644
index c209d34..0000000
--- a/packages/CaptivePortalLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sకి సైన్ ఇన్ చేయండి"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించు"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-th/strings.xml b/packages/CaptivePortalLogin/res/values-th/strings.xml
deleted file mode 100644
index 11a2131..0000000
--- a/packages/CaptivePortalLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ใช้เครือข่ายนี้ตามที่เป็นอยู่"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ไม่ใช้เครือข่ายนี้"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ลงชื่อเข้าใช้เครือข่าย"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ลงชื่อเข้าใช้ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
-    <string name="ok" msgid="1509280796718850364">"ตกลง"</string>
-    <string name="page_info" msgid="4048529256302257195">"ข้อมูลหน้าเว็บ"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"ที่อยู่:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"คำเตือนเกี่ยวกับความปลอดภัย"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"ดูใบรับรอง"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"ใบรับรองนี้ไม่ได้มาจากผู้ออกที่เชื่อถือได้"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"ชื่อไซต์ไม่ตรงกับในใบรับรอง"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"ใบรับรองนี้หมดอายุแล้ว"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"ใบรับรองนี้ยังใช้งานไม่ได้"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"ใบรับรองนี้มีวันที่ไม่ถูกต้อง"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"ใบรับรองนี้ไม่ถูกต้อง"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"ข้อผิดพลาดใบรับรองที่ไม่รู้จัก"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
deleted file mode 100644
index 07a2479..0000000
--- a/packages/CaptivePortalLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gamitin ang network na ito nang walang pagbabago"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Huwag gamitin ang network na ito"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Mag-sign in sa network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Mag-sign in sa %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"May mga isyu sa seguridad ang network kung saan mo sinusubukang sumali."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Halimbawa, maaaring hindi sa organisasyong ipinapakita ang page sa pag-log in."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Impormasyon ng pahina"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Address:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Babala sa seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Tingnan ang certificate"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Ang certificate ay hindi mula sa isang pinagkakatiwalaang kinauukulan."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Ang pangalan ng site ay hindi tumutugma sa pangalan sa certificate."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Nag-expire na ang certificate na ito."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Wala pang bisa ang certificate na ito."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Ang certificate ay mayroong di-wastong petsa."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Di-wasto ang certificate na ito."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Hindi kilalang error ng certificate."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tr/strings.xml b/packages/CaptivePortalLogin/res/values-tr/strings.xml
deleted file mode 100644
index cdedd33..0000000
--- a/packages/CaptivePortalLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu ağı olduğu gibi kullan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ağda oturum açın"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s üzerinde oturum açın"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Yine de tarayıcıyla devam et"</string>
-    <string name="ok" msgid="1509280796718850364">"Tamam"</string>
-    <string name="page_info" msgid="4048529256302257195">"Sayfa bilgileri"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Adres:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Güvenlik uyarısı"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Sertifikayı görüntüle"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Bu sertifika güvenilir bir yetkiliden değil."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Sitenin adı sertifika üzerindeki adla eşleşmiyor."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Bu sertifikanın süresi dolmuş."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Bu sertifika henüz geçerli değil."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Bu sertifikanın tarihi geçersiz."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Bu sertifika geçersiz."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Bilinmeyen sertifika hatası."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uk/strings.xml b/packages/CaptivePortalLogin/res/values-uk/strings.xml
deleted file mode 100644
index 0f4cd16..0000000
--- a/packages/CaptivePortalLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Використовувати цю мережу як є"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не використовувати цю мережу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увійти в мережу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увійти в обліковий запис %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Наприклад, сторінка входу може не належати вказаній організації."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усе одно продовжити у веб-переглядачі"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Інфо про стор."</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Адреса:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Застереж. про небезп."</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Переглянути сертиф."</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Сертифікат видано ненадійним центром сертифікації."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Назва сайту не збігається з назвою в сертифікаті."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Термін дії сертиф. завершився."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Цей сертифікат ще не дійсний."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Цей сертифікат має недійсну дату."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Цей сертифікат недійсний."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Помилка невідомого сертифіката."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ur/strings.xml b/packages/CaptivePortalLogin/res/values-ur/strings.xml
deleted file mode 100644
index 05d8fb9..0000000
--- a/packages/CaptivePortalLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"نیٹ ورک میں سائن ان کریں"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏%1$s میں سائن ان کریں"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"جس نیٹ ورک میں آپ شامل ہونے کی کوشش کر رہے ہیں اس میں سیکیورٹی کے مسائل ہیں۔"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uz/strings.xml b/packages/CaptivePortalLogin/res/values-uz/strings.xml
deleted file mode 100644
index cac96ea..0000000
--- a/packages/CaptivePortalLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Tarmoqqa kirish"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s hisobiga kirish"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"E’tiborsiz qoldirilsin va brauzer ochilsin"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
deleted file mode 100644
index 9c702b9..0000000
--- a/packages/CaptivePortalLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sử dụng mạng này"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Không sử dụng mạng này"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Đăng nhập vào mạng"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Đăng nhập vào %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ví dụ, trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vẫn tiếp tục qua trình duyệt"</string>
-    <string name="ok" msgid="1509280796718850364">"OK"</string>
-    <string name="page_info" msgid="4048529256302257195">"Thông tin trang"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Địa chỉ:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Cảnh báo bảo mật"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Xem chứng chỉ"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Chứng chỉ này không xuất phát từ tổ chức phát hành đáng tin cậy."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Tên của trang web không khớp với tên trên chứng chỉ."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Chứng chỉ này đã hết hạn."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Chứng chỉ này chưa hợp lệ."</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Chứng chỉ này có ngày không hợp lệ."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Chứng chỉ này không hợp lệ."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Lỗi chứng chỉ không xác định."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 70c2a08..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"直接使用此网络"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登录到网络"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登录%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您尝试加入的网络存在安全问题。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如，登录页面可能并不属于页面上显示的单位。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"仍然通过浏览器继续操作"</string>
-    <string name="ok" msgid="1509280796718850364">"确定"</string>
-    <string name="page_info" msgid="4048529256302257195">"网页信息"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"网址："</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"安全警告"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"查看证书"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"该证书并非来自可信的授权中心。"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"网站的名称与证书上的名称不一致。"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"该证书已过期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"该证书尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"该证书的日期无效。"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"该证书无效。"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"未知证书错误。"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index df1c700..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依照現況使用這個網絡"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網絡"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入「%1$s」"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您正在嘗試加入的網絡有安全性問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如，登入頁面並不屬於所顯示的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ok" msgid="1509280796718850364">"確定"</string>
-    <string name="page_info" msgid="4048529256302257195">"網頁資訊"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"地址："</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"查看憑證"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"這個憑證並非由受信任的權威機構發出。"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"網站名稱與憑證上的名稱不相符。"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"這個憑證已過期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"這個憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"此憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"此憑證是無效的。"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"不明的憑證錯誤。"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 2a2e397..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依現況使用這個網路"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網路"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入 %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"你嘗試加入的網路有安全問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如，登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ok" msgid="1509280796718850364">"確定"</string>
-    <string name="page_info" msgid="4048529256302257195">"頁面資訊"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"位址："</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"檢視憑證"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"這個憑證並非來自信任的授權單位。"</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"網站名稱與憑證上的名稱不相符。"</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"此憑證已過期"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"這個憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"這個憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"這個憑證無效。"</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"不明的憑證錯誤。"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zu/strings.xml b/packages/CaptivePortalLogin/res/values-zu/strings.xml
deleted file mode 100644
index 7943645..0000000
--- a/packages/CaptivePortalLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"I-CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sebenzisa le nethiwekhi njengoba injalo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ungasebenzisi le nethiwekhi"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ngena ngemvume kunethiwekhi"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ngena ngemvume ku-%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Qhubeka noma kunjalo ngesiphequluli"</string>
-    <string name="ok" msgid="1509280796718850364">"KULUNGILE"</string>
-    <string name="page_info" msgid="4048529256302257195">"Ulwazi lekhasi"</string>
-    <string name="page_info_address" msgid="2222306609532903254">"Ikheli:"</string>
-    <string name="ssl_security_warning_title" msgid="6607795404322797541">"Isexwayiso sokuvikeleka"</string>
-    <string name="ssl_error_view_certificate" msgid="1472768887529093862">"Buka isitifiketi"</string>
-    <string name="ssl_error_untrusted" msgid="7754507359360636447">"Lesi sitifiketi asiphumi embusweni othembekile."</string>
-    <string name="ssl_error_mismatch" msgid="3809794439740523641">"Igama lale ngosi alifani negama elikusitifiketi."</string>
-    <string name="ssl_error_expired" msgid="5739349389499575559">"Lesi sitifiketi siphelelwe yisikhathi"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8193083327719048247">"Lesi sitifiketi asilungile okwamanje"</string>
-    <string name="ssl_error_date_invalid" msgid="3705563379257285534">"Lesi sitifiketi sinosuku olungalungile."</string>
-    <string name="ssl_error_invalid" msgid="9041704741505449967">"Lesi sitifiketi asilungile."</string>
-    <string name="ssl_error_unknown" msgid="5679243486524754571">"Iphutha lesitifiketi elingaziwa."</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/dimens.xml b/packages/CaptivePortalLogin/res/values/dimens.xml
deleted file mode 100644
index 55c1e590..0000000
--- a/packages/CaptivePortalLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/strings.xml b/packages/CaptivePortalLogin/res/values/strings.xml
deleted file mode 100644
index e9698db..0000000
--- a/packages/CaptivePortalLogin/res/values/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">CaptivePortalLogin</string>
-    <string name="action_use_network">Use this network as is</string>
-    <string name="action_do_not_use_network">Do not use this network</string>
-    <string name="action_bar_label">Sign in to network</string>
-    <string name="action_bar_title">Sign in to %1$s</string>
-    <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
-    <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string>
-    <string name="ssl_error_continue">Continue anyway via browser</string>
-    <string name="ssl_error_untrusted">This certificate isn\'t from a trusted authority.</string>
-    <string name="ssl_error_mismatch">The name of the site doesn\'t match the name on the certificate.</string>
-    <string name="ssl_error_expired">This certificate has expired.</string>
-    <string name="ssl_error_not_yet_valid">This certificate isn\'t valid yet.</string>
-    <string name="ssl_error_date_invalid">This certificate has an invalid date.</string>
-    <string name="ssl_error_invalid">This certificate is invalid.</string>
-    <string name="ssl_error_unknown">Unknown certificate error.</string>
-    <string name="ssl_security_warning_title">Security warning</string>
-    <string name="ssl_error_view_certificate">View certificate</string>
-    <string name="ok">OK</string>
-    <string name="page_info_address">Address:</string>
-    <string name="page_info">Page info</string>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/CaptivePortalLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-</resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
deleted file mode 100644
index 3d5710d..0000000
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Copyright (C) 2014 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.captiveportallogin;
-
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Application;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.CaptivePortal;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.Proxy;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.webkit.CookieManager;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Objects;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class CaptivePortalLoginActivity extends Activity {
-    private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    public static final String HTTP_LOCATION_HEADER_NAME = "Location";
-
-    private enum Result {
-        DISMISSED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_DISMISSED),
-        UNWANTED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_UNWANTED),
-        WANTED_AS_IS(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_WANTED_AS_IS);
-
-        final int metricsEvent;
-        Result(int metricsEvent) { this.metricsEvent = metricsEvent; }
-    };
-
-    private URL mUrl;
-    private CaptivePortalProbeSpec mProbeSpec;
-    private String mUserAgent;
-    private Network mNetwork;
-    private CaptivePortal mCaptivePortal;
-    private NetworkCallback mNetworkCallback;
-    private ConnectivityManager mCm;
-    private WifiManager mWifiManager;
-    private boolean mLaunchBrowser = false;
-    private MyWebViewClient mWebViewClient;
-    private SwipeRefreshLayout mSwipeRefreshLayout;
-    // Ensures that done() happens once exactly, handling concurrent callers with atomic operations.
-    private final AtomicBoolean isDone = new AtomicBoolean(false);
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
-        logMetricsEvent(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
-
-        mCm = getSystemService(ConnectivityManager.class);
-        mWifiManager = getSystemService(WifiManager.class);
-        mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
-        mUserAgent =
-                getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
-        mUrl = getUrl();
-        if (mUrl == null) {
-            // getUrl() failed to parse the url provided in the intent: bail out in a way that
-            // at least provides network access.
-            done(Result.WANTED_AS_IS);
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onCreate for %s", mUrl.toString()));
-        }
-
-        final String spec = getIntent().getStringExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC);
-        try {
-            mProbeSpec = CaptivePortalProbeSpec.parseSpecOrNull(spec);
-        } catch (Exception e) {
-            // Make extra sure that invalid configurations do not cause crashes
-            mProbeSpec = null;
-        }
-
-        mNetworkCallback = new NetworkCallback() {
-            @Override
-            public void onLost(Network lostNetwork) {
-                // If the network disappears while the app is up, exit.
-                if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED);
-            }
-        };
-        mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkCallback);
-
-        // If the network has disappeared, exit.
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null) {
-            finishAndRemoveTask();
-            return;
-        }
-
-        // Also initializes proxy system properties.
-        mNetwork = mNetwork.getPrivateDnsBypassingCopy();
-        mCm.bindProcessToNetwork(mNetwork);
-
-        // Proxy system properties must be initialized before setContentView is called because
-        // setContentView initializes the WebView logic which in turn reads the system properties.
-        setContentView(R.layout.activity_captive_portal_login);
-
-        getActionBar().setDisplayShowHomeEnabled(false);
-        getActionBar().setElevation(0); // remove shadow
-        getActionBar().setTitle(getHeaderTitle());
-        getActionBar().setSubtitle("");
-
-        final WebView webview = getWebview();
-        webview.clearCache(true);
-        CookieManager.getInstance().setAcceptThirdPartyCookies(webview, true);
-        WebSettings webSettings = webview.getSettings();
-        webSettings.setJavaScriptEnabled(true);
-        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
-        webSettings.setUseWideViewPort(true);
-        webSettings.setLoadWithOverviewMode(true);
-        webSettings.setSupportZoom(true);
-        webSettings.setBuiltInZoomControls(true);
-        webSettings.setDisplayZoomControls(false);
-        webSettings.setDomStorageEnabled(true);
-        mWebViewClient = new MyWebViewClient();
-        webview.setWebViewClient(mWebViewClient);
-        webview.setWebChromeClient(new MyWebChromeClient());
-        // Start initial page load so WebView finishes loading proxy settings.
-        // Actual load of mUrl is initiated by MyWebViewClient.
-        webview.loadData("", "text/html", null);
-
-        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
-        mSwipeRefreshLayout.setOnRefreshListener(() -> {
-                webview.reload();
-                mSwipeRefreshLayout.setRefreshing(true);
-            });
-
-    }
-
-    // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
-    private void setWebViewProxy() {
-        // TODO: migrate to androidx WebView proxy setting API as soon as it is finalized
-        try {
-            final Field loadedApkField = Application.class.getDeclaredField("mLoadedApk");
-            final Class<?> loadedApkClass = loadedApkField.getType();
-            final Object loadedApk = loadedApkField.get(getApplication());
-            Field receiversField = loadedApkClass.getDeclaredField("mReceivers");
-            receiversField.setAccessible(true);
-            ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
-            for (Object receiverMap : receivers.values()) {
-                for (Object rec : ((ArrayMap) receiverMap).keySet()) {
-                    Class clazz = rec.getClass();
-                    if (clazz.getName().contains("ProxyChangeListener")) {
-                        Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
-                                Intent.class);
-                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
-                        onReceiveMethod.invoke(rec, getApplicationContext(), intent);
-                        Log.v(TAG, "Prompting WebView proxy reload.");
-                    }
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Exception while setting WebView proxy: " + e);
-        }
-    }
-
-    private void done(Result result) {
-        if (isDone.getAndSet(true)) {
-            // isDone was already true: done() already called
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
-        }
-        logMetricsEvent(result.metricsEvent);
-        switch (result) {
-            case DISMISSED:
-                mCaptivePortal.reportCaptivePortalDismissed();
-                break;
-            case UNWANTED:
-                mCaptivePortal.ignoreNetwork();
-                break;
-            case WANTED_AS_IS:
-                mCaptivePortal.useNetwork();
-                break;
-        }
-        finishAndRemoveTask();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.captive_portal_login, menu);
-        return true;
-    }
-
-    @Override
-    public void onBackPressed() {
-        WebView myWebView = findViewById(R.id.webview);
-        if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
-            myWebView.goBack();
-        } else {
-            super.onBackPressed();
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        final Result result;
-        final String action;
-        final int id = item.getItemId();
-        switch (id) {
-            case R.id.action_use_network:
-                result = Result.WANTED_AS_IS;
-                action = "USE_NETWORK";
-                break;
-            case R.id.action_do_not_use_network:
-                result = Result.UNWANTED;
-                action = "DO_NOT_USE_NETWORK";
-                break;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onOptionsItemSelect %s for %s", action, mUrl.toString()));
-        }
-        done(result);
-        return true;
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        final WebView webview = (WebView) findViewById(R.id.webview);
-        if (webview != null) {
-            webview.stopLoading();
-            webview.setWebViewClient(null);
-            webview.setWebChromeClient(null);
-            webview.destroy();
-        }
-        if (mNetworkCallback != null) {
-            // mNetworkCallback is not null if mUrl is not null.
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-        }
-        if (mLaunchBrowser) {
-            // Give time for this network to become default. After 500ms just proceed.
-            for (int i = 0; i < 5; i++) {
-                // TODO: This misses when mNetwork underlies a VPN.
-                if (mNetwork.equals(mCm.getActiveNetwork())) break;
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                }
-            }
-            final String url = mUrl.toString();
-            if (DBG) {
-                Log.d(TAG, "starting activity with intent ACTION_VIEW for " + url);
-            }
-            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-        }
-    }
-
-    private URL getUrl() {
-        String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
-        if (url == null) {
-            url = mCm.getCaptivePortalServerUrl();
-        }
-        return makeURL(url);
-    }
-
-    private static URL makeURL(String url) {
-        try {
-            return new URL(url);
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + url);
-        }
-        return null;
-    }
-
-    private static String host(URL url) {
-        if (url == null) {
-            return null;
-        }
-        return url.getHost();
-    }
-
-    private static String sanitizeURL(URL url) {
-        // In non-Debug build, only show host to avoid leaking private info.
-        return isDebuggable() ? Objects.toString(url) : host(url);
-    }
-
-    private static boolean isDebuggable() {
-        return SystemProperties.getInt("ro.debuggable", 0) == 1;
-    }
-
-    private void testForCaptivePortal() {
-        // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
-        new Thread(new Runnable() {
-            public void run() {
-                // Give time for captive portal to open.
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                }
-                HttpURLConnection urlConnection = null;
-                int httpResponseCode = 500;
-                String locationHeader = null;
-                try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
-                    urlConnection.setInstanceFollowRedirects(false);
-                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setUseCaches(false);
-                    if (mUserAgent != null) {
-                       urlConnection.setRequestProperty("User-Agent", mUserAgent);
-                    }
-                    // cannot read request header after connection
-                    String requestHeader = urlConnection.getRequestProperties().toString();
-
-                    urlConnection.getInputStream();
-                    httpResponseCode = urlConnection.getResponseCode();
-                    locationHeader = urlConnection.getHeaderField(HTTP_LOCATION_HEADER_NAME);
-                    if (DBG) {
-                        Log.d(TAG, "probe at " + mUrl +
-                                " ret=" + httpResponseCode +
-                                " request=" + requestHeader +
-                                " headers=" + urlConnection.getHeaderFields());
-                    }
-                } catch (IOException e) {
-                } finally {
-                    if (urlConnection != null) urlConnection.disconnect();
-                }
-                if (isDismissed(httpResponseCode, locationHeader, mProbeSpec)) {
-                    done(Result.DISMISSED);
-                }
-            }
-        }).start();
-    }
-
-    private static boolean isDismissed(
-            int httpResponseCode, String locationHeader, CaptivePortalProbeSpec probeSpec) {
-        return (probeSpec != null)
-                ? probeSpec.getResult(httpResponseCode, locationHeader).isSuccessful()
-                : (httpResponseCode == 204);
-    }
-
-    private class MyWebViewClient extends WebViewClient {
-        private static final String INTERNAL_ASSETS = "file:///android_asset/";
-
-        private final String mBrowserBailOutToken = Long.toString(new Random().nextLong());
-        private final String mCertificateOutToken = Long.toString(new Random().nextLong());
-        // How many Android device-independent-pixels per scaled-pixel
-        // dp/sp = (px/sp) / (px/dp) = (1/sp) / (1/dp)
-        private final float mDpPerSp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
-                    getResources().getDisplayMetrics()) /
-                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
-                    getResources().getDisplayMetrics());
-        private int mPagesLoaded;
-        private String mMainFrameUrl;
-
-        // If we haven't finished cleaning up the history, don't allow going back.
-        public boolean allowBack() {
-            return mPagesLoaded > 1;
-        }
-
-        private String mSslErrorTitle = null;
-        private SslErrorHandler mSslErrorHandler = null;
-        private SslError mSslError = null;
-
-        @Override
-        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
-            if (urlString.contains(mBrowserBailOutToken)) {
-                mLaunchBrowser = true;
-                done(Result.WANTED_AS_IS);
-                return;
-            }
-            // The first page load is used only to cause the WebView to
-            // fetch the proxy settings.  Don't update the URL bar, and
-            // don't check if the captive portal is still there.
-            if (mPagesLoaded == 0) {
-                return;
-            }
-            final URL url = makeURL(urlString);
-            Log.d(TAG, "onPageStarted: " + sanitizeURL(url));
-            // For internally generated pages, leave URL bar listing prior URL as this is the URL
-            // the page refers to.
-            if (!urlString.startsWith(INTERNAL_ASSETS)) {
-                String subtitle = (url != null) ? getHeaderSubtitle(url) : urlString;
-                getActionBar().setSubtitle(subtitle);
-            }
-            getProgressBar().setVisibility(View.VISIBLE);
-            testForCaptivePortal();
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            mPagesLoaded++;
-            getProgressBar().setVisibility(View.INVISIBLE);
-            mSwipeRefreshLayout.setRefreshing(false);
-            if (mPagesLoaded == 1) {
-                // Now that WebView has loaded at least one page we know it has read in the proxy
-                // settings.  Now prompt the WebView read the Network-specific proxy settings.
-                setWebViewProxy();
-                // Load the real page.
-                view.loadUrl(mUrl.toString());
-                return;
-            } else if (mPagesLoaded == 2) {
-                // Prevent going back to empty first page.
-                // Fix for missing focus, see b/62449959 for details. Remove it once we get a
-                // newer version of WebView (60.x.y).
-                view.requestFocus();
-                view.clearHistory();
-            }
-            testForCaptivePortal();
-        }
-
-        // Convert Android scaled-pixels (sp) to HTML size.
-        private String sp(int sp) {
-            // Convert sp to dp's.
-            float dp = sp * mDpPerSp;
-            // Apply a scale factor to make things look right.
-            dp *= 1.3;
-            // Convert dp's to HTML size.
-            // HTML px's are scaled just like dp's, so just add "px" suffix.
-            return Integer.toString((int)dp) + "px";
-        }
-
-        // Check if webview is trying to load the main frame and record its url.
-        @Override
-        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-            if (request.isForMainFrame()) {
-                mMainFrameUrl = request.getUrl().toString();
-            }
-            // Be careful that two shouldOverrideUrlLoading methods are overridden, but
-            // shouldOverrideUrlLoading(WebView view, String url) was deprecated in API level 24.
-            // TODO: delete deprecated one ??
-            return shouldOverrideUrlLoading(view, mMainFrameUrl);
-        }
-
-        // A web page consisting of a large broken lock icon to indicate SSL failure.
-
-        @Override
-        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-            final URL errorUrl = makeURL(error.getUrl());
-            final URL mainFrameUrl = makeURL(mMainFrameUrl);
-            Log.d(TAG, String.format("SSL error: %s, url: %s, certificate: %s",
-                    sslErrorName(error), sanitizeURL(errorUrl), error.getCertificate()));
-            if (errorUrl == null
-                    // Ignore SSL errors from resources by comparing the main frame url with SSL
-                    // error url.
-                    || !errorUrl.equals(mainFrameUrl)) {
-                Log.d(TAG, "onReceivedSslError: mMainFrameUrl = " + mMainFrameUrl);
-                handler.cancel();
-                return;
-            }
-            logMetricsEvent(MetricsEvent.CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR);
-            final String sslErrorPage = makeSslErrorPage();
-            view.loadDataWithBaseURL(INTERNAL_ASSETS, sslErrorPage, "text/HTML", "UTF-8", null);
-            mSslErrorTitle = view.getTitle() == null ? "" : view.getTitle();
-            mSslErrorHandler = handler;
-            mSslError = error;
-        }
-
-        private String makeSslErrorPage() {
-            final String warningMsg = getString(R.string.ssl_error_warning);
-            final String exampleMsg = getString(R.string.ssl_error_example);
-            final String continueMsg = getString(R.string.ssl_error_continue);
-            final String certificateMsg = getString(R.string.ssl_error_view_certificate);
-            return String.join("\n",
-                    "<html>",
-                    "<head>",
-                    "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
-                    "  <style>",
-                    "    body {",
-                    "      background-color:#fafafa;",
-                    "      margin:auto;",
-                    "      width:80%;",
-                    "      margin-top: 96px",
-                    "    }",
-                    "    img {",
-                    "      height:48px;",
-                    "      width:48px;",
-                    "    }",
-                    "    div.warn {",
-                    "      font-size:" + sp(16) + ";",
-                    "      line-height:1.28;",
-                    "      margin-top:16px;",
-                    "      opacity:0.87;",
-                    "    }",
-                    "    div.example {",
-                    "      font-size:" + sp(14) + ";",
-                    "      line-height:1.21905;",
-                    "      margin-top:16px;",
-                    "      opacity:0.54;",
-                    "    }",
-                    "    a {",
-                    "      color:#4285F4;",
-                    "      display:inline-block;",
-                    "      font-size:" + sp(14) + ";",
-                    "      font-weight:bold;",
-                    "      height:48px;",
-                    "      margin-top:24px;",
-                    "      text-decoration:none;",
-                    "      text-transform:uppercase;",
-                    "    }",
-                    "    a.certificate {",
-                    "      margin-top:0px;",
-                    "    }",
-                    "  </style>",
-                    "</head>",
-                    "<body>",
-                    "  <p><img src=quantum_ic_warning_amber_96.png><br>",
-                    "  <div class=warn>" + warningMsg + "</div>",
-                    "  <div class=example>" + exampleMsg + "</div>",
-                    "  <a href=" + mBrowserBailOutToken + ">" + continueMsg + "</a><br>",
-                    "  <a class=certificate href=" + mCertificateOutToken + ">" + certificateMsg +
-                            "</a>",
-                    "</body>",
-                    "</html>");
-        }
-
-        @Override
-        public boolean shouldOverrideUrlLoading (WebView view, String url) {
-            if (url.startsWith("tel:")) {
-                startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
-                return true;
-            }
-            if (url.contains(mCertificateOutToken) && mSslError != null) {
-                showSslAlertDialog(mSslErrorHandler, mSslError, mSslErrorTitle);
-                return true;
-            }
-            return false;
-        }
-        private void showSslAlertDialog(SslErrorHandler handler, SslError error, String title) {
-            final LayoutInflater factory = LayoutInflater.from(CaptivePortalLoginActivity.this);
-            final View sslWarningView = factory.inflate(R.layout.ssl_warning, null);
-
-            // Set Security certificate
-            setViewSecurityCertificate(sslWarningView.findViewById(R.id.certificate_layout), error);
-            ((TextView) sslWarningView.findViewById(R.id.ssl_error_type))
-                    .setText(sslErrorName(error));
-            ((TextView) sslWarningView.findViewById(R.id.title)).setText(mSslErrorTitle);
-            ((TextView) sslWarningView.findViewById(R.id.address)).setText(error.getUrl());
-
-            AlertDialog sslAlertDialog = new AlertDialog.Builder(CaptivePortalLoginActivity.this)
-                    .setTitle(R.string.ssl_security_warning_title)
-                    .setView(sslWarningView)
-                    .setPositiveButton(R.string.ok, (DialogInterface dialog, int whichButton) -> {
-                        // handler.cancel is called via OnCancelListener.
-                        dialog.cancel();
-                    })
-                    .setOnCancelListener((DialogInterface dialogInterface) -> handler.cancel())
-                    .create();
-            sslAlertDialog.show();
-        }
-
-        private void setViewSecurityCertificate(LinearLayout certificateLayout, SslError error) {
-            ((TextView) certificateLayout.findViewById(R.id.ssl_error_msg))
-                    .setText(sslErrorMessage(error));
-            SslCertificate cert = error.getCertificate();
-            // TODO: call the method directly once inflateCertificateView is @SystemApi
-            try {
-                final View certificateView = (View) SslCertificate.class.getMethod(
-                        "inflateCertificateView", Context.class)
-                        .invoke(cert, CaptivePortalLoginActivity.this);
-                certificateLayout.addView(certificateView);
-            } catch (ReflectiveOperationException | SecurityException e) {
-                Log.e(TAG, "Could not create certificate view", e);
-            }
-        }
-    }
-
-    private class MyWebChromeClient extends WebChromeClient {
-        @Override
-        public void onProgressChanged(WebView view, int newProgress) {
-            getProgressBar().setProgress(newProgress);
-        }
-    }
-
-    private ProgressBar getProgressBar() {
-        return findViewById(R.id.progress_bar);
-    }
-
-    private WebView getWebview() {
-        return findViewById(R.id.webview);
-    }
-
-    private String getHeaderTitle() {
-        NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        final String ssid = getSsid();
-        if (TextUtils.isEmpty(ssid)
-                || nc == null || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-            return getString(R.string.action_bar_label);
-        }
-        return getString(R.string.action_bar_title, ssid);
-    }
-
-    // TODO: remove once SSID is obtained from NetworkCapabilities
-    private String getSsid() {
-        if (mWifiManager == null) {
-            return null;
-        }
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        return removeDoubleQuotes(wifiInfo.getSSID());
-    }
-
-    private static String removeDoubleQuotes(String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    private String getHeaderSubtitle(URL url) {
-        String host = host(url);
-        final String https = "https";
-        if (https.equals(url.getProtocol())) {
-            return https + "://" + host;
-        }
-        return host;
-    }
-
-    private void logMetricsEvent(int event) {
-        mCaptivePortal.logEvent(event, getPackageName());
-    }
-
-    private static final SparseArray<String> SSL_ERRORS = new SparseArray<>();
-    static {
-        SSL_ERRORS.put(SslError.SSL_NOTYETVALID,  "SSL_NOTYETVALID");
-        SSL_ERRORS.put(SslError.SSL_EXPIRED,      "SSL_EXPIRED");
-        SSL_ERRORS.put(SslError.SSL_IDMISMATCH,   "SSL_IDMISMATCH");
-        SSL_ERRORS.put(SslError.SSL_UNTRUSTED,    "SSL_UNTRUSTED");
-        SSL_ERRORS.put(SslError.SSL_DATE_INVALID, "SSL_DATE_INVALID");
-        SSL_ERRORS.put(SslError.SSL_INVALID,      "SSL_INVALID");
-    }
-
-    private static String sslErrorName(SslError error) {
-        return SSL_ERRORS.get(error.getPrimaryError(), "UNKNOWN");
-    }
-
-    private static final SparseArray<Integer> SSL_ERROR_MSGS = new SparseArray<>();
-    static {
-        SSL_ERROR_MSGS.put(SslError.SSL_NOTYETVALID,  R.string.ssl_error_not_yet_valid);
-        SSL_ERROR_MSGS.put(SslError.SSL_EXPIRED,      R.string.ssl_error_expired);
-        SSL_ERROR_MSGS.put(SslError.SSL_IDMISMATCH,   R.string.ssl_error_mismatch);
-        SSL_ERROR_MSGS.put(SslError.SSL_UNTRUSTED,    R.string.ssl_error_untrusted);
-        SSL_ERROR_MSGS.put(SslError.SSL_DATE_INVALID, R.string.ssl_error_date_invalid);
-        SSL_ERROR_MSGS.put(SslError.SSL_INVALID,      R.string.ssl_error_invalid);
-    }
-
-    private static Integer sslErrorMessage(SslError error) {
-        return SSL_ERROR_MSGS.get(error.getPrimaryError(), R.string.ssl_error_unknown);
-    }
-}
diff --git a/packages/ExtServices/Android.bp b/packages/ExtServices/Android.bp
deleted file mode 100644
index db94eec..0000000
--- a/packages/ExtServices/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_app {
-    name: "ExtServices",
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    certificate: "platform",
-    aaptflags: ["--shared-lib"],
-    export_package_resources: true,
-    optimize: {
-        proguard_flags_files: ["proguard.proguard"],
-    },
-    privileged: true,
-}
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
deleted file mode 100644
index 45e557c..0000000
--- a/packages/ExtServices/AndroidManifest.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    package="android.ext.services"
-    android:versionCode="1"
-    android:versionName="1"
-    coreApp="true">
-
-    <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
-
-    <application android:label="@string/app_name"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true">
-
-        <service android:name=".storage.CacheQuotaServiceImpl"
-             android:permission="android.permission.BIND_CACHE_QUOTA_SERVICE">
-            <intent-filter>
-                <action android:name="android.app.usage.CacheQuotaService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".resolver.LRResolverRankerService"
-                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
-                 android:priority="-1" >
-            <intent-filter>
-                <action android:name="android.service.resolver.ResolverRankerService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".notification.Assistant"
-                 android:label="@string/notification_assistant"
-                 android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"
-                 android:exported="true">
-            <intent-filter>
-                <action android:name="android.service.notification.NotificationAssistantService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".autofill.AutofillFieldClassificationServiceImpl"
-             android:permission="android.permission.BIND_AUTOFILL_FIELD_CLASSIFICATION_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.autofill.AutofillFieldClassificationService" />
-            </intent-filter>
-            <meta-data
-                android:name="android.autofill.field_classification.default_algorithm"
-                android:resource="@string/autofill_field_classification_default_algorithm" />
-            <meta-data
-                android:name="android.autofill.field_classification.available_algorithms"
-                android:resource="@array/autofill_field_classification_available_algorithms" />
-        </service>
-
-        <library android:name="android.ext.services"/>
-    </application>
-
-</manifest>
diff --git a/packages/ExtServices/MODULE_LICENSE_APACHE2 b/packages/ExtServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/packages/ExtServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/ExtServices/NOTICE b/packages/ExtServices/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/packages/ExtServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/packages/ExtServices/OWNERS b/packages/ExtServices/OWNERS
deleted file mode 100644
index 7640b91..0000000
--- a/packages/ExtServices/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-baligh@google.com
-delphij@google.com
diff --git a/packages/ExtServices/proguard.proguard b/packages/ExtServices/proguard.proguard
deleted file mode 100644
index e5dfbe1..0000000
--- a/packages/ExtServices/proguard.proguard
+++ /dev/null
@@ -1,7 +0,0 @@
--keepparameternames
--keepattributes Exceptions,InnerClasses,Signature,Deprecated,
-                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-
--keep public class * {
-    public protected *;
-}
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
deleted file mode 100644
index 72647ab..0000000
--- a/packages/ExtServices/res/values/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name">Android Services Library</string>
-
-    <string name="notification_assistant">Notification Assistant</string>
-    <string name="prompt_block_reason">Too many dismissals:views</string>
-
-    <string name="autofill_field_classification_default_algorithm">EDIT_DISTANCE</string>
-    <string-array name="autofill_field_classification_available_algorithms">
-        <item>EDIT_DISTANCE</item>
-    </string-array>
-</resources>
diff --git a/packages/ExtServices/src/android/ext/services/Version.java b/packages/ExtServices/src/android/ext/services/Version.java
deleted file mode 100644
index 026cccd..0000000
--- a/packages/ExtServices/src/android/ext/services/Version.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services;
-
-/**
- * Class that provides the version of the library.
- */
-public final class Version {
-
-    private Version() {
-        /* do nothing - hide constructor */
-    }
-
-    /**
-     * Gets the version of the library.
-     *
-     * @return The version.
-     */
-    public static int getVersionCode() {
-        return 1;
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java b/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
deleted file mode 100644
index 9ba7e09..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.ext.services.autofill;
-
-import static android.ext.services.autofill.EditDistanceScorer.DEFAULT_ALGORITHM;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.service.autofill.AutofillFieldClassificationService;
-import android.util.Log;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.List;
-
-public class AutofillFieldClassificationServiceImpl extends AutofillFieldClassificationService {
-
-    private static final String TAG = "AutofillFieldClassificationServiceImpl";
-
-    @Nullable
-    @Override
-    public float[][] onGetScores(@Nullable String algorithmName,
-            @Nullable Bundle algorithmArgs, @NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
-        if (ArrayUtils.isEmpty(actualValues) || ArrayUtils.isEmpty(userDataValues)) {
-            Log.w(TAG, "getScores(): empty currentvalues (" + actualValues + ") or userValues ("
-                    + userDataValues + ")");
-            return null;
-        }
-        if (algorithmName != null && !algorithmName.equals(DEFAULT_ALGORITHM)) {
-            Log.w(TAG, "Ignoring invalid algorithm (" + algorithmName + ") and using "
-                    + DEFAULT_ALGORITHM + " instead");
-        }
-
-        return EditDistanceScorer.getScores(actualValues, userDataValues);
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java b/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
deleted file mode 100644
index 302b160..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.ext.services.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.Log;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.List;
-
-final class EditDistanceScorer {
-
-    private static final String TAG = "EditDistanceScorer";
-
-    // TODO(b/70291841): STOPSHIP - set to false before launching
-    private static final boolean DEBUG = true;
-
-    static final String DEFAULT_ALGORITHM = "EDIT_DISTANCE";
-
-    /**
-     * Gets the field classification score of 2 values based on the edit distance between them.
-     *
-     * <p>The score is defined as: @(max_length - edit_distance) / max_length
-     */
-    @VisibleForTesting
-    static float getScore(@Nullable AutofillValue actualValue, @Nullable String userDataValue) {
-        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
-
-        final String actualValueText = actualValue.getTextValue().toString();
-        final int actualValueLength = actualValueText.length();
-        final int userDatalength = userDataValue.length();
-        if (userDatalength == 0) {
-            return (actualValueLength == 0) ? 1 : 0;
-        }
-
-        final int distance = editDistance(actualValueText.toLowerCase(),
-                userDataValue.toLowerCase());
-        final int maxLength = Math.max(actualValueLength, userDatalength);
-        return ((float) maxLength - distance) / maxLength;
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @return the edit distance between the two strings
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    public static int editDistance(@NonNull String s, @NonNull String t) {
-        return editDistance(s, t, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @param max the maximum edit distance that we care about; if for example the string length
-     *     delta is greater than this we don't bother computing the exact edit distance since the
-     *     caller has indicated they're not interested in the result
-     * @return the edit distance between the two strings, or some other value greater than that if
-     *     the edit distance is at least as big as the {@code max} parameter
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    private static int editDistance(@NonNull String s, @NonNull String t, int max) {
-        if (s.equals(t)) {
-            return 0;
-        }
-
-        if (Math.abs(s.length() - t.length()) > max) {
-            // The string lengths differ more than the allowed edit distance;
-            // no point in even attempting to compute the edit distance (requires
-            // O(n*m) storage and O(n*m) speed, where n and m are the string lengths)
-            return Integer.MAX_VALUE;
-        }
-
-        int m = s.length();
-        int n = t.length();
-        int[][] d = new int[m + 1][n + 1];
-        for (int i = 0; i <= m; i++) {
-            d[i][0] = i;
-        }
-        for (int j = 0; j <= n; j++) {
-            d[0][j] = j;
-        }
-        for (int j = 1; j <= n; j++) {
-            for (int i = 1; i <= m; i++) {
-                if (s.charAt(i - 1) == t.charAt(j - 1)) {
-                    d[i][j] = d[i - 1][j - 1];
-                } else {
-                    int deletion = d[i - 1][j] + 1;
-                    int insertion = d[i][j - 1] + 1;
-                    int substitution = d[i - 1][j - 1] + 1;
-                    d[i][j] = Math.min(deletion, Math.min(insertion, substitution));
-                }
-            }
-        }
-
-        return d[m][n];
-    }
-    /**
-     * Gets the scores in a batch.
-     */
-    static float[][] getScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
-        final int actualValuesSize = actualValues.size();
-        final int userDataValuesSize = userDataValues.size();
-        if (DEBUG) {
-            Log.d(TAG, "getScores() will return a " + actualValuesSize + "x"
-                    + userDataValuesSize + " matrix for " + DEFAULT_ALGORITHM);
-        }
-        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
-
-        for (int i = 0; i < actualValuesSize; i++) {
-            for (int j = 0; j < userDataValuesSize; j++) {
-                final float score = getScore(actualValues.get(i), userDataValues.get(j));
-                scores[i][j] = score;
-            }
-        }
-        return scores;
-    }
-
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
deleted file mode 100644
index f878822..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/**
- * 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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-
-import android.app.INotificationManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.ext.services.R;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.util.ArrayMap;
-import android.util.AtomicFile;
-import android.util.Log;
-import android.util.Slog;
-import android.util.Xml;
-
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.XmlUtils;
-
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Map;
-
-/**
- * Notification assistant that provides guidance on notification channel blocking
- */
-public class Assistant extends NotificationAssistantService {
-    private static final String TAG = "ExtAssistant";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final String TAG_ASSISTANT = "assistant";
-    private static final String TAG_IMPRESSION = "impression-set";
-    private static final String ATT_KEY = "key";
-    private static final int DB_VERSION = 1;
-    private static final String ATTR_VERSION = "version";
-
-    private static final ArrayList<Integer> PREJUDICAL_DISMISSALS = new ArrayList<>();
-    static {
-        PREJUDICAL_DISMISSALS.add(REASON_CANCEL);
-        PREJUDICAL_DISMISSALS.add(REASON_LISTENER_CANCEL);
-    }
-
-    private float mDismissToViewRatioLimit;
-    private int mStreakLimit;
-
-    // key : impressions tracker
-    // TODO: prune deleted channels and apps
-    final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
-    // SBN key : channel id
-    ArrayMap<String, String> mLiveNotifications = new ArrayMap<>();
-
-    private Ranking mFakeRanking = null;
-    private AtomicFile mFile = null;
-
-    public Assistant() {
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        // Contexts are correctly hooked up by the creation step, which is required for the observer
-        // to be hooked up/initialized.
-        new SettingsObserver(mHandler);
-    }
-
-    private void loadFile() {
-        if (DEBUG) Slog.d(TAG, "loadFile");
-        AsyncTask.execute(() -> {
-            InputStream infile = null;
-            try {
-                infile = mFile.openRead();
-                readXml(infile);
-            } catch (FileNotFoundException e) {
-                Log.d(TAG, "File doesn't exist or isn't readable yet");
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to read channel impressions", e);
-            } catch (NumberFormatException | XmlPullParserException e) {
-                Log.e(TAG, "Unable to parse channel impressions", e);
-            } finally {
-                IoUtils.closeQuietly(infile);
-            }
-        });
-    }
-
-    protected void readXml(InputStream stream)
-            throws XmlPullParserException, NumberFormatException, IOException {
-        final XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(stream, StandardCharsets.UTF_8.name());
-        final int outerDepth = parser.getDepth();
-        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-            if (!TAG_ASSISTANT.equals(parser.getName())) {
-                continue;
-            }
-            final int impressionOuterDepth = parser.getDepth();
-            while (XmlUtils.nextElementWithin(parser, impressionOuterDepth)) {
-                if (!TAG_IMPRESSION.equals(parser.getName())) {
-                    continue;
-                }
-                String key = parser.getAttributeValue(null, ATT_KEY);
-                ChannelImpressions ci = createChannelImpressionsWithThresholds();
-                ci.populateFromXml(parser);
-                synchronized (mkeyToImpressions) {
-                    ci.append(mkeyToImpressions.get(key));
-                    mkeyToImpressions.put(key, ci);
-                }
-            }
-        }
-    }
-
-    private void saveFile() throws IOException {
-        AsyncTask.execute(() -> {
-            final FileOutputStream stream;
-            try {
-                stream = mFile.startWrite();
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save policy file", e);
-                return;
-            }
-            try {
-                final XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, StandardCharsets.UTF_8.name());
-                writeXml(out);
-                mFile.finishWrite(stream);
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save impressions file, restoring backup", e);
-                mFile.failWrite(stream);
-            }
-        });
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        out.startDocument(null, true);
-        out.startTag(null, TAG_ASSISTANT);
-        out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
-        synchronized (mkeyToImpressions) {
-            for (Map.Entry<String, ChannelImpressions> entry
-                    : mkeyToImpressions.entrySet()) {
-                // TODO: ensure channel still exists
-                out.startTag(null, TAG_IMPRESSION);
-                out.attribute(null, ATT_KEY, entry.getKey());
-                entry.getValue().writeXml(out);
-                out.endTag(null, TAG_IMPRESSION);
-            }
-        }
-        out.endTag(null, TAG_ASSISTANT);
-        out.endDocument();
-    }
-
-    @Override
-    public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
-        if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey());
-        return null;
-    }
-
-    @Override
-    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
-        if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
-        try {
-            Ranking ranking = getRanking(sbn.getKey(), rankingMap);
-            if (ranking != null && ranking.getChannel() != null) {
-                String key = getKey(
-                        sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
-                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                        createChannelImpressionsWithThresholds());
-                if (ranking.getImportance() > IMPORTANCE_MIN && ci.shouldTriggerBlock()) {
-                    adjustNotification(createNegativeAdjustment(
-                            sbn.getPackageName(), sbn.getKey(), sbn.getUserId()));
-                }
-                mkeyToImpressions.put(key, ci);
-                mLiveNotifications.put(sbn.getKey(), ranking.getChannel().getId());
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred processing post", e);
-        }
-    }
-
-    @Override
-    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
-            NotificationStats stats, int reason) {
-        try {
-            boolean updatedImpressions = false;
-            String channelId = mLiveNotifications.remove(sbn.getKey());
-            String key = getKey(sbn.getPackageName(), sbn.getUserId(), channelId);
-            synchronized (mkeyToImpressions) {
-                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                        createChannelImpressionsWithThresholds());
-                if (stats.hasSeen()) {
-                    ci.incrementViews();
-                    updatedImpressions = true;
-                }
-                if (PREJUDICAL_DISMISSALS.contains(reason)) {
-                    if ((!sbn.isAppGroup() || sbn.getNotification().isGroupChild())
-                            && !stats.hasInteracted()
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_AOD
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_PEEK
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_OTHER) {
-                        if (DEBUG) Log.i(TAG, "increment dismissals " + key);
-                        ci.incrementDismissals();
-                        updatedImpressions = true;
-                    } else {
-                        if (DEBUG) Slog.i(TAG, "reset streak " + key);
-                        if (ci.getStreak() > 0) {
-                            updatedImpressions = true;
-                        }
-                        ci.resetStreak();
-                    }
-                }
-                mkeyToImpressions.put(key, ci);
-            }
-            if (updatedImpressions) {
-                saveFile();
-            }
-        } catch (Throwable e) {
-            Slog.e(TAG, "Error occurred processing removal", e);
-        }
-    }
-
-    @Override
-    public void onNotificationSnoozedUntilContext(StatusBarNotification sbn,
-            String snoozeCriterionId) {
-    }
-
-    @Override
-    public void onListenerConnected() {
-        if (DEBUG) Log.i(TAG, "CONNECTED");
-        try {
-            mFile = new AtomicFile(new File(new File(
-                    Environment.getDataUserCePackageDirectory(
-                            StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                    "assistant"), "blocking_helper_stats.xml"));
-            loadFile();
-            for (StatusBarNotification sbn : getActiveNotifications()) {
-                onNotificationPosted(sbn);
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred on connection", e);
-        }
-    }
-
-    protected String getKey(String pkg, int userId, String channelId) {
-        return pkg + "|" + userId + "|" + channelId;
-    }
-
-    private Ranking getRanking(String key, RankingMap rankingMap) {
-        if (mFakeRanking != null) {
-            return mFakeRanking;
-        }
-        Ranking ranking = new Ranking();
-        rankingMap.getRanking(key, ranking);
-        return ranking;
-    }
-
-    private Adjustment createNegativeAdjustment(String packageName, String key, int user) {
-        if (DEBUG) Log.d(TAG, "User probably doesn't want " + key);
-        Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
-        return new Adjustment(packageName, key,  signals,
-                getContext().getString(R.string.prompt_block_reason), user);
-    }
-
-    // for testing
-
-    protected void setFile(AtomicFile file) {
-        mFile = file;
-    }
-
-    protected void setFakeRanking(Ranking ranking) {
-        mFakeRanking = ranking;
-    }
-
-    protected void setNoMan(INotificationManager noMan) {
-        mNoMan = noMan;
-    }
-
-    protected void setContext(Context context) {
-        mSystemContext = context;
-    }
-
-    protected ChannelImpressions getImpressions(String key) {
-        synchronized (mkeyToImpressions) {
-            return mkeyToImpressions.get(key);
-        }
-    }
-
-    protected void insertImpressions(String key, ChannelImpressions ci) {
-        synchronized (mkeyToImpressions) {
-            mkeyToImpressions.put(key, ci);
-        }
-    }
-
-    private ChannelImpressions createChannelImpressionsWithThresholds() {
-        ChannelImpressions impressions = new ChannelImpressions();
-        impressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
-        return impressions;
-    }
-
-    /**
-     * Observer for updates on blocking helper threshold values.
-     */
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri STREAK_LIMIT_URI =
-                Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
-        private final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
-                Settings.Global.getUriFor(
-                        Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-            ContentResolver resolver = getApplicationContext().getContentResolver();
-            resolver.registerContentObserver(
-                    DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, getUserId());
-            resolver.registerContentObserver(STREAK_LIMIT_URI, false, this, getUserId());
-
-            // Update all uris on creation.
-            update(null);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            update(uri);
-        }
-
-        private void update(Uri uri) {
-            ContentResolver resolver = getApplicationContext().getContentResolver();
-            if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
-                mDismissToViewRatioLimit = Settings.Global.getFloat(
-                        resolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                        ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
-            }
-            if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
-                mStreakLimit = Settings.Global.getInt(
-                        resolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
-                        ChannelImpressions.DEFAULT_STREAK_LIMIT);
-            }
-
-            // Update all existing channel impression objects with any new limits/thresholds.
-            synchronized (mkeyToImpressions) {
-                for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
-                    channelImpressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java b/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
deleted file mode 100644
index 29ee920..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * 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.ext.services.notification;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-
-public final class ChannelImpressions implements Parcelable {
-    private static final String TAG = "ExtAssistant.CI";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    static final float DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT = .8f;
-    static final int DEFAULT_STREAK_LIMIT = 2;
-    static final String ATT_DISMISSALS = "dismisses";
-    static final String ATT_VIEWS = "views";
-    static final String ATT_STREAK = "streak";
-
-    private int mDismissals = 0;
-    private int mViews = 0;
-    private int mStreak = 0;
-
-    private float mDismissToViewRatioLimit;
-    private int mStreakLimit;
-
-    public ChannelImpressions() {
-        mDismissToViewRatioLimit = DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-        mStreakLimit = DEFAULT_STREAK_LIMIT;
-    }
-
-    protected ChannelImpressions(Parcel in) {
-        mDismissals = in.readInt();
-        mViews = in.readInt();
-        mStreak = in.readInt();
-        mDismissToViewRatioLimit = in.readFloat();
-        mStreakLimit = in.readInt();
-    }
-
-    public int getStreak() {
-        return mStreak;
-    }
-
-    public int getDismissals() {
-        return mDismissals;
-    }
-
-    public int getViews() {
-        return mViews;
-    }
-
-    public void incrementDismissals() {
-        mDismissals++;
-        mStreak++;
-    }
-
-    void updateThresholds(float dismissToViewRatioLimit, int streakLimit) {
-        mDismissToViewRatioLimit = dismissToViewRatioLimit;
-        mStreakLimit = streakLimit;
-    }
-
-    @VisibleForTesting
-    float getDismissToViewRatioLimit() {
-        return mDismissToViewRatioLimit;
-    }
-
-    @VisibleForTesting
-    int getStreakLimit() {
-        return mStreakLimit;
-    }
-
-    public void append(ChannelImpressions additionalImpressions) {
-        if (additionalImpressions != null) {
-            mViews += additionalImpressions.getViews();
-            mStreak += additionalImpressions.getStreak();
-            mDismissals += additionalImpressions.getDismissals();
-        }
-    }
-
-    public void incrementViews() {
-        mViews++;
-    }
-
-    public void resetStreak() {
-        mStreak = 0;
-    }
-
-    public boolean shouldTriggerBlock() {
-        if (getViews() == 0) {
-            return false;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "should trigger? " + getDismissals() + " " + getViews() + " " + getStreak());
-        }
-        return ((float) getDismissals() / getViews()) > mDismissToViewRatioLimit
-                && getStreak() > mStreakLimit;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDismissals);
-        dest.writeInt(mViews);
-        dest.writeInt(mStreak);
-        dest.writeFloat(mDismissToViewRatioLimit);
-        dest.writeInt(mStreakLimit);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Creator<ChannelImpressions> CREATOR = new Creator<ChannelImpressions>() {
-        @Override
-        public ChannelImpressions createFromParcel(Parcel in) {
-            return new ChannelImpressions(in);
-        }
-
-        @Override
-        public ChannelImpressions[] newArray(int size) {
-            return new ChannelImpressions[size];
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ChannelImpressions that = (ChannelImpressions) o;
-
-        if (mDismissals != that.mDismissals) return false;
-        if (mViews != that.mViews) return false;
-        return mStreak == that.mStreak;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mDismissals;
-        result = 31 * result + mViews;
-        result = 31 * result + mStreak;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder("ChannelImpressions{");
-        sb.append("mDismissals=").append(mDismissals);
-        sb.append(", mViews=").append(mViews);
-        sb.append(", mStreak=").append(mStreak);
-        sb.append(", thresholds=(").append(mDismissToViewRatioLimit);
-        sb.append(",").append(mStreakLimit);
-        sb.append(")}");
-        return sb.toString();
-    }
-
-    protected void populateFromXml(XmlPullParser parser) {
-        mDismissals = safeInt(parser, ATT_DISMISSALS, 0);
-        mStreak = safeInt(parser, ATT_STREAK, 0);
-        mViews = safeInt(parser, ATT_VIEWS, 0);
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        if (mDismissals != 0) {
-            out.attribute(null, ATT_DISMISSALS, String.valueOf(mDismissals));
-        }
-        if (mStreak != 0) {
-            out.attribute(null, ATT_STREAK, String.valueOf(mStreak));
-        }
-        if (mViews != 0) {
-            out.attribute(null, ATT_VIEWS, String.valueOf(mViews));
-        }
-    }
-
-    private static int safeInt(XmlPullParser parser, String att, int defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseInt(val, defValue);
-    }
-
-    private static int tryParseInt(String value, int defValue) {
-        if (TextUtils.isEmpty(value)) return defValue;
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return defValue;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java b/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
deleted file mode 100644
index 9d7a568..0000000
--- a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.ext.services.resolver;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.storage.StorageManager;
-import android.service.resolver.ResolverRankerService;
-import android.service.resolver.ResolverTarget;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used
- * in {@link ResolverComparator}.
- */
-public final class LRResolverRankerService extends ResolverRankerService {
-    private static final String TAG = "LRResolverRankerService";
-
-    private static final boolean DEBUG = false;
-
-    private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
-    private static final String BIAS_PREF_KEY = "bias";
-    private static final String VERSION_PREF_KEY = "version";
-
-    private static final String LAUNCH_SCORE = "launch";
-    private static final String TIME_SPENT_SCORE = "timeSpent";
-    private static final String RECENCY_SCORE = "recency";
-    private static final String CHOOSER_SCORE = "chooser";
-
-    // parameters for a pre-trained model, to initialize the app ranker. When updating the
-    // pre-trained model, please update these params, as well as initModel().
-    private static final int CURRENT_VERSION = 1;
-    private static final float LEARNING_RATE = 0.0001f;
-    private static final float REGULARIZER_PARAM = 0.0001f;
-
-    private SharedPreferences mParamSharedPref;
-    private ArrayMap<String, Float> mFeatureWeights;
-    private float mBias;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        initModel();
-        return super.onBind(intent);
-    }
-
-    @Override
-    public void onPredictSharingProbabilities(List<ResolverTarget> targets) {
-        final int size = targets.size();
-        for (int i = 0; i < size; ++i) {
-            ResolverTarget target = targets.get(i);
-            ArrayMap<String, Float> features = getFeatures(target);
-            target.setSelectProbability(predict(features));
-        }
-    }
-
-    @Override
-    public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) {
-        final int size = targets.size();
-        if (selectedPosition < 0 || selectedPosition >= size) {
-            if (DEBUG) {
-                Log.d(TAG, "Invalid Position of Selected App " + selectedPosition);
-            }
-            return;
-        }
-        final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition));
-        final float positiveProbability = targets.get(selectedPosition).getSelectProbability();
-        final int targetSize = targets.size();
-        for (int i = 0; i < targetSize; ++i) {
-            if (i == selectedPosition) {
-                continue;
-            }
-            final ArrayMap<String, Float> negative = getFeatures(targets.get(i));
-            final float negativeProbability = targets.get(i).getSelectProbability();
-            if (negativeProbability > positiveProbability) {
-                update(negative, negativeProbability, false);
-                update(positive, positiveProbability, true);
-            }
-        }
-        commitUpdate();
-    }
-
-    private void initModel() {
-        mParamSharedPref = getParamSharedPref();
-        mFeatureWeights = new ArrayMap<>(4);
-        if (mParamSharedPref == null ||
-                mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
-            // Initializing the app ranker to a pre-trained model. When updating the pre-trained
-            // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
-            // REGULARIZER_PARAM.
-            mBias = -1.6568f;
-            mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
-            mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
-            mFeatureWeights.put(RECENCY_SCORE, 0.269f);
-            mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
-        } else {
-            mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
-            mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
-            mFeatureWeights.put(
-                    TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
-            mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
-            mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
-        }
-    }
-
-    private ArrayMap<String, Float> getFeatures(ResolverTarget target) {
-        ArrayMap<String, Float> features = new ArrayMap<>(4);
-        features.put(RECENCY_SCORE, target.getRecencyScore());
-        features.put(TIME_SPENT_SCORE, target.getTimeSpentScore());
-        features.put(LAUNCH_SCORE, target.getLaunchScore());
-        features.put(CHOOSER_SCORE, target.getChooserScore());
-        return features;
-    }
-
-    private float predict(ArrayMap<String, Float> target) {
-        if (target == null) {
-            return 0.0f;
-        }
-        final int featureSize = target.size();
-        float sum = 0.0f;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            sum += weight * target.valueAt(i);
-        }
-        return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
-    }
-
-    private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
-        if (target == null) {
-            return;
-        }
-        final int featureSize = target.size();
-        float error = isSelected ? 1.0f - predict : -predict;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            mBias += LEARNING_RATE * error;
-            currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
-                    LEARNING_RATE * error * target.valueAt(i);
-            mFeatureWeights.put(featureName, currentWeight);
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
-        }
-    }
-
-    private void commitUpdate() {
-        try {
-            SharedPreferences.Editor editor = mParamSharedPref.edit();
-            editor.putFloat(BIAS_PREF_KEY, mBias);
-            final int size = mFeatureWeights.size();
-            for (int i = 0; i < size; i++) {
-                editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
-            }
-            editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
-            editor.apply();
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to commit update" + e);
-        }
-    }
-
-    private SharedPreferences getParamSharedPref() {
-        // The package info in the context isn't initialized in the way it is for normal apps,
-        // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
-        // build the path manually below using the same policy that appears in ContextImpl.
-        if (DEBUG) {
-            Log.d(TAG, "Context Package Name: " + getPackageName());
-        }
-        final File prefsFile = new File(new File(
-                Environment.getDataUserCePackageDirectory(
-                        StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                "shared_prefs"),
-                PARAM_SHARED_PREF_NAME + ".xml");
-        return getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
deleted file mode 100644
index 862f50b2..0000000
--- a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.ext.services.storage;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.CacheQuotaService;
-import android.os.Environment;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.util.ArrayMap;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * CacheQuotaServiceImpl implements the CacheQuotaService with a strategy for populating the quota
- * of {@link CacheQuotaHint}.
- */
-public class CacheQuotaServiceImpl extends CacheQuotaService {
-    private static final double CACHE_RESERVE_RATIO = 0.15;
-
-    @Override
-    public List<CacheQuotaHint> onComputeCacheQuotaHints(List<CacheQuotaHint> requests) {
-        ArrayMap<String, List<CacheQuotaHint>> byUuid = new ArrayMap<>();
-        final int requestCount = requests.size();
-        for (int i = 0; i < requestCount; i++) {
-            CacheQuotaHint request = requests.get(i);
-            String uuid = request.getVolumeUuid();
-            List<CacheQuotaHint> listForUuid = byUuid.get(uuid);
-            if (listForUuid == null) {
-                listForUuid = new ArrayList<>();
-                byUuid.put(uuid, listForUuid);
-            }
-            listForUuid.add(request);
-        }
-
-        List<CacheQuotaHint> processed = new ArrayList<>();
-        byUuid.entrySet().forEach(
-                requestListEntry -> {
-                    // Collapse all usage stats to the same uid.
-                    Map<Integer, List<CacheQuotaHint>> byUid = requestListEntry.getValue()
-                            .stream()
-                            .collect(Collectors.groupingBy(CacheQuotaHint::getUid));
-                    byUid.values().forEach(uidGroupedList -> {
-                        int size = uidGroupedList.size();
-                        if (size < 2) {
-                            return;
-                        }
-                        CacheQuotaHint first = uidGroupedList.get(0);
-                        for (int i = 1; i < size; i++) {
-                            /* Note: We can't use the UsageStats built-in addition function because
-                                     UIDs may span multiple packages and usage stats adding has
-                                     matching package names as a precondition. */
-                            first.getUsageStats().mTotalTimeInForeground +=
-                                    uidGroupedList.get(i).getUsageStats().mTotalTimeInForeground;
-                        }
-                    });
-
-                    // Because the foreground stats have been added to the first element, we need
-                    // a list of only the first values (which contain the merged foreground time).
-                    List<CacheQuotaHint> flattenedRequests =
-                            byUid.values()
-                                 .stream()
-                                 .map(entryList -> entryList.get(0))
-                                 .filter(entry -> entry.getUsageStats().mTotalTimeInForeground != 0)
-                                 .sorted(sCacheQuotaRequestComparator)
-                                 .collect(Collectors.toList());
-
-                    // Because the elements are sorted, we can use the index to also be the sorted
-                    // index for cache quota calculation.
-                    double sum = getSumOfFairShares(flattenedRequests.size());
-                    String uuid = requestListEntry.getKey();
-                    long reservedSize = getReservedCacheSize(uuid);
-                    for (int count = 0; count < flattenedRequests.size(); count++) {
-                        double share = getFairShareForPosition(count) / sum;
-                        CacheQuotaHint entry = flattenedRequests.get(count);
-                        CacheQuotaHint.Builder builder = new CacheQuotaHint.Builder(entry);
-                        builder.setQuota(Math.round(share * reservedSize));
-                        processed.add(builder.build());
-                    }
-                }
-        );
-
-        return processed.stream()
-                .filter(request -> request.getQuota() > 0).collect(Collectors.toList());
-    }
-
-    private double getFairShareForPosition(int position) {
-        double value = 1.0 / Math.log(position + 3) - 0.285;
-        return (value > 0.01) ? value : 0.01;
-    }
-
-    private double getSumOfFairShares(int size) {
-        double sum = 0;
-        for (int i = 0; i < size; i++) {
-            sum += getFairShareForPosition(i);
-        }
-        return sum;
-    }
-
-    private long getReservedCacheSize(String uuid) {
-        // TODO: Revisit the cache size after running more storage tests.
-        // TODO: Figure out how to ensure ExtServices has the permissions to call
-        //       StorageStatsManager, because this is ignoring the cache...
-        StorageManager storageManager = getSystemService(StorageManager.class);
-        long freeBytes = 0;
-        if (uuid == StorageManager.UUID_PRIVATE_INTERNAL) { // regular equals because of null
-            freeBytes = Environment.getDataDirectory().getUsableSpace();
-        } else {
-            final VolumeInfo vol = storageManager.findVolumeByUuid(uuid);
-            freeBytes = vol.getPath().getUsableSpace();
-        }
-        return Math.round(freeBytes * CACHE_RESERVE_RATIO);
-    }
-
-    // Compares based upon foreground time.
-    private static Comparator<CacheQuotaHint> sCacheQuotaRequestComparator =
-            new Comparator<CacheQuotaHint>() {
-        @Override
-        public int compare(CacheQuotaHint o, CacheQuotaHint t1) {
-            long x = t1.getUsageStats().getTotalTimeInForeground();
-            long y = o.getUsageStats().getTotalTimeInForeground();
-            return (x < y) ? -1 : ((x == y) ? 0 : 1);
-        }
-    };
-}
diff --git a/packages/ExtServices/tests/Android.bp b/packages/ExtServices/tests/Android.bp
deleted file mode 100644
index db16027..0000000
--- a/packages/ExtServices/tests/Android.bp
+++ /dev/null
@@ -1,19 +0,0 @@
-android_test {
-    name: "ExtServicesUnitTests",
-    certificate: "platform",
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-    static_libs: [
-        "androidx.test.rules",
-        "mockito-target-minus-junit4",
-        "androidx.test.espresso.core",
-        "truth-prebuilt",
-        "testables",
-    ],
-    // Include all test java files.
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    instrumentation_for: "ExtServices",
-}
diff --git a/packages/ExtServices/tests/AndroidManifest.xml b/packages/ExtServices/tests/AndroidManifest.xml
deleted file mode 100644
index 42293b5..0000000
--- a/packages/ExtServices/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.ext.services.tests.unit">
-
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.ext.services"
-                     android:label="ExtServices Test Cases">
-    </instrumentation>
-
-</manifest>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/AndroidTest.xml b/packages/ExtServices/tests/AndroidTest.xml
deleted file mode 100644
index cd26ebc..0000000
--- a/packages/ExtServices/tests/AndroidTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs Tests for ExtServices">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="ExtServicesUnitTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="ExtServicesUnitTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.ext.services.tests.unit" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
deleted file mode 100644
index 48c076e..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 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.ext.services.autofill;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.autofill.AutofillValue;
-
-/**
- * Contains the base tests that does not rely on the specific algorithm implementation.
- */
-public class AutofillFieldClassificationServiceImplTest {
-
-    private final AutofillFieldClassificationServiceImpl mService =
-            new AutofillFieldClassificationServiceImpl();
-
-    @Test
-    public void testOnGetScores_nullActualValues() {
-        assertThat(mService.onGetScores(null, null, null, Arrays.asList("whatever"))).isNull();
-    }
-
-    @Test
-    public void testOnGetScores_emptyActualValues() {
-        assertThat(mService.onGetScores(null, null, Collections.emptyList(),
-                Arrays.asList("whatever"))).isNull();
-    }
-
-    @Test
-    public void testOnGetScores_nullUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), null)).isNull();
-    }
-
-    @Test
-    public void testOnGetScores_emptyUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), Collections.emptyList()))
-                        .isNull();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
deleted file mode 100644
index afe2236..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2018 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.ext.services.autofill;
-
-import static android.ext.services.autofill.EditDistanceScorer.getScore;
-import static android.ext.services.autofill.EditDistanceScorer.getScores;
-import static android.view.autofill.AutofillValue.forText;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class EditDistanceScorerTest {
-
-    @Test
-    public void testGetScore_nullValue() {
-        assertFloat(getScore(null, "D'OH!"), 0);
-    }
-
-    @Test
-    public void testGetScore_nonTextValue() {
-        assertFloat(getScore(AutofillValue.forToggle(true), "D'OH!"), 0);
-    }
-
-    @Test
-    public void testGetScore_nullUserData() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), null), 0);
-    }
-
-    @Test
-    public void testGetScore_fullMatch() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
-        assertFloat(getScore(AutofillValue.forText(""), ""), 1);
-    }
-
-    @Test
-    public void testGetScore_fullMatchMixedCase() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
-    }
-
-    @Test
-    public void testGetScore_mismatchDifferentSizes() {
-        assertFloat(getScore(AutofillValue.forText("X"), "Xy"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Xy"), "X"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
-                "1600 Amphitheatre Pkwy"), 0.88F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
-                "1600 Amphitheatre Parkway"), 0.88F);
-    }
-
-    @Test
-    public void testGetScore_partialMatch() {
-        assertFloat(getScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
-        assertFloat(getScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
-    }
-
-    @Test
-    public void testGetScores() {
-        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"));
-        final List<String> userDataValues = Arrays.asList("a", "B", "ab", "c");
-        final float[][] expectedScores = new float[][] {
-            new float[] { 1F, 0F, 0.5F, 0F },
-            new float[] { 0F, 1F, 0.5F, 0F }
-        };
-        final float[][] actualScores = getScores(actualValues, userDataValues);
-
-        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
-        // messages in case of error, so we need to check.
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores.length).isEqualTo(2);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[0].length).isEqualTo(4);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[1].length).isEqualTo(4);
-        for (int i = 0; i < actualScores.length; i++) {
-            final float[] line = actualScores[i];
-            for (int j = 0; j < line.length; j++) {
-                float cell = line[j];
-                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
-                        .of(expectedScores[i][j]);
-            }
-        }
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
-    }
-
-    public static String toString(float[][] matrix) {
-        final StringBuilder string = new StringBuilder("[ ");
-        for (int i = 0; i < matrix.length; i++) {
-            string.append(Arrays.toString(matrix[i])).append(" ");
-        }
-        return string.append(" ]").toString();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
deleted file mode 100644
index 6ef25e5..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/**
- * 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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Application;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.test.ServiceTestCase;
-import android.testing.TestableContext;
-import android.util.AtomicFile;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.util.FastXmlSerializer;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-
-public class AssistantTest extends ServiceTestCase<Assistant> {
-
-    private static final String PKG1 = "pkg1";
-    private static final int UID1 = 1;
-    private static final NotificationChannel P1C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-    private static final NotificationChannel P1C2 =
-            new NotificationChannel("p1c2", "", IMPORTANCE_DEFAULT);
-    private static final NotificationChannel P1C3 =
-            new NotificationChannel("p1c3", "", IMPORTANCE_MIN);
-    private static final String PKG2 = "pkg2";
-
-    private static final int UID2 = 2;
-    private static final NotificationChannel P2C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-
-    @Mock INotificationManager mNoMan;
-    @Mock AtomicFile mFile;
-
-    Assistant mAssistant;
-    Application mApplication;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    public AssistantTest() {
-        super(Assistant.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Intent startIntent =
-                new Intent("android.service.notification.NotificationAssistantService");
-        startIntent.setPackage("android.ext.services");
-
-        // To bypass real calls to global settings values, set the Settings values here.
-        Settings.Global.putFloat(mContext.getContentResolver(),
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT, 0.8f);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, 2);
-        mApplication = (Application) InstrumentationRegistry.getInstrumentation().
-                getTargetContext().getApplicationContext();
-        // Force the test to use the correct application instead of trying to use a mock application
-        setApplication(mApplication);
-        bindService(startIntent);
-        mAssistant = getService();
-        mAssistant.setNoMan(mNoMan);
-        mAssistant.setFile(mFile);
-        when(mFile.startWrite()).thenReturn(mock(FileOutputStream.class));
-    }
-
-    private StatusBarNotification generateSbn(String pkg, int uid, NotificationChannel channel,
-            String tag, String groupKey) {
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setContentTitle("foo")
-                .setGroup(groupKey)
-                .build();
-
-        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 0, tag, uid, uid, n,
-                UserHandle.SYSTEM, null, 0);
-
-        return sbn;
-    }
-
-    private Ranking generateRanking(StatusBarNotification sbn, NotificationChannel channel) {
-        Ranking mockRanking = mock(Ranking.class);
-        when(mockRanking.getChannel()).thenReturn(channel);
-        when(mockRanking.getImportance()).thenReturn(channel.getImportance());
-        when(mockRanking.getKey()).thenReturn(sbn.getKey());
-        when(mockRanking.getOverrideGroupKey()).thenReturn(null);
-        return mockRanking;
-    }
-
-    private void almostBlockChannel(String pkg, int uid, NotificationChannel channel) {
-        for (int i = 0; i < ChannelImpressions.DEFAULT_STREAK_LIMIT; i++) {
-            dismissBadNotification(pkg, uid, channel, String.valueOf(i));
-        }
-    }
-
-    private void dismissBadNotification(String pkg, int uid, NotificationChannel channel,
-            String tag) {
-        StatusBarNotification sbn = generateSbn(pkg, uid, channel, tag, null);
-        mAssistant.setFakeRanking(generateRanking(sbn, channel));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.setFakeRanking(mock(Ranking.class));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-    }
-
-    @Test
-    public void testNoAdjustmentForInitialPost() throws Exception {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, null, null);
-
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testMinCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C3);
-        dismissBadNotification(PKG1, UID1, P1C3, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C3));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testGroupChildCanTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testGroupSummaryCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        sbn.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAodCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_AOD);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testInteractedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        stats.setExpanded();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppDismissedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_APP_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG2, UID2, P2C1, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P2C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testChannelSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C2, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C2));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testReadXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        int streak1 = 2;
-        int views1 = 5;
-        int dismiss1 = 9;
-
-        int streak1a = 3;
-        int views1a = 10;
-        int dismiss1a = 99;
-        String key1a = mAssistant.getKey("pkg1", 1, "channel1a");
-
-        int streak2 = 7;
-        int views2 = 77;
-        int dismiss2 = 777;
-        String key2 = mAssistant.getKey("pkg2", 2, "channel2");
-
-        String xml = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
-                + "<assistant version=\"1\">\n"
-                + "<impression-set key=\"" + key1 + "\" "
-                + "dismisses=\"" + dismiss1 + "\" views=\"" + views1
-                + "\" streak=\"" + streak1 + "\"/>\n"
-                + "<impression-set key=\"" + key1a + "\" "
-                + "dismisses=\"" + dismiss1a + "\" views=\"" + views1a
-                + "\" streak=\"" + streak1a + "\"/>\n"
-                + "<impression-set key=\"" + key2 + "\" "
-                + "dismisses=\"" + dismiss2 + "\" views=\"" + views2
-                + "\" streak=\"" + streak2 + "\"/>\n"
-                + "</assistant>\n";
-        mAssistant.readXml(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())));
-
-        ChannelImpressions c1 = mAssistant.getImpressions(key1);
-        assertEquals(2, c1.getStreak());
-        assertEquals(5, c1.getViews());
-        assertEquals(9, c1.getDismissals());
-
-        ChannelImpressions c1a = mAssistant.getImpressions(key1a);
-        assertEquals(3, c1a.getStreak());
-        assertEquals(10, c1a.getViews());
-        assertEquals(99, c1a.getDismissals());
-
-        ChannelImpressions c2 = mAssistant.getImpressions(key2);
-        assertEquals(7, c2.getStreak());
-        assertEquals(77, c2.getViews());
-        assertEquals(777, c2.getDismissals());
-    }
-
-    @Test
-    public void testRoundTripXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci1 = new ChannelImpressions();
-        String key2 = mAssistant.getKey("pkg1", 1, "channel2");
-        ChannelImpressions ci2 = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-        ChannelImpressions ci3 = new ChannelImpressions();
-        String key3 = mAssistant.getKey("pkg3", 3, "channel2");
-        for (int i = 0; i < 9; i++) {
-            ci3.incrementViews();
-            if (i % 3 == 0) {
-                ci3.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key1, ci1);
-        mAssistant.insertImpressions(key2, ci2);
-        mAssistant.insertImpressions(key3, ci3);
-
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        mAssistant.writeXml(serializer);
-
-        Assistant assistant = new Assistant();
-        assistant.readXml(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())));
-
-        assertEquals(ci1, assistant.getImpressions(key1));
-        assertEquals(ci2, assistant.getImpressions(key2));
-        assertEquals(ci3, assistant.getImpressions(key3));
-    }
-
-    @Test
-    public void testSettingsProviderUpdate() {
-        ContentResolver resolver = mApplication.getContentResolver();
-
-        // Set up channels
-        String key = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci.incrementViews();
-            if (i % 2 == 0) {
-                ci.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key, ci);
-
-        // With default values, the blocking helper shouldn't be triggered.
-        assertEquals(false, ci.shouldTriggerBlock());
-
-        // Update settings values.
-        float newDismissToViewRatioLimit = 0f;
-        int newStreakLimit = 0;
-        Settings.Global.putFloat(resolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                newDismissToViewRatioLimit);
-        Settings.Global.putInt(resolver,
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, newStreakLimit);
-
-        // Notify for the settings values we updated.
-        resolver.notifyChange(
-                Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT), null);
-        resolver.notifyChange(
-                Settings.Global.getUriFor(
-                        Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT),
-                null);
-
-        // With the new threshold, the blocking helper should be triggered.
-        assertEquals(true, ci.shouldTriggerBlock());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
deleted file mode 100644
index 3253802..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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.ext.services.notification;
-
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_STREAK_LIMIT;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ChannelImpressionsTest {
-
-    @Test
-    public void testNoResultNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT - 1; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock_breakStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            if (i == DEFAULT_STREAK_LIMIT - 1) {
-                ci.resetStreak();
-            }
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testStreakBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testRatio_NoBlockEvenWithStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            ci.incrementViews();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testAppend() {
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.incrementViews();
-        ci.incrementDismissals();
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.incrementViews();
-        ci2.incrementDismissals();
-        ci2.incrementViews();
-
-        ci.append(ci2);
-        assertEquals(3, ci.getViews());
-        assertEquals(2, ci.getDismissals());
-        assertEquals(2, ci.getStreak());
-
-        assertEquals(2, ci2.getViews());
-        assertEquals(1, ci2.getDismissals());
-        assertEquals(1, ci2.getStreak());
-
-        // no crash
-        ci.append(null);
-    }
-
-    @Test
-    public void testUpdateThresholds_streakLimitsCorrectlyApplied() {
-        int updatedStreakLimit = DEFAULT_STREAK_LIMIT + 3;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i <= updatedStreakLimit; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i < updatedStreakLimit; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-        assertFalse(ci2.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testUpdateThresholds_ratioLimitsCorrectlyApplied() {
-        float updatedDismissRatio = .99f;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        // N views, N-1 dismissals, which doesn't satisfy the ratio = 1 criteria.
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            if (i != DEFAULT_STREAK_LIMIT) {
-                ci.incrementDismissals();
-            }
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-        assertTrue(ci2.shouldTriggerBlock());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
deleted file mode 100644
index df4738f..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.ext.services.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.UsageStats;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.test.ServiceTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CacheQuotaServiceImplTest extends ServiceTestCase<CacheQuotaServiceImpl> {
-    private static final String sTestVolUuid = "uuid";
-    private static final String sSecondTestVolUuid = "otherUuid";
-
-    @Mock private Context mContext;
-    @Mock private File mFile;
-    @Mock private VolumeInfo mVolume;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS) private StorageManager mStorageManager;
-
-    public CacheQuotaServiceImplTest() {
-        super(CacheQuotaServiceImpl.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(getSystemContext()));
-        setContext(mContext);
-        when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager);
-
-        when(mFile.getUsableSpace()).thenReturn(10000L);
-        when(mVolume.getPath()).thenReturn(mFile);
-        when(mStorageManager.findVolumeByUuid(sTestVolUuid)).thenReturn(mVolume);
-        when(mStorageManager.findVolumeByUuid(sSecondTestVolUuid)).thenReturn(mVolume);
-
-        Intent intent = new Intent(getContext(), CacheQuotaServiceImpl.class);
-        startService(intent);
-    }
-
-    @Test
-    public void testNoApps() {
-        CacheQuotaServiceImpl service = getService();
-        assertEquals(service.onComputeCacheQuotaHints(new ArrayList()).size(), 0);
-    }
-
-    @Test
-    public void testOneApp() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        CacheQuotaHint request = makeNewRequest("com.test", sTestVolUuid, 1001, 100L);
-        requests.add(request);
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500L);
-    }
-
-    @Test
-    public void testTwoAppsOneVolume() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        // Note that the sizes are just the cache area split up.
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(883);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500 - 883);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumes() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testMultipleAppsPerUidIsCollated() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumesTwoUuidsShouldBESeparate() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    private CacheQuotaHint makeNewRequest(String packageName, String uuid, int uid, long foregroundTime) {
-        UsageStats stats = new UsageStats();
-        stats.mPackageName = packageName;
-        stats.mTotalTimeInForeground = foregroundTime;
-        return new CacheQuotaHint.Builder()
-                .setVolumeUuid(uuid).setUid(uid).setUsageStats(stats).setQuota(-1).build();
-    }
-}
diff --git a/packages/NetworkPermissionConfig/Android.bp b/packages/NetworkPermissionConfig/Android.bp
deleted file mode 100644
index 6e50459..0000000
--- a/packages/NetworkPermissionConfig/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-java_defaults {
-    name: "NetworkPermissionConfigDefaults",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    min_sdk_version: "28",
-    privileged: true,
-    manifest: "AndroidManifest.xml",
-}
-
-// Stub APK to define permissions for NetworkStack
-android_app {
-    name: "NetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative stub APK signed with platform certificate. To use with InProcessNetworkStack.
-android_app {
-    name: "PlatformNetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "platform",
-    overrides: ["NetworkPermissionConfig"],
-}
diff --git a/packages/NetworkPermissionConfig/AndroidManifest.xml b/packages/NetworkPermissionConfig/AndroidManifest.xml
deleted file mode 100644
index 34f987c..0000000
--- a/packages/NetworkPermissionConfig/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.networkstack.permissionconfig"
-    android:sharedUserId="android.uid.networkstack"
-    android:versionCode="11"
-    android:versionName="Q-initial">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <!--
-    This package only exists to define the below permissions, and enforce that they are only
-    granted to apps sharing the same signature.
-    Permissions defined here are intended to be used only by the NetworkStack: both
-    NetworkStack and this stub APK are to be signed with a dedicated certificate to ensure
-    that, with the below permissions being signature permissions.
-
-    This APK *must* be installed, even if the NetworkStack app is not installed, because otherwise,
-    any application will be able to define this permission and the system will give that application
-    full access to the network stack.
-     -->
-    <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
-                android:protectionLevel="signature"/>
-
-    <application android:name="com.android.server.NetworkPermissionConfig"/>
-</manifest>
diff --git a/packages/NetworkPermissionConfig/OWNERS b/packages/NetworkPermissionConfig/OWNERS
deleted file mode 100644
index ceaa065..0000000
--- a/packages/NetworkPermissionConfig/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-baligh@google.com
-lorenzo@google.com
-delphij@google.com
diff --git a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
deleted file mode 100644
index c904e23..0000000
--- a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.app.Application;
-
-/**
- * Empty application for NetworkPermissionConfig that only exists because
- * soong builds complain if APKs have no source file.
- */
-public class NetworkPermissionConfig extends Application {
-}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
deleted file mode 100644
index 3b644e9..0000000
--- a/packages/NetworkStack/Android.bp
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-// Copyright (C) 2018 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.
-//
-
-java_library {
-    name: "captiveportal-lib",
-    srcs: ["common/**/*.java"],
-    libs: [
-        "androidx.annotation_annotation",
-    ],
-    sdk_version: "system_current",
-}
-
-java_defaults {
-    name: "NetworkStackCommon",
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-}
-
-// Library including the network stack, used to compile both variants of the network stack
-android_library {
-    name: "NetworkStackBase",
-    defaults: ["NetworkStackCommon"],
-    srcs: [
-        "src/**/*.java",
-        ":framework-networkstack-shared-srcs",
-        ":services-networkstack-shared-srcs",
-        ":statslog-networkstack-java-gen",
-    ],
-    static_libs: [
-        "androidx.annotation_annotation",
-        "ipmemorystore-client",
-        "netd_aidl_interface-V2-java",
-        "networkstack-aidl-interfaces-V3-java",
-        "datastallprotosnano",
-        "networkstackprotosnano",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifestBase.xml",
-}
-
-cc_library_shared {
-    name: "libnetworkstackutilsjni",
-    srcs: [
-        "jni/network_stack_utils_jni.cpp"
-    ],
-    sdk_version: "current",
-    shared_libs: [
-        "liblog",
-        "libnativehelper_compat_libc++",
-    ],
-
-    // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
-    //   java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
-    // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
-    // build because soong complains of:
-    //   module NetworkStack missing dependencies: libc++_shared
-    //
-    // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
-    // we depend on do not dynamically link libc++. This is currently the case, because liblog is
-    // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
-    //
-    // TODO: find a better solution for this in R.
-    stl: "c++_static",
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-    ],
-}
-
-java_defaults {
-    name: "NetworkStackAppCommon",
-    defaults: ["NetworkStackCommon"],
-    privileged: true,
-    static_libs: [
-        "NetworkStackBase",
-    ],
-    jni_libs: [
-        "libnativehelper_compat_libc++",
-        "libnetworkstackutilsjni",
-    ],
-    // Resources already included in NetworkStackBase
-    resource_dirs: [],
-    jarjar_rules: "jarjar-rules-shared.txt",
-    optimize: {
-        proguard_flags_files: ["proguard.flags"],
-    },
-}
-
-// Non-updatable network stack running in the system server process for devices not using the module
-android_app {
-    name: "InProcessNetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "platform",
-    manifest: "AndroidManifest_InProcess.xml",
-    // InProcessNetworkStack is a replacement for NetworkStack
-    overrides: ["NetworkStack"],
-    // The permission configuration *must* be included to ensure security of the device
-    required: ["PlatformNetworkPermissionConfig"],
-}
-
-// Updatable network stack packaged as an application
-android_app {
-    name: "NetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "networkstack",
-    manifest: "AndroidManifest.xml",
-    use_embedded_native_libs: true,
-    // The permission configuration *must* be included to ensure security of the device
-    required: ["NetworkPermissionConfig"],
-}
-
-genrule {
-    name: "statslog-networkstack-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module network_stack" +
-         " --javaPackage com.android.networkstack.metrics --javaClass NetworkStackStatsLog",
-    out: ["com/android/networkstack/metrics/NetworkStackStatsLog.java"],
-}
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
deleted file mode 100644
index bb838a2..0000000
--- a/packages/NetworkStack/AndroidManifest.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack"
-          android:sharedUserId="android.uid.networkstack">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-
-    <!-- Permissions must be defined here, and not in the base manifest, as the network stack
-         running in the system server process does not need any permission, and having privileged
-         permissions added would cause crashes on startup unless they are also added to the
-         privileged permissions whitelist for that package. -->
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <!-- Send latency broadcast as current user -->
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
-    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-    <!-- Signature permission defined in NetworkStackStub -->
-    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-    <application
-        android:extractNativeLibs="false"
-        android:persistent="true">
-        <service android:name="com.android.server.NetworkStackService">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml
deleted file mode 100644
index 69a4da4..0000000
--- a/packages/NetworkStack/AndroidManifestBase.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack"
-          android:versionCode="11"
-          android:versionName="Q-initial">
-    <application
-        android:label="NetworkStack"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true"
-        android:usesCleartextTraffic="true">
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifest_InProcess.xml b/packages/NetworkStack/AndroidManifest_InProcess.xml
deleted file mode 100644
index 2778a2a..0000000
--- a/packages/NetworkStack/AndroidManifest_InProcess.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack.inprocess"
-          android:sharedUserId="android.uid.system"
-          android:process="system">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <application>
-        <service android:name="com.android.server.NetworkStackService" android:process="system">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector.InProcess"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:process="system"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/OWNERS b/packages/NetworkStack/OWNERS
deleted file mode 100644
index 09dd8f8..0000000
--- a/packages/NetworkStack/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-lorenzo@google.com
-reminv@google.com
-baligh@google.com
-delphij@google.com
diff --git a/packages/NetworkStack/TEST_MAPPING b/packages/NetworkStack/TEST_MAPPING
deleted file mode 100644
index fe9731fe..0000000
--- a/packages/NetworkStack/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "NetworkStackTests"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/NetworkStack/common/CaptivePortalProbeResult.java b/packages/NetworkStack/common/CaptivePortalProbeResult.java
deleted file mode 100644
index 48cd48b..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeResult.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 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.captiveportal;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Result of calling isCaptivePortal().
- * @hide
- */
-public final class CaptivePortalProbeResult {
-    public static final int SUCCESS_CODE = 204;
-    public static final int FAILED_CODE = 599;
-    public static final int PORTAL_CODE = 302;
-    // Set partial connectivity http response code to -1 to prevent conflict with the other http
-    // response codes. Besides the default http response code of probe result is set as 599 in
-    // NetworkMonitor#sendParallelHttpProbes(), so response code will be set as -1 only when
-    // NetworkMonitor detects partial connectivity.
-    /**
-     * @hide
-     */
-    public static final int PARTIAL_CODE = -1;
-
-    @NonNull
-    public static final CaptivePortalProbeResult FAILED = new CaptivePortalProbeResult(FAILED_CODE);
-    @NonNull
-    public static final CaptivePortalProbeResult SUCCESS =
-            new CaptivePortalProbeResult(SUCCESS_CODE);
-    public static final CaptivePortalProbeResult PARTIAL =
-            new CaptivePortalProbeResult(PARTIAL_CODE);
-
-    private final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
-    @Nullable
-    public final String redirectUrl;      // Redirect destination returned from Internet probe.
-    @Nullable
-    public final String detectUrl;        // URL where a 204 response code indicates
-                                          // captive portal has been appeased.
-    @Nullable
-    public final CaptivePortalProbeSpec probeSpec;
-
-    public CaptivePortalProbeResult(int httpResponseCode) {
-        this(httpResponseCode, null, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl) {
-        this(httpResponseCode, redirectUrl, detectUrl, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec) {
-        mHttpResponseCode = httpResponseCode;
-        this.redirectUrl = redirectUrl;
-        this.detectUrl = detectUrl;
-        this.probeSpec = probeSpec;
-    }
-
-    public boolean isSuccessful() {
-        return mHttpResponseCode == SUCCESS_CODE;
-    }
-
-    public boolean isPortal() {
-        return !isSuccessful() && (mHttpResponseCode >= 200) && (mHttpResponseCode <= 399);
-    }
-
-    public boolean isFailed() {
-        return !isSuccessful() && !isPortal();
-    }
-
-    public boolean isPartialConnectivity() {
-        return mHttpResponseCode == PARTIAL_CODE;
-    }
-}
diff --git a/packages/NetworkStack/common/CaptivePortalProbeSpec.java b/packages/NetworkStack/common/CaptivePortalProbeSpec.java
deleted file mode 100644
index bf983a5..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeSpec.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2018 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.captiveportal;
-
-import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE;
-import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/** @hide */
-public abstract class CaptivePortalProbeSpec {
-    private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName();
-    private static final String REGEX_SEPARATOR = "@@/@@";
-    private static final String SPEC_SEPARATOR = "@@,@@";
-
-    private final String mEncodedSpec;
-    private final URL mUrl;
-
-    CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) {
-        mEncodedSpec = checkNotNull(encodedSpec);
-        mUrl = checkNotNull(url);
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}.
-     *
-     * <p>The valid format is a URL followed by two regular expressions, each separated by "@@/@@".
-     * @throws MalformedURLException The URL has invalid format for {@link URL#URL(String)}.
-     * @throws ParseException The string is empty, does not match the above format, or a regular
-     * expression is invalid for {@link Pattern#compile(String)}.
-     * @hide
-     */
-    @VisibleForTesting
-    @NonNull
-    public static CaptivePortalProbeSpec parseSpec(@NonNull String spec) throws ParseException,
-            MalformedURLException {
-        if (TextUtils.isEmpty(spec)) {
-            throw new ParseException("Empty probe spec", 0 /* errorOffset */);
-        }
-
-        String[] splits = TextUtils.split(spec, REGEX_SEPARATOR);
-        if (splits.length != 3) {
-            throw new ParseException("Probe spec does not have 3 parts", 0 /* errorOffset */);
-        }
-
-        final int statusRegexPos = splits[0].length() + REGEX_SEPARATOR.length();
-        final int locationRegexPos = statusRegexPos + splits[1].length() + REGEX_SEPARATOR.length();
-        final Pattern statusRegex = parsePatternIfNonEmpty(splits[1], statusRegexPos);
-        final Pattern locationRegex = parsePatternIfNonEmpty(splits[2], locationRegexPos);
-
-        return new RegexMatchProbeSpec(spec, new URL(splits[0]), statusRegex, locationRegex);
-    }
-
-    @Nullable
-    private static Pattern parsePatternIfNonEmpty(@Nullable String pattern, int pos)
-            throws ParseException {
-        if (TextUtils.isEmpty(pattern)) {
-            return null;
-        }
-        try {
-            return Pattern.compile(pattern);
-        } catch (PatternSyntaxException e) {
-            throw new ParseException(
-                    String.format("Invalid status pattern [%s]: %s", pattern, e),
-                    pos /* errorOffset */);
-        }
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}, or return a fallback spec
-     * based on the status code of the provided URL if the spec cannot be parsed.
-     */
-    @Nullable
-    public static CaptivePortalProbeSpec parseSpecOrNull(@Nullable String spec) {
-        if (spec != null) {
-            try {
-                return parseSpec(spec);
-            } catch (ParseException | MalformedURLException e) {
-                Log.e(TAG, "Invalid probe spec: " + spec, e);
-                // Fall through
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Parse a config String to build an array of {@link CaptivePortalProbeSpec}.
-     *
-     * <p>Each spec is separated by @@,@@ and follows the format for {@link #parseSpec(String)}.
-     * <p>This method does not throw but ignores any entry that could not be parsed.
-     */
-    @NonNull
-    public static Collection<CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(
-            @NonNull String settingsVal) {
-        List<CaptivePortalProbeSpec> specs = new ArrayList<>();
-        if (settingsVal != null) {
-            for (String spec : TextUtils.split(settingsVal, SPEC_SEPARATOR)) {
-                try {
-                    specs.add(parseSpec(spec));
-                } catch (ParseException | MalformedURLException e) {
-                    Log.e(TAG, "Invalid probe spec: " + spec, e);
-                }
-            }
-        }
-
-        if (specs.isEmpty()) {
-            Log.e(TAG, String.format("could not create any validation spec from %s", settingsVal));
-        }
-        return specs;
-    }
-
-    /**
-     * Get the probe result from HTTP status and location header.
-     */
-    @NonNull
-    public abstract CaptivePortalProbeResult getResult(int status, @Nullable String locationHeader);
-
-    @NonNull
-    public String getEncodedSpec() {
-        return mEncodedSpec;
-    }
-
-    @NonNull
-    public URL getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * Implementation of {@link CaptivePortalProbeSpec} that is based on configurable regular
-     * expressions for the HTTP status code and location header (if any). Matches indicate that
-     * the page is not a portal.
-     * This probe cannot fail: it always returns SUCCESS_CODE or PORTAL_CODE
-     */
-    private static class RegexMatchProbeSpec extends CaptivePortalProbeSpec {
-        @Nullable
-        final Pattern mStatusRegex;
-        @Nullable
-        final Pattern mLocationHeaderRegex;
-
-        RegexMatchProbeSpec(
-                String spec, URL url, Pattern statusRegex, Pattern locationHeaderRegex) {
-            super(spec, url);
-            mStatusRegex = statusRegex;
-            mLocationHeaderRegex = locationHeaderRegex;
-        }
-
-        @Override
-        public CaptivePortalProbeResult getResult(int status, String locationHeader) {
-            final boolean statusMatch = safeMatch(String.valueOf(status), mStatusRegex);
-            final boolean locationMatch = safeMatch(locationHeader, mLocationHeaderRegex);
-            final int returnCode = statusMatch && locationMatch ? SUCCESS_CODE : PORTAL_CODE;
-            return new CaptivePortalProbeResult(
-                    returnCode, locationHeader, getUrl().toString(), this);
-        }
-    }
-
-    private static boolean safeMatch(@Nullable String value, @Nullable Pattern pattern) {
-        // No value is a match ("no location header" passes the location rule for non-redirects)
-        return pattern == null || TextUtils.isEmpty(value) || pattern.matcher(value).matches();
-    }
-
-    // Throws NullPointerException if the input is null.
-    private static <T> T checkNotNull(T object) {
-        if (object == null) throw new NullPointerException();
-        return object;
-    }
-}
diff --git a/packages/NetworkStack/jarjar-rules-shared.txt b/packages/NetworkStack/jarjar-rules-shared.txt
deleted file mode 100644
index 7346b1a..0000000
--- a/packages/NetworkStack/jarjar-rules-shared.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-rule com.android.internal.util.** android.net.networkstack.util.@1
-
-rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1
-rule android.net.shared.InetAddressUtils* android.net.networkstack.shared.InetAddressUtils@1
-
-# Ignore DhcpResultsParcelable, but jarjar DhcpResults
-# TODO: move DhcpResults into services.net and delete from here
-rule android.net.DhcpResultsParcelable* @0
-rule android.net.DhcpResults* android.net.networkstack.DhcpResults@1
-rule android.net.LocalLog* android.net.networkstack.LocalLog@1
diff --git a/packages/NetworkStack/jni/network_stack_utils_jni.cpp b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
deleted file mode 100644
index f2ba575..0000000
--- a/packages/NetworkStack/jni/network_stack_utils_jni.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2019, 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.
- */
-
-#define LOG_TAG "NetworkStackUtils-JNI"
-
-#include <errno.h>
-#include <jni.h>
-#include <linux/filter.h>
-#include <linux/if_arp.h>
-#include <net/if.h>
-#include <netinet/ether.h>
-#include <netinet/icmp6.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-#include <stdlib.h>
-
-#include <string>
-
-#include <nativehelper/JNIHelp.h>
-#include <android/log.h>
-
-namespace android {
-constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils";
-
-static const uint32_t kEtherTypeOffset = offsetof(ether_header, ether_type);
-static const uint32_t kEtherHeaderLen = sizeof(ether_header);
-static const uint32_t kIPv4Protocol = kEtherHeaderLen + offsetof(iphdr, protocol);
-static const uint32_t kIPv4FlagsOffset = kEtherHeaderLen + offsetof(iphdr, frag_off);
-static const uint32_t kIPv6NextHeader = kEtherHeaderLen + offsetof(ip6_hdr, ip6_nxt);
-static const uint32_t kIPv6PayloadStart = kEtherHeaderLen + sizeof(ip6_hdr);
-static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type);
-static const uint32_t kUDPSrcPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, source);
-static const uint32_t kUDPDstPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, dest);
-static const uint16_t kDhcpClientPort = 68;
-
-static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst) {
-    if (env->GetArrayLength(addr) != len) {
-        return false;
-    }
-    env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
-    return true;
-}
-
-static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
-        jbyteArray ipv4Addr, jstring ifname, jobject javaFd) {
-    arpreq req = {};
-    sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
-    sockaddr& ethAddrStruct = req.arp_ha;
-
-    ethAddrStruct.sa_family = ARPHRD_ETHER;
-    if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
-        return;
-    }
-
-    netAddrStruct.sin_family = AF_INET;
-    if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
-        return;
-    }
-
-    int ifLen = env->GetStringLength(ifname);
-    // IFNAMSIZ includes the terminating NULL character
-    if (ifLen >= IFNAMSIZ) {
-        jniThrowException(env, "java/io/IOException", "ifname too long");
-        return;
-    }
-    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
-
-    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (fd < 0) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
-        return;
-    }
-    // See also: man 7 arp
-    if (ioctl(fd, SIOCSARP, &req)) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
-        return;
-    }
-}
-
-static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, jobject javaFd) {
-    static sock_filter filter_code[] = {
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 6),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 4, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-static void network_stack_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject javaFd,
-        jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachRaFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    static sock_filter filter_code[] = {
-        // Check IPv6 Next Header is ICMPv6.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    IPPROTO_ICMPV6, 0, 3),
-
-        // Check ICMPv6 type is Router Advertisement.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    ND_ROUTER_ADVERT, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-// TODO: Move all this filter code into libnetutils.
-static void network_stack_utils_attachControlPacketFilter(
-        JNIEnv *env, jobject clazz, jobject javaFd, jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachControlPacketFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    // Capture all:
-    //     - ARPs
-    //     - DHCPv4 packets
-    //     - Router Advertisements & Solicitations
-    //     - Neighbor Advertisements & Solicitations
-    //
-    // tcpdump:
-    //     arp or
-    //     '(ip and udp port 68)' or
-    //     '(icmp6 and ip6[40] >= 133 and ip6[40] <= 136)'
-    static sock_filter filter_code[] = {
-        // Load the link layer next payload field.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS,  kEtherTypeOffset),
-
-        // Accept all ARP.
-        // TODO: Figure out how to better filter ARPs on noisy networks.
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_ARP, 16, 0),
-
-        // If IPv4:
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IP, 0, 9),
-
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 14),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 12, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the source port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPSrcPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 8, 0),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 6, 7),
-
-        // IPv6 ...
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IPV6, 0, 6),
-        // ... check IPv6 Next Header is ICMPv6 (ignore fragments), ...
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_ICMPV6, 0, 4),
-        // ... and check the ICMPv6 type is one of RS/RA/NS/NA.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JGE  | BPF_K,   ND_ROUTER_SOLICIT, 0, 2),
-        BPF_JUMP(BPF_JMP | BPF_JGT  | BPF_K,   ND_NEIGHBOR_ADVERT, 1, 0),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gNetworkStackUtilsMethods[] = {
-    /* name, signature, funcPtr */
-    { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_addArpEntry },
-    { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachDhcpFilter },
-    { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachRaFilter },
-    { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachControlPacketFilter },
-};
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (jniRegisterNativeMethods(env, NETWORKSTACKUTILS_PKG_NAME,
-            gNetworkStackUtilsMethods, NELEM(gNetworkStackUtilsMethods)) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-
-}
-}; // namespace android
diff --git a/packages/NetworkStack/proguard.flags b/packages/NetworkStack/proguard.flags
deleted file mode 100644
index c60f6c3..0000000
--- a/packages/NetworkStack/proguard.flags
+++ /dev/null
@@ -1,9 +0,0 @@
--keepclassmembers class android.net.ip.IpClient {
-    static final int CMD_*;
-    static final int EVENT_*;
-}
-
--keepclassmembers class android.net.dhcp.DhcpClient {
-    static final int CMD_*;
-    static final int EVENT_*;
-}
diff --git a/packages/NetworkStack/res/values-mcc460/config.xml b/packages/NetworkStack/res/values-mcc460/config.xml
deleted file mode 100644
index fd4a848..0000000
--- a/packages/NetworkStack/res/values-mcc460/config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- Network validation URL configuration for devices using a Chinese SIM (MCC 460).
-         The below URLs are often whitelisted by captive portals, so they should not be used in the
-         general case as this could degrade the user experience (portals not detected properly).
-         However in China the default URLs are not accessible in general. The below alternatives
-         should allow users to connect to local networks normally. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://connectivitycheck.gstatic.com/generate_204</string>
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.googleapis.cn/generate_204</item>
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
deleted file mode 100644
index 478ed6b..0000000
--- a/packages/NetworkStack/res/values/config.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!--
-    OEMs that wish to change the below settings must do so via a runtime resource overlay package
-    and *NOT* by changing this file. This file is part of the NetworkStack mainline module.
-    The overlays must apply to the config_* values, not the default_* values. The default_*
-    values are meant to be the default when no other configuration is specified.
-    -->
-
-    <!-- DNS probe timeout for network validation. Enough for 3 DNS queries 5 seconds apart. -->
-    <integer name="default_captive_portal_dns_probe_timeout">12500</integer>
-
-    <!-- HTTP URL for network validation, to use for detecting captive portals. -->
-    <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
-
-    <!-- HTTPS URL for network validation, to use for confirming internet connectivity. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://www.google.com/generate_204</string>
-
-    <!-- List of fallback URLs to use for detecting captive portals. -->
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.google.com/gen_204</item>
-        <item>http://play.googleapis.com/generate_204</item>
-    </string-array>
-
-    <!-- List of fallback probe specs to use for detecting captive portals.
-         This is an alternative to fallback URLs that provides more flexibility on detection rules.
-         Empty, so unused by default. -->
-    <string-array name="default_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Configuration hooks for the above settings.
-         Empty by default but may be overridden by RROs. -->
-    <integer name="config_captive_portal_dns_probe_timeout"></integer>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_http_url" translatable="false"></string>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_https_url" translatable="false"></string>
-    <string-array name="config_captive_portal_fallback_urls" translatable="false">
-    </string-array>
-    <string-array name="config_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Customized default DNS Servers address. -->
-    <string-array name="config_default_dns_servers" translatable="false">
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java b/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
deleted file mode 100644
index 41715b2..0000000
--- a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 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.NonNull;
-import android.content.Context;
-
-import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-
-/**
- * service used to communicate with the ip memory store service in network stack,
- * which is running in the same module.
- * @see com.android.server.connectivity.ipmemorystore.IpMemoryStoreService
- * @hide
- */
-public class NetworkStackIpMemoryStore extends IpMemoryStoreClient {
-    @NonNull private final IIpMemoryStore mService;
-
-    public NetworkStackIpMemoryStore(@NonNull final Context context,
-            @NonNull final IIpMemoryStore service) {
-        super(context);
-        mService = service;
-    }
-
-    @Override
-    protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
-        cb.accept(mService);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
deleted file mode 100644
index f054319..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ /dev/null
@@ -1,1981 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_RAW;
-
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.ApfProgramEvent;
-import android.net.metrics.ApfStats;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * For networks that support packet filtering via APF programs, {@code ApfFilter}
- * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
- * filter out redundant duplicate ones.
- *
- * Threading model:
- * A collection of RAs we've received is kept in mRas. Generating APF programs uses mRas to
- * know what RAs to filter for, thus generating APF programs is dependent on mRas.
- * mRas can be accessed by multiple threads:
- * - ReceiveThread, which listens for RAs and adds them to mRas, and generates APF programs.
- * - callers of:
- *    - setMulticastFilter(), which can cause an APF program to be generated.
- *    - dump(), which dumps mRas among other things.
- *    - shutdown(), which clears mRas.
- * So access to mRas is synchronized.
- *
- * @hide
- */
-public class ApfFilter {
-
-    // Helper class for specifying functional filter parameters.
-    public static class ApfConfiguration {
-        public ApfCapabilities apfCapabilities;
-        public boolean multicastFilter;
-        public boolean ieee802_3Filter;
-        public int[] ethTypeBlackList;
-    }
-
-    // Enums describing the outcome of receiving an RA packet.
-    private static enum ProcessRaResult {
-        MATCH,          // Received RA matched a known RA
-        DROPPED,        // Received RA ignored due to MAX_RAS
-        PARSE_ERROR,    // Received RA could not be parsed
-        ZERO_LIFETIME,  // Received RA had 0 lifetime
-        UPDATE_NEW_RA,  // APF program updated for new RA
-        UPDATE_EXPIRY   // APF program updated for expiry
-    }
-
-    /**
-     * APF packet counters.
-     *
-     * Packet counters are 32bit big-endian values, and allocated near the end of the APF data
-     * buffer, using negative byte offsets, where -4 is equivalent to maximumApfProgramSize - 4,
-     * the last writable 32bit word.
-     */
-    @VisibleForTesting
-    public static enum Counter {
-        RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
-        TOTAL_PACKETS,
-        PASSED_ARP,
-        PASSED_DHCP,
-        PASSED_IPV4,
-        PASSED_IPV6_NON_ICMP,
-        PASSED_IPV4_UNICAST,
-        PASSED_IPV6_ICMP,
-        PASSED_IPV6_UNICAST_NON_ICMP,
-        PASSED_ARP_NON_IPV4,
-        PASSED_ARP_UNKNOWN,
-        PASSED_ARP_UNICAST_REPLY,
-        PASSED_NON_IP_UNICAST,
-        DROPPED_ETH_BROADCAST,
-        DROPPED_RA,
-        DROPPED_GARP_REPLY,
-        DROPPED_ARP_OTHER_HOST,
-        DROPPED_IPV4_L2_BROADCAST,
-        DROPPED_IPV4_BROADCAST_ADDR,
-        DROPPED_IPV4_BROADCAST_NET,
-        DROPPED_IPV4_MULTICAST,
-        DROPPED_IPV6_ROUTER_SOLICITATION,
-        DROPPED_IPV6_MULTICAST_NA,
-        DROPPED_IPV6_MULTICAST,
-        DROPPED_IPV6_MULTICAST_PING,
-        DROPPED_IPV6_NON_ICMP_MULTICAST,
-        DROPPED_802_3_FRAME,
-        DROPPED_ETHERTYPE_BLACKLISTED,
-        DROPPED_ARP_REPLY_SPA_NO_HOST,
-        DROPPED_IPV4_KEEPALIVE_ACK,
-        DROPPED_IPV6_KEEPALIVE_ACK,
-        DROPPED_IPV4_NATT_KEEPALIVE;
-
-        // Returns the negative byte offset from the end of the APF data segment for
-        // a given counter.
-        public int offset() {
-            return - this.ordinal() * 4;  // Currently, all counters are 32bit long.
-        }
-
-        // Returns the total size of the data segment in bytes.
-        public static int totalSize() {
-            return (Counter.class.getEnumConstants().length - 1) * 4;
-        }
-    }
-
-    /**
-     * When APFv4 is supported, loads R1 with the offset of the specified counter.
-     */
-    private void maybeSetupCounter(ApfGenerator gen, Counter c) {
-        if (mApfCapabilities.hasDataAccess()) {
-            gen.addLoadImmediate(Register.R1, c.offset());
-        }
-    }
-
-    // When APFv4 is supported, these point to the trampolines generated by emitEpilogue().
-    // Otherwise, they're just aliases for PASS_LABEL and DROP_LABEL.
-    private final String mCountAndPassLabel;
-    private final String mCountAndDropLabel;
-
-    // Thread to listen for RAs.
-    @VisibleForTesting
-    class ReceiveThread extends Thread {
-        private final byte[] mPacket = new byte[1514];
-        private final FileDescriptor mSocket;
-        private final long mStart = SystemClock.elapsedRealtime();
-
-        private int mReceivedRas = 0;
-        private int mMatchingRas = 0;
-        private int mDroppedRas = 0;
-        private int mParseErrors = 0;
-        private int mZeroLifetimeRas = 0;
-        private int mProgramUpdates = 0;
-
-        private volatile boolean mStopped;
-
-        public ReceiveThread(FileDescriptor socket) {
-            mSocket = socket;
-        }
-
-        public void halt() {
-            mStopped = true;
-            // Interrupts the read() call the thread is blocked in.
-            NetworkStackUtils.closeSocketQuietly(mSocket);
-        }
-
-        @Override
-        public void run() {
-            log("begin monitoring");
-            while (!mStopped) {
-                try {
-                    int length = Os.read(mSocket, mPacket, 0, mPacket.length);
-                    updateStats(processRa(mPacket, length));
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                    }
-                }
-            }
-            logStats();
-        }
-
-        private void updateStats(ProcessRaResult result) {
-            mReceivedRas++;
-            switch(result) {
-                case MATCH:
-                    mMatchingRas++;
-                    return;
-                case DROPPED:
-                    mDroppedRas++;
-                    return;
-                case PARSE_ERROR:
-                    mParseErrors++;
-                    return;
-                case ZERO_LIFETIME:
-                    mZeroLifetimeRas++;
-                    return;
-                case UPDATE_EXPIRY:
-                    mMatchingRas++;
-                    mProgramUpdates++;
-                    return;
-                case UPDATE_NEW_RA:
-                    mProgramUpdates++;
-                    return;
-            }
-        }
-
-        private void logStats() {
-            final long nowMs = SystemClock.elapsedRealtime();
-            synchronized (this) {
-                final ApfStats stats = new ApfStats.Builder()
-                        .setReceivedRas(mReceivedRas)
-                        .setMatchingRas(mMatchingRas)
-                        .setDroppedRas(mDroppedRas)
-                        .setParseErrors(mParseErrors)
-                        .setZeroLifetimeRas(mZeroLifetimeRas)
-                        .setProgramUpdates(mProgramUpdates)
-                        .setDurationMs(nowMs - mStart)
-                        .setMaxProgramSize(mApfCapabilities.maximumApfProgramSize)
-                        .setProgramUpdatesAll(mNumProgramUpdates)
-                        .setProgramUpdatesAllowingMulticast(mNumProgramUpdatesAllowingMulticast)
-                        .build();
-                mMetricsLog.log(stats);
-                logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS);
-            }
-        }
-    }
-
-    private static final String TAG = "ApfFilter";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int ETH_HEADER_LEN = 14;
-    private static final int ETH_DEST_ADDR_OFFSET = 0;
-    private static final int ETH_ETHERTYPE_OFFSET = 12;
-    private static final int ETH_TYPE_MIN = 0x0600;
-    private static final int ETH_TYPE_MAX = 0xFFFF;
-    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
-            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-    // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
-    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
-    // Endianness is not an issue for this constant because the APF interpreter always operates in
-    // network byte order.
-    private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
-    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
-    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
-    private static final int IPV4_ANY_HOST_ADDRESS = 0;
-    private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255
-    private static final int IPV4_HEADER_LEN = 20; // Without options
-
-    // Traffic class and Flow label are not byte aligned. Luckily we
-    // don't care about either value so we'll consider bytes 1-3 of the
-    // IPv6 header as don't care.
-    private static final int IPV6_FLOW_LABEL_OFFSET = ETH_HEADER_LEN + 1;
-    private static final int IPV6_FLOW_LABEL_LEN = 3;
-    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
-    private static final int IPV6_HEADER_LEN = 40;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-
-    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int UDP_HEADER_LEN = 8;
-
-    private static final int TCP_HEADER_SIZE_OFFSET = 12;
-
-    private static final int DHCP_CLIENT_PORT = 68;
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
-
-    private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-    };
-    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
-    // Opcode: ARP request (0x0001), ARP reply (0x0002)
-    private static final short ARP_OPCODE_REQUEST = 1;
-    private static final short ARP_OPCODE_REPLY = 2;
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-    // Do not log ApfProgramEvents whose actual lifetimes was less than this.
-    private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
-    // Limit on the Black List size to cap on program usage for this
-    // TODO: Select a proper max length
-    private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
-
-    private final ApfCapabilities mApfCapabilities;
-    private final IpClientCallbacksWrapper mIpClientCallback;
-    private final InterfaceParams mInterfaceParams;
-    private final IpConnectivityLog mMetricsLog;
-
-    @VisibleForTesting
-    byte[] mHardwareAddress;
-    @VisibleForTesting
-    ReceiveThread mReceiveThread;
-    @GuardedBy("this")
-    private long mUniqueCounter;
-    @GuardedBy("this")
-    private boolean mMulticastFilter;
-    @GuardedBy("this")
-    private boolean mInDozeMode;
-    private final boolean mDrop802_3Frames;
-    private final int[] mEthTypeBlackList;
-
-    // Detects doze mode state transitions.
-    private final BroadcastReceiver mDeviceIdleReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
-                PowerManager powerManager =
-                        (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-                final boolean deviceIdle = powerManager.isDeviceIdleMode();
-                setDozeMode(deviceIdle);
-            }
-        }
-    };
-    private final Context mContext;
-
-    // Our IPv4 address, if we have just one, otherwise null.
-    @GuardedBy("this")
-    private byte[] mIPv4Address;
-    // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null.
-    @GuardedBy("this")
-    private int mIPv4PrefixLength;
-
-    @VisibleForTesting
-    ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams,
-            IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) {
-        mApfCapabilities = config.apfCapabilities;
-        mIpClientCallback = ipClientCallback;
-        mInterfaceParams = ifParams;
-        mMulticastFilter = config.multicastFilter;
-        mDrop802_3Frames = config.ieee802_3Filter;
-        mContext = context;
-
-        if (mApfCapabilities.hasDataAccess()) {
-            mCountAndPassLabel = "countAndPass";
-            mCountAndDropLabel = "countAndDrop";
-        } else {
-            // APFv4 unsupported: turn jumps to the counter trampolines to immediately PASS or DROP,
-            // preserving the original pre-APFv4 behavior.
-            mCountAndPassLabel = ApfGenerator.PASS_LABEL;
-            mCountAndDropLabel = ApfGenerator.DROP_LABEL;
-        }
-
-        // Now fill the black list from the passed array
-        mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
-
-        mMetricsLog = log;
-
-        // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
-        maybeStartFilter();
-
-        // Listen for doze-mode transition changes to enable/disable the IPv6 multicast filter.
-        mContext.registerReceiver(mDeviceIdleReceiver,
-                new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
-    }
-
-    public synchronized void setDataSnapshot(byte[] data) {
-        mDataSnapshot = data;
-    }
-
-    private void log(String s) {
-        Log.d(TAG, "(" + mInterfaceParams.name + "): " + s);
-    }
-
-    @GuardedBy("this")
-    private long getUniqueNumberLocked() {
-        return mUniqueCounter++;
-    }
-
-    @GuardedBy("this")
-    private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) {
-        ArrayList<Integer> bl = new ArrayList<Integer>();
-
-        for (int p : ethTypeBlackList) {
-            // Check if the protocol is a valid ether type
-            if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) {
-                continue;
-            }
-
-            // Check if the protocol is not repeated in the passed array
-            if (bl.contains(p)) {
-                continue;
-            }
-
-            // Check if list reach its max size
-            if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) {
-                Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() +
-                        ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols");
-                break;
-            }
-
-            // Now add the protocol to the list
-            bl.add(p);
-        }
-
-        return bl.stream().mapToInt(Integer::intValue).toArray();
-    }
-
-    /**
-     * Attempt to start listening for RAs and, if RAs are received, generating and installing
-     * filters to ignore useless RAs.
-     */
-    @VisibleForTesting
-    void maybeStartFilter() {
-        FileDescriptor socket;
-        try {
-            mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
-            synchronized(this) {
-                // Clear the APF memory to reset all counters upon connecting to the first AP
-                // in an SSID. This is limited to APFv4 devices because this large write triggers
-                // a crash on some older devices (b/78905546).
-                if (mApfCapabilities.hasDataAccess()) {
-                    byte[] zeroes = new byte[mApfCapabilities.maximumApfProgramSize];
-                    mIpClientCallback.installPacketFilter(zeroes);
-                }
-
-                // Install basic filters
-                installNewProgramLocked();
-            }
-            socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
-            SocketAddress addr = makePacketSocketAddress(
-                    (short) ETH_P_IPV6, mInterfaceParams.index);
-            Os.bind(socket, addr);
-            NetworkStackUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error starting filter", e);
-            return;
-        }
-        mReceiveThread = new ReceiveThread(socket);
-        mReceiveThread.start();
-    }
-
-    // Returns seconds since device boot.
-    @VisibleForTesting
-    protected long currentTimeSeconds() {
-        return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
-    }
-
-    public static class InvalidRaException extends Exception {
-        public InvalidRaException(String m) {
-            super(m);
-        }
-    }
-
-    // A class to hold information about an RA.
-    @VisibleForTesting
-    class Ra {
-        // From RFC4861:
-        private static final int ICMP6_RA_HEADER_LEN = 16;
-        private static final int ICMP6_RA_CHECKSUM_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-        private static final int ICMP6_RA_CHECKSUM_LEN = 2;
-        private static final int ICMP6_RA_OPTION_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_LEN = 2;
-        // Prefix information option.
-        private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
-        private static final int ICMP6_PREFIX_OPTION_LEN = 32;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN = 4;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN = 4;
-
-        // From RFC6106: Recursive DNS Server option
-        private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-        // From RFC6106: DNS Search List option
-        private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-        // From RFC4191: Route Information option
-        private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-        // Above three options all have the same format:
-        private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
-
-        // Note: mPacket's position() cannot be assumed to be reset.
-        private final ByteBuffer mPacket;
-        // List of binary ranges that include the whole packet except the lifetimes.
-        // Pairs consist of offset and length.
-        private final ArrayList<Pair<Integer, Integer>> mNonLifetimes =
-                new ArrayList<Pair<Integer, Integer>>();
-        // Minimum lifetime in packet
-        long mMinLifetime;
-        // When the packet was last captured, in seconds since Unix Epoch
-        long mLastSeen;
-
-        // For debugging only. Offsets into the packet where PIOs are.
-        private final ArrayList<Integer> mPrefixOptionOffsets = new ArrayList<>();
-
-        // For debugging only. Offsets into the packet where RDNSS options are.
-        private final ArrayList<Integer> mRdnssOptionOffsets = new ArrayList<>();
-
-        // For debugging only. How many times this RA was seen.
-        int seenCount = 0;
-
-        // For debugging only. Returns the hex representation of the last matching packet.
-        String getLastMatchingPacket() {
-            return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(),
-                    false /* lowercase */);
-        }
-
-        // For debugging only. Returns the string representation of the IPv6 address starting at
-        // position pos in the packet.
-        private String IPv6AddresstoString(int pos) {
-            try {
-                byte[] array = mPacket.array();
-                // Can't just call copyOfRange() and see if it throws, because if it reads past the
-                // end it pads with zeros instead of throwing.
-                if (pos < 0 || pos + 16 > array.length || pos + 16 < pos) {
-                    return "???";
-                }
-                byte[] addressBytes = Arrays.copyOfRange(array, pos, pos + 16);
-                InetAddress address = (Inet6Address) InetAddress.getByAddress(addressBytes);
-                return address.getHostAddress();
-            } catch (UnsupportedOperationException e) {
-                // array() failed. Cannot happen, mPacket is array-backed and read-write.
-                return "???";
-            } catch (ClassCastException|UnknownHostException e) {
-                // Cannot happen.
-                return "???";
-            }
-        }
-
-        // Can't be static because it's in a non-static inner class.
-        // TODO: Make this static once RA is its own class.
-        private void prefixOptionToString(StringBuffer sb, int offset) {
-            String prefix = IPv6AddresstoString(offset + 16);
-            int length = getUint8(mPacket, offset + 2);
-            long valid = getUint32(mPacket, offset + 4);
-            long preferred = getUint32(mPacket, offset + 8);
-            sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
-        }
-
-        private void rdnssOptionToString(StringBuffer sb, int offset) {
-            int optLen = getUint8(mPacket, offset + 1) * 8;
-            if (optLen < 24) return;  // Malformed or empty.
-            long lifetime = getUint32(mPacket, offset + 4);
-            int numServers = (optLen - 8) / 16;
-            sb.append("DNS ").append(lifetime).append("s");
-            for (int server = 0; server < numServers; server++) {
-                sb.append(" ").append(IPv6AddresstoString(offset + 8 + 16 * server));
-            }
-        }
-
-        public String toString() {
-            try {
-                StringBuffer sb = new StringBuffer();
-                sb.append(String.format("RA %s -> %s %ds ",
-                        IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
-                        IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
-                        getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
-                for (int i: mPrefixOptionOffsets) {
-                    prefixOptionToString(sb, i);
-                }
-                for (int i: mRdnssOptionOffsets) {
-                    rdnssOptionToString(sb, i);
-                }
-                return sb.toString();
-            } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
-                return "<Malformed RA>";
-            }
-        }
-
-        /**
-         * Add a binary range of the packet that does not include a lifetime to mNonLifetimes.
-         * Assumes mPacket.position() is as far as we've parsed the packet.
-         * @param lastNonLifetimeStart offset within packet of where the last binary range of
-         *                             data not including a lifetime.
-         * @param lifetimeOffset offset from mPacket.position() to the next lifetime data.
-         * @param lifetimeLength length of the next lifetime data.
-         * @return offset within packet of where the next binary range of data not including
-         *         a lifetime. This can be passed into the next invocation of this function
-         *         via {@code lastNonLifetimeStart}.
-         */
-        private int addNonLifetime(int lastNonLifetimeStart, int lifetimeOffset,
-                int lifetimeLength) {
-            lifetimeOffset += mPacket.position();
-            mNonLifetimes.add(new Pair<Integer, Integer>(lastNonLifetimeStart,
-                    lifetimeOffset - lastNonLifetimeStart));
-            return lifetimeOffset + lifetimeLength;
-        }
-
-        private int addNonLifetimeU32(int lastNonLifetimeStart) {
-            return addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN);
-        }
-
-        // Note that this parses RA and may throw InvalidRaException (from
-        // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
-        // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
-        // specifications.
-        Ra(byte[] packet, int length) throws InvalidRaException {
-            if (length < ICMP6_RA_OPTION_OFFSET) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-            mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
-            mLastSeen = currentTimeSeconds();
-
-            // Sanity check packet in case a packet arrives before we attach RA filter
-            // to our packet socket. b/29586253
-            if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
-                    getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
-                    getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMPV6_ROUTER_ADVERTISEMENT) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-
-            RaEvent.Builder builder = new RaEvent.Builder();
-
-            // Ignore the flow label and low 4 bits of traffic class.
-            int lastNonLifetimeStart = addNonLifetime(0,
-                    IPV6_FLOW_LABEL_OFFSET,
-                    IPV6_FLOW_LABEL_LEN);
-
-            // Ignore the checksum.
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_CHECKSUM_OFFSET,
-                    ICMP6_RA_CHECKSUM_LEN);
-
-            // Parse router lifetime
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_ROUTER_LIFETIME_OFFSET,
-                    ICMP6_RA_ROUTER_LIFETIME_LEN);
-            builder.updateRouterLifetime(getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET));
-
-            // Ensures that the RA is not truncated.
-            mPacket.position(ICMP6_RA_OPTION_OFFSET);
-            while (mPacket.hasRemaining()) {
-                final int position = mPacket.position();
-                final int optionType = getUint8(mPacket, position);
-                final int optionLength = getUint8(mPacket, position + 1) * 8;
-                long lifetime;
-                switch (optionType) {
-                    case ICMP6_PREFIX_OPTION_TYPE:
-                        // Parse valid lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET);
-                        builder.updatePrefixValidLifetime(lifetime);
-                        // Parse preferred lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET);
-                        builder.updatePrefixPreferredLifetime(lifetime);
-                        mPrefixOptionOffsets.add(position);
-                        break;
-                    // These three options have the same lifetime offset and size, and
-                    // are processed with the same specialized addNonLifetimeU32:
-                    case ICMP6_RDNSS_OPTION_TYPE:
-                        mRdnssOptionOffsets.add(position);
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRdnssLifetime(lifetime);
-                        break;
-                    case ICMP6_ROUTE_INFO_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRouteInfoLifetime(lifetime);
-                        break;
-                    case ICMP6_DNSSL_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateDnsslLifetime(lifetime);
-                        break;
-                    default:
-                        // RFC4861 section 4.2 dictates we ignore unknown options for fowards
-                        // compatibility.
-                        break;
-                }
-                if (optionLength <= 0) {
-                    throw new InvalidRaException(String.format(
-                        "Invalid option length opt=%d len=%d", optionType, optionLength));
-                }
-                mPacket.position(position + optionLength);
-            }
-            // Mark non-lifetime bytes since last lifetime.
-            addNonLifetime(lastNonLifetimeStart, 0, 0);
-            mMinLifetime = minLifetime(packet, length);
-            mMetricsLog.log(builder.build());
-        }
-
-        // Ignoring lifetimes (which may change) does {@code packet} match this RA?
-        boolean matches(byte[] packet, int length) {
-            if (length != mPacket.capacity()) return false;
-            byte[] referencePacket = mPacket.array();
-            for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) {
-                for (int i = nonLifetime.first; i < (nonLifetime.first + nonLifetime.second); i++) {
-                    if (packet[i] != referencePacket[i]) return false;
-                }
-            }
-            return true;
-        }
-
-        // What is the minimum of all lifetimes within {@code packet} in seconds?
-        // Precondition: matches(packet, length) already returned true.
-        long minLifetime(byte[] packet, int length) {
-            long minLifetime = Long.MAX_VALUE;
-            // Wrap packet in ByteBuffer so we can read big-endian values easily
-            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
-            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
-                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
-
-                // The flow label is in mNonLifetimes, but it's not a lifetime.
-                if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                    continue;
-                }
-
-                // The checksum is in mNonLifetimes, but it's not a lifetime.
-                if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                    continue;
-                }
-
-                final int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
-                final long optionLifetime;
-                switch (lifetimeLength) {
-                    case 2:
-                        optionLifetime = getUint16(byteBuffer, offset);
-                        break;
-                    case 4:
-                        optionLifetime = getUint32(byteBuffer, offset);
-                        break;
-                    default:
-                        throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
-                }
-                minLifetime = Math.min(minLifetime, optionLifetime);
-            }
-            return minLifetime;
-        }
-
-        // How many seconds does this RA's have to live, taking into account the fact
-        // that we might have seen it a while ago.
-        long currentLifetime() {
-            return mMinLifetime - (currentTimeSeconds() - mLastSeen);
-        }
-
-        boolean isExpired() {
-            // TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
-            // have to calculate the filter lifetime specially as a fraction of 0 is still 0.
-            return currentLifetime() <= 0;
-        }
-
-        // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
-        // Jump to the next filter if packet doesn't match this RA.
-        @GuardedBy("ApfFilter.this")
-        long generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            String nextFilterLabel = "Ra" + getUniqueNumberLocked();
-            // Skip if packet is not the right size
-            gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-            gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel);
-            int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER);
-            // Skip filter if expired
-            gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-            gen.addJumpIfR0GreaterThan(filterLifetime, nextFilterLabel);
-            for (int i = 0; i < mNonLifetimes.size(); i++) {
-                // Generate code to match the packet bytes
-                Pair<Integer, Integer> nonLifetime = mNonLifetimes.get(i);
-                // Don't generate JNEBS instruction for 0 bytes as it always fails the
-                // ASSERT_FORWARD_IN_PROGRAM(pc + cmp_imm - 1) check where cmp_imm is
-                // the number of bytes to compare. nonLifetime is zero between the
-                // valid and preferred lifetimes in the prefix option.
-                if (nonLifetime.second != 0) {
-                    gen.addLoadImmediate(Register.R0, nonLifetime.first);
-                    gen.addJumpIfBytesNotEqual(Register.R0,
-                            Arrays.copyOfRange(mPacket.array(), nonLifetime.first,
-                                               nonLifetime.first + nonLifetime.second),
-                            nextFilterLabel);
-                }
-                // Generate code to test the lifetimes haven't gone down too far
-                if ((i + 1) < mNonLifetimes.size()) {
-                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
-                    int offset = nonLifetime.first + nonLifetime.second;
-
-                    // Skip the Flow label.
-                    if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                        continue;
-                    }
-                    // Skip the checksum.
-                    if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                        continue;
-                    }
-                    int length = nextNonLifetime.first - offset;
-                    switch (length) {
-                        case 4: gen.addLoad32(Register.R0, offset); break;
-                        case 2: gen.addLoad16(Register.R0, offset); break;
-                        default: throw new IllegalStateException("bogus lifetime size " + length);
-                    }
-                    gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
-                }
-            }
-            maybeSetupCounter(gen, Counter.DROPPED_RA);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-            return filterLifetime;
-        }
-    }
-
-    // TODO: Refactor these subclasses to avoid so much repetition.
-    private abstract static class KeepalivePacket {
-        // Note that the offset starts from IP header.
-        // These must be added ether header length when generating program.
-        static final int IP_HEADER_OFFSET = 0;
-        static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    // A class to hold NAT-T keepalive ack information.
-    private class NattKeepaliveResponse extends KeepalivePacket {
-        static final int UDP_LENGTH_OFFSET = 4;
-        static final int UDP_HEADER_LEN = 8;
-
-        protected class NattKeepaliveResponseData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-
-            NattKeepaliveResponseData(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-            }
-        }
-
-        protected final NattKeepaliveResponseData mPacket;
-        protected final byte[] mSrcDstAddr;
-        protected final byte[] mPortFingerprint;
-        // NAT-T keepalive packet
-        protected final byte[] mPayload = {(byte) 0xff};
-
-        NattKeepaliveResponse(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-            mPacket = new NattKeepaliveResponseData(sentKeepalivePacket);
-            mSrcDstAddr = concatArrays(mPacket.srcAddress, mPacket.dstAddress);
-            mPortFingerprint = generatePortFingerprint(mPacket.srcPort, mPacket.dstPort);
-        }
-
-        byte[] generatePortFingerprint(int srcPort, int dstPort) {
-            final ByteBuffer fp = ByteBuffer.allocate(4);
-            fp.order(ByteOrder.BIG_ENDIAN);
-            fp.putShort((short) srcPort);
-            fp.putShort((short) dstPort);
-            return fp.array();
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // A NAT-T keepalive packet contains 1 byte payload with the value 0xff
-            // Check payload length is 1
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addSwap();
-            gen.addLoad16(Register.R0, IPV4_TOTAL_LENGTH_OFFSET);
-            gen.addNeg(Register.R1);
-            gen.addAddR1();
-            gen.addJumpIfR0NotEquals(1, nextFilterLabel);
-
-            // Check that the ports match
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(ETH_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortFingerprint, nextFilterLabel);
-
-            // Payload offset = R0 + UDP header length
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPayload, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_NATT_KEEPALIVE);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-    }
-
-    // A class to hold TCP keepalive ack information.
-    private abstract static class TcpKeepaliveAck extends KeepalivePacket {
-        protected static class TcpKeepaliveAckData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-            public final int seq;
-            public final int ack;
-
-            // Create the characteristics of the ack packet from the sent keepalive packet.
-            TcpKeepaliveAckData(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-                seq = sentKeepalivePacket.ack;
-                ack = sentKeepalivePacket.seq + 1;
-            }
-        }
-
-        protected final TcpKeepaliveAckData mPacket;
-        protected final byte[] mSrcDstAddr;
-        protected final byte[] mPortSeqAckFingerprint;
-
-        TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) {
-            mPacket = packet;
-            mSrcDstAddr = srcDstAddr;
-            mPortSeqAckFingerprint = generatePortSeqAckFingerprint(mPacket.srcPort,
-                    mPacket.dstPort, mPacket.seq, mPacket.ack);
-        }
-
-        static byte[] generatePortSeqAckFingerprint(int srcPort, int dstPort, int seq, int ack) {
-            final ByteBuffer fp = ByteBuffer.allocate(12);
-            fp.order(ByteOrder.BIG_ENDIAN);
-            fp.putShort((short) srcPort);
-            fp.putShort((short) dstPort);
-            fp.putInt(seq);
-            fp.putInt(ack);
-            return fp.array();
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s , seq=%d, ack=%d",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort),
-                        Integer.toUnsignedLong(mPacket.seq),
-                        Integer.toUnsignedLong(mPacket.ack));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
-
-        TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV4(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // Skip to the next filter if it's not zero-sized :
-            // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0
-            // Load the IP header size into R1
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            // Load the TCP header size into R0 (it's indexed by R1)
-            gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET);
-            // Size offset is in the top nibble, but it must be multiplied by 4, and the two
-            // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2.
-            gen.addRightShift(2);
-            // R0 += R1 -> R0 contains TCP + IP headers length
-            gen.addAddR1();
-            // Load IPv4 total length
-            gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET);
-            gen.addNeg(Register.R0);
-            gen.addAddR1();
-            gen.addJumpIfR0NotEquals(0, nextFilterLabel);
-            // Add IPv4 header length
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-    }
-
-    private class TcpKeepaliveAckV6 extends TcpKeepaliveAck {
-        TcpKeepaliveAckV6(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV6(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            throw new UnsupportedOperationException("IPv6 TCP Keepalive is not supported yet");
-        }
-    }
-
-    // Maximum number of RAs to filter for.
-    private static final int MAX_RAS = 10;
-
-    @GuardedBy("this")
-    private ArrayList<Ra> mRas = new ArrayList<>();
-    @GuardedBy("this")
-    private SparseArray<KeepalivePacket> mKeepalivePackets = new SparseArray<>();
-
-    // There is always some marginal benefit to updating the installed APF program when an RA is
-    // seen because we can extend the program's lifetime slightly, but there is some cost to
-    // updating the program, so don't bother unless the program is going to expire soon. This
-    // constant defines "soon" in seconds.
-    private static final long MAX_PROGRAM_LIFETIME_WORTH_REFRESHING = 30;
-    // We don't want to filter an RA for it's whole lifetime as it'll be expired by the time we ever
-    // see a refresh.  Using half the lifetime might be a good idea except for the fact that
-    // packets may be dropped, so let's use 6.
-    private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
-
-    // When did we last install a filter program? In seconds since Unix Epoch.
-    @GuardedBy("this")
-    private long mLastTimeInstalledProgram;
-    // How long should the last installed filter program live for? In seconds.
-    @GuardedBy("this")
-    private long mLastInstalledProgramMinLifetime;
-    @GuardedBy("this")
-    private ApfProgramEvent.Builder mLastInstallEvent;
-
-    // For debugging only. The last program installed.
-    @GuardedBy("this")
-    private byte[] mLastInstalledProgram;
-
-    /**
-     * For debugging only. Contains the latest APF buffer snapshot captured from the firmware.
-     *
-     * A typical size for this buffer is 4KB. It is present only if the WiFi HAL supports
-     * IWifiStaIface#readApfPacketFilterData(), and the APF interpreter advertised support for
-     * the opcodes to access the data buffer (LDDW and STDW).
-     */
-    @GuardedBy("this") @Nullable
-    private byte[] mDataSnapshot;
-
-    // How many times the program was updated since we started.
-    @GuardedBy("this")
-    private int mNumProgramUpdates = 0;
-    // How many times the program was updated since we started for allowing multicast traffic.
-    @GuardedBy("this")
-    private int mNumProgramUpdatesAllowingMulticast = 0;
-
-    /**
-     * Generate filter code to process ARP packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is ARP
-     */
-    @GuardedBy("this")
-    private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the ARP filter program does:
-        //
-        // if not ARP IPv4
-        //   pass
-        // if not ARP IPv4 reply or request
-        //   pass
-        // if ARP reply source ip is 0.0.0.0
-        //   drop
-        // if unicast ARP reply
-        //   pass
-        // if interface has no IPv4 address
-        //   if target ip is 0.0.0.0
-        //      drop
-        // else
-        //   if target ip is not the interface ip
-        //      drop
-        // pass
-
-        final String checkTargetIPv4 = "checkTargetIPv4";
-
-        // Pass if not ARP IPv4.
-        gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
-        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
-
-        // Pass if unknown ARP opcode.
-        gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
-        gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
-        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
-
-        // Drop if ARP reply source IP is 0.0.0.0
-        gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
-        maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
-        gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-
-        // Pass if unicast reply.
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-
-        // Either a unicast request, a unicast reply, or a broadcast reply.
-        gen.defineLabel(checkTargetIPv4);
-        if (mIPv4Address == null) {
-            // When there is no IPv4 address, drop GARP replies (b/29404209).
-            gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
-            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-        } else {
-            // When there is an IPv4 address, drop unicast/broadcast requests
-            // and broadcast replies with a different target IPv4 address.
-            gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
-            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
-        }
-
-        maybeSetupCounter(gen, Counter.PASSED_ARP);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    /**
-     * Generate filter code to process IPv4 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is IPv4
-     */
-    @GuardedBy("this")
-    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv4 filter program does:
-        //
-        // if filtering multicast (i.e. multicast lock not held):
-        //   if it's DHCP destined to our MAC:
-        //     pass
-        //   if it's L2 broadcast:
-        //     drop
-        //   if it's IPv4 multicast:
-        //     drop
-        //   if it's IPv4 broadcast:
-        //     drop
-        // if keepalive ack
-        //   drop
-        // pass
-
-        if (mMulticastFilter) {
-            final String skipDhcpv4Filter = "skip_dhcp_v4_filter";
-
-            // Pass DHCP addressed to us.
-            // Check it's UDP.
-            gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
-            gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter);
-            // Check it's not a fragment. This matches the BPF filter installed by the DHCP client.
-            gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET);
-            gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter);
-            // Check it's addressed to DHCP client port.
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
-            gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter);
-            // Check it's DHCP to our MAC address.
-            gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
-            // NOTE: Relies on R1 containing IPv4 header offset.
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
-            maybeSetupCounter(gen, Counter.PASSED_DHCP);
-            gen.addJump(mCountAndPassLabel);
-
-            // Drop all multicasts/broadcasts.
-            gen.defineLabel(skipDhcpv4Filter);
-
-            // If IPv4 destination address is in multicast range, drop.
-            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addAnd(0xf0);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
-            gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
-
-            // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
-            gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
-            if (mIPv4Address != null && mIPv4PrefixLength < 31) {
-                maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
-                int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
-                gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
-            }
-
-            // If any TCP keepalive filter matches, drop
-            generateV4KeepaliveFilters(gen);
-
-            // If any NAT-T keepalive filter matches, drop
-            generateV4NattKeepaliveFilters(gen);
-
-            // Otherwise, this is an IPv4 unicast, pass
-            // If L2 broadcast packet, drop.
-            // TODO: can we invert this condition to fall through to the common pass case below?
-            maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
-            gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
-            gen.addJump(mCountAndDropLabel);
-        } else {
-            generateV4KeepaliveFilters(gen);
-            generateV4NattKeepaliveFilters(gen);
-        }
-
-        // Otherwise, pass
-        maybeSetupCounter(gen, Counter.PASSED_IPV4);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    private void generateKeepaliveFilters(ApfGenerator gen, Class<?> filterType, int proto,
-            int offset, String label) throws IllegalInstructionException {
-        final boolean haveKeepaliveResponses = NetworkStackUtils.any(mKeepalivePackets,
-                ack -> filterType.isInstance(ack));
-
-        // If no keepalive packets of this type
-        if (!haveKeepaliveResponses) return;
-
-        // If not the right proto, skip keepalive filters
-        gen.addLoad8(Register.R0, offset);
-        gen.addJumpIfR0NotEquals(proto, label);
-
-        // Drop Keepalive responses
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket response = mKeepalivePackets.valueAt(i);
-            if (filterType.isInstance(response)) response.generateFilterLocked(gen);
-        }
-
-        gen.defineLabel(label);
-    }
-
-    private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV4.class, IPPROTO_TCP, IPV4_PROTOCOL_OFFSET,
-                "skip_v4_keepalive_filter");
-    }
-
-    private void generateV4NattKeepaliveFilters(ApfGenerator gen)
-            throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, NattKeepaliveResponse.class,
-                IPPROTO_UDP, IPV4_PROTOCOL_OFFSET, "skip_v4_nattkeepalive_filter");
-    }
-
-    /**
-     * Generate filter code to process IPv6 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets.
-     * Preconditions:
-     *  - Packet being filtered is IPv6
-     */
-    @GuardedBy("this")
-    private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv6 filter program does:
-        //
-        // if we're dropping multicast
-        //   if it's not IPCMv6 or it's ICMPv6 but we're in doze mode:
-        //     if it's multicast:
-        //       drop
-        //     pass
-        // if it's ICMPv6 RS to any:
-        //   drop
-        // if it's ICMPv6 NA to ff02::1:
-        //   drop
-        // if keepalive ack
-        //   drop
-
-        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
-
-        // Drop multicast if the multicast filter is enabled.
-        if (mMulticastFilter) {
-            final String skipIPv6MulticastFilterLabel = "skipIPv6MulticastFilter";
-            final String dropAllIPv6MulticastsLabel = "dropAllIPv6Multicast";
-
-            // While in doze mode, drop ICMPv6 multicast pings, let the others pass.
-            // While awake, let all ICMPv6 multicasts through.
-            if (mInDozeMode) {
-                // Not ICMPv6? -> Proceed to multicast filtering
-                gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, dropAllIPv6MulticastsLabel);
-
-                // ICMPv6 but not ECHO? -> Skip the multicast filter.
-                // (ICMPv6 ECHO requests will go through the multicast filter below).
-                gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-                gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel);
-            } else {
-                gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel);
-            }
-
-            // Drop all other packets sent to ff00::/8 (multicast prefix).
-            gen.defineLabel(dropAllIPv6MulticastsLabel);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
-            gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
-            // If any keepalive filter matches, drop
-            generateV6KeepaliveFilters(gen);
-            // Not multicast. Pass.
-            maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
-            gen.addJump(mCountAndPassLabel);
-            gen.defineLabel(skipIPv6MulticastFilterLabel);
-        } else {
-            generateV6KeepaliveFilters(gen);
-            // If not ICMPv6, pass.
-            maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
-            gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
-        }
-
-        // If we got this far, the packet is ICMPv6.  Drop some specific types.
-
-        // Add unsolicited multicast neighbor announcements filter
-        String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
-        gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-        // Drop all router solicitations (b/32833400)
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
-        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
-        // If not neighbor announcements, skip filter.
-        gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
-        // If to ff02::1, drop.
-        // TODO: Drop only if they don't contain the address of on-link neighbours.
-        gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
-                skipUnsolicitedMulticastNALabel);
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
-        gen.addJump(mCountAndDropLabel);
-        gen.defineLabel(skipUnsolicitedMulticastNALabel);
-    }
-
-    private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV6.class, IPPROTO_TCP, IPV6_NEXT_HEADER_OFFSET,
-                "skip_v6_keepalive_filter");
-    }
-
-    /**
-     * Begin generating an APF program to:
-     * <ul>
-     * <li>Drop/Pass 802.3 frames (based on policy)
-     * <li>Drop packets with EtherType within the Black List
-     * <li>Drop ARP requests not for us, if mIPv4Address is set,
-     * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
-     * <li>Drop IPv4 multicast packets, if mMulticastFilter,
-     * <li>Pass all other IPv4 packets,
-     * <li>Drop all broadcast non-IP non-ARP packets.
-     * <li>Pass all non-ICMPv6 IPv6 packets,
-     * <li>Pass all non-IPv4 and non-IPv6 packets,
-     * <li>Drop IPv6 ICMPv6 NAs to ff02::1.
-     * <li>Drop IPv6 ICMPv6 RSs.
-     * <li>Filter IPv4 packets (see generateIPv4FilterLocked())
-     * <li>Filter IPv6 packets (see generateIPv6FilterLocked())
-     * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
-     *     insertion of RA filters here, or if there aren't any, just passes the packets.
-     * </ul>
-     */
-    @GuardedBy("this")
-    private ApfGenerator emitPrologueLocked() throws IllegalInstructionException {
-        // This is guaranteed to succeed because of the check in maybeCreate.
-        ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported);
-
-        if (mApfCapabilities.hasDataAccess()) {
-            // Increment TOTAL_PACKETS
-            maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
-            gen.addLoadData(Register.R0, 0);  // load counter
-            gen.addAdd(1);
-            gen.addStoreData(Register.R0, 0);  // write-back counter
-        }
-
-        // Here's a basic summary of what the initial program does:
-        //
-        // if it's a 802.3 Frame (ethtype < 0x0600):
-        //    drop or pass based on configurations
-        // if it has a ether-type that belongs to the black list
-        //    drop
-        // if it's ARP:
-        //   insert ARP filter to drop or pass these appropriately
-        // if it's IPv4:
-        //   insert IPv4 filter to drop or pass these appropriately
-        // if it's not IPv6:
-        //   if it's broadcast:
-        //     drop
-        //   pass
-        // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets
-
-        gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET);
-
-        if (mDrop802_3Frames) {
-            // drop 802.3 frames (ethtype < 0x0600)
-            maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
-            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
-        }
-
-        // Handle ether-type black list
-        maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
-        for (int p : mEthTypeBlackList) {
-            gen.addJumpIfR0Equals(p, mCountAndDropLabel);
-        }
-
-        // Add ARP filters:
-        String skipArpFiltersLabel = "skipArpFilters";
-        gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel);
-        generateArpFilterLocked(gen);
-        gen.defineLabel(skipArpFiltersLabel);
-
-        // Add IPv4 filters:
-        String skipIPv4FiltersLabel = "skipIPv4Filters";
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP filter, since that filter does not fall through, but either drops or
-        // passes.
-        gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel);
-        generateIPv4FilterLocked(gen);
-        gen.defineLabel(skipIPv4FiltersLabel);
-
-        // Check for IPv6:
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP or IPv4 filters, since those filters do not fall through, but either
-        // drop or pass.
-        String ipv6FilterLabel = "IPv6Filters";
-        gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel);
-
-        // Drop non-IP non-ARP broadcasts, pass the rest
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-        maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
-        gen.addJump(mCountAndDropLabel);
-
-        // Add IPv6 filters:
-        gen.defineLabel(ipv6FilterLabel);
-        generateIPv6FilterLocked(gen);
-        return gen;
-    }
-
-    /**
-     * Append packet counting epilogue to the APF program.
-     *
-     * Currently, the epilogue consists of two trampolines which count passed and dropped packets
-     * before jumping to the actual PASS and DROP labels.
-     */
-    @GuardedBy("this")
-    private void emitEpilogue(ApfGenerator gen) throws IllegalInstructionException {
-        // If APFv4 is unsupported, no epilogue is necessary: if execution reached this far, it
-        // will just fall-through to the PASS label.
-        if (!mApfCapabilities.hasDataAccess()) return;
-
-        // Execution will reach the bottom of the program if none of the filters match,
-        // which will pass the packet to the application processor.
-        maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
-
-        // Append the count & pass trampoline, which increments the counter at the data address
-        // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
-        // the entire sequence inline for every counter.
-        gen.defineLabel(mCountAndPassLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.PASS_LABEL);
-
-        // Same as above for the count & drop trampoline.
-        gen.defineLabel(mCountAndDropLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.DROP_LABEL);
-    }
-
-    /**
-     * Generate and install a new filter program.
-     */
-    @GuardedBy("this")
-    @VisibleForTesting
-    void installNewProgramLocked() {
-        purgeExpiredRasLocked();
-        ArrayList<Ra> rasToFilter = new ArrayList<>();
-        final byte[] program;
-        long programMinLifetime = Long.MAX_VALUE;
-        long maximumApfProgramSize = mApfCapabilities.maximumApfProgramSize;
-        if (mApfCapabilities.hasDataAccess()) {
-            // Reserve space for the counters.
-            maximumApfProgramSize -= Counter.totalSize();
-        }
-
-        try {
-            // Step 1: Determine how many RA filters we can fit in the program.
-            ApfGenerator gen = emitPrologueLocked();
-
-            // The epilogue normally goes after the RA filters, but add it early to include its
-            // length when estimating the total.
-            emitEpilogue(gen);
-
-            // Can't fit the program even without any RA filters?
-            if (gen.programLengthOverEstimate() > maximumApfProgramSize) {
-                Log.e(TAG, "Program exceeds maximum size " + maximumApfProgramSize);
-                return;
-            }
-
-            for (Ra ra : mRas) {
-                ra.generateFilterLocked(gen);
-                // Stop if we get too big.
-                if (gen.programLengthOverEstimate() > maximumApfProgramSize) break;
-                rasToFilter.add(ra);
-            }
-
-            // Step 2: Actually generate the program
-            gen = emitPrologueLocked();
-            for (Ra ra : rasToFilter) {
-                programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
-            }
-            emitEpilogue(gen);
-            program = gen.generate();
-        } catch (IllegalInstructionException|IllegalStateException e) {
-            Log.e(TAG, "Failed to generate APF program.", e);
-            return;
-        }
-        final long now = currentTimeSeconds();
-        mLastTimeInstalledProgram = now;
-        mLastInstalledProgramMinLifetime = programMinLifetime;
-        mLastInstalledProgram = program;
-        mNumProgramUpdates++;
-
-        if (VDBG) {
-            hexDump("Installing filter: ", program, program.length);
-        }
-        mIpClientCallback.installPacketFilter(program);
-        logApfProgramEventLocked(now);
-        mLastInstallEvent = new ApfProgramEvent.Builder()
-                .setLifetime(programMinLifetime)
-                .setFilteredRas(rasToFilter.size())
-                .setCurrentRas(mRas.size())
-                .setProgramLength(program.length)
-                .setFlags(mIPv4Address != null, mMulticastFilter);
-    }
-
-    @GuardedBy("this")
-    private void logApfProgramEventLocked(long now) {
-        if (mLastInstallEvent == null) {
-            return;
-        }
-        ApfProgramEvent.Builder ev = mLastInstallEvent;
-        mLastInstallEvent = null;
-        final long actualLifetime = now - mLastTimeInstalledProgram;
-        ev.setActualLifetime(actualLifetime);
-        if (actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
-            return;
-        }
-        mMetricsLog.log(ev.build());
-    }
-
-    /**
-     * Returns {@code true} if a new program should be installed because the current one dies soon.
-     */
-    private boolean shouldInstallnewProgram() {
-        long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
-        return expiry < currentTimeSeconds() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
-    }
-
-    private void hexDump(String msg, byte[] packet, int length) {
-        log(msg + HexDump.toHexString(packet, 0, length, false /* lowercase */));
-    }
-
-    @GuardedBy("this")
-    private void purgeExpiredRasLocked() {
-        for (int i = 0; i < mRas.size();) {
-            if (mRas.get(i).isExpired()) {
-                log("Expiring " + mRas.get(i));
-                mRas.remove(i);
-            } else {
-                i++;
-            }
-        }
-    }
-
-    /**
-     * Process an RA packet, updating the list of known RAs and installing a new APF program
-     * if the current APF program should be updated.
-     * @return a ProcessRaResult enum describing what action was performed.
-     */
-    @VisibleForTesting
-    synchronized ProcessRaResult processRa(byte[] packet, int length) {
-        if (VDBG) hexDump("Read packet = ", packet, length);
-
-        // Have we seen this RA before?
-        for (int i = 0; i < mRas.size(); i++) {
-            Ra ra = mRas.get(i);
-            if (ra.matches(packet, length)) {
-                if (VDBG) log("matched RA " + ra);
-                // Update lifetimes.
-                ra.mLastSeen = currentTimeSeconds();
-                ra.mMinLifetime = ra.minLifetime(packet, length);
-                ra.seenCount++;
-
-                // Keep mRas in LRU order so as to prioritize generating filters for recently seen
-                // RAs. LRU prioritizes this because RA filters are generated in order from mRas
-                // until the filter program exceeds the maximum filter program size allowed by the
-                // chipset, so RAs appearing earlier in mRas are more likely to make it into the
-                // filter program.
-                // TODO: consider sorting the RAs in order of increasing expiry time as well.
-                // Swap to front of array.
-                mRas.add(0, mRas.remove(i));
-
-                // If the current program doesn't expire for a while, don't update.
-                if (shouldInstallnewProgram()) {
-                    installNewProgramLocked();
-                    return ProcessRaResult.UPDATE_EXPIRY;
-                }
-                return ProcessRaResult.MATCH;
-            }
-        }
-        purgeExpiredRasLocked();
-        // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
-        if (mRas.size() >= MAX_RAS) {
-            return ProcessRaResult.DROPPED;
-        }
-        final Ra ra;
-        try {
-            ra = new Ra(packet, length);
-        } catch (Exception e) {
-            Log.e(TAG, "Error parsing RA", e);
-            return ProcessRaResult.PARSE_ERROR;
-        }
-        // Ignore 0 lifetime RAs.
-        if (ra.isExpired()) {
-            return ProcessRaResult.ZERO_LIFETIME;
-        }
-        log("Adding " + ra);
-        mRas.add(ra);
-        installNewProgramLocked();
-        return ProcessRaResult.UPDATE_NEW_RA;
-    }
-
-    /**
-     * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
-     * filtering using APF programs.
-     */
-    public static ApfFilter maybeCreate(Context context, ApfConfiguration config,
-            InterfaceParams ifParams, IpClientCallbacksWrapper ipClientCallback) {
-        if (context == null || config == null || ifParams == null) return null;
-        ApfCapabilities apfCapabilities =  config.apfCapabilities;
-        if (apfCapabilities == null) return null;
-        if (apfCapabilities.apfVersionSupported == 0) return null;
-        if (apfCapabilities.maximumApfProgramSize < 512) {
-            Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
-            return null;
-        }
-        // For now only support generating programs for Ethernet frames. If this restriction is
-        // lifted:
-        //   1. the program generator will need its offsets adjusted.
-        //   2. the packet filter attached to our packet socket will need its offset adjusted.
-        if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
-        if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) {
-            Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
-            return null;
-        }
-
-        return new ApfFilter(context, config, ifParams, ipClientCallback, new IpConnectivityLog());
-    }
-
-    public synchronized void shutdown() {
-        if (mReceiveThread != null) {
-            log("shutting down");
-            mReceiveThread.halt();  // Also closes socket.
-            mReceiveThread = null;
-        }
-        mRas.clear();
-        mContext.unregisterReceiver(mDeviceIdleReceiver);
-    }
-
-    public synchronized void setMulticastFilter(boolean isEnabled) {
-        if (mMulticastFilter == isEnabled) return;
-        mMulticastFilter = isEnabled;
-        if (!isEnabled) {
-            mNumProgramUpdatesAllowingMulticast++;
-        }
-        installNewProgramLocked();
-    }
-
-    @VisibleForTesting
-    public synchronized void setDozeMode(boolean isEnabled) {
-        if (mInDozeMode == isEnabled) return;
-        mInDozeMode = isEnabled;
-        installNewProgramLocked();
-    }
-
-    /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */
-    private static LinkAddress findIPv4LinkAddress(LinkProperties lp) {
-        LinkAddress ipv4Address = null;
-        for (LinkAddress address : lp.getLinkAddresses()) {
-            if (!(address.getAddress() instanceof Inet4Address)) {
-                continue;
-            }
-            if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) {
-                // More than one IPv4 address, abort.
-                return null;
-            }
-            ipv4Address = address;
-        }
-        return ipv4Address;
-    }
-
-    public synchronized void setLinkProperties(LinkProperties lp) {
-        // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state.
-        final LinkAddress ipv4Address = findIPv4LinkAddress(lp);
-        final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null;
-        final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0;
-        if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) {
-            return;
-        }
-        mIPv4Address = addr;
-        mIPv4PrefixLength = prefix;
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add TCP keepalive ack packet filter.
-     * This will add a filter to drop acks to the keepalive packet passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addTcpKeepalivePacketFilter(final int slot,
-            final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding keepalive ack(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("Keepalive slot " + slot + " is occupied");
-        }
-        final int ipVersion = sentKeepalivePacket.srcAddress.length == 4 ? 4 : 6;
-        mKeepalivePackets.put(slot, (ipVersion == 4)
-                ? new TcpKeepaliveAckV4(sentKeepalivePacket)
-                : new TcpKeepaliveAckV6(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add NAT-T keepalive packet filter.
-     * This will add a filter to drop NAT-T keepalive packet which is passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addNattKeepalivePacketFilter(final int slot,
-            final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding NAT-T keepalive packet(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("NAT-T Keepalive slot " + slot + " is occupied");
-        }
-        if (sentKeepalivePacket.srcAddress.length != 4) {
-            throw new IllegalArgumentException("NAT-T keepalive is only supported on IPv4");
-        }
-        mKeepalivePackets.put(slot, new NattKeepaliveResponse(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Remove keepalive packet filter.
-     *
-     * @param slot The index used to access the filter.
-     */
-    public synchronized void removeKeepalivePacketFilter(int slot) {
-        log("Removing keepalive packet(" + slot + ")");
-        mKeepalivePackets.remove(slot);
-        installNewProgramLocked();
-    }
-
-    static public long counterValue(byte[] data, Counter counter)
-            throws ArrayIndexOutOfBoundsException {
-        // Follow the same wrap-around addressing scheme of the interpreter.
-        int offset = counter.offset();
-        if (offset < 0) {
-            offset = data.length + offset;
-        }
-
-        // Decode 32bit big-endian integer into a long so we can count up beyond 2^31.
-        long value = 0;
-        for (int i = 0; i < 4; i++) {
-            value = value << 8 | (data[offset] & 0xFF);
-            offset++;
-        }
-        return value;
-    }
-
-    public synchronized void dump(IndentingPrintWriter pw) {
-        pw.println("Capabilities: " + mApfCapabilities);
-        pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
-        pw.println("Multicast: " + (mMulticastFilter ? "DROP" : "ALLOW"));
-        try {
-            pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address).getHostAddress());
-        } catch (UnknownHostException|NullPointerException e) {}
-
-        if (mLastTimeInstalledProgram == 0) {
-            pw.println("No program installed.");
-            return;
-        }
-        pw.println("Program updates: " + mNumProgramUpdates);
-        pw.println(String.format(
-                "Last program length %d, installed %ds ago, lifetime %ds",
-                mLastInstalledProgram.length, currentTimeSeconds() - mLastTimeInstalledProgram,
-                mLastInstalledProgramMinLifetime));
-
-        pw.println("RA filters:");
-        pw.increaseIndent();
-        for (Ra ra: mRas) {
-            pw.println(ra);
-            pw.increaseIndent();
-            pw.println(String.format(
-                    "Seen: %d, last %ds ago", ra.seenCount, currentTimeSeconds() - ra.mLastSeen));
-            if (DBG) {
-                pw.println("Last match:");
-                pw.increaseIndent();
-                pw.println(ra.getLastMatchingPacket());
-                pw.decreaseIndent();
-            }
-            pw.decreaseIndent();
-        }
-        pw.decreaseIndent();
-
-        pw.println("TCP Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof TcpKeepaliveAck) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println("NAT-T Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof NattKeepaliveResponse) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        if (DBG) {
-            pw.println("Last program:");
-            pw.increaseIndent();
-            pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
-            pw.decreaseIndent();
-        }
-
-        pw.println("APF packet counters: ");
-        pw.increaseIndent();
-        if (!mApfCapabilities.hasDataAccess()) {
-            pw.println("APF counters not supported");
-        } else if (mDataSnapshot == null) {
-            pw.println("No last snapshot.");
-        } else {
-            try {
-                Counter[] counters = Counter.class.getEnumConstants();
-                for (Counter c : Arrays.asList(counters).subList(1, counters.length)) {
-                    long value = counterValue(mDataSnapshot, c);
-                    // Only print non-zero counters
-                    if (value != 0) {
-                        pw.println(c.toString() + ": " + value);
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                pw.println("Uh-oh: " + e);
-            }
-            if (VDBG) {
-                pw.println("Raw data dump: ");
-                pw.println(HexDump.dumpHexString(mDataSnapshot));
-            }
-        }
-        pw.decreaseIndent();
-    }
-
-    // TODO: move to android.net.NetworkUtils
-    @VisibleForTesting
-    public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) {
-        return bytesToBEInt(addrBytes) | (int) (Integer.toUnsignedLong(-1) >>> prefixLength);
-    }
-
-    private static int uint8(byte b) {
-        return b & 0xff;
-    }
-
-    private static int getUint16(ByteBuffer buffer, int position) {
-        return buffer.getShort(position) & 0xffff;
-    }
-
-    private static long getUint32(ByteBuffer buffer, int position) {
-        return Integer.toUnsignedLong(buffer.getInt(position));
-    }
-
-    private static int getUint8(ByteBuffer buffer, int position) {
-        return uint8(buffer.get(position));
-    }
-
-    private static int bytesToBEInt(byte[] bytes) {
-        return (uint8(bytes[0]) << 24)
-                + (uint8(bytes[1]) << 16)
-                + (uint8(bytes[2]) << 8)
-                + (uint8(bytes[3]));
-    }
-
-    private static byte[] concatArrays(final byte[]... arr) {
-        int size = 0;
-        for (byte[] a : arr) {
-            size += a.length;
-        }
-        final byte[] result = new byte[size];
-        int offset = 0;
-        for (byte[] a : arr) {
-            System.arraycopy(a, 0, result, offset, a.length);
-            offset += a.length;
-        }
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
deleted file mode 100644
index 44ce2db..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * APF assembler/generator.  A tool for generating an APF program.
- *
- * Call add*() functions to add instructions to the program, then call
- * {@link generate} to get the APF bytecode for the program.
- *
- * @hide
- */
-public class ApfGenerator {
-    /**
-     * This exception is thrown when an attempt is made to generate an illegal instruction.
-     */
-    public static class IllegalInstructionException extends Exception {
-        IllegalInstructionException(String msg) {
-            super(msg);
-        }
-    }
-    private enum Opcodes {
-        LABEL(-1),
-        LDB(1),    // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
-        LDH(2),    // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
-        LDW(3),    // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
-        LDBX(4),   // Load 1 byte from immediate offset plus register, e.g. "ldbx R0, [5]R0"
-        LDHX(5),   // Load 2 byte from immediate offset plus register, e.g. "ldhx R0, [5]R0"
-        LDWX(6),   // Load 4 byte from immediate offset plus register, e.g. "ldwx R0, [5]R0"
-        ADD(7),    // Add, e.g. "add R0,5"
-        MUL(8),    // Multiply, e.g. "mul R0,5"
-        DIV(9),    // Divide, e.g. "div R0,5"
-        AND(10),   // And, e.g. "and R0,5"
-        OR(11),    // Or, e.g. "or R0,5"
-        SH(12),    // Left shift, e.g, "sh R0, 5" or "sh R0, -5" (shifts right)
-        LI(13),    // Load immediate, e.g. "li R0,5" (immediate encoded as signed value)
-        JMP(14),   // Jump, e.g. "jmp label"
-        JEQ(15),   // Compare equal and branch, e.g. "jeq R0,5,label"
-        JNE(16),   // Compare not equal and branch, e.g. "jne R0,5,label"
-        JGT(17),   // Compare greater than and branch, e.g. "jgt R0,5,label"
-        JLT(18),   // Compare less than and branch, e.g. "jlt R0,5,label"
-        JSET(19),  // Compare any bits set and branch, e.g. "jset R0,5,label"
-        JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455"
-        EXT(21),   // Followed by immediate indicating ExtendedOpcodes.
-        LDDW(22),  // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1"
-        STDW(23);  // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1"
-
-        final int value;
-
-        private Opcodes(int value) {
-            this.value = value;
-        }
-    }
-    // Extended opcodes. Primary opcode is Opcodes.EXT. ExtendedOpcodes are encoded in the immediate
-    // field.
-    private enum ExtendedOpcodes {
-        LDM(0),   // Load from memory, e.g. "ldm R0,5"
-        STM(16),  // Store to memory, e.g. "stm R0,5"
-        NOT(32),  // Not, e.g. "not R0"
-        NEG(33),  // Negate, e.g. "neg R0"
-        SWAP(34), // Swap, e.g. "swap R0,R1"
-        MOVE(35);  // Move, e.g. "move R0,R1"
-
-        final int value;
-
-        private ExtendedOpcodes(int value) {
-            this.value = value;
-        }
-    }
-    public enum Register {
-        R0(0),
-        R1(1);
-
-        final int value;
-
-        private Register(int value) {
-            this.value = value;
-        }
-    }
-    private class Instruction {
-        private final byte mOpcode;   // A "Opcode" value.
-        private final byte mRegister; // A "Register" value.
-        private boolean mHasImm;
-        private byte mImmSize;
-        private boolean mImmSigned;
-        private int mImm;
-        // When mOpcode is a jump:
-        private byte mTargetLabelSize;
-        private String mTargetLabel;
-        // When mOpcode == Opcodes.LABEL:
-        private String mLabel;
-        // When mOpcode == Opcodes.JNEBS:
-        private byte[] mCompareBytes;
-        // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}.
-        int offset;
-
-        Instruction(Opcodes opcode, Register register) {
-            mOpcode = (byte)opcode.value;
-            mRegister = (byte)register.value;
-        }
-
-        Instruction(Opcodes opcode) {
-            this(opcode, Register.R0);
-        }
-
-        void setImm(int imm, boolean signed) {
-            mHasImm = true;
-            mImm = imm;
-            mImmSigned = signed;
-            mImmSize = calculateImmSize(imm, signed);
-        }
-
-        void setUnsignedImm(int imm) {
-            setImm(imm, false);
-        }
-
-        void setSignedImm(int imm) {
-            setImm(imm, true);
-        }
-
-        void setLabel(String label) throws IllegalInstructionException {
-            if (mLabels.containsKey(label)) {
-                throw new IllegalInstructionException("duplicate label " + label);
-            }
-            if (mOpcode != Opcodes.LABEL.value) {
-                throw new IllegalStateException("adding label to non-label instruction");
-            }
-            mLabel = label;
-            mLabels.put(label, this);
-        }
-
-        void setTargetLabel(String label) {
-            mTargetLabel = label;
-            mTargetLabelSize = 4; // May shrink later on in generate().
-        }
-
-        void setCompareBytes(byte[] bytes) {
-            if (mOpcode != Opcodes.JNEBS.value) {
-                throw new IllegalStateException("adding compare bytes to non-JNEBS instruction");
-            }
-            mCompareBytes = bytes;
-        }
-
-        /**
-         * @return size of instruction in bytes.
-         */
-        int size() {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return 0;
-            }
-            int size = 1;
-            if (mHasImm) {
-                size += generatedImmSize();
-            }
-            if (mTargetLabel != null) {
-                size += generatedImmSize();
-            }
-            if (mCompareBytes != null) {
-                size += mCompareBytes.length;
-            }
-            return size;
-        }
-
-        /**
-         * Resize immediate value field so that it's only as big as required to
-         * contain the offset of the jump destination.
-         * @return {@code true} if shrunk.
-         */
-        boolean shrink() throws IllegalInstructionException {
-            if (mTargetLabel == null) {
-                return false;
-            }
-            int oldSize = size();
-            int oldTargetLabelSize = mTargetLabelSize;
-            mTargetLabelSize = calculateImmSize(calculateTargetLabelOffset(), false);
-            if (mTargetLabelSize > oldTargetLabelSize) {
-                throw new IllegalStateException("instruction grew");
-            }
-            return size() < oldSize;
-        }
-
-        /**
-         * Assemble value for instruction size field.
-         */
-        private byte generateImmSizeField() {
-            byte immSize = generatedImmSize();
-            // Encode size field to fit in 2 bits: 0->0, 1->1, 2->2, 3->4.
-            return immSize == 4 ? 3 : immSize;
-        }
-
-        /**
-         * Assemble first byte of generated instruction.
-         */
-        private byte generateInstructionByte() {
-            byte sizeField = generateImmSizeField();
-            return (byte)((mOpcode << 3) | (sizeField << 1) | mRegister);
-        }
-
-        /**
-         * Write {@code value} at offset {@code writingOffset} into {@code bytecode}.
-         * {@link generatedImmSize} bytes are written. {@code value} is truncated to
-         * {@code generatedImmSize} bytes. {@code value} is treated simply as a
-         * 32-bit value, so unsigned values should be zero extended and the truncation
-         * should simply throw away their zero-ed upper bits, and signed values should
-         * be sign extended and the truncation should simply throw away their signed
-         * upper bits.
-         */
-        private int writeValue(int value, byte[] bytecode, int writingOffset) {
-            for (int i = generatedImmSize() - 1; i >= 0; i--) {
-                bytecode[writingOffset++] = (byte)((value >> (i * 8)) & 255);
-            }
-            return writingOffset;
-        }
-
-        /**
-         * Generate bytecode for this instruction at offset {@link offset}.
-         */
-        void generate(byte[] bytecode) throws IllegalInstructionException {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return;
-            }
-            int writingOffset = offset;
-            bytecode[writingOffset++] = generateInstructionByte();
-            if (mTargetLabel != null) {
-                writingOffset = writeValue(calculateTargetLabelOffset(), bytecode, writingOffset);
-            }
-            if (mHasImm) {
-                writingOffset = writeValue(mImm, bytecode, writingOffset);
-            }
-            if (mCompareBytes != null) {
-                System.arraycopy(mCompareBytes, 0, bytecode, writingOffset, mCompareBytes.length);
-                writingOffset += mCompareBytes.length;
-            }
-            if ((writingOffset - offset) != size()) {
-                throw new IllegalStateException("wrote " + (writingOffset - offset) +
-                        " but should have written " + size());
-            }
-        }
-
-        /**
-         * Calculate the size of either the immediate field or the target label field, if either is
-         * present. Most instructions have either an immediate or a target label field, but for the
-         * instructions that have both, the size of the target label field must be the same as the
-         * size of the immediate field, because there is only one length field in the instruction
-         * byte, hence why this function simply takes the maximum of the two sizes, so neither is
-         * truncated.
-         */
-        private byte generatedImmSize() {
-            return mImmSize > mTargetLabelSize ? mImmSize : mTargetLabelSize;
-        }
-
-        private int calculateTargetLabelOffset() throws IllegalInstructionException {
-            Instruction targetLabelInstruction;
-            if (mTargetLabel == DROP_LABEL) {
-                targetLabelInstruction = mDropLabel;
-            } else if (mTargetLabel == PASS_LABEL) {
-                targetLabelInstruction = mPassLabel;
-            } else {
-                targetLabelInstruction = mLabels.get(mTargetLabel);
-            }
-            if (targetLabelInstruction == null) {
-                throw new IllegalInstructionException("label not found: " + mTargetLabel);
-            }
-            // Calculate distance from end of this instruction to instruction.offset.
-            final int targetLabelOffset = targetLabelInstruction.offset - (offset + size());
-            if (targetLabelOffset < 0) {
-                throw new IllegalInstructionException("backward branches disallowed; label: " +
-                        mTargetLabel);
-            }
-            return targetLabelOffset;
-        }
-
-        private byte calculateImmSize(int imm, boolean signed) {
-            if (imm == 0) {
-                return 0;
-            }
-            if (signed && (imm >= -128 && imm <= 127) ||
-                    !signed && (imm >= 0 && imm <= 255)) {
-                return 1;
-            }
-            if (signed && (imm >= -32768 && imm <= 32767) ||
-                    !signed && (imm >= 0 && imm <= 65535)) {
-                return 2;
-            }
-            return 4;
-        }
-    }
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be dropped.
-     */
-    public static final String DROP_LABEL = "__DROP__";
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be passed to the AP.
-     */
-    public static final String PASS_LABEL = "__PASS__";
-
-    /**
-     * Number of memory slots available for access via APF stores to memory and loads from memory.
-     * The memory slots are numbered 0 to {@code MEMORY_SLOTS} - 1. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int MEMORY_SLOTS = 16;
-
-    /**
-     * Memory slot number that is prefilled with the IPv4 header length.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int IPV4_HEADER_SIZE_MEMORY_SLOT = 13;
-
-    /**
-     * Memory slot number that is prefilled with the size of the packet being filtered in bytes.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int PACKET_SIZE_MEMORY_SLOT = 14;
-
-    /**
-     * Memory slot number that is prefilled with the age of the filter in seconds. The age of the
-     * filter is the time since the filter was installed until now.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int FILTER_AGE_MEMORY_SLOT = 15;
-
-    /**
-     * First memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int FIRST_PREFILLED_MEMORY_SLOT = IPV4_HEADER_SIZE_MEMORY_SLOT;
-
-    /**
-     * Last memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT;
-
-    // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h
-    private static final int MIN_APF_VERSION = 2;
-
-    private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>();
-    private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>();
-    private final Instruction mDropLabel = new Instruction(Opcodes.LABEL);
-    private final Instruction mPassLabel = new Instruction(Opcodes.LABEL);
-    private final int mVersion;
-    private boolean mGenerated;
-
-    /**
-     * Creates an ApfGenerator instance which is able to emit instructions for the specified
-     * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if
-     * the requested version is unsupported.
-     */
-    ApfGenerator(int version) throws IllegalInstructionException {
-        mVersion = version;
-        requireApfVersion(MIN_APF_VERSION);
-    }
-
-    /**
-     * Returns true if the ApfGenerator supports the specified {@code version}, otherwise false.
-     */
-    public static boolean supportsVersion(int version) {
-        return version >= MIN_APF_VERSION;
-    }
-
-    private void requireApfVersion(int minimumVersion) throws IllegalInstructionException {
-        if (mVersion < minimumVersion) {
-            throw new IllegalInstructionException("Requires APF >= " + minimumVersion);
-        }
-    }
-
-    private void addInstruction(Instruction instruction) {
-        if (mGenerated) {
-            throw new IllegalStateException("Program already generated");
-        }
-        mInstructions.add(instruction);
-    }
-
-    /**
-     * Define a label at the current end of the program. Jumps can jump to this label. Labels are
-     * their own separate instructions, though with size 0. This facilitates having labels with
-     * no corresponding code to execute, for example a label at the end of a program. For example
-     * an {@link ApfGenerator} might be passed to a function that adds a filter like so:
-     * <pre>
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   jump to drop label
-     *   define "next_filter" here
-     * </pre>
-     * In this case "next_filter" may not have any generated code associated with it.
-     */
-    public ApfGenerator defineLabel(String name) throws IllegalInstructionException {
-        Instruction instruction = new Instruction(Opcodes.LABEL);
-        instruction.setLabel(name);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an unconditional jump instruction to the end of the program.
-     */
-    public ApfGenerator addJump(String target) {
-        Instruction instruction = new Instruction(Opcodes.JMP);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load the byte at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad8(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDB, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad16(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDH, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad32(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDW, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load a byte from the packet into
-     * {@code register}. The offset of the loaded byte from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad8Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDBX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits from the packet into
-     * {@code register}. The offset of the loaded 16-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad16Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDHX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits from the packet into
-     * {@code register}. The offset of the loaded 32-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad32Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDWX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add {@code value} to register R0.
-     */
-    public ApfGenerator addAdd(int value) {
-        Instruction instruction = new Instruction(Opcodes.ADD);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by {@code value}.
-     */
-    public ApfGenerator addMul(int value) {
-        Instruction instruction = new Instruction(Opcodes.MUL);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by {@code value}.
-     */
-    public ApfGenerator addDiv(int value) {
-        Instruction instruction = new Instruction(Opcodes.DIV);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with {@code value}.
-     */
-    public ApfGenerator addAnd(int value) {
-        Instruction instruction = new Instruction(Opcodes.AND);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with {@code value}.
-     */
-    public ApfGenerator addOr(int value) {
-        Instruction instruction = new Instruction(Opcodes.OR);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift left register R0 by {@code value} bits.
-     */
-    public ApfGenerator addLeftShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift right register R0 by {@code value}
-     * bits.
-     */
-    public ApfGenerator addRightShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(-value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add register R1 to register R0.
-     */
-    public ApfGenerator addAddR1() {
-        Instruction instruction = new Instruction(Opcodes.ADD, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by register R1.
-     */
-    public ApfGenerator addMulR1() {
-        Instruction instruction = new Instruction(Opcodes.MUL, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by register R1.
-     */
-    public ApfGenerator addDivR1() {
-        Instruction instruction = new Instruction(Opcodes.DIV, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addAndR1() {
-        Instruction instruction = new Instruction(Opcodes.AND, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addOrR1() {
-        Instruction instruction = new Instruction(Opcodes.OR, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift register R0 left by the value in
-     * register R1.
-     */
-    public ApfGenerator addLeftShiftR1() {
-        Instruction instruction = new Instruction(Opcodes.SH, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move {@code value} into {@code register}.
-     */
-    public ApfGenerator addLoadImmediate(Register register, int value) {
-        Instruction instruction = new Instruction(Opcodes.LI, register);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals {@code value}.
-     */
-    public ApfGenerator addJumpIfR0Equals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal {@code value}.
-     */
-    public ApfGenerator addJumpIfR0NotEquals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0GreaterThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0LessThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in {@code value}.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSet(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals register R1's value.
-     */
-    public ApfGenerator addJumpIfR0EqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal register R1's value.
-     */
-    public ApfGenerator addJumpIfR0NotEqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0GreaterThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0LessThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in R1's value.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSetR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
-     * packet at an offset specified by {@code register} match {@code bytes}.
-     */
-    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
-            throws IllegalInstructionException {
-        if (register == Register.R1) {
-            throw new IllegalInstructionException("JNEBS fails with R1");
-        }
-        Instruction instruction = new Instruction(Opcodes.JNEBS, register);
-        instruction.setUnsignedImm(bytes.length);
-        instruction.setTargetLabel(target);
-        instruction.setCompareBytes(bytes);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load memory slot {@code slot} into
-     * {@code register}.
-     */
-    public ApfGenerator addLoadFromMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.LDM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store {@code register} into memory slot
-     * {@code slot}.
-     */
-    public ApfGenerator addStoreToMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.STM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically not {@code register}.
-     */
-    public ApfGenerator addNot(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NOT.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to negate {@code register}.
-     */
-    public ApfGenerator addNeg(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NEG.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to swap the values in register R0 and register R1.
-     */
-    public ApfGenerator addSwap() {
-        Instruction instruction = new Instruction(Opcodes.EXT);
-        instruction.setUnsignedImm(ExtendedOpcodes.SWAP.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move the value into
-     * {@code register} from the other register.
-     */
-    public ApfGenerator addMove(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.MOVE.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32 bits from the data memory into
-     * {@code register}. The source address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addLoadData(Register destinationRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store 32 bits from {@code register} into the
-     * data memory. The destination address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addStoreData(Register sourceRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Updates instruction offset fields using latest instruction sizes.
-     * @return current program length in bytes.
-     */
-    private int updateInstructionOffsets() {
-        int offset = 0;
-        for (Instruction instruction : mInstructions) {
-            instruction.offset = offset;
-            offset += instruction.size();
-        }
-        return offset;
-    }
-
-    /**
-     * Returns an overestimate of the size of the generated program. {@link #generate} may return
-     * a program that is smaller.
-     */
-    public int programLengthOverEstimate() {
-        return updateInstructionOffsets();
-    }
-
-    /**
-     * Generate the bytecode for the APF program.
-     * @return the bytecode.
-     * @throws IllegalStateException if a label is referenced but not defined.
-     */
-    public byte[] generate() throws IllegalInstructionException {
-        // Enforce that we can only generate once because we cannot unshrink instructions and
-        // PASS/DROP labels may move further away requiring unshrinking if we add further
-        // instructions.
-        if (mGenerated) {
-            throw new IllegalStateException("Can only generate() once!");
-        }
-        mGenerated = true;
-        int total_size;
-        boolean shrunk;
-        // Shrink the immediate value fields of instructions.
-        // As we shrink the instructions some branch offset
-        // fields may shrink also, thereby shrinking the
-        // instructions further. Loop until we've reached the
-        // minimum size. Rarely will this loop more than a few times.
-        // Limit iterations to avoid O(n^2) behavior.
-        int iterations_remaining = 10;
-        do {
-            total_size = updateInstructionOffsets();
-            // Update drop and pass label offsets.
-            mDropLabel.offset = total_size + 1;
-            mPassLabel.offset = total_size;
-            // Limit run-time in aberant circumstances.
-            if (iterations_remaining-- == 0) break;
-            // Attempt to shrink instructions.
-            shrunk = false;
-            for (Instruction instruction : mInstructions) {
-                if (instruction.shrink()) {
-                    shrunk = true;
-                }
-            }
-        } while (shrunk);
-        // Generate bytecode for instructions.
-        byte[] bytecode = new byte[total_size];
-        for (Instruction instruction : mInstructions) {
-            instruction.generate(bytecode);
-        }
-        return bytecode;
-    }
-}
-
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
deleted file mode 100644
index b2eb4e2..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-ACK packet.
- */
-class DhcpAckPacket extends DhcpPacket {
-
-    /**
-     * The address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mBroadcast = broadcast;
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = " DNS servers: ";
-
-        for (Inet4Address dnsServer: mDnsServers) {
-            dnsServers += dnsServer.toString() + " ";
-        }
-
-        return s + " ACK: your new IP " + mYourIp +
-                ", netmask " + mSubnetMask +
-                ", gateways " + mGateways + dnsServers +
-                ", lease time " + mLeaseTime;
-    }
-
-    /**
-     * Fills in a packet with the requested ACK parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated ACK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-
-    /**
-     * Un-boxes an Integer, returning 0 if a null reference is supplied.
-     */
-    private static final int getInt(Integer v) {
-        if (v == null) {
-            return 0;
-        } else {
-            return v.intValue();
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
deleted file mode 100644
index ca6c17a..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.util.NetworkStackUtils.closeSocketQuietly;
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_RAW;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_RCVBUF;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.content.Context;
-import android.net.DhcpResults;
-import android.net.InetAddresses;
-import android.net.TrafficStats;
-import android.net.ip.IpClient;
-import android.net.metrics.DhcpClientEvent;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SocketUtils;
-import android.os.Message;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.util.HexDump;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.internal.util.WakeupMessage;
-import com.android.networkstack.R;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * A DHCPv4 client.
- *
- * Written to behave similarly to the DhcpStateMachine + dhcpcd 5.5.6 combination used in Android
- * 5.1 and below, as configured on Nexus 6. The interface is the same as DhcpStateMachine.
- *
- * TODO:
- *
- * - Exponential backoff when receiving NAKs (not specified by the RFC, but current behaviour).
- * - Support persisting lease state and support INIT-REBOOT. Android 5.1 does this, but it does not
- *   do so correctly: instead of requesting the lease last obtained on a particular network (e.g., a
- *   given SSID), it requests the last-leased IP address on the same interface, causing a delay if
- *   the server NAKs or a timeout if it doesn't.
- *
- * Known differences from current behaviour:
- *
- * - Does not request the "static routes" option.
- * - Does not support BOOTP servers. DHCP has been around since 1993, should be everywhere now.
- * - Requests the "broadcast" option, but does nothing with it.
- * - Rejects invalid subnet masks such as 255.255.255.1 (current code treats that as 255.255.255.0).
- *
- * @hide
- */
-public class DhcpClient extends StateMachine {
-
-    private static final String TAG = "DhcpClient";
-    private static final boolean DBG = true;
-    private static final boolean STATE_DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean MSG_DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean PACKET_DBG = Log.isLoggable(TAG, Log.DEBUG);
-
-    // Metrics events: must be kept in sync with server-side aggregation code.
-    /** Represents transitions from DhcpInitState to DhcpBoundState */
-    private static final String EVENT_INITIAL_BOUND = "InitialBoundState";
-    /** Represents transitions from and to DhcpBoundState via DhcpRenewingState */
-    private static final String EVENT_RENEWING_BOUND = "RenewingBoundState";
-
-    // Timers and timeouts.
-    private static final int SECONDS = 1000;
-    private static final int FIRST_TIMEOUT_MS   =   2 * SECONDS;
-    private static final int MAX_TIMEOUT_MS     = 128 * SECONDS;
-
-    // This is not strictly needed, since the client is asynchronous and implements exponential
-    // backoff. It's maintained for backwards compatibility with the previous DHCP code, which was
-    // a blocking operation with a 30-second timeout. We pick 36 seconds so we can send packets at
-    // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
-    private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
-
-    // DhcpClient uses IpClient's handler.
-    private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE;
-
-    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
-    /* Commands from controller to start/stop DHCP */
-    public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
-    public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
-
-    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
-    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 3;
-    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
-     * success/failure */
-    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 4;
-    /* Notification from DHCP state machine before quitting */
-    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 5;
-
-    /* Command from controller to indicate DHCP discovery/renewal can continue
-     * after pre DHCP action is complete */
-    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 6;
-
-    /* Command and event notification to/from IpManager requesting the setting
-     * (or clearing) of an IPv4 LinkAddress.
-     */
-    public static final int CMD_CLEAR_LINKADDRESS           = PUBLIC_BASE + 7;
-    public static final int CMD_CONFIGURE_LINKADDRESS       = PUBLIC_BASE + 8;
-    public static final int EVENT_LINKADDRESS_CONFIGURED    = PUBLIC_BASE + 9;
-
-    /* Message.arg1 arguments to CMD_POST_DHCP_ACTION notification */
-    public static final int DHCP_SUCCESS = 1;
-    public static final int DHCP_FAILURE = 2;
-
-    // Internal messages.
-    private static final int PRIVATE_BASE         = IpClient.DHCPCLIENT_CMD_BASE + 100;
-    private static final int CMD_KICK             = PRIVATE_BASE + 1;
-    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
-    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
-    private static final int CMD_RENEW_DHCP       = PRIVATE_BASE + 4;
-    private static final int CMD_REBIND_DHCP      = PRIVATE_BASE + 5;
-    private static final int CMD_EXPIRE_DHCP      = PRIVATE_BASE + 6;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { DhcpClient.class };
-    private static final SparseArray<String> sMessageNames =
-            MessageUtils.findMessageNames(sMessageClasses);
-
-    // DHCP parameters that we request.
-    /* package */ static final byte[] REQUESTED_PARAMS = new byte[] {
-        DHCP_SUBNET_MASK,
-        DHCP_ROUTER,
-        DHCP_DNS_SERVER,
-        DHCP_DOMAIN_NAME,
-        DHCP_MTU,
-        DHCP_BROADCAST_ADDRESS,  // TODO: currently ignored.
-        DHCP_LEASE_TIME,
-        DHCP_RENEWAL_TIME,
-        DHCP_REBINDING_TIME,
-        DHCP_VENDOR_INFO,
-    };
-
-    // DHCP flag that means "yes, we support unicast."
-    private static final boolean DO_UNICAST   = false;
-
-    // System services / libraries we use.
-    private final Context mContext;
-    private final Random mRandom;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-
-    // Sockets.
-    // - We use a packet socket to receive, because servers send us packets bound for IP addresses
-    //   which we have not yet configured, and the kernel protocol stack drops these.
-    // - We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can
-    //   be off-link as well as on-link).
-    private FileDescriptor mPacketSock;
-    private FileDescriptor mUdpSock;
-    private ReceiveThread mReceiveThread;
-
-    // State variables.
-    private final StateMachine mController;
-    private final WakeupMessage mKickAlarm;
-    private final WakeupMessage mTimeoutAlarm;
-    private final WakeupMessage mRenewAlarm;
-    private final WakeupMessage mRebindAlarm;
-    private final WakeupMessage mExpiryAlarm;
-    private final String mIfaceName;
-
-    private boolean mRegisteredForPreDhcpNotification;
-    private InterfaceParams mIface;
-    // TODO: MacAddress-ify more of this class hierarchy.
-    private byte[] mHwAddr;
-    private SocketAddress mInterfaceBroadcastAddr;
-    private int mTransactionId;
-    private long mTransactionStartMillis;
-    private DhcpResults mDhcpLease;
-    private long mDhcpLeaseExpiry;
-    private DhcpResults mOffer;
-
-    // Milliseconds SystemClock timestamps used to record transition times to DhcpBoundState.
-    private long mLastInitEnterTime;
-    private long mLastBoundExitTime;
-
-    // States.
-    private State mStoppedState = new StoppedState();
-    private State mDhcpState = new DhcpState();
-    private State mDhcpInitState = new DhcpInitState();
-    private State mDhcpSelectingState = new DhcpSelectingState();
-    private State mDhcpRequestingState = new DhcpRequestingState();
-    private State mDhcpHaveLeaseState = new DhcpHaveLeaseState();
-    private State mConfiguringInterfaceState = new ConfiguringInterfaceState();
-    private State mDhcpBoundState = new DhcpBoundState();
-    private State mDhcpRenewingState = new DhcpRenewingState();
-    private State mDhcpRebindingState = new DhcpRebindingState();
-    private State mDhcpInitRebootState = new DhcpInitRebootState();
-    private State mDhcpRebootingState = new DhcpRebootingState();
-    private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
-    private State mWaitBeforeRenewalState = new WaitBeforeRenewalState(mDhcpRenewingState);
-
-    private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
-        cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
-        return new WakeupMessage(mContext, getHandler(), cmdName, cmd);
-    }
-
-    // TODO: Take an InterfaceParams instance instead of an interface name String.
-    private DhcpClient(Context context, StateMachine controller, String iface) {
-        super(TAG, controller.getHandler());
-
-        mContext = context;
-        mController = controller;
-        mIfaceName = iface;
-
-        addState(mStoppedState);
-        addState(mDhcpState);
-            addState(mDhcpInitState, mDhcpState);
-            addState(mWaitBeforeStartState, mDhcpState);
-            addState(mDhcpSelectingState, mDhcpState);
-            addState(mDhcpRequestingState, mDhcpState);
-            addState(mDhcpHaveLeaseState, mDhcpState);
-                addState(mConfiguringInterfaceState, mDhcpHaveLeaseState);
-                addState(mDhcpBoundState, mDhcpHaveLeaseState);
-                addState(mWaitBeforeRenewalState, mDhcpHaveLeaseState);
-                addState(mDhcpRenewingState, mDhcpHaveLeaseState);
-                addState(mDhcpRebindingState, mDhcpHaveLeaseState);
-            addState(mDhcpInitRebootState, mDhcpState);
-            addState(mDhcpRebootingState, mDhcpState);
-
-        setInitialState(mStoppedState);
-
-        mRandom = new Random();
-
-        // Used to schedule packet retransmissions.
-        mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
-        // Used to time out PacketRetransmittingStates.
-        mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
-        // Used to schedule DHCP reacquisition.
-        mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
-        mRebindAlarm = makeWakeupMessage("REBIND", CMD_REBIND_DHCP);
-        mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
-    }
-
-    public void registerForPreDhcpNotification() {
-        mRegisteredForPreDhcpNotification = true;
-    }
-
-    public static DhcpClient makeDhcpClient(
-            Context context, StateMachine controller, InterfaceParams ifParams) {
-        DhcpClient client = new DhcpClient(context, controller, ifParams.name);
-        client.mIface = ifParams;
-        client.start();
-        return client;
-    }
-
-    private boolean initInterface() {
-        if (mIface == null) mIface = InterfaceParams.getByName(mIfaceName);
-        if (mIface == null) {
-            Log.e(TAG, "Can't determine InterfaceParams for " + mIfaceName);
-            return false;
-        }
-
-        mHwAddr = mIface.macAddr.toByteArray();
-        mInterfaceBroadcastAddr = makePacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST);
-        return true;
-    }
-
-    private void startNewTransaction() {
-        mTransactionId = mRandom.nextInt();
-        mTransactionStartMillis = SystemClock.elapsedRealtime();
-    }
-
-    private boolean initSockets() {
-        return initPacketSocket() && initUdpSocket();
-    }
-
-    private boolean initPacketSocket() {
-        try {
-            mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
-            SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index);
-            Os.bind(mPacketSock, addr);
-            NetworkStackUtils.attachDhcpFilter(mPacketSock);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating packet socket", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean initUdpSocket() {
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_DHCP);
-        try {
-            mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-            SocketUtils.bindSocketToInterface(mUdpSock, mIfaceName);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
-            Os.bind(mUdpSock, IPV4_ADDR_ANY, DhcpPacket.DHCP_CLIENT);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating UDP socket", e);
-            return false;
-        } finally {
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        return true;
-    }
-
-    private boolean connectUdpSock(Inet4Address to) {
-        try {
-            Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
-            return true;
-        } catch (SocketException|ErrnoException e) {
-            Log.e(TAG, "Error connecting UDP socket", e);
-            return false;
-        }
-    }
-
-    private void closeSockets() {
-        closeSocketQuietly(mUdpSock);
-        closeSocketQuietly(mPacketSock);
-    }
-
-    class ReceiveThread extends Thread {
-
-        private final byte[] mPacket = new byte[DhcpPacket.MAX_LENGTH];
-        private volatile boolean mStopped = false;
-
-        public void halt() {
-            mStopped = true;
-            closeSockets();  // Interrupts the read() call the thread is blocked in.
-        }
-
-        @Override
-        public void run() {
-            if (DBG) Log.d(TAG, "Receive thread started");
-            while (!mStopped) {
-                int length = 0;  // Or compiler can't tell it's initialized if a parse error occurs.
-                try {
-                    length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
-                    DhcpPacket packet = null;
-                    packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
-                    if (DBG) Log.d(TAG, "Received packet: " + packet);
-                    sendMessage(CMD_RECEIVED_PACKET, packet);
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                        logError(DhcpErrorEvent.RECEIVE_ERROR);
-                    }
-                } catch (DhcpPacket.ParseException e) {
-                    Log.e(TAG, "Can't parse packet: " + e.getMessage());
-                    if (PACKET_DBG) {
-                        Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
-                    }
-                    if (e.errorCode == DhcpErrorEvent.DHCP_NO_COOKIE) {
-                        int snetTagId = 0x534e4554;
-                        String bugId = "31850211";
-                        int uid = -1;
-                        String data = DhcpPacket.ParseException.class.getName();
-                        EventLog.writeEvent(snetTagId, bugId, uid, data);
-                    }
-                    logError(e.errorCode);
-                }
-            }
-            if (DBG) Log.d(TAG, "Receive thread stopped");
-        }
-    }
-
-    private short getSecs() {
-        return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
-    }
-
-    private boolean transmitPacket(ByteBuffer buf, String description, int encap, Inet4Address to) {
-        try {
-            if (encap == DhcpPacket.ENCAP_L2) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
-            } else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                // We only send L3-encapped broadcasts in DhcpRebindingState,
-                // where we have an IP address and an unconnected UDP socket.
-                //
-                // N.B.: We only need this codepath because DhcpRequestPacket
-                // hardcodes the source IP address to 0.0.0.0. We could reuse
-                // the packet socket if this ever changes.
-                Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
-            } else {
-                // It's safe to call getpeername here, because we only send unicast packets if we
-                // have an IP address, and we connect the UDP socket in DhcpBoundState#enter.
-                if (DBG) Log.d(TAG, String.format("Unicasting %s to %s",
-                        description, Os.getpeername(mUdpSock)));
-                Os.write(mUdpSock, buf);
-            }
-        } catch(ErrnoException|IOException e) {
-            Log.e(TAG, "Can't send packet: ", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean sendDiscoverPacket() {
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
-                DO_UNICAST, REQUESTED_PARAMS);
-        return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
-    }
-
-    private boolean sendRequestPacket(
-            Inet4Address clientAddress, Inet4Address requestedAddress,
-            Inet4Address serverAddress, Inet4Address to) {
-        // TODO: should we use the transaction ID from the server?
-        final int encap = INADDR_ANY.equals(clientAddress)
-                ? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
-
-        ByteBuffer packet = DhcpPacket.buildRequestPacket(
-                encap, mTransactionId, getSecs(), clientAddress,
-                DO_UNICAST, mHwAddr, requestedAddress,
-                serverAddress, REQUESTED_PARAMS, null);
-        String serverStr = (serverAddress != null) ? serverAddress.getHostAddress() : null;
-        String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
-                             " request=" + requestedAddress.getHostAddress() +
-                             " serverid=" + serverStr;
-        return transmitPacket(packet, description, encap, to);
-    }
-
-    private void scheduleLeaseTimers() {
-        if (mDhcpLeaseExpiry == 0) {
-            Log.d(TAG, "Infinite lease, no timer scheduling needed");
-            return;
-        }
-
-        final long now = SystemClock.elapsedRealtime();
-
-        // TODO: consider getting the renew and rebind timers from T1 and T2.
-        // See also:
-        //     https://tools.ietf.org/html/rfc2131#section-4.4.5
-        //     https://tools.ietf.org/html/rfc1533#section-9.9
-        //     https://tools.ietf.org/html/rfc1533#section-9.10
-        final long remainingDelay = mDhcpLeaseExpiry - now;
-        final long renewDelay = remainingDelay / 2;
-        final long rebindDelay = remainingDelay * 7 / 8;
-        mRenewAlarm.schedule(now + renewDelay);
-        mRebindAlarm.schedule(now + rebindDelay);
-        mExpiryAlarm.schedule(now + remainingDelay);
-        Log.d(TAG, "Scheduling renewal in " + (renewDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling rebind in " + (rebindDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling expiry in " + (remainingDelay / 1000) + "s");
-    }
-
-    private void notifySuccess() {
-        mController.sendMessage(
-                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
-    }
-
-    private void notifyFailure() {
-        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
-    }
-
-    private void acceptDhcpResults(DhcpResults results, String msg) {
-        mDhcpLease = results;
-        if (mDhcpLease.dnsServers.isEmpty()) {
-            // supplement customized dns servers
-            String[] dnsServersList =
-                    mContext.getResources().getStringArray(R.array.config_default_dns_servers);
-            for (final String dnsServer : dnsServersList) {
-                try {
-                    mDhcpLease.dnsServers.add(InetAddresses.parseNumericAddress(dnsServer));
-                } catch (IllegalArgumentException e) {
-                    Log.e(TAG, "Invalid default DNS server: " + dnsServer, e);
-                }
-            }
-        }
-        mOffer = null;
-        Log.d(TAG, msg + " lease: " + mDhcpLease);
-        notifySuccess();
-    }
-
-    private void clearDhcpState() {
-        mDhcpLease = null;
-        mDhcpLeaseExpiry = 0;
-        mOffer = null;
-    }
-
-    /**
-     * Quit the DhcpStateMachine.
-     *
-     * @hide
-     */
-    public void doQuit() {
-        Log.d(TAG, "doQuit");
-        quit();
-    }
-
-    @Override
-    protected void onQuitting() {
-        Log.d(TAG, "onQuitting");
-        mController.sendMessage(CMD_ON_QUIT);
-    }
-
-    abstract class LoggingState extends State {
-        private long mEnterTimeMs;
-
-        @Override
-        public void enter() {
-            if (STATE_DBG) Log.d(TAG, "Entering state " + getName());
-            mEnterTimeMs = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public void exit() {
-            long durationMs = SystemClock.elapsedRealtime() - mEnterTimeMs;
-            logState(getName(), (int) durationMs);
-        }
-
-        private String messageName(int what) {
-            return sMessageNames.get(what, Integer.toString(what));
-        }
-
-        private String messageToString(Message message) {
-            long now = SystemClock.uptimeMillis();
-            return new StringBuilder(" ")
-                    .append(message.getWhen() - now)
-                    .append(messageName(message.what))
-                    .append(" ").append(message.arg1)
-                    .append(" ").append(message.arg2)
-                    .append(" ").append(message.obj)
-                    .toString();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (MSG_DBG) {
-                Log.d(TAG, getName() + messageToString(message));
-            }
-            return NOT_HANDLED;
-        }
-
-        @Override
-        public String getName() {
-            // All DhcpClient's states are inner classes with a well defined name.
-            // Use getSimpleName() and avoid super's getName() creating new String instances.
-            return getClass().getSimpleName();
-        }
-    }
-
-    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with
-    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.
-    abstract class WaitBeforeOtherState extends LoggingState {
-        protected State mOtherState;
-
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_PRE_DHCP_ACTION);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    transitionTo(mOtherState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class StoppedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_START_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeStartState);
-                    } else {
-                        transitionTo(mDhcpInitState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class WaitBeforeStartState extends WaitBeforeOtherState {
-        public WaitBeforeStartState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class WaitBeforeRenewalState extends WaitBeforeOtherState {
-        public WaitBeforeRenewalState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class DhcpState extends State {
-        @Override
-        public void enter() {
-            clearDhcpState();
-            if (initInterface() && initSockets()) {
-                mReceiveThread = new ReceiveThread();
-                mReceiveThread.start();
-            } else {
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mReceiveThread != null) {
-                mReceiveThread.halt();  // Also closes sockets.
-                mReceiveThread = null;
-            }
-            clearDhcpState();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    public boolean isValidPacket(DhcpPacket packet) {
-        // TODO: check checksum.
-        int xid = packet.getTransactionId();
-        if (xid != mTransactionId) {
-            Log.d(TAG, "Unexpected transaction ID " + xid + ", expected " + mTransactionId);
-            return false;
-        }
-        if (!Arrays.equals(packet.getClientMac(), mHwAddr)) {
-            Log.d(TAG, "MAC addr mismatch: got " +
-                    HexDump.toHexString(packet.getClientMac()) + ", expected " +
-                    HexDump.toHexString(packet.getClientMac()));
-            return false;
-        }
-        return true;
-    }
-
-    public void setDhcpLeaseExpiry(DhcpPacket packet) {
-        long leaseTimeMillis = packet.getLeaseTimeMillis();
-        mDhcpLeaseExpiry =
-                (leaseTimeMillis > 0) ? SystemClock.elapsedRealtime() + leaseTimeMillis : 0;
-    }
-
-    /**
-     * Retransmits packets using jittered exponential backoff with an optional timeout. Packet
-     * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. If a subclass
-     * sets mTimeout to a positive value, then timeout() is called by an AlarmManager alarm mTimeout
-     * milliseconds after entering the state. Kicks and timeouts are cancelled when leaving the
-     * state.
-     *
-     * Concrete subclasses must implement sendPacket, which is called when the alarm fires and a
-     * packet needs to be transmitted, and receivePacket, which is triggered by CMD_RECEIVED_PACKET
-     * sent by the receive thread. They may also set mTimeout and implement timeout.
-     */
-    abstract class PacketRetransmittingState extends LoggingState {
-
-        private int mTimer;
-        protected int mTimeout = 0;
-
-        @Override
-        public void enter() {
-            super.enter();
-            initTimer();
-            maybeInitTimeout();
-            sendMessage(CMD_KICK);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_KICK:
-                    sendPacket();
-                    scheduleKick();
-                    return HANDLED;
-                case CMD_RECEIVED_PACKET:
-                    receivePacket((DhcpPacket) message.obj);
-                    return HANDLED;
-                case CMD_TIMEOUT:
-                    timeout();
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mKickAlarm.cancel();
-            mTimeoutAlarm.cancel();
-        }
-
-        abstract protected boolean sendPacket();
-        abstract protected void receivePacket(DhcpPacket packet);
-        protected void timeout() {}
-
-        protected void initTimer() {
-            mTimer = FIRST_TIMEOUT_MS;
-        }
-
-        protected int jitterTimer(int baseTimer) {
-            int maxJitter = baseTimer / 10;
-            int jitter = mRandom.nextInt(2 * maxJitter) - maxJitter;
-            return baseTimer + jitter;
-        }
-
-        protected void scheduleKick() {
-            long now = SystemClock.elapsedRealtime();
-            long timeout = jitterTimer(mTimer);
-            long alarmTime = now + timeout;
-            mKickAlarm.schedule(alarmTime);
-            mTimer *= 2;
-            if (mTimer > MAX_TIMEOUT_MS) {
-                mTimer = MAX_TIMEOUT_MS;
-            }
-        }
-
-        protected void maybeInitTimeout() {
-            if (mTimeout > 0) {
-                long alarmTime = SystemClock.elapsedRealtime() + mTimeout;
-                mTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-    }
-
-    class DhcpInitState extends PacketRetransmittingState {
-        public DhcpInitState() {
-            super();
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-            mLastInitEnterTime = SystemClock.elapsedRealtime();
-        }
-
-        protected boolean sendPacket() {
-            return sendDiscoverPacket();
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if (!(packet instanceof DhcpOfferPacket)) return;
-            mOffer = packet.toDhcpResults();
-            if (mOffer != null) {
-                Log.d(TAG, "Got pending lease: " + mOffer);
-                transitionTo(mDhcpRequestingState);
-            }
-        }
-    }
-
-    // Not implemented. We request the first offer we receive.
-    class DhcpSelectingState extends LoggingState {
-    }
-
-    class DhcpRequestingState extends PacketRetransmittingState {
-        public DhcpRequestingState() {
-            mTimeout = DHCP_TIMEOUT_MS / 2;
-        }
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    INADDR_ANY,                                    // ciaddr
-                    (Inet4Address) mOffer.ipAddress.getAddress(),  // DHCP_REQUESTED_IP
-                    (Inet4Address) mOffer.serverAddress,           // DHCP_SERVER_IDENTIFIER
-                    INADDR_BROADCAST);                             // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    setDhcpLeaseExpiry(packet);
-                    acceptDhcpResults(results, "Confirmed");
-                    transitionTo(mConfiguringInterfaceState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                // TODO: Wait a while before returning into INIT state.
-                Log.d(TAG, "Received NAK, returning to INIT");
-                mOffer = null;
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected void timeout() {
-            // After sending REQUESTs unsuccessfully for a while, go back to init.
-            transitionTo(mDhcpInitState);
-        }
-    }
-
-    class DhcpHaveLeaseState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_EXPIRE_DHCP:
-                    Log.d(TAG, "Lease expired!");
-                    notifyFailure();
-                    transitionTo(mDhcpInitState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            // Clear any extant alarms.
-            mRenewAlarm.cancel();
-            mRebindAlarm.cancel();
-            mExpiryAlarm.cancel();
-            clearDhcpState();
-            // Tell IpManager to clear the IPv4 address. There is no need to
-            // wait for confirmation since any subsequent packets are sent from
-            // INADDR_ANY anyway (DISCOVER, REQUEST).
-            mController.sendMessage(CMD_CLEAR_LINKADDRESS);
-        }
-    }
-
-    class ConfiguringInterfaceState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_CONFIGURE_LINKADDRESS, mDhcpLease.ipAddress);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case EVENT_LINKADDRESS_CONFIGURED:
-                    transitionTo(mDhcpBoundState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class DhcpBoundState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            if (mDhcpLease.serverAddress != null && !connectUdpSock(mDhcpLease.serverAddress)) {
-                // There's likely no point in going into DhcpInitState here, we'll probably
-                // just repeat the transaction, get the same IP address as before, and fail.
-                //
-                // NOTE: It is observed that connectUdpSock() basically never fails, due to
-                // SO_BINDTODEVICE. Examining the local socket address shows it will happily
-                // return an IPv4 address from another interface, or even return "0.0.0.0".
-                //
-                // TODO: Consider deleting this check, following testing on several kernels.
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-
-            scheduleLeaseTimers();
-            logTimeToBoundState();
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mLastBoundExitTime = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_RENEW_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeRenewalState);
-                    } else {
-                        transitionTo(mDhcpRenewingState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void logTimeToBoundState() {
-            long now = SystemClock.elapsedRealtime();
-            if (mLastBoundExitTime > mLastInitEnterTime) {
-                logState(EVENT_RENEWING_BOUND, (int) (now - mLastBoundExitTime));
-            } else {
-                logState(EVENT_INITIAL_BOUND, (int) (now - mLastInitEnterTime));
-            }
-        }
-    }
-
-    abstract class DhcpReacquiringState extends PacketRetransmittingState {
-        protected String mLeaseMsg;
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-        }
-
-        abstract protected Inet4Address packetDestination();
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    (Inet4Address) mDhcpLease.ipAddress.getAddress(),  // ciaddr
-                    INADDR_ANY,                                        // DHCP_REQUESTED_IP
-                    null,                                              // DHCP_SERVER_IDENTIFIER
-                    packetDestination());                              // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                final DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
-                        Log.d(TAG, "Renewed lease not for our current IP address!");
-                        notifyFailure();
-                        transitionTo(mDhcpInitState);
-                    }
-                    setDhcpLeaseExpiry(packet);
-                    // Updating our notion of DhcpResults here only causes the
-                    // DNS servers and routes to be updated in LinkProperties
-                    // in IpManager and by any overridden relevant handlers of
-                    // the registered IpManager.Callback.  IP address changes
-                    // are not supported here.
-                    acceptDhcpResults(results, mLeaseMsg);
-                    transitionTo(mDhcpBoundState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                Log.d(TAG, "Received NAK, returning to INIT");
-                notifyFailure();
-                transitionTo(mDhcpInitState);
-            }
-        }
-    }
-
-    class DhcpRenewingState extends DhcpReacquiringState {
-        public DhcpRenewingState() {
-            mLeaseMsg = "Renewed";
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (super.processMessage(message) == HANDLED) {
-                return HANDLED;
-            }
-
-            switch (message.what) {
-                case CMD_REBIND_DHCP:
-                    transitionTo(mDhcpRebindingState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            // Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
-            // http://b/25343517 . Try to make things work anyway by using broadcast renews.
-            return (mDhcpLease.serverAddress != null) ?
-                    mDhcpLease.serverAddress : INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpRebindingState extends DhcpReacquiringState {
-        public DhcpRebindingState() {
-            mLeaseMsg = "Rebound";
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-
-            // We need to broadcast and possibly reconnect the socket to a
-            // completely different server.
-            closeSocketQuietly(mUdpSock);
-            if (!initUdpSocket()) {
-                Log.e(TAG, "Failed to recreate UDP socket");
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            return INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpInitRebootState extends LoggingState {
-    }
-
-    class DhcpRebootingState extends LoggingState {
-    }
-
-    private void logError(int errorCode) {
-        mMetricsLog.log(mIfaceName, new DhcpErrorEvent(errorCode));
-    }
-
-    private void logState(String name, int durationMs) {
-        final DhcpClientEvent event = new DhcpClientEvent.Builder()
-                .setMsg(name)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mIfaceName, event);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
deleted file mode 100644
index 7ecdea7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DECLINE packet.
- */
-class DhcpDeclinePacket extends DhcpPacket {
-    /**
-     * Generates a DECLINE packet with the specified parameters.
-     */
-    DhcpDeclinePacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                      Inet4Address nextIp, Inet4Address relayIp,
-                      byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DECLINE";
-    }
-
-    /**
-     * Fills in a packet with the requested DECLINE attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to the DECLINE packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DECLINE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        // RFC 2131 says we MUST NOT include our common client TLVs or the parameter request list.
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
deleted file mode 100644
index 11f2b61..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DISCOVER packet.
- */
-class DhcpDiscoverPacket extends DhcpPacket {
-    /**
-     * The IP address of the client which sent this packet.
-     */
-    final Inet4Address mSrcIp;
-
-    /**
-     * Generates a DISCOVER packet with the specified parameters.
-     */
-    DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast, Inet4Address srcIp) {
-        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-        mSrcIp = srcIp;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DISCOVER " +
-                (mBroadcast ? "broadcast " : "unicast ");
-    }
-
-    /**
-     * Fills in a packet with the requested DISCOVER parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
-                mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to a DISCOVER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DISCOVER);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
deleted file mode 100644
index 7a83466..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the (unused) DHCP-INFORM packet.
- */
-class DhcpInformPacket extends DhcpPacket {
-    /**
-     * Generates an INFORM packet with the specified parameters.
-     */
-    DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                     Inet4Address nextIp, Inet4Address relayIp,
-                     byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " INFORM";
-    }
-
-    /**
-     * Builds an INFORM packet.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds additional parameters to the INFORM packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
deleted file mode 100644
index 6849cfa..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.os.SystemClock;
-import android.text.TextUtils;
-
-import com.android.internal.util.HexDump;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * An IPv4 address assignment done through DHCPv4.
- * @hide
- */
-public class DhcpLease {
-    public static final long EXPIRATION_NEVER = Long.MAX_VALUE;
-    public static final String HOSTNAME_NONE = null;
-
-    @Nullable
-    private final byte[] mClientId;
-    @NonNull
-    private final MacAddress mHwAddr;
-    @NonNull
-    private final Inet4Address mNetAddr;
-    /**
-     * Expiration time for the lease, to compare with {@link SystemClock#elapsedRealtime()}.
-     */
-    private final long mExpTime;
-    @Nullable
-    private final String mHostname;
-
-    public DhcpLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address netAddr, long expTime, @Nullable String hostname) {
-        mClientId = (clientId == null ? null : Arrays.copyOf(clientId, clientId.length));
-        mHwAddr = hwAddr;
-        mNetAddr = netAddr;
-        mExpTime = expTime;
-        mHostname = hostname;
-    }
-
-    /**
-     * Get the clientId associated with this lease, if any.
-     *
-     * <p>If the lease is not associated to a clientId, this returns null.
-     */
-    @Nullable
-    public byte[] getClientId() {
-        if (mClientId == null) {
-            return null;
-        }
-        return Arrays.copyOf(mClientId, mClientId.length);
-    }
-
-    @NonNull
-    public MacAddress getHwAddr() {
-        return mHwAddr;
-    }
-
-    @Nullable
-    public String getHostname() {
-        return mHostname;
-    }
-
-    @NonNull
-    public Inet4Address getNetAddr() {
-        return mNetAddr;
-    }
-
-    public long getExpTime() {
-        return mExpTime;
-    }
-
-    /**
-     * Push back the expiration time of this lease. If the provided time is sooner than the original
-     * expiration time, the lease time will not be updated.
-     *
-     * <p>The lease hostname is updated with the provided one if set.
-     * @return A {@link DhcpLease} with expiration time set to max(expTime, currentExpTime)
-     */
-    public DhcpLease renewedLease(long expTime, @Nullable String hostname) {
-        return new DhcpLease(mClientId, mHwAddr, mNetAddr, Math.max(expTime, mExpTime),
-                (hostname == null ? mHostname : hostname));
-    }
-
-    /**
-     * Determine whether this lease matches a client with the specified parameters.
-     * @param clientId clientId of the client if any, or null otherwise.
-     * @param hwAddr Hardware address of the client.
-     */
-    public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        if (mClientId != null) {
-            return Arrays.equals(mClientId, clientId);
-        } else {
-            return clientId == null && mHwAddr.equals(hwAddr);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof DhcpLease)) {
-            return false;
-        }
-        final DhcpLease other = (DhcpLease) obj;
-        return Arrays.equals(mClientId, other.mClientId)
-                && mHwAddr.equals(other.mHwAddr)
-                && mNetAddr.equals(other.mNetAddr)
-                && mExpTime == other.mExpTime
-                && TextUtils.equals(mHostname, other.mHostname);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mClientId, mHwAddr, mNetAddr, mHostname, mExpTime);
-    }
-
-    static String clientIdToString(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        return HexDump.toHexString(bytes);
-    }
-
-    static String inet4AddrToString(@Nullable Inet4Address addr) {
-        return (addr == null) ? "null" : addr.getHostAddress();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("clientId: %s, hwAddr: %s, netAddr: %s, expTime: %d, hostname: %s",
-                clientIdToString(mClientId), mHwAddr.toString(), inet4AddrToString(mNetAddr),
-                mExpTime, mHostname);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
deleted file mode 100644
index 0a15cd7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.dhcp.DhcpLease.EXPIRATION_NEVER;
-import static android.net.dhcp.DhcpLease.inet4AddrToString;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_BITS;
-
-import static java.lang.Math.min;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-import android.util.ArrayMap;
-
-import java.net.Inet4Address;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * A repository managing IPv4 address assignments through DHCPv4.
- *
- * <p>This class is not thread-safe. All public methods should be called on a common thread or
- * use some synchronization mechanism.
- *
- * <p>Methods are optimized for a small number of allocated leases, assuming that most of the time
- * only 2~10 addresses will be allocated, which is the common case. Managing a large number of
- * addresses is supported but will be slower: some operations have complexity in O(num_leases).
- * @hide
- */
-class DhcpLeaseRepository {
-    public static final byte[] CLIENTID_UNSPEC = null;
-    public static final Inet4Address INETADDR_UNSPEC = null;
-
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Clock mClock;
-
-    @NonNull
-    private IpPrefix mPrefix;
-    @NonNull
-    private Set<Inet4Address> mReservedAddrs;
-    private int mSubnetAddr;
-    private int mSubnetMask;
-    private int mNumAddresses;
-    private long mLeaseTimeMs;
-
-    /**
-     * Next timestamp when committed or declined leases should be checked for expired ones. This
-     * will always be lower than or equal to the time for the first lease to expire: it's OK not to
-     * update this when removing entries, but it must always be updated when adding/updating.
-     */
-    private long mNextExpirationCheck = EXPIRATION_NEVER;
-
-    static class DhcpLeaseException extends Exception {
-        DhcpLeaseException(String message) {
-            super(message);
-        }
-    }
-
-    static class OutOfAddressesException extends DhcpLeaseException {
-        OutOfAddressesException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidAddressException extends DhcpLeaseException {
-        InvalidAddressException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidSubnetException extends DhcpLeaseException {
-        InvalidSubnetException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Leases by IP address
-     */
-    private final ArrayMap<Inet4Address, DhcpLease> mCommittedLeases = new ArrayMap<>();
-
-    /**
-     * Map address -> expiration timestamp in ms. Addresses are guaranteed to be valid as defined
-     * by {@link #isValidAddress(Inet4Address)}, but are not necessarily otherwise available for
-     * assignment.
-     */
-    private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>();
-
-    DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs, @NonNull SharedLog log, @NonNull Clock clock) {
-        updateParams(prefix, reservedAddrs, leaseTimeMs);
-        mLog = log;
-        mClock = clock;
-    }
-
-    public void updateParams(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs) {
-        mPrefix = prefix;
-        mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
-        mSubnetMask = prefixLengthToV4NetmaskIntHTH(prefix.getPrefixLength());
-        mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
-        mNumAddresses = 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
-        mLeaseTimeMs = leaseTimeMs;
-
-        cleanMap(mCommittedLeases);
-        cleanMap(mDeclinedAddrs);
-    }
-
-    /**
-     * From a map keyed by {@link Inet4Address}, remove entries where the key is invalid (as
-     * specified by {@link #isValidAddress(Inet4Address)}), or is a reserved address.
-     */
-    private <T> void cleanMap(Map<Inet4Address, T> map) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next().getKey();
-            if (!isValidAddress(addr) || mReservedAddrs.contains(addr)) {
-                it.remove();
-            }
-        }
-    }
-
-    /**
-     * Get a DHCP offer, to reply to a DHCPDISCOVER. Follows RFC2131 #4.3.1.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param relayAddr Internet address of the relay (giaddr), can be {@link Inet4Address#ANY}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param hostname Client-provided hostname, or {@link DhcpLease#HOSTNAME_NONE}
-     * @throws OutOfAddressesException The server does not have any available address
-     * @throws InvalidSubnetException The lease was requested from an unsupported subnet
-     */
-    @NonNull
-    public DhcpLease getOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address relayAddr, @Nullable Inet4Address reqAddr,
-            @Nullable String hostname) throws OutOfAddressesException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        final long expTime = currentTime + mLeaseTimeMs;
-
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-
-        final DhcpLease currentLease = findByClient(clientId, hwAddr);
-        final DhcpLease newLease;
-        if (currentLease != null) {
-            newLease = currentLease.renewedLease(expTime, hostname);
-            mLog.log("Offering extended lease " + newLease);
-            // Do not update lease time in the map: the offer is not committed yet.
-        } else if (reqAddr != null && isValidAddress(reqAddr) && isAvailable(reqAddr)) {
-            newLease = new DhcpLease(clientId, hwAddr, reqAddr, expTime, hostname);
-            mLog.log("Offering requested lease " + newLease);
-        } else {
-            newLease = makeNewOffer(clientId, hwAddr, expTime, hostname);
-            mLog.log("Offering new generated lease " + newLease);
-        }
-        return newLease;
-    }
-
-    private void checkValidRelayAddr(@Nullable Inet4Address relayAddr)
-            throws InvalidSubnetException {
-        // As per #4.3.1, addresses are assigned based on the relay address if present. This
-        // implementation only assigns addresses if the relayAddr is inside our configured subnet.
-        // This also applies when the client requested a specific address for consistency between
-        // requests, and with older behavior.
-        if (isIpAddrOutsidePrefix(mPrefix, relayAddr)) {
-            throw new InvalidSubnetException("Lease requested by relay from outside of subnet");
-        }
-    }
-
-    private static boolean isIpAddrOutsidePrefix(@NonNull IpPrefix prefix,
-            @Nullable Inet4Address addr) {
-        return addr != null && !addr.equals(IPV4_ADDR_ANY) && !prefix.contains(addr);
-    }
-
-    @Nullable
-    private DhcpLease findByClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        for (DhcpLease lease : mCommittedLeases.values()) {
-            if (lease.matchesClient(clientId, hwAddr)) {
-                return lease;
-            }
-        }
-
-        // Note this differs from dnsmasq behavior, which would match by hwAddr if clientId was
-        // given but no lease keyed on clientId matched. This would prevent one interface from
-        // obtaining multiple leases with different clientId.
-        return null;
-    }
-
-    /**
-     * Make a lease conformant to a client DHCPREQUEST or renew the client's existing lease,
-     * commit it to the repository and return it.
-     *
-     * <p>This method always succeeds and commits the lease if it does not throw, and has no side
-     * effects if it throws.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param sidSet Whether the server identifier was set in the request
-     * @return The newly created or renewed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    @NonNull
-    public DhcpLease requestLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address clientAddr, @NonNull Inet4Address relayAddr,
-            @Nullable Inet4Address reqAddr, boolean sidSet, @Nullable String hostname)
-            throws InvalidAddressException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-        final DhcpLease assignedLease = findByClient(clientId, hwAddr);
-
-        final Inet4Address leaseAddr = reqAddr != null ? reqAddr : clientAddr;
-        if (assignedLease != null) {
-            if (sidSet && reqAddr != null) {
-                // Client in SELECTING state; remove any current lease before creating a new one.
-                mCommittedLeases.remove(assignedLease.getNetAddr());
-            } else if (!assignedLease.getNetAddr().equals(leaseAddr)) {
-                // reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr.
-                // reqAddr set with sid not set (INIT-REBOOT): client verifying configuration.
-                // In both cases, throw if clientAddr or reqAddr does not match the known lease.
-                throw new InvalidAddressException("Incorrect address for client in "
-                        + (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING"));
-            }
-        }
-
-        // In the init-reboot case, RFC2131 #4.3.2 says that the server must not reply if
-        // assignedLease == null, but dnsmasq will let the client use the requested address if
-        // available, when configured with --dhcp-authoritative. This is preferable to avoid issues
-        // if the server lost the lease DB: the client would not get a reply because the server
-        // does not know their lease.
-        // Similarly in RENEWING/REBINDING state, create a lease when possible if the
-        // client-provided lease is unknown.
-        final DhcpLease lease =
-                checkClientAndMakeLease(clientId, hwAddr, leaseAddr, hostname, currentTime);
-        mLog.logf("DHCPREQUEST assignedLease %s, reqAddr=%s, sidSet=%s: created/renewed lease %s",
-                assignedLease, inet4AddrToString(reqAddr), sidSet, lease);
-        return lease;
-    }
-
-    /**
-     * Check that the client can request the specified address, make or renew the lease if yes, and
-     * commit it.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw, and has no
-     * side-effect if it throws.
-     *
-     * @return The newly created or renewed, committed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    private DhcpLease checkClientAndMakeLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr, @Nullable String hostname, long currentTime)
-            throws InvalidAddressException {
-        final long expTime = currentTime + mLeaseTimeMs;
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease != null && !currentLease.matchesClient(clientId, hwAddr)) {
-            throw new InvalidAddressException("Address in use");
-        }
-
-        final DhcpLease lease;
-        if (currentLease == null) {
-            if (isValidAddress(addr) && !mReservedAddrs.contains(addr)) {
-                lease = new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            } else {
-                throw new InvalidAddressException("Lease not found and address unavailable");
-            }
-        } else {
-            lease = currentLease.renewedLease(expTime, hostname);
-        }
-        commitLease(lease);
-        return lease;
-    }
-
-    private void commitLease(@NonNull DhcpLease lease) {
-        mCommittedLeases.put(lease.getNetAddr(), lease);
-        maybeUpdateEarliestExpiration(lease.getExpTime());
-    }
-
-    /**
-     * Delete a committed lease from the repository.
-     *
-     * @return true if a lease matching parameters was found.
-     */
-    public boolean releaseLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr) {
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease == null) {
-            mLog.w("Could not release unknown lease for " + inet4AddrToString(addr));
-            return false;
-        }
-        if (currentLease.matchesClient(clientId, hwAddr)) {
-            mCommittedLeases.remove(addr);
-            mLog.log("Released lease " + currentLease);
-            return true;
-        }
-        mLog.w(String.format("Not releasing lease %s: does not match client (cid %s, hwAddr %s)",
-                currentLease, DhcpLease.clientIdToString(clientId), hwAddr));
-        return false;
-    }
-
-    public void markLeaseDeclined(@NonNull Inet4Address addr) {
-        if (mDeclinedAddrs.containsKey(addr) || !isValidAddress(addr)) {
-            mLog.logf("Not marking %s as declined: already declined or not assignable",
-                    inet4AddrToString(addr));
-            return;
-        }
-        final long expTime = mClock.elapsedRealtime() + mLeaseTimeMs;
-        mDeclinedAddrs.put(addr, expTime);
-        mLog.logf("Marked %s as declined expiring %d", inet4AddrToString(addr), expTime);
-        maybeUpdateEarliestExpiration(expTime);
-    }
-
-    /**
-     * Get the list of currently valid committed leases in the repository.
-     */
-    @NonNull
-    public List<DhcpLease> getCommittedLeases() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new ArrayList<>(mCommittedLeases.values());
-    }
-
-    /**
-     * Get the set of addresses that have been marked as declined in the repository.
-     */
-    @NonNull
-    public Set<Inet4Address> getDeclinedAddresses() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new HashSet<>(mDeclinedAddrs.keySet());
-    }
-
-    /**
-     * Given the expiration time of a new committed lease or declined address, update
-     * {@link #mNextExpirationCheck} so it stays lower than or equal to the time for the first lease
-     * to expire.
-     */
-    private void maybeUpdateEarliestExpiration(long expTime) {
-        if (expTime < mNextExpirationCheck) {
-            mNextExpirationCheck = expTime;
-        }
-    }
-
-    /**
-     * Remove expired entries from a map keyed by {@link Inet4Address}.
-     *
-     * @param tag Type of lease in the map, for logging
-     * @param getExpTime Functor returning the expiration time for an object in the map.
-     *                   Must not return null.
-     * @return The lowest expiration time among entries remaining in the map
-     */
-    private <T> long removeExpired(long currentTime, @NonNull Map<Inet4Address, T> map,
-            @NonNull String tag, @NonNull Function<T, Long> getExpTime) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        long firstExpiration = EXPIRATION_NEVER;
-        while (it.hasNext()) {
-            final Entry<Inet4Address, T> lease = it.next();
-            final long expTime = getExpTime.apply(lease.getValue());
-            if (expTime <= currentTime) {
-                mLog.logf("Removing expired %s lease for %s (expTime=%s, currentTime=%s)",
-                        tag, lease.getKey(), expTime, currentTime);
-                it.remove();
-            } else {
-                firstExpiration = min(firstExpiration, expTime);
-            }
-        }
-        return firstExpiration;
-    }
-
-    /**
-     * Go through committed and declined leases and remove the expired ones.
-     */
-    private void removeExpiredLeases(long currentTime) {
-        if (currentTime < mNextExpirationCheck) {
-            return;
-        }
-
-        final long commExp = removeExpired(
-                currentTime, mCommittedLeases, "committed", DhcpLease::getExpTime);
-        final long declExp = removeExpired(
-                currentTime, mDeclinedAddrs, "declined", Function.identity());
-
-        mNextExpirationCheck = min(commExp, declExp);
-    }
-
-    private boolean isAvailable(@NonNull Inet4Address addr) {
-        return !mReservedAddrs.contains(addr) && !mCommittedLeases.containsKey(addr);
-    }
-
-    /**
-     * Get the 0-based index of an address in the subnet.
-     *
-     * <p>Given ordering of addresses 5.6.7.8 < 5.6.7.9 < 5.6.8.0, the index on a subnet is defined
-     * so that the first address is 0, the second 1, etc. For example on a /16, 192.168.0.0 -> 0,
-     * 192.168.0.1 -> 1, 192.168.1.0 -> 256
-     *
-     */
-    private int getAddrIndex(int addr) {
-        return addr & ~mSubnetMask;
-    }
-
-    private int getAddrByIndex(int index) {
-        return mSubnetAddr | index;
-    }
-
-    /**
-     * Get a valid address starting from the supplied one.
-     *
-     * <p>This only checks that the address is numerically valid for assignment, not whether it is
-     * already in use. The return value is always inside the configured prefix, even if the supplied
-     * address is not.
-     *
-     * <p>If the provided address is valid, it is returned as-is. Otherwise, the next valid
-     * address (with the ordering in {@link #getAddrIndex(int)}) is returned.
-     */
-    private int getValidAddress(int addr) {
-        final int lastByteMask = 0xff;
-        int addrIndex = getAddrIndex(addr); // 0-based index of the address in the subnet
-
-        // Some OSes do not handle addresses in .255 or .0 correctly: avoid those.
-        final int lastByte = getAddrByIndex(addrIndex) & lastByteMask;
-        if (lastByte == lastByteMask) {
-            // Avoid .255 address, and .0 address that follows
-            addrIndex = (addrIndex + 2) % mNumAddresses;
-        } else if (lastByte == 0) {
-            // Avoid .0 address
-            addrIndex = (addrIndex + 1) % mNumAddresses;
-        }
-
-        // Do not use first or last address of range
-        if (addrIndex == 0 || addrIndex == mNumAddresses - 1) {
-            // Always valid and not end of range since prefixLength is at most 30 in serving params
-            addrIndex = 1;
-        }
-        return getAddrByIndex(addrIndex);
-    }
-
-    /**
-     * Returns whether the address is in the configured subnet and part of the assignable range.
-     */
-    private boolean isValidAddress(Inet4Address addr) {
-        final int intAddr = inet4AddressToIntHTH(addr);
-        return getValidAddress(intAddr) == intAddr;
-    }
-
-    private int getNextAddress(int addr) {
-        final int addrIndex = getAddrIndex(addr);
-        final int nextAddress = getAddrByIndex((addrIndex + 1) % mNumAddresses);
-        return getValidAddress(nextAddress);
-    }
-
-    /**
-     * Calculate a first candidate address for a client by hashing the hardware address.
-     *
-     * <p>This will be a valid address as checked by {@link #getValidAddress(int)}, but may be
-     * in use.
-     *
-     * @return An IPv4 address encoded as 32-bit int
-     */
-    private int getFirstClientAddress(MacAddress hwAddr) {
-        // This follows dnsmasq behavior. Advantages are: clients will often get the same
-        // offers for different DISCOVER even if the lease was not yet accepted or has expired,
-        // and address generation will generally not need to loop through many allocated addresses
-        // until it finds a free one.
-        int hash = 0;
-        for (byte b : hwAddr.toByteArray()) {
-            hash += b + (b << 8) + (b << 16);
-        }
-        // This implementation will not always result in the same IPs as dnsmasq would give out in
-        // Android <= P, because it includes invalid and reserved addresses in mNumAddresses while
-        // the configured ranges for dnsmasq did not.
-        final int addrIndex = hash % mNumAddresses;
-        return getValidAddress(getAddrByIndex(addrIndex));
-    }
-
-    /**
-     * Create a lease that can be offered to respond to a client DISCOVER.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw. If no non-declined
-     * address is available, it will try to offer the oldest declined address if valid.
-     *
-     * @throws OutOfAddressesException The server has no address left to offer
-     */
-    private DhcpLease makeNewOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            long expTime, @Nullable String hostname) throws OutOfAddressesException {
-        int intAddr = getFirstClientAddress(hwAddr);
-        // Loop until a free address is found, or there are no more addresses.
-        // There is slightly less than this many usable addresses, but some extra looping is OK
-        for (int i = 0; i < mNumAddresses; i++) {
-            final Inet4Address addr = intToInet4AddressHTH(intAddr);
-            if (isAvailable(addr) && !mDeclinedAddrs.containsKey(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-            intAddr = getNextAddress(intAddr);
-        }
-
-        // Try freeing DECLINEd addresses if out of addresses.
-        final Iterator<Inet4Address> it = mDeclinedAddrs.keySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next();
-            it.remove();
-            mLog.logf("Out of addresses in address pool: dropped declined addr %s",
-                    inet4AddrToString(addr));
-            // isValidAddress() is always verified for entries in mDeclinedAddrs.
-            // However declined addresses may have been requested (typically by the machine that was
-            // already using the address) after being declined.
-            if (isAvailable(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-        }
-
-        throw new OutOfAddressesException("No address available for offer");
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
deleted file mode 100644
index 1da0b73..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-NAK packet.
- */
-class DhcpNakPacket extends DhcpPacket {
-    /**
-     * Generates a NAK packet with the specified parameters.
-     */
-    DhcpNakPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast) {
-        super(transId, secs, INADDR_ANY /* clientIp */, INADDR_ANY /* yourIp */,
-                INADDR_ANY /* nextIp */, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " NAK, reason " + (mMessage == null ? "(none)" : mMessage);
-    }
-
-    /**
-     * Fills in a packet with the requested NAK attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        // Constructor does not set values for layers <= 3: use empty values
-        Inet4Address destIp = INADDR_ANY;
-        Inet4Address srcIp = INADDR_ANY;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated NAK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_NAK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addTlv(buffer, DHCP_MESSAGE, mMessage);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
deleted file mode 100644
index 0eba77e..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-OFFER packet.
- */
-class DhcpOfferPacket extends DhcpPacket {
-    /**
-     * The IP address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    /**
-     * Generates a OFFER packet with the specified parameters.
-     */
-    DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = ", DNS servers: ";
-
-        if (mDnsServers != null) {
-            for (Inet4Address dnsServer: mDnsServers) {
-                dnsServers += dnsServer + " ";
-            }
-        }
-
-        return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
-                dnsServers + ", gateways " + mGateways +
-                " lease time " + mLeaseTime + ", domain " + mDomainName;
-    }
-
-    /**
-     * Fills in a packet with the specified OFFER attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the server-generated OFFER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_OFFER);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
deleted file mode 100644
index a15d423..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
+++ /dev/null
@@ -1,1397 +0,0 @@
-package android.net.dhcp;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.shared.Inet4AddressUtils;
-import android.os.Build;
-import android.os.SystemProperties;
-import android.system.OsConstants;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.UnsupportedEncodingException;
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.ShortBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Defines basic data and operations needed to build and use packets for the
- * DHCP protocol.  Subclasses create the specific packets used at each
- * stage of the negotiation.
- *
- * @hide
- */
-public abstract class DhcpPacket {
-    protected static final String TAG = "DhcpPacket";
-
-    // TODO: use NetworkStackConstants.IPV4_MIN_MTU once this class is moved to the network stack.
-    private static final int IPV4_MIN_MTU = 68;
-
-    // dhcpcd has a minimum lease of 20 seconds, but DhcpStateMachine would refuse to wake up the
-    // CPU for anything shorter than 5 minutes. For sanity's sake, this must be higher than the
-    // DHCP client timeout.
-    public static final int MINIMUM_LEASE = 60;
-    public static final int INFINITE_LEASE = (int) 0xffffffff;
-
-    public static final Inet4Address INADDR_ANY = IPV4_ADDR_ANY;
-    public static final Inet4Address INADDR_BROADCAST = IPV4_ADDR_ALL;
-    public static final byte[] ETHER_BROADCAST = new byte[] {
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-    };
-
-    /**
-     * Packet encapsulations.
-     */
-    public static final int ENCAP_L2 = 0;    // EthernetII header included
-    public static final int ENCAP_L3 = 1;    // IP/UDP header included
-    public static final int ENCAP_BOOTP = 2; // BOOTP contents only
-
-    /**
-     * Minimum length of a DHCP packet, excluding options, in the above encapsulations.
-     */
-    public static final int MIN_PACKET_LENGTH_BOOTP = 236;  // See diagram in RFC 2131, section 2.
-    public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
-    public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
-
-    public static final int HWADDR_LEN = 16;
-    public static final int MAX_OPTION_LEN = 255;
-
-    /**
-     * The minimum and maximum MTU that we are prepared to use. We set the minimum to the minimum
-     * IPv6 MTU because the IPv6 stack enters unusual codepaths when the link MTU drops below 1280,
-     * and does not recover if the MTU is brought above 1280 again. We set the maximum to 1500
-     * because in general it is risky to assume that the hardware is able to send/receive packets
-     * larger than 1500 bytes even if the network supports it.
-     */
-    private static final int MIN_MTU = 1280;
-    private static final int MAX_MTU = 1500;
-
-    /**
-     * IP layer definitions.
-     */
-    private static final byte IP_TYPE_UDP = (byte) 0x11;
-
-    /**
-     * IP: Version 4, Header Length 20 bytes
-     */
-    private static final byte IP_VERSION_HEADER_LEN = (byte) 0x45;
-
-    /**
-     * IP: Flags 0, Fragment Offset 0, Don't Fragment
-     */
-    private static final short IP_FLAGS_OFFSET = (short) 0x4000;
-
-    /**
-     * IP: TOS
-     */
-    private static final byte IP_TOS_LOWDELAY = (byte) 0x10;
-
-    /**
-     * IP: TTL -- use default 64 from RFC1340
-     */
-    private static final byte IP_TTL = (byte) 0x40;
-
-    /**
-     * The client DHCP port.
-     */
-    static final short DHCP_CLIENT = (short) 68;
-
-    /**
-     * The server DHCP port.
-     */
-    static final short DHCP_SERVER = (short) 67;
-
-    /**
-     * The message op code indicating a request from a client.
-     */
-    protected static final byte DHCP_BOOTREQUEST = (byte) 1;
-
-    /**
-     * The message op code indicating a response from the server.
-     */
-    protected static final byte DHCP_BOOTREPLY = (byte) 2;
-
-    /**
-     * The code type used to identify an Ethernet MAC address in the
-     * Client-ID field.
-     */
-    protected static final byte CLIENT_ID_ETHER = (byte) 1;
-
-    /**
-     * The maximum length of a packet that can be constructed.
-     */
-    protected static final int MAX_LENGTH = 1500;
-
-    /**
-     * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
-     */
-    private static final int DHCP_MAGIC_COOKIE = 0x63825363;
-
-    /**
-     * DHCP Optional Type: DHCP Subnet Mask
-     */
-    protected static final byte DHCP_SUBNET_MASK = 1;
-    protected Inet4Address mSubnetMask;
-
-    /**
-     * DHCP Optional Type: DHCP Router
-     */
-    protected static final byte DHCP_ROUTER = 3;
-    protected List <Inet4Address> mGateways;
-
-    /**
-     * DHCP Optional Type: DHCP DNS Server
-     */
-    protected static final byte DHCP_DNS_SERVER = 6;
-    protected List<Inet4Address> mDnsServers;
-
-    /**
-     * DHCP Optional Type: DHCP Host Name
-     */
-    protected static final byte DHCP_HOST_NAME = 12;
-    protected String mHostName;
-
-    /**
-     * DHCP Optional Type: DHCP DOMAIN NAME
-     */
-    protected static final byte DHCP_DOMAIN_NAME = 15;
-    protected String mDomainName;
-
-    /**
-     * DHCP Optional Type: DHCP Interface MTU
-     */
-    protected static final byte DHCP_MTU = 26;
-    protected Short mMtu;
-
-    /**
-     * DHCP Optional Type: DHCP BROADCAST ADDRESS
-     */
-    protected static final byte DHCP_BROADCAST_ADDRESS = 28;
-    protected Inet4Address mBroadcastAddress;
-
-    /**
-     * DHCP Optional Type: Vendor specific information
-     */
-    protected static final byte DHCP_VENDOR_INFO = 43;
-    protected String mVendorInfo;
-
-    /**
-     * Value of the vendor specific option used to indicate that the network is metered
-     */
-    public static final String VENDOR_INFO_ANDROID_METERED = "ANDROID_METERED";
-
-    /**
-     * DHCP Optional Type: Option overload option
-     */
-    protected static final byte DHCP_OPTION_OVERLOAD = 52;
-
-    /**
-     * Possible values of the option overload option.
-     */
-    private static final byte OPTION_OVERLOAD_FILE = 1;
-    private static final byte OPTION_OVERLOAD_SNAME = 2;
-    private static final byte OPTION_OVERLOAD_BOTH = 3;
-
-    /**
-     * DHCP Optional Type: DHCP Requested IP Address
-     */
-    protected static final byte DHCP_REQUESTED_IP = 50;
-    protected Inet4Address mRequestedIp;
-
-    /**
-     * DHCP Optional Type: DHCP Lease Time
-     */
-    protected static final byte DHCP_LEASE_TIME = 51;
-    protected Integer mLeaseTime;
-
-    /**
-     * DHCP Optional Type: DHCP Message Type
-     */
-    protected static final byte DHCP_MESSAGE_TYPE = 53;
-    // the actual type values
-    protected static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
-    protected static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
-    protected static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
-    protected static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
-    protected static final byte DHCP_MESSAGE_TYPE_ACK = 5;
-    protected static final byte DHCP_MESSAGE_TYPE_NAK = 6;
-    protected static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
-    protected static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
-
-    /**
-     * DHCP Optional Type: DHCP Server Identifier
-     */
-    protected static final byte DHCP_SERVER_IDENTIFIER = 54;
-    protected Inet4Address mServerIdentifier;
-
-    /**
-     * DHCP Optional Type: DHCP Parameter List
-     */
-    protected static final byte DHCP_PARAMETER_LIST = 55;
-    protected byte[] mRequestedParams;
-
-    /**
-     * DHCP Optional Type: DHCP MESSAGE
-     */
-    protected static final byte DHCP_MESSAGE = 56;
-    protected String mMessage;
-
-    /**
-     * DHCP Optional Type: Maximum DHCP Message Size
-     */
-    protected static final byte DHCP_MAX_MESSAGE_SIZE = 57;
-    protected Short mMaxMessageSize;
-
-    /**
-     * DHCP Optional Type: DHCP Renewal Time Value
-     */
-    protected static final byte DHCP_RENEWAL_TIME = 58;
-    protected Integer mT1;
-
-    /**
-     * DHCP Optional Type: Rebinding Time Value
-     */
-    protected static final byte DHCP_REBINDING_TIME = 59;
-    protected Integer mT2;
-
-    /**
-     * DHCP Optional Type: Vendor Class Identifier
-     */
-    protected static final byte DHCP_VENDOR_CLASS_ID = 60;
-    protected String mVendorId;
-
-    /**
-     * DHCP Optional Type: DHCP Client Identifier
-     */
-    protected static final byte DHCP_CLIENT_IDENTIFIER = 61;
-    protected byte[] mClientId;
-
-    /**
-     * DHCP zero-length option code: pad
-     */
-    protected static final byte DHCP_OPTION_PAD = 0x00;
-
-    /**
-     * DHCP zero-length option code: end of options
-     */
-    protected static final byte DHCP_OPTION_END = (byte) 0xff;
-
-    /**
-     * The transaction identifier used in this particular DHCP negotiation
-     */
-    protected final int mTransId;
-
-    /**
-     * The seconds field in the BOOTP header. Per RFC, should be nonzero in client requests only.
-     */
-    protected final short mSecs;
-
-    /**
-     * The IP address of the client host.  This address is typically
-     * proposed by the client (from an earlier DHCP negotiation) or
-     * supplied by the server.
-     */
-    protected final Inet4Address mClientIp;
-    protected final Inet4Address mYourIp;
-    private final Inet4Address mNextIp;
-    protected final Inet4Address mRelayIp;
-
-    /**
-     * Does the client request a broadcast response?
-     */
-    protected boolean mBroadcast;
-
-    /**
-     * The six-octet MAC of the client.
-     */
-    protected final byte[] mClientMac;
-
-    /**
-     * The server host name from server.
-     */
-    protected String mServerHostName;
-
-    /**
-     * Asks the packet object to create a ByteBuffer serialization of
-     * the packet for transmission.
-     */
-    public abstract ByteBuffer buildPacket(int encap, short destUdp,
-        short srcUdp);
-
-    /**
-     * Allows the concrete class to fill in packet-type-specific details,
-     * typically optional parameters at the end of the packet.
-     */
-    abstract void finishPacket(ByteBuffer buffer);
-
-    // Set in unit tests, to ensure that the test does not break when run on different devices and
-    // on different releases.
-    static String testOverrideVendorId = null;
-    static String testOverrideHostname = null;
-
-    protected DhcpPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                         Inet4Address nextIp, Inet4Address relayIp,
-                         byte[] clientMac, boolean broadcast) {
-        mTransId = transId;
-        mSecs = secs;
-        mClientIp = clientIp;
-        mYourIp = yourIp;
-        mNextIp = nextIp;
-        mRelayIp = relayIp;
-        mClientMac = clientMac;
-        mBroadcast = broadcast;
-    }
-
-    /**
-     * Returns the transaction ID.
-     */
-    public int getTransactionId() {
-        return mTransId;
-    }
-
-    /**
-     * Returns the client MAC.
-     */
-    public byte[] getClientMac() {
-        return mClientMac;
-    }
-
-    // TODO: refactor DhcpClient to set clientId when constructing packets and remove
-    // hasExplicitClientId logic
-    /**
-     * Returns whether a client ID was set in the options for this packet.
-     */
-    public boolean hasExplicitClientId() {
-        return mClientId != null;
-    }
-
-    /**
-     * Convenience method to return the client ID if it was set explicitly, or null otherwise.
-     */
-    @Nullable
-    public byte[] getExplicitClientIdOrNull() {
-        return hasExplicitClientId() ? getClientId() : null;
-    }
-
-    /**
-     * Returns the client ID. If not set explicitly, this follows RFC 2132 and creates a client ID
-     * based on the hardware address.
-     */
-    public byte[] getClientId() {
-        final byte[] clientId;
-        if (hasExplicitClientId()) {
-            clientId = Arrays.copyOf(mClientId, mClientId.length);
-        } else {
-            clientId = new byte[mClientMac.length + 1];
-            clientId[0] = CLIENT_ID_ETHER;
-            System.arraycopy(mClientMac, 0, clientId, 1, mClientMac.length);
-        }
-        return clientId;
-    }
-
-    /**
-     * Returns whether a parameter is included in the parameter request list option of this packet.
-     *
-     * <p>If there is no parameter request list option in the packet, false is returned.
-     *
-     * @param paramId ID of the parameter, such as {@link #DHCP_MTU} or {@link #DHCP_HOST_NAME}.
-     */
-    public boolean hasRequestedParam(byte paramId) {
-        if (mRequestedParams == null) {
-            return false;
-        }
-
-        for (byte reqParam : mRequestedParams) {
-            if (reqParam == paramId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Creates a new L3 packet (including IP header) containing the
-     * DHCP udp packet.  This method relies upon the delegated method
-     * finishPacket() to insert the per-packet contents.
-     */
-    protected void fillInPacket(int encap, Inet4Address destIp,
-        Inet4Address srcIp, short destUdp, short srcUdp, ByteBuffer buf,
-        byte requestCode, boolean broadcast) {
-        byte[] destIpArray = destIp.getAddress();
-        byte[] srcIpArray = srcIp.getAddress();
-        int ipHeaderOffset = 0;
-        int ipLengthOffset = 0;
-        int ipChecksumOffset = 0;
-        int endIpHeader = 0;
-        int udpHeaderOffset = 0;
-        int udpLengthOffset = 0;
-        int udpChecksumOffset = 0;
-
-        buf.clear();
-        buf.order(ByteOrder.BIG_ENDIAN);
-
-        if (encap == ENCAP_L2) {
-            buf.put(ETHER_BROADCAST);
-            buf.put(mClientMac);
-            buf.putShort((short) OsConstants.ETH_P_IP);
-        }
-
-        // if a full IP packet needs to be generated, put the IP & UDP
-        // headers in place, and pre-populate with artificial values
-        // needed to seed the IP checksum.
-        if (encap <= ENCAP_L3) {
-            ipHeaderOffset = buf.position();
-            buf.put(IP_VERSION_HEADER_LEN);
-            buf.put(IP_TOS_LOWDELAY);    // tos: IPTOS_LOWDELAY
-            ipLengthOffset = buf.position();
-            buf.putShort((short)0);  // length
-            buf.putShort((short)0);  // id
-            buf.putShort(IP_FLAGS_OFFSET); // ip offset: don't fragment
-            buf.put(IP_TTL);    // TTL: use default 64 from RFC1340
-            buf.put(IP_TYPE_UDP);
-            ipChecksumOffset = buf.position();
-            buf.putShort((short) 0); // checksum
-
-            buf.put(srcIpArray);
-            buf.put(destIpArray);
-            endIpHeader = buf.position();
-
-            // UDP header
-            udpHeaderOffset = buf.position();
-            buf.putShort(srcUdp);
-            buf.putShort(destUdp);
-            udpLengthOffset = buf.position();
-            buf.putShort((short) 0); // length
-            udpChecksumOffset = buf.position();
-            buf.putShort((short) 0); // UDP checksum -- initially zero
-        }
-
-        // DHCP payload
-        buf.put(requestCode);
-        buf.put((byte) 1); // Hardware Type: Ethernet
-        buf.put((byte) mClientMac.length); // Hardware Address Length
-        buf.put((byte) 0); // Hop Count
-        buf.putInt(mTransId);  // Transaction ID
-        buf.putShort(mSecs); // Elapsed Seconds
-
-        if (broadcast) {
-            buf.putShort((short) 0x8000); // Flags
-        } else {
-            buf.putShort((short) 0x0000); // Flags
-        }
-
-        buf.put(mClientIp.getAddress());
-        buf.put(mYourIp.getAddress());
-        buf.put(mNextIp.getAddress());
-        buf.put(mRelayIp.getAddress());
-        buf.put(mClientMac);
-        buf.position(buf.position() +
-                     (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
-                     + 64     // empty server host name (64 bytes)
-                     + 128);  // empty boot file name (128 bytes)
-        buf.putInt(DHCP_MAGIC_COOKIE); // magic number
-        finishPacket(buf);
-
-        // round up to an even number of octets
-        if ((buf.position() & 1) == 1) {
-            buf.put((byte) 0);
-        }
-
-        // If an IP packet is being built, the IP & UDP checksums must be
-        // computed.
-        if (encap <= ENCAP_L3) {
-            // fix UDP header: insert length
-            short udpLen = (short)(buf.position() - udpHeaderOffset);
-            buf.putShort(udpLengthOffset, udpLen);
-            // fix UDP header: checksum
-            // checksum for UDP at udpChecksumOffset
-            int udpSeed = 0;
-
-            // apply IPv4 pseudo-header.  Read IP address src and destination
-            // values from the IP header and accumulate checksum.
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 2));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 4));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 6));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 8));
-
-            // accumulate extra data for the pseudo-header
-            udpSeed += IP_TYPE_UDP;
-            udpSeed += udpLen;
-            // and compute UDP checksum
-            buf.putShort(udpChecksumOffset, (short) checksum(buf, udpSeed,
-                                                             udpHeaderOffset,
-                                                             buf.position()));
-            // fix IP header: insert length
-            buf.putShort(ipLengthOffset, (short)(buf.position() - ipHeaderOffset));
-            // fixup IP-header checksum
-            buf.putShort(ipChecksumOffset,
-                         (short) checksum(buf, 0, ipHeaderOffset, endIpHeader));
-        }
-    }
-
-    /**
-     * Converts a signed short value to an unsigned int value.  Needed
-     * because Java does not have unsigned types.
-     */
-    private static int intAbs(short v) {
-        return v & 0xFFFF;
-    }
-
-    /**
-     * Performs an IP checksum (used in IP header and across UDP
-     * payload) on the specified portion of a ByteBuffer.  The seed
-     * allows the checksum to commence with a specified value.
-     */
-    private int checksum(ByteBuffer buf, int seed, int start, int end) {
-        int sum = seed;
-        int bufPosition = buf.position();
-
-        // set position of original ByteBuffer, so that the ShortBuffer
-        // will be correctly initialized
-        buf.position(start);
-        ShortBuffer shortBuf = buf.asShortBuffer();
-
-        // re-set ByteBuffer position
-        buf.position(bufPosition);
-
-        short[] shortArray = new short[(end - start) / 2];
-        shortBuf.get(shortArray);
-
-        for (short s : shortArray) {
-            sum += intAbs(s);
-        }
-
-        start += shortArray.length * 2;
-
-        // see if a singleton byte remains
-        if (end != start) {
-            short b = buf.get(start);
-
-            // make it unsigned
-            if (b < 0) {
-                b += 256;
-            }
-
-            sum += b * 256;
-        }
-
-        sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
-        sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF);
-        int negated = ~sum;
-        return intAbs((short) negated);
-    }
-
-    /**
-     * Adds an optional parameter containing a single byte value.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, byte value) {
-        buf.put(type);
-        buf.put((byte) 1);
-        buf.put(value);
-    }
-
-    /**
-     * Adds an optional parameter containing an array of bytes.
-     *
-     * <p>This method is a no-op if the payload argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable byte[] payload) {
-        if (payload != null) {
-            if (payload.length > MAX_OPTION_LEN) {
-                throw new IllegalArgumentException("DHCP option too long: "
-                        + payload.length + " vs. " + MAX_OPTION_LEN);
-            }
-            buf.put(type);
-            buf.put((byte) payload.length);
-            buf.put(payload);
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an IP address.
-     *
-     * <p>This method is a no-op if the address argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Inet4Address addr) {
-        if (addr != null) {
-            addTlv(buf, type, addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a list of IP addresses.
-     *
-     * <p>This method is a no-op if the addresses argument is null or empty.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable List<Inet4Address> addrs) {
-        if (addrs == null || addrs.size() == 0) return;
-
-        int optionLen = 4 * addrs.size();
-        if (optionLen > MAX_OPTION_LEN) {
-            throw new IllegalArgumentException("DHCP option too long: "
-                    + optionLen + " vs. " + MAX_OPTION_LEN);
-        }
-
-        buf.put(type);
-        buf.put((byte)(optionLen));
-
-        for (Inet4Address addr : addrs) {
-            buf.put(addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a short integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Short value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 2);
-            buf.putShort(value.shortValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a simple integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Integer value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 4);
-            buf.putInt(value.intValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an ASCII string.
-     *
-     * <p>This method is a no-op if the string argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable String str) {
-        if (str != null) {
-            try {
-                addTlv(buf, type, str.getBytes("US-ASCII"));
-            } catch (UnsupportedEncodingException e) {
-                throw new IllegalArgumentException("String is not US-ASCII: " + str);
-            }
-        }
-    }
-
-    /**
-     * Adds the special end-of-optional-parameters indicator.
-     */
-    protected static void addTlvEnd(ByteBuffer buf) {
-        buf.put((byte) 0xFF);
-    }
-
-    private String getVendorId() {
-        if (testOverrideVendorId != null) return testOverrideVendorId;
-        return "android-dhcp-" + Build.VERSION.RELEASE;
-    }
-
-    private String getHostname() {
-        if (testOverrideHostname != null) return testOverrideHostname;
-        return SystemProperties.get("net.hostname");
-    }
-
-    /**
-     * Adds common client TLVs.
-     *
-     * TODO: Does this belong here? The alternative would be to modify all the buildXyzPacket
-     * methods to take them.
-     */
-    protected void addCommonClientTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_MAX_MESSAGE_SIZE, (short) MAX_LENGTH);
-        addTlv(buf, DHCP_VENDOR_CLASS_ID, getVendorId());
-        final String hn = getHostname();
-        if (!TextUtils.isEmpty(hn)) addTlv(buf, DHCP_HOST_NAME, hn);
-    }
-
-    protected void addCommonServerTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_LEASE_TIME, mLeaseTime);
-        if (mLeaseTime != null && mLeaseTime != INFINITE_LEASE) {
-            // The client should renew at 1/2 the lease-expiry interval
-            addTlv(buf, DHCP_RENEWAL_TIME, (int) (Integer.toUnsignedLong(mLeaseTime) / 2));
-            // Default rebinding time is set as below by RFC2131
-            addTlv(buf, DHCP_REBINDING_TIME,
-                    (int) (Integer.toUnsignedLong(mLeaseTime) * 875L / 1000L));
-        }
-        addTlv(buf, DHCP_SUBNET_MASK, mSubnetMask);
-        addTlv(buf, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
-        addTlv(buf, DHCP_ROUTER, mGateways);
-        addTlv(buf, DHCP_DNS_SERVER, mDnsServers);
-        addTlv(buf, DHCP_DOMAIN_NAME, mDomainName);
-        addTlv(buf, DHCP_HOST_NAME, mHostName);
-        addTlv(buf, DHCP_VENDOR_INFO, mVendorInfo);
-        if (mMtu != null && Short.toUnsignedInt(mMtu) >= IPV4_MIN_MTU) {
-            addTlv(buf, DHCP_MTU, mMtu);
-        }
-    }
-
-    /**
-     * Converts a MAC from an array of octets to an ASCII string.
-     */
-    public static String macToString(byte[] mac) {
-        String macAddr = "";
-
-        for (int i = 0; i < mac.length; i++) {
-            String hexString = "0" + Integer.toHexString(mac[i]);
-
-            // substring operation grabs the last 2 digits: this
-            // allows signed bytes to be converted correctly.
-            macAddr += hexString.substring(hexString.length() - 2);
-
-            if (i != (mac.length - 1)) {
-                macAddr += ":";
-            }
-        }
-
-        return macAddr;
-    }
-
-    public String toString() {
-        String macAddr = macToString(mClientMac);
-
-        return macAddr;
-    }
-
-    /**
-     * Reads a four-octet value from a ByteBuffer and construct
-     * an IPv4 address from that value.
-     */
-    private static Inet4Address readIpAddress(ByteBuffer packet) {
-        Inet4Address result = null;
-        byte[] ipAddr = new byte[4];
-        packet.get(ipAddr);
-
-        try {
-            result = (Inet4Address) Inet4Address.getByAddress(ipAddr);
-        } catch (UnknownHostException ex) {
-            // ipAddr is numeric, so this should not be
-            // triggered.  However, if it is, just nullify
-            result = null;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads a string of specified length from the buffer.
-     */
-    private static String readAsciiString(ByteBuffer buf, int byteCount, boolean nullOk) {
-        byte[] bytes = new byte[byteCount];
-        buf.get(bytes);
-        int length = bytes.length;
-        if (!nullOk) {
-            // Stop at the first null byte. This is because some DHCP options (e.g., the domain
-            // name) are passed to netd via FrameworkListener, which refuses arguments containing
-            // null bytes. We don't do this by default because vendorInfo is an opaque string which
-            // could in theory contain null bytes.
-            for (length = 0; length < bytes.length; length++) {
-                if (bytes[length] == 0) {
-                    break;
-                }
-            }
-        }
-        return new String(bytes, 0, length, StandardCharsets.US_ASCII);
-    }
-
-    private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
-    }
-
-    private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
-    }
-
-    public static class ParseException extends Exception {
-        public final int errorCode;
-        public ParseException(int errorCode, String msg, Object... args) {
-            super(String.format(msg, args));
-            this.errorCode = errorCode;
-        }
-    }
-
-    /**
-     * Creates a concrete DhcpPacket from the supplied ByteBuffer.  The
-     * buffer may have an L2 encapsulation (which is the full EthernetII
-     * format starting with the source-address MAC) or an L3 encapsulation
-     * (which starts with the IP header).
-     * <br>
-     * A subset of the optional parameters are parsed and are stored
-     * in object fields.
-     */
-    @VisibleForTesting
-    static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
-    {
-        // bootp parameters
-        int transactionId;
-        short secs;
-        Inet4Address clientIp;
-        Inet4Address yourIp;
-        Inet4Address nextIp;
-        Inet4Address relayIp;
-        byte[] clientMac;
-        byte[] clientId = null;
-        List<Inet4Address> dnsServers = new ArrayList<>();
-        List<Inet4Address> gateways = new ArrayList<>();  // aka router
-        Inet4Address serverIdentifier = null;
-        Inet4Address netMask = null;
-        String message = null;
-        String vendorId = null;
-        String vendorInfo = null;
-        byte[] expectedParams = null;
-        String hostName = null;
-        String domainName = null;
-        Inet4Address ipSrc = null;
-        Inet4Address ipDst = null;
-        Inet4Address bcAddr = null;
-        Inet4Address requestedIp = null;
-        String serverHostName;
-        byte optionOverload = 0;
-
-        // The following are all unsigned integers. Internally we store them as signed integers of
-        // the same length because that way we're guaranteed that they can't be out of the range of
-        // the unsigned field in the packet. Callers wanting to pass in an unsigned value will need
-        // to cast it.
-        Short mtu = null;
-        Short maxMessageSize = null;
-        Integer leaseTime = null;
-        Integer T1 = null;
-        Integer T2 = null;
-
-        // dhcp options
-        byte dhcpType = (byte) 0xFF;
-
-        packet.order(ByteOrder.BIG_ENDIAN);
-
-        // check to see if we need to parse L2, IP, and UDP encaps
-        if (pktType == ENCAP_L2) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
-                throw new ParseException(DhcpErrorEvent.L2_TOO_SHORT,
-                        "L2 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L2);
-            }
-
-            byte[] l2dst = new byte[6];
-            byte[] l2src = new byte[6];
-
-            packet.get(l2dst);
-            packet.get(l2src);
-
-            short l2type = packet.getShort();
-
-            if (l2type != OsConstants.ETH_P_IP) {
-                throw new ParseException(DhcpErrorEvent.L2_WRONG_ETH_TYPE,
-                        "Unexpected L2 type 0x%04x, expected 0x%04x", l2type, OsConstants.ETH_P_IP);
-            }
-        }
-
-        if (pktType <= ENCAP_L3) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
-                throw new ParseException(DhcpErrorEvent.L3_TOO_SHORT,
-                        "L3 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L3);
-            }
-
-            byte ipTypeAndLength = packet.get();
-            int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
-            if (ipVersion != 4) {
-                throw new ParseException(
-                        DhcpErrorEvent.L3_NOT_IPV4, "Invalid IP version %d", ipVersion);
-            }
-
-            // System.out.println("ipType is " + ipType);
-            byte ipDiffServicesField = packet.get();
-            short ipTotalLength = packet.getShort();
-            short ipIdentification = packet.getShort();
-            byte ipFlags = packet.get();
-            byte ipFragOffset = packet.get();
-            byte ipTTL = packet.get();
-            byte ipProto = packet.get();
-            short ipChksm = packet.getShort();
-
-            ipSrc = readIpAddress(packet);
-            ipDst = readIpAddress(packet);
-
-            if (ipProto != IP_TYPE_UDP) {
-                throw new ParseException(
-                        DhcpErrorEvent.L4_NOT_UDP, "Protocol not UDP: %d", ipProto);
-            }
-
-            // Skip options. This cannot cause us to read beyond the end of the buffer because the
-            // IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
-            // MIN_PACKET_LENGTH_L3.
-            int optionWords = ((ipTypeAndLength & 0x0f) - 5);
-            for (int i = 0; i < optionWords; i++) {
-                packet.getInt();
-            }
-
-            // assume UDP
-            short udpSrcPort = packet.getShort();
-            short udpDstPort = packet.getShort();
-            short udpLen = packet.getShort();
-            short udpChkSum = packet.getShort();
-
-            // Only accept packets to or from the well-known client port (expressly permitting
-            // packets from ports other than the well-known server port; http://b/24687559), and
-            // server-to-server packets, e.g. for relays.
-            if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
-                !isPacketServerToServer(udpSrcPort, udpDstPort)) {
-                // This should almost never happen because we use SO_ATTACH_FILTER on the packet
-                // socket to drop packets that don't have the right source ports. However, it's
-                // possible that a packet arrives between when the socket is bound and when the
-                // filter is set. http://b/26696823 .
-                throw new ParseException(DhcpErrorEvent.L4_WRONG_PORT,
-                        "Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
-            }
-        }
-
-        // We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
-        if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
-            throw new ParseException(DhcpErrorEvent.BOOTP_TOO_SHORT,
-                        "Invalid type or BOOTP packet too short, %d < %d",
-                        packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
-        }
-
-        byte type = packet.get();
-        byte hwType = packet.get();
-        int addrLen = packet.get() & 0xff;
-        byte hops = packet.get();
-        transactionId = packet.getInt();
-        secs = packet.getShort();
-        short bootpFlags = packet.getShort();
-        boolean broadcast = (bootpFlags & 0x8000) != 0;
-        byte[] ipv4addr = new byte[4];
-
-        try {
-            packet.get(ipv4addr);
-            clientIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            yourIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            nextIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-        } catch (UnknownHostException ex) {
-            throw new ParseException(DhcpErrorEvent.L3_INVALID_IP,
-                    "Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
-        }
-
-        // Some DHCP servers have been known to announce invalid client hardware address values such
-        // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
-        // all but only checks that the interface MAC address matches the first bytes of the address
-        // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
-        // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
-        // TODO: evaluate whether to make this test more liberal.
-        if (addrLen > HWADDR_LEN) {
-            addrLen = ETHER_BROADCAST.length;
-        }
-
-        clientMac = new byte[addrLen];
-        packet.get(clientMac);
-
-        // skip over address padding (16 octets allocated)
-        packet.position(packet.position() + (16 - addrLen));
-        serverHostName = readAsciiString(packet, 64, false);
-        packet.position(packet.position() + 128);
-
-        // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
-        if (packet.remaining() < 4) {
-            throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
-        }
-
-        int dhcpMagicCookie = packet.getInt();
-        if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
-            throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE,
-                    "Bad magic cookie 0x%08x, should be 0x%08x",
-                    dhcpMagicCookie, DHCP_MAGIC_COOKIE);
-        }
-
-        // parse options
-        boolean notFinishedOptions = true;
-
-        while ((packet.position() < packet.limit()) && notFinishedOptions) {
-            final byte optionType = packet.get(); // cannot underflow because position < limit
-            try {
-                if (optionType == DHCP_OPTION_END) {
-                    notFinishedOptions = false;
-                } else if (optionType == DHCP_OPTION_PAD) {
-                    // The pad option doesn't have a length field. Nothing to do.
-                } else {
-                    int optionLen = packet.get() & 0xFF;
-                    int expectedLen = 0;
-
-                    switch(optionType) {
-                        case DHCP_SUBNET_MASK:
-                            netMask = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_ROUTER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                gateways.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_DNS_SERVER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                dnsServers.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_HOST_NAME:
-                            expectedLen = optionLen;
-                            hostName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MTU:
-                            expectedLen = 2;
-                            mtu = packet.getShort();
-                            break;
-                        case DHCP_DOMAIN_NAME:
-                            expectedLen = optionLen;
-                            domainName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_BROADCAST_ADDRESS:
-                            bcAddr = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_REQUESTED_IP:
-                            requestedIp = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_LEASE_TIME:
-                            leaseTime = Integer.valueOf(packet.getInt());
-                            expectedLen = 4;
-                            break;
-                        case DHCP_MESSAGE_TYPE:
-                            dhcpType = packet.get();
-                            expectedLen = 1;
-                            break;
-                        case DHCP_SERVER_IDENTIFIER:
-                            serverIdentifier = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_PARAMETER_LIST:
-                            expectedParams = new byte[optionLen];
-                            packet.get(expectedParams);
-                            expectedLen = optionLen;
-                            break;
-                        case DHCP_MESSAGE:
-                            expectedLen = optionLen;
-                            message = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MAX_MESSAGE_SIZE:
-                            expectedLen = 2;
-                            maxMessageSize = Short.valueOf(packet.getShort());
-                            break;
-                        case DHCP_RENEWAL_TIME:
-                            expectedLen = 4;
-                            T1 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_REBINDING_TIME:
-                            expectedLen = 4;
-                            T2 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_VENDOR_CLASS_ID:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorId = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_CLIENT_IDENTIFIER: { // Client identifier
-                            byte[] id = new byte[optionLen];
-                            packet.get(id);
-                            expectedLen = optionLen;
-                        } break;
-                        case DHCP_VENDOR_INFO:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorInfo = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_OPTION_OVERLOAD:
-                            expectedLen = 1;
-                            optionOverload = packet.get();
-                            optionOverload &= OPTION_OVERLOAD_BOTH;
-                            break;
-                        default:
-                            // ignore any other parameters
-                            for (int i = 0; i < optionLen; i++) {
-                                expectedLen++;
-                                byte throwaway = packet.get();
-                            }
-                    }
-
-                    if (expectedLen != optionLen) {
-                        final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                                DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH, optionType);
-                        throw new ParseException(errorCode,
-                                "Invalid length %d for option %d, expected %d",
-                                optionLen, optionType, expectedLen);
-                    }
-                }
-            } catch (BufferUnderflowException e) {
-                final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                        DhcpErrorEvent.BUFFER_UNDERFLOW, optionType);
-                throw new ParseException(errorCode, "BufferUnderflowException");
-            }
-        }
-
-        DhcpPacket newPacket;
-
-        switch(dhcpType) {
-            case (byte) 0xFF:
-                throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE,
-                        "No DHCP message type option");
-            case DHCP_MESSAGE_TYPE_DISCOVER:
-                newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
-                        broadcast, ipSrc);
-                break;
-            case DHCP_MESSAGE_TYPE_OFFER:
-                newPacket = new DhcpOfferPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_REQUEST:
-                newPacket = new DhcpRequestPacket(
-                    transactionId, secs, clientIp, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_DECLINE:
-                newPacket = new DhcpDeclinePacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_ACK:
-                newPacket = new DhcpAckPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_NAK:
-                newPacket = new DhcpNakPacket(
-                        transactionId, secs, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_RELEASE:
-                if (serverIdentifier == null) {
-                    throw new ParseException(DhcpErrorEvent.MISC_ERROR,
-                            "DHCPRELEASE without server identifier");
-                }
-                newPacket = new DhcpReleasePacket(
-                        transactionId, serverIdentifier, clientIp, relayIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_INFORM:
-                newPacket = new DhcpInformPacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            default:
-                throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE,
-                        "Unimplemented DHCP type %d", dhcpType);
-        }
-
-        newPacket.mBroadcastAddress = bcAddr;
-        newPacket.mClientId = clientId;
-        newPacket.mDnsServers = dnsServers;
-        newPacket.mDomainName = domainName;
-        newPacket.mGateways = gateways;
-        newPacket.mHostName = hostName;
-        newPacket.mLeaseTime = leaseTime;
-        newPacket.mMessage = message;
-        newPacket.mMtu = mtu;
-        newPacket.mRequestedIp = requestedIp;
-        newPacket.mRequestedParams = expectedParams;
-        newPacket.mServerIdentifier = serverIdentifier;
-        newPacket.mSubnetMask = netMask;
-        newPacket.mMaxMessageSize = maxMessageSize;
-        newPacket.mT1 = T1;
-        newPacket.mT2 = T2;
-        newPacket.mVendorId = vendorId;
-        newPacket.mVendorInfo = vendorInfo;
-        if ((optionOverload & OPTION_OVERLOAD_SNAME) == 0) {
-            newPacket.mServerHostName = serverHostName;
-        } else {
-            newPacket.mServerHostName = "";
-        }
-        return newPacket;
-    }
-
-    /**
-     * Parse a packet from an array of bytes, stopping at the given length.
-     */
-    public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
-            throws ParseException {
-        ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
-        try {
-            return decodeFullPacket(buffer, pktType);
-        } catch (ParseException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new ParseException(DhcpErrorEvent.PARSING_ERROR, e.getMessage());
-        }
-    }
-
-    /**
-     *  Construct a DhcpResults object from a DHCP reply packet.
-     */
-    public DhcpResults toDhcpResults() {
-        Inet4Address ipAddress = mYourIp;
-        if (ipAddress.equals(IPV4_ADDR_ANY)) {
-            ipAddress = mClientIp;
-            if (ipAddress.equals(IPV4_ADDR_ANY)) {
-                return null;
-            }
-        }
-
-        int prefixLength;
-        if (mSubnetMask != null) {
-            try {
-                prefixLength = Inet4AddressUtils.netmaskToPrefixLength(mSubnetMask);
-            } catch (IllegalArgumentException e) {
-                // Non-contiguous netmask.
-                return null;
-            }
-        } else {
-            prefixLength = Inet4AddressUtils.getImplicitNetmask(ipAddress);
-        }
-
-        DhcpResults results = new DhcpResults();
-        try {
-            results.ipAddress = new LinkAddress(ipAddress, prefixLength);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-
-        if (mGateways.size() > 0) {
-            results.gateway = mGateways.get(0);
-        }
-
-        results.dnsServers.addAll(mDnsServers);
-        results.domains = mDomainName;
-        results.serverAddress = mServerIdentifier;
-        results.vendorInfo = mVendorInfo;
-        results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
-        results.mtu = (mMtu != null && MIN_MTU <= mMtu && mMtu <= MAX_MTU) ? mMtu : 0;
-        results.serverHostName = mServerHostName;
-
-        return results;
-    }
-
-    /**
-     * Returns the parsed lease time, in milliseconds, or 0 for infinite.
-     */
-    public long getLeaseTimeMillis() {
-        // dhcpcd treats the lack of a lease time option as an infinite lease.
-        if (mLeaseTime == null || mLeaseTime == INFINITE_LEASE) {
-            return 0;
-        } else if (0 <= mLeaseTime && mLeaseTime < MINIMUM_LEASE) {
-            return MINIMUM_LEASE * 1000;
-        } else {
-            return (mLeaseTime & 0xffffffffL) * 1000;
-        }
-    }
-
-    /**
-     * Builds a DHCP-DISCOVER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildDiscoverPacket(int encap, int transactionId,
-        short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) {
-        DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */,
-                clientMac, broadcast, INADDR_ANY /* srcIp */);
-        pkt.mRequestedParams = expectedParams;
-        return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-    }
-
-    /**
-     * Builds a DHCP-OFFER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp,
-        Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpOfferPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
-                INADDR_ANY /* clientIp */, yourIp, mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mSubnetMask = netMask;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-ACK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildAckPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp,
-        Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpAckPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
-                mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mSubnetMask = netMask;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-NAK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
-            Inet4Address relayIp, byte[] mac, boolean broadcast, String message) {
-        DhcpPacket pkt = new DhcpNakPacket(
-                transactionId, (short) 0, relayIp, mac, broadcast);
-        pkt.mMessage = message;
-        pkt.mServerIdentifier = serverIpAddr;
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-REQUEST packet from the required specified parameters.
-     */
-    public static ByteBuffer buildRequestPacket(int encap,
-        int transactionId, short secs, Inet4Address clientIp, boolean broadcast,
-        byte[] clientMac, Inet4Address requestedIpAddress,
-        Inet4Address serverIdentifier, byte[] requestedParams, String hostName) {
-        DhcpPacket pkt = new DhcpRequestPacket(transactionId, secs, clientIp,
-                INADDR_ANY /* relayIp */, clientMac, broadcast);
-        pkt.mRequestedIp = requestedIpAddress;
-        pkt.mServerIdentifier = serverIdentifier;
-        pkt.mHostName = hostName;
-        pkt.mRequestedParams = requestedParams;
-        ByteBuffer result = pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
deleted file mode 100644
index 97d26c7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.FdEventsReader;
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-
-/**
- * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
- * @hide
- */
-abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
-    static final class Payload {
-        protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH];
-        protected Inet4Address mSrcAddr;
-        protected int mSrcPort;
-    }
-
-    DhcpPacketListener(@NonNull Handler handler) {
-        super(handler, new Payload());
-    }
-
-    @Override
-    protected int recvBufSize(@NonNull Payload buffer) {
-        return buffer.mBytes.length;
-    }
-
-    @Override
-    protected final void handlePacket(@NonNull Payload recvbuf, int length) {
-        if (recvbuf.mSrcAddr == null) {
-            return;
-        }
-
-        try {
-            final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length,
-                    DhcpPacket.ENCAP_BOOTP);
-            onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort);
-        } catch (DhcpPacket.ParseException e) {
-            logParseError(recvbuf.mBytes, length, e);
-        }
-    }
-
-    @Override
-    protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
-            throws Exception {
-        final InetSocketAddress addr = new InetSocketAddress(0);
-        final int read = Os.recvfrom(
-                fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);
-
-        // Buffers with null srcAddr will be dropped in handlePacket()
-        packetBuffer.mSrcAddr = inet4AddrOrNull(addr);
-        packetBuffer.mSrcPort = addr.getPort();
-        return read;
-    }
-
-    @Nullable
-    private static Inet4Address inet4AddrOrNull(@NonNull InetSocketAddress addr) {
-        return addr.getAddress() instanceof Inet4Address
-                ? (Inet4Address) addr.getAddress()
-                : null;
-    }
-
-    protected abstract void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-            int srcPort);
-    protected abstract void logParseError(@NonNull byte[] packet, int length,
-            @NonNull DhcpPacket.ParseException e);
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
deleted file mode 100644
index 3958303..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * Implements DHCP-RELEASE
- */
-class DhcpReleasePacket extends DhcpPacket {
-
-    final Inet4Address mClientAddr;
-
-    /**
-     * Generates a RELEASE packet with the specified parameters.
-     */
-    public DhcpReleasePacket(int transId, Inet4Address serverId, Inet4Address clientAddr,
-            Inet4Address relayIp, byte[] clientMac) {
-        super(transId, (short)0, clientAddr, INADDR_ANY /* yourIp */, INADDR_ANY /* nextIp */,
-                relayIp, clientMac, false /* broadcast */);
-        mServerIdentifier = serverId;
-        mClientAddr = clientAddr;
-    }
-
-
-    @Override
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, mServerIdentifier /* destIp */, mClientIp /* srcIp */, destUdp, srcUdp,
-                result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    @Override
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_RELEASE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addCommonClientTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
deleted file mode 100644
index 231d0457..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 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.dhcp;
-
-import android.util.Log;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-REQUEST packet.
- */
-class DhcpRequestPacket extends DhcpPacket {
-    /**
-     * Generates a REQUEST packet with the specified parameters.
-     */
-    DhcpRequestPacket(int transId, short secs, Inet4Address clientIp, Inet4Address relayIp,
-            byte[] clientMac, boolean broadcast) {
-        super(transId, secs, clientIp, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " REQUEST, desired IP " + mRequestedIp + " from host '"
-            + mHostName + "', param list length "
-            + (mRequestedParams == null ? 0 : mRequestedParams.length);
-    }
-
-    /**
-     * Fills in a packet with the requested REQUEST attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, INADDR_BROADCAST, INADDR_ANY, destUdp, srcUdp,
-            result, DHCP_BOOTREQUEST, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated REQUEST packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        if (!INADDR_ANY.equals(mRequestedIp)) {
-            addTlv(buffer, DHCP_REQUESTED_IP, mRequestedIp);
-        }
-        if (!INADDR_ANY.equals(mServerIdentifier)) {
-            addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        }
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
deleted file mode 100644
index b8ab94c..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_SERVER;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.internal.util.TrafficStatsConstants.TAG_SYSTEM_DHCP_SERVER;
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.MacAddress;
-import android.net.TrafficStats;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.SocketUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * A DHCPv4 server.
- *
- * <p>This server listens for and responds to packets on a single interface. It considers itself
- * authoritative for all leases on the subnet, which means that DHCP requests for unknown leases of
- * unknown hosts receive a reply instead of being ignored.
- *
- * <p>The server is single-threaded (including send/receive operations): all internal operations are
- * done on the provided {@link Looper}. Public methods are thread-safe and will schedule operations
- * on the looper asynchronously.
- * @hide
- */
-public class DhcpServer extends IDhcpServer.Stub {
-    private static final String REPO_TAG = "Repository";
-
-    // Lease time to transmit to client instead of a negative time in case a lease expired before
-    // the server could send it (if the server process is suspended for example).
-    private static final int EXPIRED_FALLBACK_LEASE_TIME_SECS = 120;
-
-    private static final int CMD_START_DHCP_SERVER = 1;
-    private static final int CMD_STOP_DHCP_SERVER = 2;
-    private static final int CMD_UPDATE_PARAMS = 3;
-
-    @NonNull
-    private final HandlerThread mHandlerThread;
-    @NonNull
-    private final String mIfName;
-    @NonNull
-    private final DhcpLeaseRepository mLeaseRepo;
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Dependencies mDeps;
-    @NonNull
-    private final Clock mClock;
-
-    @Nullable
-    private volatile ServerHandler mHandler;
-
-    // Accessed only on the handler thread
-    @Nullable
-    private DhcpPacketListener mPacketListener;
-    @Nullable
-    private FileDescriptor mSocket;
-    @NonNull
-    private DhcpServingParams mServingParams;
-
-    /**
-     * Clock to be used by DhcpServer to track time for lease expiration.
-     *
-     * <p>The clock should track time as may be measured by clients obtaining a lease. It does not
-     * need to be monotonous across restarts of the server as long as leases are cleared when the
-     * server is stopped.
-     */
-    public static class Clock {
-        /**
-         * @see SystemClock#elapsedRealtime()
-         */
-        public long elapsedRealtime() {
-            return SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Dependencies for the DhcpServer. Useful to be mocked in tests.
-     */
-    public interface Dependencies {
-        /**
-         * Send a packet to the specified datagram socket.
-         *
-         * @param fd File descriptor of the socket.
-         * @param buffer Data to be sent.
-         * @param dst Destination address of the packet.
-         */
-        void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException;
-
-        /**
-         * Create a DhcpLeaseRepository for the server.
-         * @param servingParams Parameters used to serve DHCP requests.
-         * @param log Log to be used by the repository.
-         * @param clock Clock that the repository must use to track time.
-         */
-        DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock);
-
-        /**
-         * Create a packet listener that will send packets to be processed.
-         */
-        DhcpPacketListener makePacketListener();
-
-        /**
-         * Create a clock that the server will use to track time.
-         */
-        Clock makeClock();
-
-        /**
-         * Add an entry to the ARP cache table.
-         * @param fd Datagram socket file descriptor that must use the new entry.
-         */
-        void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException;
-
-        /**
-         * Verify that the caller is allowed to call public methods on DhcpServer.
-         * @throws SecurityException The caller is not allowed to call public methods on DhcpServer.
-         */
-        void checkCaller() throws SecurityException;
-    }
-
-    private class DependenciesImpl implements Dependencies {
-        @Override
-        public void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException {
-            Os.sendto(fd, buffer, 0, dst, DhcpPacket.DHCP_CLIENT);
-        }
-
-        @Override
-        public DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock) {
-            return new DhcpLeaseRepository(
-                    DhcpServingParams.makeIpPrefix(servingParams.serverAddr),
-                    servingParams.excludedAddrs,
-                    servingParams.dhcpLeaseTimeSecs * 1000, log.forSubComponent(REPO_TAG), clock);
-        }
-
-        @Override
-        public DhcpPacketListener makePacketListener() {
-            return new PacketListener();
-        }
-
-        @Override
-        public Clock makeClock() {
-            return new Clock();
-        }
-
-        @Override
-        public void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException {
-            NetworkStackUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
-        }
-
-        @Override
-        public void checkCaller() {
-            checkNetworkStackCallingPermission();
-        }
-    }
-
-    private static class MalformedPacketException extends Exception {
-        MalformedPacketException(String message, Throwable t) {
-            super(message, t);
-        }
-    }
-
-    public DhcpServer(@NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log) {
-        this(new HandlerThread(DhcpServer.class.getSimpleName() + "." + ifName),
-                ifName, params, log, null);
-    }
-
-    @VisibleForTesting
-    DhcpServer(@NonNull HandlerThread handlerThread, @NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log,
-            @Nullable Dependencies deps) {
-        if (deps == null) {
-            deps = new DependenciesImpl();
-        }
-        mHandlerThread = handlerThread;
-        mIfName = ifName;
-        mServingParams = params;
-        mLog = log;
-        mDeps = deps;
-        mClock = deps.makeClock();
-        mLeaseRepo = deps.makeLeaseRepository(mServingParams, mLog, mClock);
-    }
-
-    /**
-     * Start listening for and responding to packets.
-     *
-     * <p>It is not legal to call this method more than once; in particular the server cannot be
-     * restarted after being stopped.
-     */
-    @Override
-    public void start(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        mHandlerThread.start();
-        mHandler = new ServerHandler(mHandlerThread.getLooper());
-        sendMessage(CMD_START_DHCP_SERVER, cb);
-    }
-
-    /**
-     * Update serving parameters. All subsequently received requests will be handled with the new
-     * parameters, and current leases that are incompatible with the new parameters are dropped.
-     */
-    @Override
-    public void updateParams(@Nullable DhcpServingParamsParcel params,
-            @Nullable INetworkStackStatusCallback cb) throws RemoteException {
-        mDeps.checkCaller();
-        final DhcpServingParams parsedParams;
-        try {
-            // throws InvalidParameterException with null params
-            parsedParams = DhcpServingParams.fromParcelableObject(params);
-        } catch (DhcpServingParams.InvalidParameterException e) {
-            mLog.e("Invalid parameters sent to DhcpServer", e);
-            if (cb != null) {
-                cb.onStatusAvailable(STATUS_INVALID_ARGUMENT);
-            }
-            return;
-        }
-        sendMessage(CMD_UPDATE_PARAMS, new Pair<>(parsedParams, cb));
-    }
-
-    /**
-     * Stop listening for packets.
-     *
-     * <p>As the server is stopped asynchronously, some packets may still be processed shortly after
-     * calling this method.
-     */
-    @Override
-    public void stop(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        sendMessage(CMD_STOP_DHCP_SERVER, cb);
-    }
-
-    private void sendMessage(int what, @Nullable Object obj) {
-        if (mHandler == null) {
-            mLog.e("Attempting to send a command to stopped DhcpServer: " + what);
-            return;
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(what, obj));
-    }
-
-    private class ServerHandler extends Handler {
-        ServerHandler(@NonNull Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            final INetworkStackStatusCallback cb;
-            switch (msg.what) {
-                case CMD_UPDATE_PARAMS:
-                    final Pair<DhcpServingParams, INetworkStackStatusCallback> pair =
-                            (Pair<DhcpServingParams, INetworkStackStatusCallback>) msg.obj;
-                    final DhcpServingParams params = pair.first;
-                    mServingParams = params;
-                    mLeaseRepo.updateParams(
-                            DhcpServingParams.makeIpPrefix(mServingParams.serverAddr),
-                            params.excludedAddrs,
-                            params.dhcpLeaseTimeSecs);
-
-                    cb = pair.second;
-                    break;
-                case CMD_START_DHCP_SERVER:
-                    mPacketListener = mDeps.makePacketListener();
-                    mPacketListener.start();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                case CMD_STOP_DHCP_SERVER:
-                    if (mPacketListener != null) {
-                        mPacketListener.stop();
-                        mPacketListener = null;
-                    }
-                    mHandlerThread.quitSafely();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                default:
-                    return;
-            }
-            if (cb != null) {
-                try {
-                    cb.onStatusAvailable(STATUS_SUCCESS);
-                } catch (RemoteException e) {
-                    mLog.e("Could not send status back to caller", e);
-                }
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void processPacket(@NonNull DhcpPacket packet, int srcPort) {
-        final String packetType = packet.getClass().getSimpleName();
-        if (srcPort != DHCP_CLIENT) {
-            mLog.logf("Ignored packet of type %s sent from client port %d", packetType, srcPort);
-            return;
-        }
-
-        mLog.log("Received packet of type " + packetType);
-        final Inet4Address sid = packet.mServerIdentifier;
-        if (sid != null && !sid.equals(mServingParams.serverAddr.getAddress())) {
-            mLog.log("Packet ignored due to wrong server identifier: " + sid);
-            return;
-        }
-
-        try {
-            if (packet instanceof DhcpDiscoverPacket) {
-                processDiscover((DhcpDiscoverPacket) packet);
-            } else if (packet instanceof DhcpRequestPacket) {
-                processRequest((DhcpRequestPacket) packet);
-            } else if (packet instanceof DhcpReleasePacket) {
-                processRelease((DhcpReleasePacket) packet);
-            } else {
-                mLog.e("Unknown packet type: " + packet.getClass().getSimpleName());
-            }
-        } catch (MalformedPacketException e) {
-            // Not an internal error: only logging exception message, not stacktrace
-            mLog.e("Ignored malformed packet: " + e.getMessage());
-        }
-    }
-
-    private void logIgnoredPacketInvalidSubnet(DhcpLeaseRepository.InvalidSubnetException e) {
-        // Not an internal error: only logging exception message, not stacktrace
-        mLog.e("Ignored packet from invalid subnet: " + e.getMessage());
-    }
-
-    private void processDiscover(@NonNull DhcpDiscoverPacket packet)
-            throws MalformedPacketException {
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.getOffer(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mRelayIp, packet.mRequestedIp, packet.mHostName);
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            transmitNak(packet, "Out of addresses to offer");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitOffer(packet, lease, clientMac);
-    }
-
-    private void processRequest(@NonNull DhcpRequestPacket packet) throws MalformedPacketException {
-        // If set, packet SID matches with this server's ID as checked in processPacket().
-        final boolean sidSet = packet.mServerIdentifier != null;
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.requestLease(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mClientIp, packet.mRelayIp, packet.mRequestedIp, sidSet,
-                    packet.mHostName);
-        } catch (DhcpLeaseRepository.InvalidAddressException e) {
-            transmitNak(packet, "Invalid requested address");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitAck(packet, lease, clientMac);
-    }
-
-    private void processRelease(@NonNull DhcpReleasePacket packet)
-            throws MalformedPacketException {
-        final byte[] clientId = packet.getExplicitClientIdOrNull();
-        final MacAddress macAddr = getMacAddr(packet);
-        // Don't care about success (there is no ACK/NAK); logging is already done in the repository
-        mLeaseRepo.releaseLease(clientId, macAddr, packet.mClientIp);
-    }
-
-    private Inet4Address getAckOrOfferDst(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            boolean broadcastFlag) {
-        // Unless relayed or broadcast, send to client IP if already configured on the client, or to
-        // the lease address if the client has no configured address
-        if (!isEmpty(request.mRelayIp)) {
-            return request.mRelayIp;
-        } else if (broadcastFlag) {
-            return IPV4_ADDR_ALL;
-        } else if (!isEmpty(request.mClientIp)) {
-            return request.mClientIp;
-        } else {
-            return lease.getNetAddr();
-        }
-    }
-
-    /**
-     * Determine whether the broadcast flag should be set in the BOOTP packet flags. This does not
-     * apply to NAK responses, which should always have it set.
-     */
-    private static boolean getBroadcastFlag(@NonNull DhcpPacket request, @NonNull DhcpLease lease) {
-        // No broadcast flag if the client already has a configured IP to unicast to. RFC2131 #4.1
-        // has some contradictions regarding broadcast behavior if a client already has an IP
-        // configured and sends a request with both ciaddr (renew/rebind) and the broadcast flag
-        // set. Sending a unicast response to ciaddr matches previous behavior and is more
-        // efficient.
-        // If the client has no configured IP, broadcast if requested by the client or if the lease
-        // address cannot be used to send a unicast reply either.
-        return isEmpty(request.mClientIp) && (request.mBroadcast || isEmpty(lease.getNetAddr()));
-    }
-
-    /**
-     * Get the hostname from a lease if non-empty and requested in the incoming request.
-     * @param request The incoming request.
-     * @return The hostname, or null if not requested or empty.
-     */
-    @Nullable
-    private static String getHostnameIfRequested(@NonNull DhcpPacket request,
-            @NonNull DhcpLease lease) {
-        return request.hasRequestedParam(DHCP_HOST_NAME) && !TextUtils.isEmpty(lease.getHostname())
-                ? lease.getHostname()
-                : null;
-    }
-
-    private boolean transmitOffer(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final Inet4Address prefixMask =
-                getPrefixMaskAsInet4Address(mServingParams.serverAddr.getPrefixLength());
-        final Inet4Address broadcastAddr = getBroadcastAddress(
-                mServingParams.getServerInet4Addr(), mServingParams.serverAddr.getPrefixLength());
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer offerPacket = DhcpPacket.buildOfferPacket(
-                ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, lease.getNetAddr(), request.mClientMac, timeout, prefixMask,
-                broadcastAddr, new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitAck(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        // TODO: replace DhcpPacket's build methods with real builders and use common code with
-        // transmitOffer above
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId,
-                broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp,
-                lease.getNetAddr(), request.mClientIp, request.mClientMac, timeout,
-                mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(),
-                new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitNak(DhcpPacket request, String message) {
-        mLog.w("Transmitting NAK: " + message);
-        // Always set broadcast flag for NAK: client may not have a correct IP
-        final ByteBuffer nakPacket = DhcpPacket.buildNakPacket(
-                ENCAP_BOOTP, request.mTransId, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, request.mClientMac, true /* broadcast */, message);
-
-        final Inet4Address dst = isEmpty(request.mRelayIp)
-                ? IPV4_ADDR_ALL
-                : request.mRelayIp;
-        return transmitPacket(nakPacket, DhcpNakPacket.class.getSimpleName(), dst);
-    }
-
-    private boolean transmitOfferOrAckPacket(@NonNull ByteBuffer buf, @NonNull DhcpPacket request,
-            @NonNull DhcpLease lease, @NonNull MacAddress clientMac, boolean broadcastFlag) {
-        mLog.logf("Transmitting %s with lease %s", request.getClass().getSimpleName(), lease);
-        // Client may not yet respond to ARP for the lease address, which may be the destination
-        // address. Add an entry to the ARP cache to save future ARP probes and make sure the
-        // packet reaches its destination.
-        if (!addArpEntry(clientMac, lease.getNetAddr())) {
-            // Logging for error already done
-            return false;
-        }
-        final Inet4Address dst = getAckOrOfferDst(request, lease, broadcastFlag);
-        return transmitPacket(buf, request.getClass().getSimpleName(), dst);
-    }
-
-    private boolean transmitPacket(@NonNull ByteBuffer buf, @NonNull String packetTypeTag,
-            @NonNull Inet4Address dst) {
-        try {
-            mDeps.sendPacket(mSocket, buf, dst);
-        } catch (ErrnoException | IOException e) {
-            mLog.e("Can't send packet " + packetTypeTag, e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
-        try {
-            mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
-            return true;
-        } catch (IOException e) {
-            mLog.e("Error adding client to ARP table", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get the remaining lease time in seconds, starting from {@link Clock#elapsedRealtime()}.
-     *
-     * <p>This is an unsigned 32-bit integer, so it cannot be read as a standard (signed) Java int.
-     * The return value is only intended to be used to populate the lease time field in a DHCP
-     * response, considering that lease time is an unsigned 32-bit integer field in DHCP packets.
-     *
-     * <p>Lease expiration times are tracked internally with millisecond precision: this method
-     * returns a rounded down value.
-     */
-    private int getLeaseTimeout(@NonNull DhcpLease lease) {
-        final long remainingTimeSecs = (lease.getExpTime() - mClock.elapsedRealtime()) / 1000;
-        if (remainingTimeSecs < 0) {
-            mLog.e("Processing expired lease " + lease);
-            return EXPIRED_FALLBACK_LEASE_TIME_SECS;
-        }
-
-        if (remainingTimeSecs >= toUnsignedLong(INFINITE_LEASE)) {
-            return INFINITE_LEASE;
-        }
-
-        return (int) remainingTimeSecs;
-    }
-
-    /**
-     * Get the client MAC address from a packet.
-     *
-     * @throws MalformedPacketException The address in the packet uses an unsupported format.
-     */
-    @NonNull
-    private MacAddress getMacAddr(@NonNull DhcpPacket packet) throws MalformedPacketException {
-        try {
-            return MacAddress.fromBytes(packet.getClientMac());
-        } catch (IllegalArgumentException e) {
-            final String message = "Invalid MAC address in packet: "
-                    + HexDump.dumpHexString(packet.getClientMac());
-            throw new MalformedPacketException(message, e);
-        }
-    }
-
-    private static boolean isEmpty(@Nullable Inet4Address address) {
-        return address == null || IPV4_ADDR_ANY.equals(address);
-    }
-
-    private class PacketListener extends DhcpPacketListener {
-        PacketListener() {
-            super(mHandler);
-        }
-
-        @Override
-        protected void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-                int srcPort) {
-            processPacket(packet, srcPort);
-        }
-
-        @Override
-        protected void logError(@NonNull String msg, Exception e) {
-            mLog.e("Error receiving packet: " + msg, e);
-        }
-
-        @Override
-        protected void logParseError(@NonNull byte[] packet, int length,
-                @NonNull DhcpPacket.ParseException e) {
-            mLog.e("Error parsing packet", e);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            // TODO: have and use an API to set a socket tag without going through the thread tag
-            final int oldTag = TrafficStats.getAndSetThreadStatsTag(TAG_SYSTEM_DHCP_SERVER);
-            try {
-                mSocket = Os.socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                SocketUtils.bindSocketToInterface(mSocket, mIfName);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_REUSEADDR, 1);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
-                Os.bind(mSocket, IPV4_ADDR_ANY, DHCP_SERVER);
-
-                return mSocket;
-            } catch (IOException | ErrnoException e) {
-                mLog.e("Error creating UDP socket", e);
-                DhcpServer.this.stop(null);
-                return null;
-            } finally {
-                TrafficStats.setThreadStatsTag(oldTag);
-            }
-        }
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
deleted file mode 100644
index 230b693..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_MAX_MTU;
-import static com.android.server.util.NetworkStackConstants.IPV4_MIN_MTU;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.shared.Inet4AddressUtils;
-import android.util.ArraySet;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Parameters used by the DhcpServer to serve requests.
- *
- * <p>Instances are immutable. Use {@link DhcpServingParams.Builder} to instantiate.
- * @hide
- */
-public class DhcpServingParams {
-    public static final int MTU_UNSET = 0;
-    public static final int MIN_PREFIX_LENGTH = 16;
-    public static final int MAX_PREFIX_LENGTH = 30;
-
-    /** Server inet address and prefix to serve */
-    @NonNull
-    public final LinkAddress serverAddr;
-
-    /**
-     * Default routers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> defaultRouters;
-
-    /**
-     * DNS servers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> dnsServers;
-
-    /**
-     * Excluded addresses that the DHCP server is not allowed to assign to clients.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> excludedAddrs;
-
-    // DHCP uses uint32. Use long for clearer code, and check range when building.
-    public final long dhcpLeaseTimeSecs;
-    public final int linkMtu;
-
-    /**
-     * Indicates whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-     */
-    public final boolean metered;
-
-    /**
-     * Checked exception thrown when some parameters used to build {@link DhcpServingParams} are
-     * missing or invalid.
-     */
-    public static class InvalidParameterException extends Exception {
-        public InvalidParameterException(String message) {
-            super(message);
-        }
-    }
-
-    private DhcpServingParams(@NonNull LinkAddress serverAddr,
-            @NonNull Set<Inet4Address> defaultRouters,
-            @NonNull Set<Inet4Address> dnsServers, @NonNull Set<Inet4Address> excludedAddrs,
-            long dhcpLeaseTimeSecs, int linkMtu, boolean metered) {
-        this.serverAddr = serverAddr;
-        this.defaultRouters = defaultRouters;
-        this.dnsServers = dnsServers;
-        this.excludedAddrs = excludedAddrs;
-        this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-        this.linkMtu = linkMtu;
-        this.metered = metered;
-    }
-
-    /**
-     * Create parameters from a stable AIDL-compatible parcel.
-     * @throws InvalidParameterException The parameters parcelable is null or invalid.
-     */
-    public static DhcpServingParams fromParcelableObject(@Nullable DhcpServingParamsParcel parcel)
-            throws InvalidParameterException {
-        if (parcel == null) {
-            throw new InvalidParameterException("Null serving parameters");
-        }
-        final LinkAddress serverAddr = new LinkAddress(
-                intToInet4AddressHTH(parcel.serverAddr),
-                parcel.serverAddrPrefixLength);
-        return new Builder()
-                .setServerAddr(serverAddr)
-                .setDefaultRouters(toInet4AddressSet(parcel.defaultRouters))
-                .setDnsServers(toInet4AddressSet(parcel.dnsServers))
-                .setExcludedAddrs(toInet4AddressSet(parcel.excludedAddrs))
-                .setDhcpLeaseTimeSecs(parcel.dhcpLeaseTimeSecs)
-                .setLinkMtu(parcel.linkMtu)
-                .setMetered(parcel.metered)
-                .build();
-    }
-
-    private static Set<Inet4Address> toInet4AddressSet(@Nullable int[] addrs) {
-        if (addrs == null) {
-            return new HashSet<>(0);
-        }
-
-        final HashSet<Inet4Address> res = new HashSet<>();
-        for (int addr : addrs) {
-            res.add(intToInet4AddressHTH(addr));
-        }
-        return res;
-    }
-
-    @NonNull
-    public Inet4Address getServerInet4Addr() {
-        return (Inet4Address) serverAddr.getAddress();
-    }
-
-    /**
-     * Get the served prefix mask as an IPv4 address.
-     *
-     * <p>For example, if the served prefix is 192.168.42.0/24, this will return 255.255.255.0.
-     */
-    @NonNull
-    public Inet4Address getPrefixMaskAsAddress() {
-        return getPrefixMaskAsInet4Address(serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Get the server broadcast address.
-     *
-     * <p>For example, if the server {@link LinkAddress} is 192.168.42.1/24, this will return
-     * 192.168.42.255.
-     */
-    @NonNull
-    public Inet4Address getBroadcastAddress() {
-        return Inet4AddressUtils.getBroadcastAddress(
-                getServerInet4Addr(), serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Utility class to create new instances of {@link DhcpServingParams} while checking validity
-     * of the parameters.
-     */
-    public static class Builder {
-        private LinkAddress mServerAddr;
-        private Set<Inet4Address> mDefaultRouters;
-        private Set<Inet4Address> mDnsServers;
-        private Set<Inet4Address> mExcludedAddrs;
-        private long mDhcpLeaseTimeSecs;
-        private int mLinkMtu = MTU_UNSET;
-        private boolean mMetered;
-
-        /**
-         * Set the server address and served prefix for the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setServerAddr(@NonNull LinkAddress serverAddr) {
-            this.mServerAddr = serverAddr;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty set, but it must
-         * always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
-            this.mDefaultRouters = defaultRouters;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty list of routers,
-         * but it must always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
-            return setDefaultRouters(makeArraySet(defaultRouters));
-        }
-
-        /**
-         * Convenience method to build the parameters with no default router.
-         *
-         * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
-         */
-        public Builder withNoDefaultRouter() {
-            return setDefaultRouters();
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty set, but it must always be set explicitly before building the
-         * {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
-            this.mDnsServers = dnsServers;
-            return this;
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty list of servers, but it must always be set explicitly before
-         * building the {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Inet4Address... dnsServers) {
-            return setDnsServers(makeArraySet(dnsServers));
-        }
-
-        /**
-         * Convenience method to build the parameters with no DNS server.
-         *
-         * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
-         */
-        public Builder withNoDnsServer() {
-            return setDnsServers();
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
-            this.mExcludedAddrs = excludedAddrs;
-            return this;
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
-            return setExcludedAddrs(makeArraySet(excludedAddrs));
-        }
-
-        /**
-         * Set the lease time for leases assigned by the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
-            this.mDhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-            return this;
-        }
-
-        /**
-         * Set the link MTU to be advertised to DHCP clients.
-         *
-         * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
-         * is optional and defaults to {@link #MTU_UNSET}.
-         */
-        public Builder setLinkMtu(int linkMtu) {
-            this.mLinkMtu = linkMtu;
-            return this;
-        }
-
-        /**
-         * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-         *
-         * <p>If not set, the default value is false.
-         */
-        public Builder setMetered(boolean metered) {
-            this.mMetered = metered;
-            return this;
-        }
-
-        /**
-         * Create a new {@link DhcpServingParams} instance based on parameters set in the builder.
-         *
-         * <p>This method has no side-effects. If it does not throw, a valid
-         * {@link DhcpServingParams} is returned.
-         * @return The constructed parameters.
-         * @throws InvalidParameterException At least one parameter is missing or invalid.
-         */
-        @NonNull
-        public DhcpServingParams build() throws InvalidParameterException {
-            if (mServerAddr == null) {
-                throw new InvalidParameterException("Missing serverAddr");
-            }
-            if (mDefaultRouters == null) {
-                throw new InvalidParameterException("Missing defaultRouters");
-            }
-            if (mDnsServers == null) {
-                // Empty set is OK, but enforce explicitly setting it
-                throw new InvalidParameterException("Missing dnsServers");
-            }
-            if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
-                throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs);
-            }
-            if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) {
-                throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu);
-            }
-            if (!mServerAddr.isIpv4()) {
-                throw new InvalidParameterException("serverAddr must be IPv4");
-            }
-            if (mServerAddr.getPrefixLength() < MIN_PREFIX_LENGTH
-                    || mServerAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
-                throw new InvalidParameterException("Prefix length is not in supported range");
-            }
-
-            final IpPrefix prefix = makeIpPrefix(mServerAddr);
-            for (Inet4Address addr : mDefaultRouters) {
-                if (!prefix.contains(addr)) {
-                    throw new InvalidParameterException(String.format(
-                            "Default router %s is not in server prefix %s", addr, mServerAddr));
-                }
-            }
-
-            final Set<Inet4Address> excl = new HashSet<>();
-            if (mExcludedAddrs != null) {
-                excl.addAll(mExcludedAddrs);
-            }
-            excl.add((Inet4Address) mServerAddr.getAddress());
-            excl.addAll(mDefaultRouters);
-            excl.addAll(mDnsServers);
-
-            return new DhcpServingParams(mServerAddr,
-                    Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)),
-                    Collections.unmodifiableSet(new HashSet<>(mDnsServers)),
-                    Collections.unmodifiableSet(excl),
-                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered);
-        }
-    }
-
-    /**
-     * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress.
-     */
-    @NonNull
-    static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
-        return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
-    }
-
-    private static <T> ArraySet<T> makeArraySet(T[] elements) {
-        final ArraySet<T> set = new ArraySet<>(elements.length);
-        set.addAll(Arrays.asList(elements));
-        return set;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
deleted file mode 100644
index eb49218..0000000
--- a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ALL;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOCK_RAW;
-
-import android.net.util.ConnectivityPacketSummary;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.os.Handler;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * Critical connectivity packet tracking daemon.
- *
- * Tracks ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * This class's constructor, start() and stop() methods must only be called
- * from the same thread on which the passed in |log| is accessed.
- *
- * Log lines include a hexdump of the packet, which can be decoded via:
- *
- *     echo -n H3XSTR1NG | sed -e 's/\([0-9A-F][0-9A-F]\)/\1 /g' -e 's/^/000000 /'
- *                       | text2pcap - -
- *                       | tcpdump -n -vv -e -r -
- *
- * @hide
- */
-public class ConnectivityPacketTracker {
-    private static final String TAG = ConnectivityPacketTracker.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final String MARK_START = "--- START ---";
-    private static final String MARK_STOP = "--- STOP ---";
-    private static final String MARK_NAMED_START = "--- START (%s) ---";
-    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
-
-    private final String mTag;
-    private final LocalLog mLog;
-    private final PacketReader mPacketListener;
-    private boolean mRunning;
-    private String mDisplayName;
-
-    public ConnectivityPacketTracker(Handler h, InterfaceParams ifParams, LocalLog log) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mTag = TAG + "." + ifParams.name;
-        mLog = log;
-        mPacketListener = new PacketListener(h, ifParams);
-    }
-
-    public void start(String displayName) {
-        mRunning = true;
-        mDisplayName = displayName;
-        mPacketListener.start();
-    }
-
-    public void stop() {
-        mPacketListener.stop();
-        mRunning = false;
-        mDisplayName = null;
-    }
-
-    private final class PacketListener extends PacketReader {
-        private final InterfaceParams mInterface;
-
-        PacketListener(Handler h, InterfaceParams ifParams) {
-            super(h, ifParams.defaultMtu);
-            mInterface = ifParams;
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, 0);
-                NetworkStackUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
-                Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
-            } catch (ErrnoException | IOException e) {
-                logError("Failed to create packet tracking socket: ", e);
-                closeFd(s);
-                return null;
-            }
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            final String summary = ConnectivityPacketSummary.summarize(
-                    mInterface.macAddr, recvbuf, length);
-            if (summary == null) return;
-
-            if (DBG) Log.d(mTag, summary);
-            addLogEntry(summary + "\n[" + HexDump.toHexString(recvbuf, 0, length) + "]");
-        }
-
-        @Override
-        protected void onStart() {
-            final String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_START
-                    : String.format(MARK_NAMED_START, mDisplayName);
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void onStop() {
-            String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_STOP
-                    : String.format(MARK_NAMED_STOP, mDisplayName);
-            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void logError(String msg, Exception e) {
-            Log.e(mTag, msg, e);
-            addLogEntry(msg + e);
-        }
-
-        private void addLogEntry(String entry) {
-            mLog.log(entry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
deleted file mode 100644
index 266b1b0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * 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.ip;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.ProvisioningConfigurationParcelable;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
-import android.net.dhcp.DhcpClient;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpManagerEvent;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IState;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.WakeupMessage;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService.NetworkStackServiceManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-
-/**
- * IpClient
- *
- * This class provides the interface to IP-layer provisioning and maintenance
- * functionality that can be used by transport layers like Wi-Fi, Ethernet,
- * et cetera.
- *
- * [ Lifetime ]
- * IpClient is designed to be instantiated as soon as the interface name is
- * known and can be as long-lived as the class containing it (i.e. declaring
- * it "private final" is okay).
- *
- * @hide
- */
-public class IpClient extends StateMachine {
-    private static final boolean DBG = false;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
-    private static final SparseArray<String> sWhatToString =
-            MessageUtils.findMessageNames(sMessageClasses);
-    // Two static concurrent hashmaps of interface name to logging classes.
-    // One holds StateMachine logs and the other connectivity packet logs.
-    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
-    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
-    private final NetworkStackIpMemoryStore mIpMemoryStore;
-
-    /**
-     * Dump all state machine and connectivity packet logs to the specified writer.
-     * @param skippedIfaces Interfaces for which logs should not be dumped.
-     */
-    public static void dumpAllLogs(PrintWriter writer, Set<String> skippedIfaces) {
-        for (String ifname : sSmLogs.keySet()) {
-            if (skippedIfaces.contains(ifname)) continue;
-
-            writer.println(String.format("--- BEGIN %s ---", ifname));
-
-            final SharedLog smLog = sSmLogs.get(ifname);
-            if (smLog != null) {
-                writer.println("State machine log:");
-                smLog.dump(null, writer, null);
-            }
-
-            writer.println("");
-
-            final LocalLog pktLog = sPktLogs.get(ifname);
-            if (pktLog != null) {
-                writer.println("Connectivity packet log:");
-                pktLog.readOnlyLocalLog().dump(null, writer, null);
-            }
-
-            writer.println(String.format("--- END %s ---", ifname));
-        }
-    }
-
-    // Use a wrapper class to log in order to ensure complete and detailed
-    // logging. This method is lighter weight than annotations/reflection
-    // and has the following benefits:
-    //
-    //     - No invoked method can be forgotten.
-    //       Any new method added to IpClient.Callback must be overridden
-    //       here or it will never be called.
-    //
-    //     - No invoking call site can be forgotten.
-    //       Centralized logging in this way means call sites don't need to
-    //       remember to log, and therefore no call site can be forgotten.
-    //
-    //     - No variation in log format among call sites.
-    //       Encourages logging of any available arguments, and all call sites
-    //       are necessarily logged identically.
-    //
-    // NOTE: Log first because passed objects may or may not be thread-safe and
-    // once passed on to the callback they may be modified by another thread.
-    //
-    // TODO: Find an lighter weight approach.
-    public static class IpClientCallbacksWrapper {
-        private static final String PREFIX = "INVOKE ";
-        private final IIpClientCallbacks mCallback;
-        private final SharedLog mLog;
-
-        @VisibleForTesting
-        protected IpClientCallbacksWrapper(IIpClientCallbacks callback, SharedLog log) {
-            mCallback = callback;
-            mLog = log;
-        }
-
-        private void log(String msg) {
-            mLog.log(PREFIX + msg);
-        }
-
-        private void log(String msg, Throwable e) {
-            mLog.e(PREFIX + msg, e);
-        }
-
-        public void onPreDhcpAction() {
-            log("onPreDhcpAction()");
-            try {
-                mCallback.onPreDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPreDhcpAction", e);
-            }
-        }
-
-        public void onPostDhcpAction() {
-            log("onPostDhcpAction()");
-            try {
-                mCallback.onPostDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPostDhcpAction", e);
-            }
-        }
-
-        public void onNewDhcpResults(DhcpResults dhcpResults) {
-            log("onNewDhcpResults({" + dhcpResults + "})");
-            try {
-                mCallback.onNewDhcpResults(toStableParcelable(dhcpResults));
-            } catch (RemoteException e) {
-                log("Failed to call onNewDhcpResults", e);
-            }
-        }
-
-        public void onProvisioningSuccess(LinkProperties newLp) {
-            log("onProvisioningSuccess({" + newLp + "})");
-            try {
-                mCallback.onProvisioningSuccess(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningSuccess", e);
-            }
-        }
-
-        public void onProvisioningFailure(LinkProperties newLp) {
-            log("onProvisioningFailure({" + newLp + "})");
-            try {
-                mCallback.onProvisioningFailure(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningFailure", e);
-            }
-        }
-
-        public void onLinkPropertiesChange(LinkProperties newLp) {
-            log("onLinkPropertiesChange({" + newLp + "})");
-            try {
-                mCallback.onLinkPropertiesChange(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onLinkPropertiesChange", e);
-            }
-        }
-
-        public void onReachabilityLost(String logMsg) {
-            log("onReachabilityLost(" + logMsg + ")");
-            try {
-                mCallback.onReachabilityLost(logMsg);
-            } catch (RemoteException e) {
-                log("Failed to call onReachabilityLost", e);
-            }
-        }
-
-        public void onQuit() {
-            log("onQuit()");
-            try {
-                mCallback.onQuit();
-            } catch (RemoteException e) {
-                log("Failed to call onQuit", e);
-            }
-        }
-
-        public void installPacketFilter(byte[] filter) {
-            log("installPacketFilter(byte[" + filter.length + "])");
-            try {
-                mCallback.installPacketFilter(filter);
-            } catch (RemoteException e) {
-                log("Failed to call installPacketFilter", e);
-            }
-        }
-
-        public void startReadPacketFilter() {
-            log("startReadPacketFilter()");
-            try {
-                mCallback.startReadPacketFilter();
-            } catch (RemoteException e) {
-                log("Failed to call startReadPacketFilter", e);
-            }
-        }
-
-        public void setFallbackMulticastFilter(boolean enabled) {
-            log("setFallbackMulticastFilter(" + enabled + ")");
-            try {
-                mCallback.setFallbackMulticastFilter(enabled);
-            } catch (RemoteException e) {
-                log("Failed to call setFallbackMulticastFilter", e);
-            }
-        }
-
-        public void setNeighborDiscoveryOffload(boolean enable) {
-            log("setNeighborDiscoveryOffload(" + enable + ")");
-            try {
-                mCallback.setNeighborDiscoveryOffload(enable);
-            } catch (RemoteException e) {
-                log("Failed to call setNeighborDiscoveryOffload", e);
-            }
-        }
-    }
-
-    public static final String DUMP_ARG_CONFIRM = "confirm";
-
-    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
-    private static final int CMD_TERMINATE_AFTER_STOP             = 1;
-    private static final int CMD_STOP                             = 2;
-    private static final int CMD_START                            = 3;
-    private static final int CMD_CONFIRM                          = 4;
-    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
-    // Triggered by NetlinkTracker to communicate netlink events.
-    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
-    private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
-    private static final int CMD_UPDATE_HTTP_PROXY                = 8;
-    private static final int CMD_SET_MULTICAST_FILTER             = 9;
-    private static final int EVENT_PROVISIONING_TIMEOUT           = 10;
-    private static final int EVENT_DHCPACTION_TIMEOUT             = 11;
-    private static final int EVENT_READ_PACKET_FILTER_COMPLETE    = 12;
-    private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
-    private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
-    private static final int CMD_UPDATE_L2KEY_GROUPHINT = 15;
-
-    // Internal commands to use instead of trying to call transitionTo() inside
-    // a given State's enter() method. Calling transitionTo() from enter/exit
-    // encounters a Log.wtf() that can cause trouble on eng builds.
-    private static final int CMD_JUMP_STARTED_TO_RUNNING          = 100;
-    private static final int CMD_JUMP_RUNNING_TO_STOPPING         = 101;
-    private static final int CMD_JUMP_STOPPING_TO_STOPPED         = 102;
-
-    // IpClient shares a handler with DhcpClient: commands must not overlap
-    public static final int DHCPCLIENT_CMD_BASE = 1000;
-
-    private static final int MAX_LOG_RECORDS = 500;
-    private static final int MAX_PACKET_RECORDS = 100;
-
-    private static final boolean NO_CALLBACKS = false;
-    private static final boolean SEND_CALLBACKS = true;
-
-    // This must match the interface prefix in clatd.c.
-    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
-    private static final String CLAT_PREFIX = "v4-";
-
-    private static final int IMMEDIATE_FAILURE_DURATION = 0;
-
-    private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
-    private static final int PROV_CHANGE_LOST_PROVISIONING = 2;
-    private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
-    private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
-
-    private final State mStoppedState = new StoppedState();
-    private final State mStoppingState = new StoppingState();
-    private final State mStartedState = new StartedState();
-    private final State mRunningState = new RunningState();
-
-    private final String mTag;
-    private final Context mContext;
-    private final String mInterfaceName;
-    private final String mClatInterfaceName;
-    @VisibleForTesting
-    protected final IpClientCallbacksWrapper mCallback;
-    private final Dependencies mDependencies;
-    private final CountDownLatch mShutdownLatch;
-    private final ConnectivityManager mCm;
-    private final INetd mNetd;
-    private final NetworkObserverRegistry mObserverRegistry;
-    private final IpClientLinkObserver mLinkObserver;
-    private final WakeupMessage mProvisioningTimeoutAlarm;
-    private final WakeupMessage mDhcpActionTimeoutAlarm;
-    private final SharedLog mLog;
-    private final LocalLog mConnectivityPacketLog;
-    private final MessageHandlingLogger mMsgStateLogger;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private final InterfaceController mInterfaceCtrl;
-
-    private InterfaceParams mInterfaceParams;
-
-    /**
-     * Non-final member variables accessed only from within our StateMachine.
-     */
-    private LinkProperties mLinkProperties;
-    private android.net.shared.ProvisioningConfiguration mConfiguration;
-    private IpReachabilityMonitor mIpReachabilityMonitor;
-    private DhcpClient mDhcpClient;
-    private DhcpResults mDhcpResults;
-    private String mTcpBufferSizes;
-    private ProxyInfo mHttpProxy;
-    private ApfFilter mApfFilter;
-    private String mL2Key; // The L2 key for this network, for writing into the memory store
-    private String mGroupHint; // The group hint for this network, for writing into the memory store
-    private boolean mMulticastFiltering;
-    private long mStartTimeMillis;
-
-    /**
-     * Reading the snapshot is an asynchronous operation initiated by invoking
-     * Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
-     * EVENT_READ_PACKET_FILTER_COMPLETE message. The mApfDataSnapshotComplete condition variable
-     * signals when a new snapshot is ready.
-     */
-    private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
-
-    public static class Dependencies {
-        /**
-         * Get interface parameters for the specified interface.
-         */
-        public InterfaceParams getInterfaceParams(String ifname) {
-            return InterfaceParams.getByName(ifname);
-        }
-
-        /**
-         * Get a INetd connector.
-         */
-        public INetd getNetd(Context context) {
-            return INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE));
-        }
-    }
-
-    public IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager) {
-        this(context, ifName, callback, observerRegistry, nssManager, new Dependencies());
-    }
-
-    @VisibleForTesting
-    IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager,
-            Dependencies deps) {
-        super(IpClient.class.getSimpleName() + "." + ifName);
-        Preconditions.checkNotNull(ifName);
-        Preconditions.checkNotNull(callback);
-
-        mTag = getName();
-
-        mContext = context;
-        mInterfaceName = ifName;
-        mClatInterfaceName = CLAT_PREFIX + ifName;
-        mDependencies = deps;
-        mShutdownLatch = new CountDownLatch(1);
-        mCm = mContext.getSystemService(ConnectivityManager.class);
-        mObserverRegistry = observerRegistry;
-        mIpMemoryStore =
-                new NetworkStackIpMemoryStore(context, nssManager.getIpMemoryStoreService());
-
-        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
-        mLog = sSmLogs.get(mInterfaceName);
-        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
-        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
-        mMsgStateLogger = new MessageHandlingLogger();
-        mCallback = new IpClientCallbacksWrapper(callback, mLog);
-
-        // TODO: Consider creating, constructing, and passing in some kind of
-        // InterfaceController.Dependencies class.
-        mNetd = deps.getNetd(mContext);
-        mInterfaceCtrl = new InterfaceController(mInterfaceName, mNetd, mLog);
-
-        mLinkObserver = new IpClientLinkObserver(
-                mInterfaceName,
-                () -> sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED)) {
-            @Override
-            public void onInterfaceAdded(String iface) {
-                super.onInterfaceAdded(iface);
-                if (mClatInterfaceName.equals(iface)) {
-                    mCallback.setNeighborDiscoveryOffload(false);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceAdded(" + iface + ")";
-                logMsg(msg);
-            }
-
-            @Override
-            public void onInterfaceRemoved(String iface) {
-                super.onInterfaceRemoved(iface);
-                // TODO: Also observe mInterfaceName going down and take some
-                // kind of appropriate action.
-                if (mClatInterfaceName.equals(iface)) {
-                    // TODO: consider sending a message to the IpClient main
-                    // StateMachine thread, in case "NDO enabled" state becomes
-                    // tied to more things that 464xlat operation.
-                    mCallback.setNeighborDiscoveryOffload(true);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceRemoved(" + iface + ")";
-                logMsg(msg);
-            }
-
-            private void logMsg(String msg) {
-                Log.d(mTag, msg);
-                getHandler().post(() -> mLog.log("OBSERVED " + msg));
-            }
-        };
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-
-        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
-        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
-
-        // Anything the StateMachine may access must have been instantiated
-        // before this point.
-        configureAndStartStateMachine();
-
-        // Anything that may send messages to the StateMachine must only be
-        // configured to do so after the StateMachine has started (above).
-        startStateMachineUpdaters();
-    }
-
-    /**
-     * Make a IIpClient connector to communicate with this IpClient.
-     */
-    public IIpClient makeConnector() {
-        return new IpClientConnector();
-    }
-
-    class IpClientConnector extends IIpClient.Stub {
-        @Override
-        public void completedPreDhcpAction() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.completedPreDhcpAction();
-        }
-        @Override
-        public void confirmConfiguration() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.confirmConfiguration();
-        }
-        @Override
-        public void readPacketFilterComplete(byte[] data) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.readPacketFilterComplete(data);
-        }
-        @Override
-        public void shutdown() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.shutdown();
-        }
-        @Override
-        public void startProvisioning(ProvisioningConfigurationParcelable req) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.startProvisioning(ProvisioningConfiguration.fromStableParcelable(req));
-        }
-        @Override
-        public void stop() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.stop();
-        }
-        @Override
-        public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setL2KeyAndGroupHint(l2Key, groupHint);
-        }
-        @Override
-        public void setTcpBufferSizes(String tcpBufferSizes) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setTcpBufferSizes(tcpBufferSizes);
-        }
-        @Override
-        public void setHttpProxy(ProxyInfo proxyInfo) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setHttpProxy(proxyInfo);
-        }
-        @Override
-        public void setMulticastFilter(boolean enabled) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setMulticastFilter(enabled);
-        }
-        @Override
-        public void addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void addNattKeepalivePacketFilter(int slot, NattKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addNattKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void removeKeepalivePacketFilter(int slot) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.removeKeepalivePacketFilter(slot);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    public String getInterfaceName() {
-        return mInterfaceName;
-    }
-
-    private void configureAndStartStateMachine() {
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mStoppedState);
-        addState(mStartedState);
-            addState(mRunningState, mStartedState);
-        addState(mStoppingState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        setInitialState(mStoppedState);
-
-        super.start();
-    }
-
-    private void startStateMachineUpdaters() {
-        mObserverRegistry.registerObserverForNonblockingCallback(mLinkObserver);
-    }
-
-    private void stopStateMachineUpdaters() {
-        mObserverRegistry.unregisterObserver(mLinkObserver);
-    }
-
-    @Override
-    protected void onQuitting() {
-        mCallback.onQuit();
-        mShutdownLatch.countDown();
-    }
-
-    /**
-     * Shut down this IpClient instance altogether.
-     */
-    public void shutdown() {
-        stop();
-        sendMessage(CMD_TERMINATE_AFTER_STOP);
-    }
-
-    /**
-     * Start provisioning with the provided parameters.
-     */
-    public void startProvisioning(ProvisioningConfiguration req) {
-        if (!req.isValid()) {
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-            return;
-        }
-
-        mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName);
-        if (mInterfaceParams == null) {
-            logError("Failed to find InterfaceParams for " + mInterfaceName);
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND);
-            return;
-        }
-
-        mCallback.setNeighborDiscoveryOffload(true);
-        sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
-    }
-
-    /**
-     * Stop this IpClient.
-     *
-     * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
-     */
-    public void stop() {
-        sendMessage(CMD_STOP);
-    }
-
-    /**
-     * Confirm the provisioning configuration.
-     */
-    public void confirmConfiguration() {
-        sendMessage(CMD_CONFIRM);
-    }
-
-    /**
-     * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
-     * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
-     * proceed.
-     */
-    public void completedPreDhcpAction() {
-        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-    }
-
-    /**
-     * Indicate that packet filter read is complete.
-     */
-    public void readPacketFilterComplete(byte[] data) {
-        sendMessage(EVENT_READ_PACKET_FILTER_COMPLETE, data);
-    }
-
-    /**
-     * Set the TCP buffer sizes to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setTcpBufferSizes(String tcpBufferSizes) {
-        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
-    }
-
-    /**
-     * Set the L2 key and group hint for storing info into the memory store.
-     */
-    public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-        sendMessage(CMD_UPDATE_L2KEY_GROUPHINT, new Pair<>(l2Key, groupHint));
-    }
-
-    /**
-     * Set the HTTP Proxy configuration to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setHttpProxy(ProxyInfo proxyInfo) {
-        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
-    }
-
-    /**
-     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
-     * if not, Callback.setFallbackMulticastFilter() is called.
-     */
-    public void setMulticastFilter(boolean enabled) {
-        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
-    }
-
-    /**
-     * Called by WifiStateMachine to add TCP keepalive packet filter before setting up
-     * keepalive offload.
-     */
-    public void addKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */, pkt);
-    }
-
-    /**
-     *  Called by WifiStateMachine to add NATT keepalive packet filter before setting up
-     *  keepalive offload.
-     */
-    public void addNattKeepalivePacketFilter(int slot,
-            @NonNull NattKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */ , pkt);
-    }
-
-    /**
-     * Called by WifiStateMachine to remove keepalive packet filter after stopping keepalive
-     * offload.
-     */
-    public void removeKeepalivePacketFilter(int slot) {
-        sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF, slot, 0 /* Unused */);
-    }
-
-    /**
-     * Dump logs of this IpClient.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
-            // Execute confirmConfiguration() and take no further action.
-            confirmConfiguration();
-            return;
-        }
-
-        // Thread-unsafe access to mApfFilter but just used for debugging.
-        final ApfFilter apfFilter = mApfFilter;
-        final android.net.shared.ProvisioningConfiguration provisioningConfig = mConfiguration;
-        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
-                ? provisioningConfig.mApfCapabilities : null;
-
-        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(mTag + " APF dump:");
-        pw.increaseIndent();
-        if (apfFilter != null) {
-            if (apfCapabilities.hasDataAccess()) {
-                // Request a new snapshot, then wait for it.
-                mApfDataSnapshotComplete.close();
-                mCallback.startReadPacketFilter();
-                if (!mApfDataSnapshotComplete.block(1000)) {
-                    pw.print("TIMEOUT: DUMPING STALE APF SNAPSHOT");
-                }
-            }
-            apfFilter.dump(pw);
-
-        } else {
-            pw.print("No active ApfFilter; ");
-            if (provisioningConfig == null) {
-                pw.println("IpClient not yet started.");
-            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
-                pw.println("Hardware does not support APF.");
-            } else {
-                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
-            }
-        }
-        pw.decreaseIndent();
-        pw.println();
-        pw.println(mTag + " current ProvisioningConfiguration:");
-        pw.increaseIndent();
-        pw.println(Objects.toString(provisioningConfig, "N/A"));
-        pw.decreaseIndent();
-
-        final IpReachabilityMonitor iprm = mIpReachabilityMonitor;
-        if (iprm != null) {
-            pw.println();
-            pw.println(mTag + " current IpReachabilityMonitor state:");
-            pw.increaseIndent();
-            iprm.dump(pw);
-            pw.decreaseIndent();
-        }
-
-        pw.println();
-        pw.println(mTag + " StateMachine dump:");
-        pw.increaseIndent();
-        mLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " connectivity packet log:");
-        pw.println();
-        pw.println("Debug with python and scapy via:");
-        pw.println("shell$ python");
-        pw.println(">>> from scapy import all as scapy");
-        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
-        pw.println();
-
-        pw.increaseIndent();
-        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
-        pw.decreaseIndent();
-    }
-
-
-    /**
-     * Internals.
-     */
-
-    @Override
-    protected String getWhatToString(int what) {
-        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
-    }
-
-    @Override
-    protected String getLogRecString(Message msg) {
-        final String logLine = String.format(
-                "%s/%d %d %d %s [%s]",
-                mInterfaceName, (mInterfaceParams == null) ? -1 : mInterfaceParams.index,
-                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
-
-        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
-        mLog.log(richerLogLine);
-        if (DBG) {
-            Log.d(mTag, richerLogLine);
-        }
-
-        mMsgStateLogger.reset();
-        return logLine;
-    }
-
-    @Override
-    protected boolean recordLogRec(Message msg) {
-        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
-        // and we already log any LinkProperties change that results in an
-        // invocation of IpClient.Callback#onLinkPropertiesChange().
-        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
-        if (!shouldLog) {
-            mMsgStateLogger.reset();
-        }
-        return shouldLog;
-    }
-
-    private void logError(String fmt, Object... args) {
-        final String msg = "ERROR " + String.format(fmt, args);
-        Log.e(mTag, msg);
-        mLog.log(msg);
-    }
-
-    // This needs to be called with care to ensure that our LinkProperties
-    // are in sync with the actual LinkProperties of the interface. For example,
-    // we should only call this if we know for sure that there are no IP addresses
-    // assigned to the interface, etc.
-    private void resetLinkProperties() {
-        mLinkObserver.clearLinkProperties();
-        mConfiguration = null;
-        mDhcpResults = null;
-        mTcpBufferSizes = "";
-        mHttpProxy = null;
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    private void recordMetric(final int type) {
-        // We may record error metrics prior to starting.
-        // Map this to IMMEDIATE_FAILURE_DURATION.
-        final long duration = (mStartTimeMillis > 0)
-                ? (SystemClock.elapsedRealtime() - mStartTimeMillis)
-                : IMMEDIATE_FAILURE_DURATION;
-        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
-    }
-
-    // For now: use WifiStateMachine's historical notion of provisioned.
-    @VisibleForTesting
-    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
-        // For historical reasons, we should connect even if all we have is
-        // an IPv4 address and nothing else.
-        if (lp.hasIpv4Address() || lp.isProvisioned()) {
-            return true;
-        }
-        if (config == null) {
-            return false;
-        }
-
-        // When an InitialConfiguration is specified, ignore any difference with previous
-        // properties and instead check if properties observed match the desired properties.
-        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
-    }
-
-    // TODO: Investigate folding all this into the existing static function
-    // LinkProperties.compareProvisioning() or some other single function that
-    // takes two LinkProperties objects and returns a ProvisioningChange
-    // object that is a correct and complete assessment of what changed, taking
-    // account of the asymmetries described in the comments in this function.
-    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
-    private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
-        int delta;
-        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
-        final boolean wasProvisioned = isProvisioned(oldLp, config);
-        final boolean isProvisioned = isProvisioned(newLp, config);
-
-        if (!wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_GAINED_PROVISIONING;
-        } else if (wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_STILL_PROVISIONED;
-        } else if (!wasProvisioned && !isProvisioned) {
-            delta = PROV_CHANGE_STILL_NOT_PROVISIONED;
-        } else {
-            // (wasProvisioned && !isProvisioned)
-            //
-            // Note that this is true even if we lose a configuration element
-            // (e.g., a default gateway) that would not be required to advance
-            // into provisioned state. This is intended: if we have a default
-            // router and we lose it, that's a sure sign of a problem, but if
-            // we connect to a network with no IPv4 DNS servers, we consider
-            // that to be a network without DNS servers and connect anyway.
-            //
-            // See the comment below.
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        final boolean lostIPv6 = oldLp.isIpv6Provisioned() && !newLp.isIpv6Provisioned();
-        final boolean lostIPv4Address = oldLp.hasIpv4Address() && !newLp.hasIpv4Address();
-        final boolean lostIPv6Router = oldLp.hasIpv6DefaultRoute() && !newLp.hasIpv6DefaultRoute();
-
-        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
-        // provisioning. Otherwise, when a hotspot that loses Internet
-        // access sends out a 0-lifetime RA to its clients, the clients
-        // will disconnect and then reconnect, avoiding the bad hotspot,
-        // instead of getting stuck on the bad hotspot. http://b/31827713 .
-        //
-        // This is incorrect because if the hotspot then regains Internet
-        // access with a different prefix, TCP connections on the
-        // deprecated addresses will remain stuck.
-        //
-        // Note that we can still be disconnected by IpReachabilityMonitor
-        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
-        // accompanying code in IpReachabilityMonitor) is unreachable.
-        final boolean ignoreIPv6ProvisioningLoss =
-                mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
-                && mCm.shouldAvoidBadWifi();
-
-        // Additionally:
-        //
-        // Partial configurations (e.g., only an IPv4 address with no DNS
-        // servers and no default route) are accepted as long as DHCPv4
-        // succeeds. On such a network, isProvisioned() will always return
-        // false, because the configuration is not complete, but we want to
-        // connect anyway. It might be a disconnected network such as a
-        // Chromecast or a wireless printer, for example.
-        //
-        // Because on such a network isProvisioned() will always return false,
-        // delta will never be LOST_PROVISIONING. So check for loss of
-        // provisioning here too.
-        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        // Additionally:
-        //
-        // If the previous link properties had a global IPv6 address and an
-        // IPv6 default route then also consider the loss of that default route
-        // to be a loss of provisioning. See b/27962810.
-        if (oldLp.hasGlobalIpv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        return delta;
-    }
-
-    private void dispatchCallback(int delta, LinkProperties newLp) {
-        switch (delta) {
-            case PROV_CHANGE_GAINED_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningSuccess()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_OK);
-                mCallback.onProvisioningSuccess(newLp);
-                break;
-
-            case PROV_CHANGE_LOST_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningFailure()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
-                mCallback.onProvisioningFailure(newLp);
-                break;
-
-            default:
-                if (DBG) {
-                    Log.d(mTag, "onLinkPropertiesChange()");
-                }
-                mCallback.onLinkPropertiesChange(newLp);
-                break;
-        }
-    }
-
-    // Updates all IpClient-related state concerned with LinkProperties.
-    // Returns a ProvisioningChange for possibly notifying other interested
-    // parties that are not fronted by IpClient.
-    private int setLinkProperties(LinkProperties newLp) {
-        if (mApfFilter != null) {
-            mApfFilter.setLinkProperties(newLp);
-        }
-        if (mIpReachabilityMonitor != null) {
-            mIpReachabilityMonitor.updateLinkProperties(newLp);
-        }
-
-        int delta = compareProvisioning(mLinkProperties, newLp);
-        mLinkProperties = new LinkProperties(newLp);
-
-        if (delta == PROV_CHANGE_GAINED_PROVISIONING) {
-            // TODO: Add a proper ProvisionedState and cancel the alarm in
-            // its enter() method.
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        return delta;
-    }
-
-    private LinkProperties assembleLinkProperties() {
-        // [1] Create a new LinkProperties object to populate.
-        LinkProperties newLp = new LinkProperties();
-        newLp.setInterfaceName(mInterfaceName);
-
-        // [2] Pull in data from netlink:
-        //         - IPv4 addresses
-        //         - IPv6 addresses
-        //         - IPv6 routes
-        //         - IPv6 DNS servers
-        //
-        // N.B.: this is fundamentally race-prone and should be fixed by
-        // changing IpClientLinkObserver from a hybrid edge/level model to an
-        // edge-only model, or by giving IpClient its own netlink socket(s)
-        // so as to track all required information directly.
-        LinkProperties netlinkLinkProperties = mLinkObserver.getLinkProperties();
-        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
-        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
-            newLp.addRoute(route);
-        }
-        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
-
-        // [3] Add in data from DHCPv4, if available.
-        //
-        // mDhcpResults is never shared with any other owner so we don't have
-        // to worry about concurrent modification.
-        if (mDhcpResults != null) {
-            final List<RouteInfo> routes =
-                    mDhcpResults.toStaticIpConfiguration().getRoutes(mInterfaceName);
-            for (RouteInfo route : routes) {
-                newLp.addRoute(route);
-            }
-            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
-            newLp.setDomains(mDhcpResults.domains);
-
-            if (mDhcpResults.mtu != 0) {
-                newLp.setMtu(mDhcpResults.mtu);
-            }
-        }
-
-        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
-        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
-            newLp.setTcpBufferSizes(mTcpBufferSizes);
-        }
-        if (mHttpProxy != null) {
-            newLp.setHttpProxy(mHttpProxy);
-        }
-
-        // [5] Add data from InitialConfiguration
-        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
-            InitialConfiguration config = mConfiguration.mInitialConfig;
-            // Add InitialConfiguration routes and dns server addresses once all addresses
-            // specified in the InitialConfiguration have been observed with Netlink.
-            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
-                for (IpPrefix prefix : config.directlyConnectedRoutes) {
-                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName, RTN_UNICAST));
-                }
-            }
-            addAllReachableDnsServers(newLp, config.dnsServers);
-        }
-        final LinkProperties oldLp = mLinkProperties;
-        if (DBG) {
-            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
-                    netlinkLinkProperties, newLp, oldLp));
-        }
-
-        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
-        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
-        return newLp;
-    }
-
-    private static void addAllReachableDnsServers(
-            LinkProperties lp, Iterable<InetAddress> dnses) {
-        // TODO: Investigate deleting this reachability check.  We should be
-        // able to pass everything down to netd and let netd do evaluation
-        // and RFC6724-style sorting.
-        for (InetAddress dns : dnses) {
-            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
-                lp.addDnsServer(dns);
-            }
-        }
-    }
-
-    // Returns false if we have lost provisioning, true otherwise.
-    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
-        final LinkProperties newLp = assembleLinkProperties();
-        if (Objects.equals(newLp, mLinkProperties)) {
-            return true;
-        }
-        final int delta = setLinkProperties(newLp);
-        // Most of the attributes stored in the memory store are deduced from
-        // the link properties, therefore when the properties update the memory
-        // store record should be updated too.
-        maybeSaveNetworkToIpMemoryStore();
-        if (sendCallbacks) {
-            dispatchCallback(delta, newLp);
-        }
-        return (delta != PROV_CHANGE_LOST_PROVISIONING);
-    }
-
-    private void handleIPv4Success(DhcpResults dhcpResults) {
-        mDhcpResults = new DhcpResults(dhcpResults);
-        final LinkProperties newLp = assembleLinkProperties();
-        final int delta = setLinkProperties(newLp);
-
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
-        }
-        mCallback.onNewDhcpResults(dhcpResults);
-        maybeSaveNetworkToIpMemoryStore();
-        dispatchCallback(delta, newLp);
-    }
-
-    private void handleIPv4Failure() {
-        // TODO: Investigate deleting this clearIPv4Address() call.
-        //
-        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
-        // that could trigger a call to this function. If we missed handling
-        // that message in StartedState for some reason we would still clear
-        // any addresses upon entry to StoppedState.
-        mInterfaceCtrl.clearIPv4Address();
-        mDhcpResults = null;
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(null)");
-        }
-        mCallback.onNewDhcpResults(null);
-
-        handleProvisioningFailure();
-    }
-
-    private void handleProvisioningFailure() {
-        final LinkProperties newLp = assembleLinkProperties();
-        int delta = setLinkProperties(newLp);
-        // If we've gotten here and we're still not provisioned treat that as
-        // a total loss of provisioning.
-        //
-        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
-        // there was no usable IPv6 obtained before a non-zero provisioning
-        // timeout expired.
-        //
-        // Regardless: GAME OVER.
-        if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        dispatchCallback(delta, newLp);
-        if (delta == PROV_CHANGE_LOST_PROVISIONING) {
-            transitionTo(mStoppingState);
-        }
-    }
-
-    private void doImmediateProvisioningFailure(int failureType) {
-        logError("onProvisioningFailure(): %s", failureType);
-        recordMetric(failureType);
-        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
-    }
-
-    private boolean startIPv4() {
-        // If we have a StaticIpConfiguration attempt to apply it and
-        // handle the result accordingly.
-        if (mConfiguration.mStaticIpConfig != null) {
-            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.getIpAddress())) {
-                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
-            } else {
-                return false;
-            }
-        } else {
-            // Start DHCPv4.
-            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams);
-            mDhcpClient.registerForPreDhcpNotification();
-            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
-        }
-
-        return true;
-    }
-
-    private boolean startIPv6() {
-        return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
-                && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
-                && mInterfaceCtrl.enableIPv6();
-    }
-
-    private boolean applyInitialConfig(InitialConfiguration config) {
-        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
-        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIpv6)) {
-            if (!mInterfaceCtrl.addAddress(addr)) return false;
-        }
-
-        return true;
-    }
-
-    private boolean startIpReachabilityMonitor() {
-        try {
-            // TODO: Fetch these parameters from settings, and install a
-            // settings observer to watch for update and re-program these
-            // parameters (Q: is this level of dynamic updatability really
-            // necessary or does reading from settings at startup suffice?).
-            final int numSolicits = 5;
-            final int interSolicitIntervalMs = 750;
-            setNeighborParameters(mNetd, mInterfaceName, numSolicits, interSolicitIntervalMs);
-        } catch (Exception e) {
-            mLog.e("Failed to adjust neighbor parameters", e);
-            // Carry on using the system defaults (currently: 3, 1000);
-        }
-
-        try {
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceParams,
-                    getHandler(),
-                    mLog,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            mCallback.onReachabilityLost(logMsg);
-                        }
-                    },
-                    mConfiguration.mUsingMultinetworkPolicyTracker);
-        } catch (IllegalArgumentException iae) {
-            // Failed to start IpReachabilityMonitor. Log it and call
-            // onProvisioningFailure() immediately.
-            //
-            // See http://b/31038971.
-            logError("IpReachabilityMonitor failure: %s", iae);
-            mIpReachabilityMonitor = null;
-        }
-
-        return (mIpReachabilityMonitor != null);
-    }
-
-    private void stopAllIP() {
-        // We don't need to worry about routes, just addresses, because:
-        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
-        //     - we don't get IPv4 routes from netlink
-        // so we neither react to nor need to wait for changes in either.
-
-        mInterfaceCtrl.disableIPv6();
-        mInterfaceCtrl.clearAllAddresses();
-    }
-
-    private void maybeSaveNetworkToIpMemoryStore() {
-        // TODO : implement this
-    }
-
-    class StoppedState extends State {
-        @Override
-        public void enter() {
-            stopAllIP();
-
-            resetLinkProperties();
-            if (mStartTimeMillis > 0) {
-                // Completed a life-cycle; send a final empty LinkProperties
-                // (cleared in resetLinkProperties() above) and record an event.
-                mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
-                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
-                mStartTimeMillis = 0;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_TERMINATE_AFTER_STOP:
-                    stopStateMachineUpdaters();
-                    quit();
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case CMD_START:
-                    mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
-                    transitionTo(mStartedState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    break;
-                }
-
-                case CMD_SET_MULTICAST_FILTER:
-                    mMulticastFiltering = (boolean) msg.obj;
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // Everything is already stopped.
-                    logError("Unexpected CMD_ON_QUIT (already stopped).");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StoppingState extends State {
-        @Override
-        public void enter() {
-            if (mDhcpClient == null) {
-                // There's no DHCPv4 for which to wait; proceed to stopped.
-                deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STOPPING_TO_STOPPED:
-                    transitionTo(mStoppedState);
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    mDhcpClient = null;
-                    transitionTo(mStoppedState);
-                    break;
-
-                default:
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StartedState extends State {
-        @Override
-        public void enter() {
-            mStartTimeMillis = SystemClock.elapsedRealtime();
-
-            if (mConfiguration.mProvisioningTimeoutMs > 0) {
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mProvisioningTimeoutMs;
-                mProvisioningTimeoutAlarm.schedule(alarmTime);
-            }
-
-            if (readyToProceed()) {
-                deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
-            } else {
-                // Clear all IPv4 and IPv6 before proceeding to RunningState.
-                // Clean up any leftover state from an abnormal exit from
-                // tethering or during an IpClient restart.
-                stopAllIP();
-            }
-        }
-
-        @Override
-        public void exit() {
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STARTED_TO_RUNNING:
-                    transitionTo(mRunningState);
-                    break;
-
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    if (readyToProceed()) {
-                        transitionTo(mRunningState);
-                    }
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    // TODO : attributes should be saved to the memory store with
-                    // these new values if they differ from the previous ones.
-                    // If the state machine is in pure StartedState, then the values to input
-                    // are not known yet and should be updated when the LinkProperties are updated.
-                    // If the state machine is in RunningState (which is a child of StartedState)
-                    // then the next NUD check should be used to store the new values to avoid
-                    // inputting current values for what may be a different L3 network.
-                    break;
-                }
-
-                case EVENT_PROVISIONING_TIMEOUT:
-                    handleProvisioningFailure();
-                    break;
-
-                default:
-                    // It's safe to process messages out of order because the
-                    // only message that can both
-                    //     a) be received at this time and
-                    //     b) affect provisioning state
-                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-
-        private boolean readyToProceed() {
-            return (!mLinkProperties.hasIpv4Address() && !mLinkProperties.hasGlobalIpv6Address());
-        }
-    }
-
-    class RunningState extends State {
-        private ConnectivityPacketTracker mPacketTracker;
-        private boolean mDhcpActionInFlight;
-
-        @Override
-        public void enter() {
-            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
-            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
-            apfConfig.multicastFilter = mMulticastFiltering;
-            // Get the Configuration for ApfFilter from Context
-            apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames();
-            apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList();
-            mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);
-            // TODO: investigate the effects of any multicast filtering racing/interfering with the
-            // rest of this IP configuration startup.
-            if (mApfFilter == null) {
-                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-            }
-
-            mPacketTracker = createPacketTracker();
-            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
-
-            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            final InitialConfiguration config = mConfiguration.mInitialConfig;
-            if ((config != null) && !applyInitialConfig(config)) {
-                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
-                doImmediateProvisioningFailure(
-                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
-                enqueueJumpToStoppingState();
-                return;
-            }
-        }
-
-        @Override
-        public void exit() {
-            stopDhcpAction();
-
-            if (mIpReachabilityMonitor != null) {
-                mIpReachabilityMonitor.stop();
-                mIpReachabilityMonitor = null;
-            }
-
-            if (mDhcpClient != null) {
-                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
-                mDhcpClient.doQuit();
-            }
-
-            if (mPacketTracker != null) {
-                mPacketTracker.stop();
-                mPacketTracker = null;
-            }
-
-            if (mApfFilter != null) {
-                mApfFilter.shutdown();
-                mApfFilter = null;
-            }
-
-            resetLinkProperties();
-        }
-
-        private void enqueueJumpToStoppingState() {
-            deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
-        }
-
-        private ConnectivityPacketTracker createPacketTracker() {
-            try {
-                return new ConnectivityPacketTracker(
-                        getHandler(), mInterfaceParams, mConnectivityPacketLog);
-            } catch (IllegalArgumentException e) {
-                return null;
-            }
-        }
-
-        private void ensureDhcpAction() {
-            if (!mDhcpActionInFlight) {
-                mCallback.onPreDhcpAction();
-                mDhcpActionInFlight = true;
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mRequestedPreDhcpActionMs;
-                mDhcpActionTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-
-        private void stopDhcpAction() {
-            mDhcpActionTimeoutAlarm.cancel();
-            if (mDhcpActionInFlight) {
-                mCallback.onPostDhcpAction();
-                mDhcpActionInFlight = false;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_RUNNING_TO_STOPPING:
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case CMD_START:
-                    logError("ALERT: START received in StartedState. Please fix caller.");
-                    break;
-
-                case CMD_CONFIRM:
-                    // TODO: Possibly introduce a second type of confirmation
-                    // that both probes (a) on-link neighbors and (b) does
-                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
-                    // roams.
-                    if (mIpReachabilityMonitor != null) {
-                        mIpReachabilityMonitor.probeAll();
-                    }
-                    break;
-
-                case EVENT_PRE_DHCP_ACTION_COMPLETE:
-                    // It's possible to reach here if, for example, someone
-                    // calls completedPreDhcpAction() after provisioning with
-                    // a static IP configuration.
-                    if (mDhcpClient != null) {
-                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_SET_MULTICAST_FILTER: {
-                    mMulticastFiltering = (boolean) msg.obj;
-                    if (mApfFilter != null) {
-                        mApfFilter.setMulticastFilter(mMulticastFiltering);
-                    } else {
-                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-                    }
-                    break;
-                }
-
-                case EVENT_READ_PACKET_FILTER_COMPLETE: {
-                    if (mApfFilter != null) {
-                        mApfFilter.setDataSnapshot((byte[]) msg.obj);
-                    }
-                    mApfDataSnapshotComplete.open();
-                    break;
-                }
-
-                case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF: {
-                    final int slot = msg.arg1;
-
-                    if (mApfFilter != null) {
-                        if (msg.obj instanceof NattKeepalivePacketDataParcelable) {
-                            mApfFilter.addNattKeepalivePacketFilter(slot,
-                                    (NattKeepalivePacketDataParcelable) msg.obj);
-                        } else if (msg.obj instanceof TcpKeepalivePacketDataParcelable) {
-                            mApfFilter.addTcpKeepalivePacketFilter(slot,
-                                    (TcpKeepalivePacketDataParcelable) msg.obj);
-                        }
-                    }
-                    break;
-                }
-
-                case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
-                    final int slot = msg.arg1;
-                    if (mApfFilter != null) {
-                        mApfFilter.removeKeepalivePacketFilter(slot);
-                    }
-                    break;
-                }
-
-                case EVENT_DHCPACTION_TIMEOUT:
-                    stopDhcpAction();
-                    break;
-
-                case DhcpClient.CMD_PRE_DHCP_ACTION:
-                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
-                        ensureDhcpAction();
-                    } else {
-                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
-                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
-                    if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
-                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
-                    } else {
-                        logError("Failed to set IPv4 address.");
-                        dispatchCallback(PROV_CHANGE_LOST_PROVISIONING,
-                                new LinkProperties(mLinkProperties));
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-                }
-
-                // This message is only received when:
-                //
-                //     a) initial address acquisition succeeds,
-                //     b) renew succeeds or is NAK'd,
-                //     c) rebind succeeds or is NAK'd, or
-                //     c) the lease expires,
-                //
-                // but never when initial address acquisition fails. The latter
-                // condition is now governed by the provisioning timeout.
-                case DhcpClient.CMD_POST_DHCP_ACTION:
-                    stopDhcpAction();
-
-                    switch (msg.arg1) {
-                        case DhcpClient.DHCP_SUCCESS:
-                            handleIPv4Success((DhcpResults) msg.obj);
-                            break;
-                        case DhcpClient.DHCP_FAILURE:
-                            handleIPv4Failure();
-                            break;
-                        default:
-                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
-                    }
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // DHCPv4 quit early for some reason.
-                    logError("Unexpected CMD_ON_QUIT.");
-                    mDhcpClient = null;
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    private static class MessageHandlingLogger {
-        public String processedInState;
-        public String receivedInState;
-
-        public void reset() {
-            processedInState = null;
-            receivedInState = null;
-        }
-
-        public void handled(State processedIn, IState receivedIn) {
-            processedInState = processedIn.getClass().getSimpleName();
-            receivedInState = receivedIn.getName();
-        }
-
-        public String toString() {
-            return String.format("rcvd_in=%s, proc_in=%s",
-                                 receivedInState, processedInState);
-        }
-    }
-
-    private static void setNeighborParameters(
-            INetd netd, String ifName, int numSolicits, int interSolicitIntervalMs)
-            throws RemoteException, IllegalArgumentException {
-        Preconditions.checkNotNull(netd);
-        Preconditions.checkArgument(!TextUtils.isEmpty(ifName));
-        Preconditions.checkArgument(numSolicits > 0);
-        Preconditions.checkArgument(interSolicitIntervalMs > 0);
-
-        for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) {
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms",
-                    Integer.toString(interSolicitIntervalMs));
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit",
-                    Integer.toString(numSolicits));
-        }
-    }
-
-    // TODO: extract out into CollectionUtils.
-    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
-        for (T t : coll) {
-            if (fn.test(t)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
-        return !any(coll, not(fn));
-    }
-
-    static <T> Predicate<T> not(Predicate<T> fn) {
-        return (t) -> !fn.test(t);
-    }
-
-    static <T> String join(String delimiter, Collection<T> coll) {
-        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
-    }
-
-    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
-        for (T t: coll) {
-            if (fn.test(t)) {
-                return t;
-            }
-        }
-        return null;
-    }
-
-    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
-        return coll.stream().filter(fn).collect(Collectors.toList());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java b/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
deleted file mode 100644
index 8ad99aa0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2014 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.ip;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.util.Log;
-
-import com.android.server.NetworkObserver;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Keeps track of link configuration received from Netd.
- *
- * An instance of this class is constructed by passing in an interface name and a callback. The
- * owner is then responsible for registering the tracker with NetworkObserverRegistry. When the
- * class receives update notifications, it applies the update to its local LinkProperties, and if
- * something has changed, notifies its owner of the update via the callback.
- *
- * The owner can then call {@code getLinkProperties()} in order to find out
- * what changed. If in the meantime the LinkProperties stored here have changed,
- * this class will return the current LinkProperties. Because each change
- * triggers an update callback after the change is made, the owner may get more
- * callbacks than strictly necessary (some of which may be no-ops), but will not
- * be out of sync once all callbacks have been processed.
- *
- * Threading model:
- *
- * - The owner of this class is expected to create it, register it, and call
- *   getLinkProperties or clearLinkProperties on its thread.
- * - Most of the methods in the class are implementing NetworkObserver and are called
- *   on the handler used to register the observer.
- * - All accesses to mLinkProperties must be synchronized(this). All the other
- *   member variables are immutable once the object is constructed.
- *
- * @hide
- */
-public class IpClientLinkObserver implements NetworkObserver {
-    private final String mTag;
-
-    /**
-     * Callback used by {@link IpClientLinkObserver} to send update notifications.
-     */
-    public interface Callback {
-        /**
-         * Called when some properties of the link were updated.
-         */
-        void update();
-    }
-
-    private final String mInterfaceName;
-    private final Callback mCallback;
-    private final LinkProperties mLinkProperties;
-    private DnsServerRepository mDnsServerRepository;
-
-    private static final boolean DBG = false;
-
-    public IpClientLinkObserver(String iface, Callback callback) {
-        mTag = "NetlinkTracker/" + iface;
-        mInterfaceName = iface;
-        mCallback = callback;
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-        mDnsServerRepository = new DnsServerRepository();
-    }
-
-    private void maybeLog(String operation, String iface, LinkAddress address) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + address + " on " + iface
-                    + " flags " + address.getFlags() + " scope " + address.getScope());
-        }
-    }
-
-    private void maybeLog(String operation, Object o) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + o.toString());
-        }
-    }
-
-    @Override
-    public void onInterfaceRemoved(String iface) {
-        maybeLog("interfaceRemoved", iface);
-        if (mInterfaceName.equals(iface)) {
-            // Our interface was removed. Clear our LinkProperties and tell our owner that they are
-            // now empty. Note that from the moment that the interface is removed, any further
-            // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd
-            // code that parses them will not be able to resolve the ifindex to an interface name.
-            clearLinkProperties();
-            mCallback.update();
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressUpdated", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressRemoved", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteUpdated(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeUpdated", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteRemoved(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeRemoved", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses));
-            boolean changed = mDnsServerRepository.addServers(lifetime, addresses);
-            if (changed) {
-                synchronized (this) {
-                    mDnsServerRepository.setDnsServersOn(mLinkProperties);
-                }
-                mCallback.update();
-            }
-        }
-    }
-
-    /**
-     * Returns a copy of this object's LinkProperties.
-     */
-    public synchronized LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
-    }
-
-    /**
-     * Reset this object's LinkProperties.
-     */
-    public synchronized void clearLinkProperties() {
-        // Clear the repository before clearing mLinkProperties. That way, if a clear() happens
-        // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
-        // mLinkProperties, as desired.
-        mDnsServerRepository = new DnsServerRepository();
-        mLinkProperties.clear();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    /**
-     * Tracks DNS server updates received from Netlink.
-     *
-     * The network may announce an arbitrary number of DNS servers in Router Advertisements at any
-     * time. Each announcement has a lifetime; when the lifetime expires, the servers should not be
-     * used any more. In this way, the network can gracefully migrate clients from one set of DNS
-     * servers to another. Announcements can both raise and lower the lifetime, and an announcement
-     * can expire servers by announcing them with a lifetime of zero.
-     *
-     * Typically the system will only use a small number (2 or 3; {@code NUM_CURRENT_SERVERS}) of
-     * DNS servers at any given time. These are referred to as the current servers. In case all the
-     * current servers expire, the class also keeps track of a larger (but limited) number of
-     * servers that are promoted to current servers when the current ones expire. In order to
-     * minimize updates to the rest of the system (and potentially expensive cache flushes) this
-     * class attempts to keep the list of current servers constant where possible. More
-     * specifically, the list of current servers is only updated if a new server is learned and
-     * there are not yet {@code NUM_CURRENT_SERVERS} current servers, or if one or more of the
-     * current servers expires or is pushed out of the set. Therefore, the current servers will not
-     * necessarily be the ones with the highest lifetime, but the ones learned first.
-     *
-     * This is by design: if instead the class always preferred the servers with the highest
-     * lifetime, a (misconfigured?) network where two or more routers announce more than
-     * {@code NUM_CURRENT_SERVERS} unique servers would cause persistent oscillations.
-     *
-     * TODO: Currently servers are only expired when a new DNS update is received.
-     * Update them using timers, or possibly on every notification received by NetlinkTracker.
-     *
-     * Threading model: run by NetlinkTracker. Methods are synchronized(this) just in case netlink
-     * notifications are sent by multiple threads. If future threads use alarms to expire, those
-     * alarms must also be synchronized(this).
-     *
-     */
-    private static class DnsServerRepository {
-
-        /** How many DNS servers we will use. 3 is suggested by RFC 6106. */
-        static final int NUM_CURRENT_SERVERS = 3;
-
-        /** How many DNS servers we'll keep track of, in total. */
-        static final int NUM_SERVERS = 12;
-
-        /** Stores up to {@code NUM_CURRENT_SERVERS} DNS servers we're currently using. */
-        private Set<InetAddress> mCurrentServers;
-
-        public static final String TAG = "DnsServerRepository";
-
-        /**
-         * Stores all the DNS servers we know about, for use when the current servers expire.
-         * Always sorted in order of decreasing expiry. The elements in this list are also the
-         * values of mIndex, and may be elements in mCurrentServers.
-         */
-        private ArrayList<DnsServerEntry> mAllServers;
-
-        /**
-         * Indexes the servers so we can update their lifetimes more quickly in the common case
-         * where servers are not being added, but only being refreshed.
-         */
-        private HashMap<InetAddress, DnsServerEntry> mIndex;
-
-        DnsServerRepository() {
-            mCurrentServers = new HashSet<>();
-            mAllServers = new ArrayList<>(NUM_SERVERS);
-            mIndex = new HashMap<>(NUM_SERVERS);
-        }
-
-        /** Sets the DNS servers of the provided LinkProperties object to the current servers. */
-        public synchronized void setDnsServersOn(LinkProperties lp) {
-            lp.setDnsServers(mCurrentServers);
-        }
-
-        /**
-         * Notifies the class of new DNS server information.
-         * @param lifetime the time in seconds that the DNS servers are valid.
-         * @param addresses the string representations of the IP addresses of DNS servers to use.
-         */
-        public synchronized boolean addServers(long lifetime, String[] addresses) {
-            // The lifetime is actually an unsigned 32-bit number, but Java doesn't have unsigned.
-            // Technically 0xffffffff (the maximum) is special and means "forever", but 2^32 seconds
-            // (136 years) is close enough.
-            long now = System.currentTimeMillis();
-            long expiry = now + 1000 * lifetime;
-
-            // Go through the list of servers. For each one, update the entry if one exists, and
-            // create one if it doesn't.
-            for (String addressString : addresses) {
-                InetAddress address;
-                try {
-                    address = InetAddresses.parseNumericAddress(addressString);
-                } catch (IllegalArgumentException ex) {
-                    continue;
-                }
-
-                if (!updateExistingEntry(address, expiry)) {
-                    // There was no entry for this server. Create one, unless it's already expired
-                    // (i.e., if the lifetime is zero; it cannot be < 0 because it's unsigned).
-                    if (expiry > now) {
-                        DnsServerEntry entry = new DnsServerEntry(address, expiry);
-                        mAllServers.add(entry);
-                        mIndex.put(address, entry);
-                    }
-                }
-            }
-
-            // Sort the servers by expiry.
-            Collections.sort(mAllServers);
-
-            // Prune excess entries and update the current server list.
-            return updateCurrentServers();
-        }
-
-        private synchronized boolean updateExistingEntry(InetAddress address, long expiry) {
-            DnsServerEntry existing = mIndex.get(address);
-            if (existing != null) {
-                existing.expiry = expiry;
-                return true;
-            }
-            return false;
-        }
-
-        private synchronized boolean updateCurrentServers() {
-            long now = System.currentTimeMillis();
-            boolean changed = false;
-
-            // Prune excess or expired entries.
-            for (int i = mAllServers.size() - 1; i >= 0; i--) {
-                if (i >= NUM_SERVERS || mAllServers.get(i).expiry < now) {
-                    DnsServerEntry removed = mAllServers.remove(i);
-                    mIndex.remove(removed.address);
-                    changed |= mCurrentServers.remove(removed.address);
-                } else {
-                    break;
-                }
-            }
-
-            // Add servers to the current set, in order of decreasing lifetime, until it has enough.
-            // Prefer existing servers over new servers in order to minimize updates to the rest of
-            // the system and avoid persistent oscillations.
-            for (DnsServerEntry entry : mAllServers) {
-                if (mCurrentServers.size() < NUM_CURRENT_SERVERS) {
-                    changed |= mCurrentServers.add(entry.address);
-                } else {
-                    break;
-                }
-            }
-            return changed;
-        }
-    }
-
-    /**
-     * Represents a DNS server entry with an expiry time.
-     *
-     * Implements Comparable so DNS server entries can be sorted by lifetime, longest-lived first.
-     * The ordering of entries with the same lifetime is unspecified, because given two servers with
-     * identical lifetimes, we don't care which one we use, and only comparing the lifetime is much
-     * faster than comparing the IP address as well.
-     *
-     * Note: this class has a natural ordering that is inconsistent with equals.
-     */
-    private static class DnsServerEntry implements Comparable<DnsServerEntry> {
-        /** The IP address of the DNS server. */
-        public final InetAddress address;
-        /** The time until which the DNS server may be used. A Java millisecond time as might be
-         * returned by currentTimeMillis(). */
-        public long expiry;
-
-        DnsServerEntry(InetAddress address, long expiry) throws IllegalArgumentException {
-            this.address = address;
-            this.expiry = expiry;
-        }
-
-        public int compareTo(DnsServerEntry other) {
-            return Long.compare(other.expiry, this.expiry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
deleted file mode 100644
index 6ae9a2b..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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.ip;
-
-import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
-import static android.net.netlink.NetlinkConstants.hexify;
-import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
-import static android.system.OsConstants.AF_NETLINK;
-import static android.system.OsConstants.NETLINK_ROUTE;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-
-import android.net.MacAddress;
-import android.net.netlink.NetlinkErrorMessage;
-import android.net.netlink.NetlinkMessage;
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNdMsg;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * IpNeighborMonitor.
- *
- * Monitors the kernel rtnetlink neighbor notifications and presents to callers
- * NeighborEvents describing each event. Callers can provide a consumer instance
- * to both filter (e.g. by interface index and IP address) and handle the
- * generated NeighborEvents.
- *
- * @hide
- */
-public class IpNeighborMonitor extends PacketReader {
-    private static final String TAG = IpNeighborMonitor.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    /**
-     * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
-     * for the given IP address on the specified interface index.
-     *
-     * @return 0 if the request was successfully passed to the kernel; otherwise return
-     *         a non-zero error code.
-     */
-    public static int startKernelNeighborProbe(int ifIndex, InetAddress ip) {
-        final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
-        if (DBG) { Log.d(TAG, msgSnippet); }
-
-        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
-                1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
-
-        try {
-            NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
-        } catch (ErrnoException e) {
-            Log.e(TAG, "Error " + msgSnippet + ": " + e);
-            return -e.errno;
-        }
-
-        return 0;
-    }
-
-    public static class NeighborEvent {
-        final long elapsedMs;
-        final short msgType;
-        final int ifindex;
-        final InetAddress ip;
-        final short nudState;
-        final MacAddress macAddr;
-
-        public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
-                short nudState, MacAddress macAddr) {
-            this.elapsedMs = elapsedMs;
-            this.msgType = msgType;
-            this.ifindex = ifindex;
-            this.ip = ip;
-            this.nudState = nudState;
-            this.macAddr = macAddr;
-        }
-
-        boolean isConnected() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
-        }
-
-        boolean isValid() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
-        }
-
-        @Override
-        public String toString() {
-            final StringJoiner j = new StringJoiner(",", "NeighborEvent{", "}");
-            return j.add("@" + elapsedMs)
-                    .add(stringForNlMsgType(msgType))
-                    .add("if=" + ifindex)
-                    .add(ip.getHostAddress())
-                    .add(StructNdMsg.stringForNudState(nudState))
-                    .add("[" + macAddr + "]")
-                    .toString();
-        }
-    }
-
-    public interface NeighborEventConsumer {
-        // Every neighbor event received on the netlink socket is passed in
-        // here. Subclasses should filter for events of interest.
-        public void accept(NeighborEvent event);
-    }
-
-    private final SharedLog mLog;
-    private final NeighborEventConsumer mConsumer;
-
-    public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) {
-        super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE);
-        mLog = log.forSubComponent(TAG);
-        mConsumer = (cb != null) ? cb : (event) -> { /* discard */ };
-    }
-
-    @Override
-    protected FileDescriptor createFd() {
-        FileDescriptor fd = null;
-
-        try {
-            fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE);
-            Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
-            NetlinkSocket.connectToKernel(fd);
-
-            if (VDBG) {
-                final SocketAddress nlAddr = Os.getsockname(fd);
-                Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}");
-            }
-        } catch (ErrnoException|SocketException e) {
-            logError("Failed to create rtnetlink socket", e);
-            NetworkStackUtils.closeSocketQuietly(fd);
-            return null;
-        }
-
-        return fd;
-    }
-
-    @Override
-    protected void handlePacket(byte[] recvbuf, int length) {
-        final long whenMs = SystemClock.elapsedRealtime();
-
-        final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length);
-        byteBuffer.order(ByteOrder.nativeOrder());
-
-        parseNetlinkMessageBuffer(byteBuffer, whenMs);
-    }
-
-    private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) {
-        while (byteBuffer.remaining() > 0) {
-            final int position = byteBuffer.position();
-            final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer);
-            if (nlMsg == null || nlMsg.getHeader() == null) {
-                byteBuffer.position(position);
-                mLog.e("unparsable netlink msg: " + hexify(byteBuffer));
-                break;
-            }
-
-            final int srcPortId = nlMsg.getHeader().nlmsg_pid;
-            if (srcPortId !=  0) {
-                mLog.e("non-kernel source portId: " + Integer.toUnsignedLong(srcPortId));
-                break;
-            }
-
-            if (nlMsg instanceof NetlinkErrorMessage) {
-                mLog.e("netlink error: " + nlMsg);
-                continue;
-            } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) {
-                mLog.i("non-rtnetlink neighbor msg: " + nlMsg);
-                continue;
-            }
-
-            evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs);
-        }
-    }
-
-    private void evaluateRtNetlinkNeighborMessage(
-            RtNetlinkNeighborMessage neighMsg, long whenMs) {
-        final short msgType = neighMsg.getHeader().nlmsg_type;
-        final StructNdMsg ndMsg = neighMsg.getNdHeader();
-        if (ndMsg == null) {
-            mLog.e("RtNetlinkNeighborMessage without ND message header!");
-            return;
-        }
-
-        final int ifindex = ndMsg.ndm_ifindex;
-        final InetAddress destination = neighMsg.getDestination();
-        final short nudState =
-                (msgType == RTM_DELNEIGH)
-                ? StructNdMsg.NUD_NONE
-                : ndMsg.ndm_state;
-
-        final NeighborEvent event = new NeighborEvent(
-                whenMs, msgType, ifindex, destination, nudState,
-                getMacAddress(neighMsg.getLinkLayerAddress()));
-
-        if (VDBG) {
-            Log.d(TAG, neighMsg.toString());
-        }
-        if (DBG) {
-            Log.d(TAG, event.toString());
-        }
-
-        mConsumer.accept(event);
-    }
-
-    private static MacAddress getMacAddress(byte[] linkLayerAddress) {
-        if (linkLayerAddress != null) {
-            try {
-                return MacAddress.fromBytes(linkLayerAddress);
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "Failed to parse link-layer address: " + hexify(linkLayerAddress));
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
deleted file mode 100644
index c19a24e..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED;
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.net.ip.IpNeighborMonitor.NeighborEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpReachabilityEvent;
-import android.net.netlink.StructNdMsg;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * IpReachabilityMonitor.
- *
- * Monitors on-link IP reachability and notifies callers whenever any on-link
- * addresses of interest appear to have become unresponsive.
- *
- * This code does not concern itself with "why" a neighbour might have become
- * unreachable. Instead, it primarily reacts to the kernel's notion of IP
- * reachability for each of the neighbours we know to be critically important
- * to normal network connectivity. As such, it is often "just the messenger":
- * the neighbours about which it warns are already deemed by the kernel to have
- * become unreachable.
- *
- *
- * How it works:
- *
- *   1. The "on-link neighbours of interest" found in a given LinkProperties
- *      instance are added to a "watch list" via #updateLinkProperties().
- *      This usually means all default gateways and any on-link DNS servers.
- *
- *   2. We listen continuously for netlink neighbour messages (RTM_NEWNEIGH,
- *      RTM_DELNEIGH), watching only for neighbours in the watch list.
- *
- *        - A neighbour going into NUD_REACHABLE, NUD_STALE, NUD_DELAY, and
- *          even NUD_PROBE is perfectly normal; we merely record the new state.
- *
- *        - A neighbour's entry may be deleted (RTM_DELNEIGH), for example due
- *          to garbage collection.  This is not necessarily of immediate
- *          concern; we record the neighbour as moving to NUD_NONE.
- *
- *        - A neighbour transitioning to NUD_FAILED (for any reason) is
- *          critically important and is handled as described below in #4.
- *
- *   3. All on-link neighbours in the watch list can be forcibly "probed" by
- *      calling #probeAll(). This should be called whenever it is important to
- *      verify that critical neighbours on the link are still reachable, e.g.
- *      when roaming between BSSIDs.
- *
- *        - The kernel will send unicast ARP requests for IPv4 neighbours and
- *          unicast NS packets for IPv6 neighbours.  The expected replies will
- *          likely be unicast.
- *
- *        - The forced probing is done holding a wakelock. The kernel may,
- *          however, initiate probing of a neighbor on its own, i.e. whenever
- *          a neighbour has expired from NUD_DELAY.
- *
- *        - The kernel sends:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/ucast_solicit
- *
- *          number of probes (usually 3) every:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/retrans_time_ms
- *
- *          number of milliseconds (usually 1000ms). This normally results in
- *          3 unicast packets, 1 per second.
- *
- *        - If no response is received to any of the probe packets, the kernel
- *          marks the neighbour as being in state NUD_FAILED, and the listening
- *          process in #2 will learn of it.
- *
- *   4. We call the supplied Callback#notifyLost() function if the loss of a
- *      neighbour in NUD_FAILED would cause IPv4 or IPv6 configuration to
- *      become incomplete (a loss of provisioning).
- *
- *        - For example, losing all our IPv4 on-link DNS servers (or losing
- *          our only IPv6 default gateway) constitutes a loss of IPv4 (IPv6)
- *          provisioning; Callback#notifyLost() would be called.
- *
- *        - Since it can be non-trivial to reacquire certain IP provisioning
- *          state it may be best for the link to disconnect completely and
- *          reconnect afresh.
- *
- * Accessing an instance of this class from multiple threads is NOT safe.
- *
- * @hide
- */
-public class IpReachabilityMonitor {
-    private static final String TAG = "IpReachabilityMonitor";
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
-
-    public interface Callback {
-        // This callback function must execute as quickly as possible as it is
-        // run on the same thread that listens to kernel neighbor updates.
-        //
-        // TODO: refactor to something like notifyProvisioningLost(String msg).
-        public void notifyLost(InetAddress ip, String logMsg);
-    }
-
-    /**
-     * Encapsulates IpReachabilityMonitor depencencies on systems that hinder unit testing.
-     * TODO: consider also wrapping MultinetworkPolicyTracker in this interface.
-     */
-    interface Dependencies {
-        void acquireWakeLock(long durationMs);
-
-        static Dependencies makeDefault(Context context, String iface) {
-            final String lockName = TAG + "." + iface;
-            final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            final WakeLock lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
-
-            return new Dependencies() {
-                public void acquireWakeLock(long durationMs) {
-                    lock.acquire(durationMs);
-                }
-            };
-        }
-    }
-
-    private final InterfaceParams mInterfaceParams;
-    private final IpNeighborMonitor mIpNeighborMonitor;
-    private final SharedLog mLog;
-    private final Callback mCallback;
-    private final Dependencies mDependencies;
-    private final boolean mUsingMultinetworkPolicyTracker;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private LinkProperties mLinkProperties = new LinkProperties();
-    private Map<InetAddress, NeighborEvent> mNeighborWatchList = new HashMap<>();
-    // Time in milliseconds of the last forced probe request.
-    private volatile long mLastProbeTimeMs;
-
-    public IpReachabilityMonitor(
-            Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
-            boolean usingMultinetworkPolicyTracker) {
-        this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker,
-                Dependencies.makeDefault(context, ifParams.name));
-    }
-
-    @VisibleForTesting
-    IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, SharedLog log,
-            Callback callback, boolean usingMultinetworkPolicyTracker, Dependencies dependencies) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mInterfaceParams = ifParams;
-        mLog = log.forSubComponent(TAG);
-        mCallback = callback;
-        mUsingMultinetworkPolicyTracker = usingMultinetworkPolicyTracker;
-        mCm = context.getSystemService(ConnectivityManager.class);
-        mDependencies = dependencies;
-
-        mIpNeighborMonitor = new IpNeighborMonitor(h, mLog,
-                (NeighborEvent event) -> {
-                    if (mInterfaceParams.index != event.ifindex) return;
-                    if (!mNeighborWatchList.containsKey(event.ip)) return;
-
-                    final NeighborEvent prev = mNeighborWatchList.put(event.ip, event);
-
-                    // TODO: Consider what to do with other states that are not within
-                    // NeighborEvent#isValid() (i.e. NUD_NONE, NUD_INCOMPLETE).
-                    if (event.nudState == StructNdMsg.NUD_FAILED) {
-                        mLog.w("ALERT neighbor went from: " + prev + " to: " + event);
-                        handleNeighborLost(event);
-                    }
-                });
-        mIpNeighborMonitor.start();
-    }
-
-    public void stop() {
-        mIpNeighborMonitor.stop();
-        clearLinkProperties();
-    }
-
-    public void dump(PrintWriter pw) {
-        if (Looper.myLooper() == mIpNeighborMonitor.getHandler().getLooper()) {
-            pw.println(describeWatchList("\n"));
-            return;
-        }
-
-        final ConditionVariable cv = new ConditionVariable(false);
-        mIpNeighborMonitor.getHandler().post(() -> {
-            pw.println(describeWatchList("\n"));
-            cv.open();
-        });
-
-        if (!cv.block(1000)) {
-            pw.println("Timed out waiting for IpReachabilityMonitor dump");
-        }
-    }
-
-    private String describeWatchList() { return describeWatchList(" "); }
-
-    private String describeWatchList(String sep) {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("iface{" + mInterfaceParams + "}," + sep);
-        sb.append("ntable=[" + sep);
-        String delimiter = "";
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            sb.append(delimiter).append(entry.getKey().getHostAddress() + "/" + entry.getValue());
-            delimiter = "," + sep;
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
-        for (RouteInfo route : routes) {
-            if (!route.hasGateway() && route.matches(ip)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void updateLinkProperties(LinkProperties lp) {
-        if (!mInterfaceParams.name.equals(lp.getInterfaceName())) {
-            // TODO: figure out whether / how to cope with interface changes.
-            Log.wtf(TAG, "requested LinkProperties interface '" + lp.getInterfaceName() +
-                    "' does not match: " + mInterfaceParams.name);
-            return;
-        }
-
-        mLinkProperties = new LinkProperties(lp);
-        Map<InetAddress, NeighborEvent> newNeighborWatchList = new HashMap<>();
-
-        final List<RouteInfo> routes = mLinkProperties.getRoutes();
-        for (RouteInfo route : routes) {
-            if (route.hasGateway()) {
-                InetAddress gw = route.getGateway();
-                if (isOnLink(routes, gw)) {
-                    newNeighborWatchList.put(gw, mNeighborWatchList.getOrDefault(gw, null));
-                }
-            }
-        }
-
-        for (InetAddress dns : lp.getDnsServers()) {
-            if (isOnLink(routes, dns)) {
-                newNeighborWatchList.put(dns, mNeighborWatchList.getOrDefault(dns, null));
-            }
-        }
-
-        mNeighborWatchList = newNeighborWatchList;
-        if (DBG) { Log.d(TAG, "watch: " + describeWatchList()); }
-    }
-
-    public void clearLinkProperties() {
-        mLinkProperties.clear();
-        mNeighborWatchList.clear();
-        if (DBG) { Log.d(TAG, "clear: " + describeWatchList()); }
-    }
-
-    private void handleNeighborLost(NeighborEvent event) {
-        final LinkProperties whatIfLp = new LinkProperties(mLinkProperties);
-
-        InetAddress ip = null;
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            // TODO: Consider using NeighborEvent#isValid() here; it's more
-            // strict but may interact badly if other entries are somehow in
-            // NUD_INCOMPLETE (say, during network attach).
-            if (entry.getValue().nudState != StructNdMsg.NUD_FAILED) continue;
-
-            ip = entry.getKey();
-            for (RouteInfo route : mLinkProperties.getRoutes()) {
-                if (ip.equals(route.getGateway())) {
-                    whatIfLp.removeRoute(route);
-                }
-            }
-
-            if (avoidingBadLinks() || !(ip instanceof Inet6Address)) {
-                // We should do this unconditionally, but alas we cannot: b/31827713.
-                whatIfLp.removeDnsServer(ip);
-            }
-        }
-
-        final boolean lostProvisioning =
-                (mLinkProperties.isIpv4Provisioned() && !whatIfLp.isIpv4Provisioned())
-                || (mLinkProperties.isIpv6Provisioned() && !whatIfLp.isIpv6Provisioned());
-
-        if (lostProvisioning) {
-            final String logMsg = "FAILURE: LOST_PROVISIONING, " + event;
-            Log.w(TAG, logMsg);
-            if (mCallback != null) {
-                // TODO: remove |ip| when the callback signature no longer has
-                // an InetAddress argument.
-                mCallback.notifyLost(ip, logMsg);
-            }
-        }
-        logNudFailed(lostProvisioning);
-    }
-
-    private boolean avoidingBadLinks() {
-        return !mUsingMultinetworkPolicyTracker || mCm.shouldAvoidBadWifi();
-    }
-
-    public void probeAll() {
-        final List<InetAddress> ipProbeList = new ArrayList<>(mNeighborWatchList.keySet());
-
-        if (!ipProbeList.isEmpty()) {
-            // Keep the CPU awake long enough to allow all ARP/ND
-            // probes a reasonable chance at success. See b/23197666.
-            //
-            // The wakelock we use is (by default) refcounted, and this version
-            // of acquire(timeout) queues a release message to keep acquisitions
-            // and releases balanced.
-            mDependencies.acquireWakeLock(getProbeWakeLockDuration());
-        }
-
-        for (InetAddress ip : ipProbeList) {
-            final int rval = IpNeighborMonitor.startKernelNeighborProbe(mInterfaceParams.index, ip);
-            mLog.log(String.format("put neighbor %s into NUD_PROBE state (rval=%d)",
-                     ip.getHostAddress(), rval));
-            logEvent(IpReachabilityEvent.PROBE, rval);
-        }
-        mLastProbeTimeMs = SystemClock.elapsedRealtime();
-    }
-
-    private static long getProbeWakeLockDuration() {
-        // Ideally, this would be computed by examining the values of:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
-        //
-        // and:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
-        //
-        // For now, just make some assumptions.
-        final long numUnicastProbes = 3;
-        final long retransTimeMs = 1000;
-        final long gracePeriodMs = 500;
-        return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
-    }
-
-    private void logEvent(int probeType, int errorCode) {
-        int eventType = probeType | (errorCode & 0xff);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    private void logNudFailed(boolean lostProvisioning) {
-        long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs;
-        boolean isFromProbe = (duration < getProbeWakeLockDuration());
-        int eventType = nudFailureEventType(isFromProbe, lostProvisioning);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    /**
-     * Returns the NUD failure event type code corresponding to the given conditions.
-     */
-    private static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
-        if (isFromProbe) {
-            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
-        } else {
-            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
deleted file mode 100644
index 08c3f60..0000000
--- a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static com.android.server.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
-import static com.android.server.util.NetworkStackConstants.ARP_PAYLOAD_LEN;
-import static com.android.server.util.NetworkStackConstants.ARP_REPLY;
-import static com.android.server.util.NetworkStackConstants.ARP_REQUEST;
-import static com.android.server.util.NetworkStackConstants.DHCP4_CLIENT_PORT;
-import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_ARP;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV4;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV6;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MIN_LENGTH;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MTU;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FLAGS_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FRAGMENT_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_IHL_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.UDP_HEADER_LEN;
-
-import android.net.MacAddress;
-import android.net.dhcp.DhcpPacket;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * Critical connectivity packet summarizing class.
- *
- * Outputs short descriptions of ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * @hide
- */
-public class ConnectivityPacketSummary {
-    private static final String TAG = ConnectivityPacketSummary.class.getSimpleName();
-
-    private final byte[] mHwAddr;
-    private final byte[] mBytes;
-    private final int mLength;
-    private final ByteBuffer mPacket;
-    private final String mSummary;
-
-    public static String summarize(MacAddress hwaddr, byte[] buffer) {
-        return summarize(hwaddr, buffer, buffer.length);
-    }
-
-    // Methods called herein perform some but by no means all error checking.
-    // They may throw runtime exceptions on malformed packets.
-    public static String summarize(MacAddress macAddr, byte[] buffer, int length) {
-        if ((macAddr == null) || (buffer == null)) return null;
-        length = Math.min(length, buffer.length);
-        return (new ConnectivityPacketSummary(macAddr, buffer, length)).toString();
-    }
-
-    private ConnectivityPacketSummary(MacAddress macAddr, byte[] buffer, int length) {
-        mHwAddr = macAddr.toByteArray();
-        mBytes = buffer;
-        mLength = Math.min(length, mBytes.length);
-        mPacket = ByteBuffer.wrap(mBytes, 0, mLength);
-        mPacket.order(ByteOrder.BIG_ENDIAN);
-
-        final StringJoiner sj = new StringJoiner(" ");
-        // TODO: support other link-layers, or even no link-layer header.
-        parseEther(sj);
-        mSummary = sj.toString();
-    }
-
-    public String toString() {
-        return mSummary;
-    }
-
-    private void parseEther(StringJoiner sj) {
-        if (mPacket.remaining() < ETHER_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(ETHER_SRC_ADDR_OFFSET);
-        final ByteBuffer srcMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(ByteBuffer.wrap(mHwAddr).equals(srcMac) ? "TX" : "RX");
-        sj.add(getMacAddressString(srcMac));
-
-        mPacket.position(ETHER_DST_ADDR_OFFSET);
-        final ByteBuffer dstMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(">").add(getMacAddressString(dstMac));
-
-        mPacket.position(ETHER_TYPE_OFFSET);
-        final int etherType = asUint(mPacket.getShort());
-        switch (etherType) {
-            case ETHER_TYPE_ARP:
-                sj.add("arp");
-                parseARP(sj);
-                break;
-            case ETHER_TYPE_IPV4:
-                sj.add("ipv4");
-                parseIPv4(sj);
-                break;
-            case ETHER_TYPE_IPV6:
-                sj.add("ipv6");
-                parseIPv6(sj);
-                break;
-            default:
-                // Unknown ether type.
-                sj.add("ethtype").add(asString(etherType));
-                break;
-        }
-    }
-
-    private void parseARP(StringJoiner sj) {
-        if (mPacket.remaining() < ARP_PAYLOAD_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        if (asUint(mPacket.getShort()) != ARP_HWTYPE_ETHER ||
-            asUint(mPacket.getShort()) != ETHER_TYPE_IPV4 ||
-            asUint(mPacket.get()) != ETHER_ADDR_LEN ||
-            asUint(mPacket.get()) != IPV4_ADDR_LEN) {
-            sj.add("unexpected header");
-            return;
-        }
-
-        final int opCode = asUint(mPacket.getShort());
-
-        final String senderHwAddr = getMacAddressString(mPacket);
-        final String senderIPv4 = getIPv4AddressString(mPacket);
-        getMacAddressString(mPacket);  // target hardware address, unused
-        final String targetIPv4 = getIPv4AddressString(mPacket);
-
-        if (opCode == ARP_REQUEST) {
-            sj.add("who-has").add(targetIPv4);
-        } else if (opCode == ARP_REPLY) {
-            sj.add("reply").add(senderIPv4).add(senderHwAddr);
-        } else {
-            sj.add("unknown opcode").add(asString(opCode));
-        }
-    }
-
-    private void parseIPv4(StringJoiner sj) {
-        if (!mPacket.hasRemaining()) {
-            sj.add("runt");
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-        final int ipv4HeaderLength = (mPacket.get(startOfIpLayer) & IPV4_IHL_MASK) * 4;
-        if (mPacket.remaining() < ipv4HeaderLength ||
-            mPacket.remaining() < IPV4_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-        final int startOfTransportLayer = startOfIpLayer + ipv4HeaderLength;
-
-        mPacket.position(startOfIpLayer + IPV4_FLAGS_OFFSET);
-        final int flagsAndFragment = asUint(mPacket.getShort());
-        final boolean isFragment = (flagsAndFragment & IPV4_FRAGMENT_MASK) != 0;
-
-        mPacket.position(startOfIpLayer + IPV4_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV4_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv4AddressString(mPacket);
-
-        mPacket.position(startOfIpLayer + IPV4_DST_ADDR_OFFSET);
-        final String dstAddr = getIPv4AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfTransportLayer);
-        if (protocol == IPPROTO_UDP) {
-            sj.add("udp");
-            if (isFragment) sj.add("fragment");
-            else parseUDP(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-            if (isFragment) sj.add("fragment");
-        }
-    }
-
-    private void parseIPv6(StringJoiner sj) {
-        if (mPacket.remaining() < IPV6_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-
-        mPacket.position(startOfIpLayer + IPV6_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV6_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv6AddressString(mPacket);
-        final String dstAddr = getIPv6AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfIpLayer + IPV6_HEADER_LEN);
-        if (protocol == IPPROTO_ICMPV6) {
-            sj.add("icmp6");
-            parseICMPv6(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-        }
-    }
-
-    private void parseICMPv6(StringJoiner sj) {
-        if (mPacket.remaining() < ICMPV6_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int icmp6Type = asUint(mPacket.get());
-        final int icmp6Code = asUint(mPacket.get());
-        mPacket.getShort();  // checksum, unused
-
-        switch (icmp6Type) {
-            case ICMPV6_ROUTER_SOLICITATION:
-                sj.add("rs");
-                parseICMPv6RouterSolicitation(sj);
-                break;
-            case ICMPV6_ROUTER_ADVERTISEMENT:
-                sj.add("ra");
-                parseICMPv6RouterAdvertisement(sj);
-                break;
-            case ICMPV6_NEIGHBOR_SOLICITATION:
-                sj.add("ns");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            case ICMPV6_NEIGHBOR_ADVERTISEMENT:
-                sj.add("na");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            default:
-                sj.add("type").add(asString(icmp6Type));
-                sj.add("code").add(asString(icmp6Code));
-                break;
-        }
-    }
-
-    private void parseICMPv6RouterSolicitation(StringJoiner sj) {
-        final int RESERVED = 4;
-        if (mPacket.remaining() < RESERVED) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6RouterAdvertisement(StringJoiner sj) {
-        final int FLAGS_AND_TIMERS = 3 * 4;
-        if (mPacket.remaining() < FLAGS_AND_TIMERS) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + FLAGS_AND_TIMERS);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborMessage(StringJoiner sj) {
-        final int RESERVED = 4;
-        final int minReq = RESERVED + IPV6_ADDR_LEN;
-        if (mPacket.remaining() < minReq) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        sj.add(getIPv6AddressString(mPacket));
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborDiscoveryOptions(StringJoiner sj) {
-        // All ND options are TLV, where T is one byte and L is one byte equal
-        // to the length of T + L + V in units of 8 octets.
-        while (mPacket.remaining() >= ICMPV6_ND_OPTION_MIN_LENGTH) {
-            final int ndType = asUint(mPacket.get());
-            final int ndLength = asUint(mPacket.get());
-            final int ndBytes = ndLength * ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR - 2;
-            if (ndBytes < 0 || ndBytes > mPacket.remaining()) {
-                sj.add("<malformed>");
-                break;
-            }
-            final int position = mPacket.position();
-
-            switch (ndType) {
-                    case ICMPV6_ND_OPTION_SLLA:
-                        sj.add("slla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_TLLA:
-                        sj.add("tlla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_MTU:
-                        sj.add("mtu");
-                        final short reserved = mPacket.getShort();
-                        sj.add(asString(mPacket.getInt()));
-                        break;
-                    default:
-                        // Skip.
-                        break;
-            }
-
-            mPacket.position(position + ndBytes);
-        }
-    }
-
-    private void parseUDP(StringJoiner sj) {
-        if (mPacket.remaining() < UDP_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int previous = mPacket.position();
-        final int srcPort = asUint(mPacket.getShort());
-        final int dstPort = asUint(mPacket.getShort());
-        sj.add(asString(srcPort)).add(">").add(asString(dstPort));
-
-        mPacket.position(previous + UDP_HEADER_LEN);
-        if (srcPort == DHCP4_CLIENT_PORT || dstPort == DHCP4_CLIENT_PORT) {
-            sj.add("dhcp4");
-            parseDHCPv4(sj);
-        }
-    }
-
-    private void parseDHCPv4(StringJoiner sj) {
-        final DhcpPacket dhcpPacket;
-        try {
-            dhcpPacket = DhcpPacket.decodeFullPacket(mBytes, mLength, DhcpPacket.ENCAP_L2);
-            sj.add(dhcpPacket.toString());
-        } catch (DhcpPacket.ParseException e) {
-            sj.add("parse error: " + e);
-        }
-    }
-
-    private static String getIPv4AddressString(ByteBuffer ipv4) {
-        return getIpAddressString(ipv4, IPV4_ADDR_LEN);
-    }
-
-    private static String getIPv6AddressString(ByteBuffer ipv6) {
-        return getIpAddressString(ipv6, IPV6_ADDR_LEN);
-    }
-
-    private static String getIpAddressString(ByteBuffer ip, int byteLength) {
-        if (ip == null || ip.remaining() < byteLength) return "invalid";
-
-        byte[] bytes = new byte[byteLength];
-        ip.get(bytes, 0, byteLength);
-        try {
-            InetAddress addr = InetAddress.getByAddress(bytes);
-            return addr.getHostAddress();
-        } catch (UnknownHostException uhe) {
-            return "unknown";
-        }
-    }
-
-    private static String getMacAddressString(ByteBuffer mac) {
-        if (mac == null || mac.remaining() < ETHER_ADDR_LEN) return "invalid";
-
-        byte[] bytes = new byte[ETHER_ADDR_LEN];
-        mac.get(bytes, 0, bytes.length);
-        Object[] printableBytes = new Object[bytes.length];
-        int i = 0;
-        for (byte b : bytes) printableBytes[i++] = new Byte(b);
-
-        final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x";
-        return String.format(MAC48_FORMAT, printableBytes);
-    }
-
-    /**
-     * Convenience method to convert an int to a String.
-     */
-    public static String asString(int i) {
-        return Integer.toString(i);
-    }
-
-    /**
-     * Convenience method to read a byte as an unsigned int.
-     */
-    public static int asUint(byte b) {
-        return (b & 0xff);
-    }
-
-    /**
-     * Convenience method to read a short as an unsigned int.
-     */
-    public static int asUint(short s) {
-        return (s & 0xffff);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/DataStallUtils.java b/packages/NetworkStack/src/android/net/util/DataStallUtils.java
deleted file mode 100644
index b6dbeb1..0000000
--- a/packages/NetworkStack/src/android/net/util/DataStallUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 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.util;
-
-/**
- * Collection of utilities for data stall.
- */
-public class DataStallUtils {
-    /**
-     * Detect data stall via using dns timeout counts.
-     */
-    public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
-    // Default configuration values for data stall detection.
-    public static final int DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = 5;
-    public static final int DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS = 60 * 1000;
-    public static final int DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS = 30 * 60 * 1000;
-    /**
-     * The threshold value for the number of consecutive dns timeout events received to be a
-     * signal of data stall. The number of consecutive timeouts needs to be {@code >=} this
-     * threshold to be considered a data stall. Set the value to {@code <= 0} to disable. Note
-     * that the value should be {@code > 0} if the DNS data stall detection is enabled.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD =
-            "data_stall_consecutive_dns_timeout_threshold";
-
-    /**
-     * The minimal time interval in milliseconds for data stall reevaluation.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL =
-            "data_stall_min_evaluate_interval";
-
-    /**
-     * DNS timeouts older than this timeout (in milliseconds) are not considered for detecting
-     * a data stall.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD =
-            "data_stall_valid_dns_time_threshold";
-
-    /**
-     * Which data stall detection signal to use. This is a bitmask constructed by bitwise-or-ing
-     * (i.e. {@code |}) the DATA_STALL_EVALUATION_TYPE_* values.
-     *
-     * Type: int
-     * Valid values:
-     *   {@link #DATA_STALL_EVALUATION_TYPE_DNS} : Use dns as a signal.
-     */
-    public static final String CONFIG_DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
-    public static final int DEFAULT_DATA_STALL_EVALUATION_TYPES = DATA_STALL_EVALUATION_TYPE_DNS;
-    // The default number of DNS events kept of the log kept for dns signal evaluation. Each event
-    // is represented by a {@link com.android.server.connectivity.NetworkMonitor#DnsResult} objects.
-    // It's also the size of array of {@link com.android.server.connectivity.nano.DnsEvent} kept in
-    // metrics. Note that increasing the size may cause statsd log buffer bust. Need to check the
-    // design in statsd when you try to increase the size.
-    public static final int DEFAULT_DNS_LOG_SIZE = 20;
-}
diff --git a/packages/NetworkStack/src/android/net/util/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java
deleted file mode 100644
index 1380ea7..0000000
--- a/packages/NetworkStack/src/android/net/util/FdEventsReader.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * This class encapsulates the mechanics of registering a file descriptor
- * with a thread's Looper and handling read events (and errors).
- *
- * Subclasses MUST implement createFd() and SHOULD override handlePacket(). They MAY override
- * onStop() and onStart().
- *
- * Subclasses can expect a call life-cycle like the following:
- *
- *     [1] when a client calls start(), createFd() is called, followed by the onStart() hook if all
- *         goes well. Implementations may override onStart() for additional initialization.
- *
- *     [2] yield, waiting for read event or error notification:
- *
- *             [a] readPacket() && handlePacket()
- *
- *             [b] if (no error):
- *                     goto 2
- *                 else:
- *                     goto 3
- *
- *     [3] when a client calls stop(), the onStop() hook is called (unless already stopped or never
- *         started). Implementations may override onStop() for additional cleanup.
- *
- * The packet receive buffer is recycled on every read call, so subclasses
- * should make any copies they would like inside their handlePacket()
- * implementation.
- *
- * All public methods MUST only be called from the same thread with which
- * the Handler constructor argument is associated.
- *
- * @param <BufferType> the type of the buffer used to read data.
- * @hide
- */
-public abstract class FdEventsReader<BufferType> {
-    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-    private static final int UNREGISTER_THIS_FD = 0;
-
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final MessageQueue mQueue;
-    @NonNull
-    private final BufferType mBuffer;
-    @Nullable
-    private FileDescriptor mFd;
-    private long mPacketsReceived;
-
-    protected static void closeFd(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
-        mHandler = h;
-        mQueue = mHandler.getLooper().getQueue();
-        mBuffer = buffer;
-    }
-
-    /** Start this FdEventsReader. */
-    public void start() {
-        if (onCorrectThread()) {
-            createAndRegisterFd();
-        } else {
-            mHandler.post(() -> {
-                logError("start() called from off-thread", null);
-                createAndRegisterFd();
-            });
-        }
-    }
-
-    /** Stop this FdEventsReader and destroy the file descriptor. */
-    public void stop() {
-        if (onCorrectThread()) {
-            unregisterAndDestroyFd();
-        } else {
-            mHandler.post(() -> {
-                logError("stop() called from off-thread", null);
-                unregisterAndDestroyFd();
-            });
-        }
-    }
-
-    @NonNull
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    protected abstract int recvBufSize(@NonNull BufferType buffer);
-
-    /** Returns the size of the receive buffer. */
-    public int recvBufSize() {
-        return recvBufSize(mBuffer);
-    }
-
-    /**
-     * Get the number of successful calls to {@link #readPacket(FileDescriptor, Object)}.
-     *
-     * <p>A call was successful if {@link #readPacket(FileDescriptor, Object)} returned a value > 0.
-     */
-    public final long numPacketsReceived() {
-        return mPacketsReceived;
-    }
-
-    /**
-     * Subclasses MUST create the listening socket here, including setting all desired socket
-     * options, interface or address/port binding, etc. The socket MUST be created nonblocking.
-     */
-    @Nullable
-    protected abstract FileDescriptor createFd();
-
-    /**
-     * Implementations MUST return the bytes read or throw an Exception.
-     *
-     * <p>The caller may throw a {@link ErrnoException} with {@link OsConstants#EAGAIN} or
-     * {@link OsConstants#EINTR}, in which case {@link FdEventsReader} will ignore the buffer
-     * contents and respectively wait for further input or retry the read immediately. For all other
-     * exceptions, the {@link FdEventsReader} will be stopped with no more interactions with this
-     * method.
-     */
-    protected abstract int readPacket(@NonNull FileDescriptor fd, @NonNull BufferType buffer)
-            throws Exception;
-
-    /**
-     * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, as the underlying byte array is
-     * reused across all reads.
-     */
-    protected void handlePacket(@NonNull BufferType recvbuf, int length) {}
-
-    /**
-     * Called by the main loop to log errors.  In some cases |e| may be null.
-     */
-    protected void logError(@NonNull String msg, @Nullable Exception e) {}
-
-    /**
-     * Called by start(), if successful, just prior to returning.
-     */
-    protected void onStart() {}
-
-    /**
-     * Called by stop() just prior to returning.
-     */
-    protected void onStop() {}
-
-    private void createAndRegisterFd() {
-        if (mFd != null) return;
-
-        try {
-            mFd = createFd();
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            closeFd(mFd);
-            mFd = null;
-        }
-
-        if (mFd == null) return;
-
-        mQueue.addOnFileDescriptorEventListener(
-                mFd,
-                FD_EVENTS,
-                (fd, events) -> {
-                    // Always call handleInput() so read/recvfrom are given
-                    // a proper chance to encounter a meaningful errno and
-                    // perhaps log a useful error message.
-                    if (!isRunning() || !handleInput()) {
-                        unregisterAndDestroyFd();
-                        return UNREGISTER_THIS_FD;
-                    }
-                    return FD_EVENTS;
-                });
-        onStart();
-    }
-
-    private boolean isRunning() {
-        return (mFd != null) && mFd.valid();
-    }
-
-    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
-    private boolean handleInput() {
-        while (isRunning()) {
-            final int bytesRead;
-
-            try {
-                bytesRead = readPacket(mFd, mBuffer);
-                if (bytesRead < 1) {
-                    if (isRunning()) logError("Socket closed, exiting", null);
-                    break;
-                }
-                mPacketsReceived++;
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EAGAIN) {
-                    // We've read everything there is to read this time around.
-                    return true;
-                } else if (e.errno == OsConstants.EINTR) {
-                    continue;
-                } else {
-                    if (isRunning()) logError("readPacket error: ", e);
-                    break;
-                }
-            } catch (Exception e) {
-                if (isRunning()) logError("readPacket error: ", e);
-                break;
-            }
-
-            try {
-                handlePacket(mBuffer, bytesRead);
-            } catch (Exception e) {
-                logError("handlePacket error: ", e);
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    private void unregisterAndDestroyFd() {
-        if (mFd == null) return;
-
-        mQueue.removeOnFileDescriptorEventListener(mFd);
-        closeFd(mFd);
-        mFd = null;
-        onStop();
-    }
-
-    private boolean onCorrectThread() {
-        return (mHandler.getLooper() == Looper.myLooper());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
deleted file mode 100644
index 541f9d8..0000000
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2019 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.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.SparseArray;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Collection of utilities for the network stack.
- */
-public class NetworkStackUtils {
-    // TODO: Refer to DeviceConfig definition.
-    public static final String NAMESPACE_CONNECTIVITY = "connectivity";
-
-    /**
-     * A list of captive portal detection specifications used in addition to the fallback URLs.
-     * Each spec has the format url@@/@@statusCodeRegex@@/@@contentRegex. Specs are separated
-     * by "@@,@@".
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
-            "captive_portal_fallback_probe_specs";
-
-    /**
-     * A comma separated list of URLs used for captive portal detection in addition to the
-     * fallback HTTP url associated with the CAPTIVE_PORTAL_FALLBACK_URL settings.
-     */
-    public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
-            "captive_portal_other_fallback_urls";
-
-    /**
-     * Which User-Agent string to use in the header of the captive portal detection probes.
-     * The User-Agent field is unset when this setting has no value (HttpUrlConnection default).
-     */
-    public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
-
-    /**
-     * Whether to use HTTPS for network validation. This is enabled by default and the setting
-     * needs to be set to 0 to disable it. This setting is a misnomer because captive portals
-     * don't actually use HTTPS, but it's consistent with the other settings.
-     */
-    public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
-
-    /**
-     * The URL used for HTTPS captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
-
-    /**
-     * The URL used for HTTP captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
-
-    /**
-     * The URL used for fallback HTTP captive portal detection when previous HTTP
-     * and HTTPS captive portal detection attemps did not return a conclusive answer.
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
-
-    /**
-     * What to do when connecting a network that presents a captive portal.
-     * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
-     *
-     * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
-     */
-    public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
-    /**
-     * Don't attempt to detect captive portals.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
-    /**
-     * When detecting a captive portal, display a notification that
-     * prompts the user to sign in.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
-    /**
-     * When detecting a captive portal, immediately disconnect from the
-     * network and do not reconnect to that network in the future.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
-    static {
-        System.loadLibrary("networkstackutilsjni");
-    }
-
-    /**
-     * @return True if the array is null or 0-length.
-     */
-    public static <T> boolean isEmpty(T[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * Close a socket, ignoring any exception while closing.
-     */
-    public static void closeSocketQuietly(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    /**
-     * Returns an int array from the given Integer list.
-     */
-    public static int[] convertToIntArray(@NonNull List<Integer> list) {
-        int[] array = new int[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * Returns a long array from the given long list.
-     */
-    public static long[] convertToLongArray(@NonNull List<Long> list) {
-        long[] array = new long[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * @return True if there exists at least one element in the sparse array for which
-     * condition {@code predicate}
-     */
-    public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) {
-        for (int i = 0; i < array.size(); ++i) {
-            if (predicate.test(array.valueAt(i))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or has no valid value.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    @Nullable
-    public static String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-            @Nullable String defaultValue) {
-        // TODO: Link to DeviceConfig API once it is ready.
-        return defaultValue;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or has no non-null
-     *                     value.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-            int defaultValue) {
-        String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */);
-        try {
-            return (value != null) ? Integer.parseInt(value) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Attaches a socket filter that accepts DHCP packets to the given socket.
-     */
-    public static native void attachDhcpFilter(FileDescriptor fd) throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachRaFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts L2-L4 signaling traffic required for IP connectivity.
-     *
-     * This includes: all ARP, ICMPv6 RS/RA/NS/NA messages, and DHCPv4 exchanges.
-     *
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachControlPacketFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Add an entry into the ARP cache.
-     */
-    public static void addArpEntry(Inet4Address ipv4Addr, android.net.MacAddress ethAddr,
-            String ifname, FileDescriptor fd) throws IOException {
-        addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
-    }
-
-    private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
-            FileDescriptor fd) throws IOException;
-
-    /**
-     * Return IP address and port in a string format.
-     */
-    public static String addressAndPortToString(InetAddress address, int port) {
-        return String.format(
-                (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",
-                        address.getHostAddress(), port);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java
deleted file mode 100644
index 4aec6b6..0000000
--- a/packages/NetworkStack/src/android/net/util/PacketReader.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 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.util;
-
-import static java.lang.Math.max;
-
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Specialization of {@link FdEventsReader} that reads packets into a byte array.
- *
- * TODO: rename this class to something more correctly descriptive (something
- * like [or less horrible than] FdReadEventsHandler?).
- *
- * @hide
- */
-public abstract class PacketReader extends FdEventsReader<byte[]> {
-
-    public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
-
-    protected PacketReader(Handler h) {
-        this(h, DEFAULT_RECV_BUF_SIZE);
-    }
-
-    protected PacketReader(Handler h, int recvBufSize) {
-        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
-    }
-
-    @Override
-    protected final int recvBufSize(byte[] buffer) {
-        return buffer.length;
-    }
-
-    /**
-     * Subclasses MAY override this to change the default read() implementation
-     * in favour of, say, recvfrom().
-     *
-     * Implementations MUST return the bytes read or throw an Exception.
-     */
-    @Override
-    protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
-        return Os.read(fd, packetBuffer, 0, packetBuffer.length);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/SharedLog.java b/packages/NetworkStack/src/android/net/util/SharedLog.java
deleted file mode 100644
index 4fabf10..0000000
--- a/packages/NetworkStack/src/android/net/util/SharedLog.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.StringJoiner;
-
-
-/**
- * Class to centralize logging functionality for tethering.
- *
- * All access to class methods other than dump() must be on the same thread.
- *
- * @hide
- */
-public class SharedLog {
-    private static final int DEFAULT_MAX_RECORDS = 500;
-    private static final String COMPONENT_DELIMITER = ".";
-
-    private enum Category {
-        NONE,
-        ERROR,
-        MARK,
-        WARN,
-    };
-
-    private final LocalLog mLocalLog;
-    // The tag to use for output to the system log. This is not output to the
-    // LocalLog because that would be redundant.
-    private final String mTag;
-    // The component (or subcomponent) of a system that is sharing this log.
-    // This can grow in depth if components call forSubComponent() to obtain
-    // their SharedLog instance. The tag is not included in the component for
-    // brevity.
-    private final String mComponent;
-
-    public SharedLog(String tag) {
-        this(DEFAULT_MAX_RECORDS, tag);
-    }
-
-    public SharedLog(int maxRecords, String tag) {
-        this(new LocalLog(maxRecords), tag, tag);
-    }
-
-    private SharedLog(LocalLog localLog, String tag, String component) {
-        mLocalLog = localLog;
-        mTag = tag;
-        mComponent = component;
-    }
-
-    public String getTag() {
-        return mTag;
-    }
-
-    /**
-     * Create a SharedLog based on this log with an additional component prefix on each logged line.
-     */
-    public SharedLog forSubComponent(String component) {
-        if (!isRootLogInstance()) {
-            component = mComponent + COMPONENT_DELIMITER + component;
-        }
-        return new SharedLog(mLocalLog, mTag, component);
-    }
-
-    /**
-     * Dump the contents of this log.
-     *
-     * <p>This method may be called on any thread.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
-    }
-
-    //////
-    // Methods that both log an entry and emit it to the system log.
-    //////
-
-    /**
-     * Log an error due to an exception. This does not include the exception stacktrace.
-     *
-     * <p>The log entry will be also added to the system log.
-     * @see #e(String, Throwable)
-     */
-    public void e(Exception e) {
-        Log.e(mTag, record(Category.ERROR, e.toString()));
-    }
-
-    /**
-     * Log an error message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void e(String msg) {
-        Log.e(mTag, record(Category.ERROR, msg));
-    }
-
-    /**
-     * Log an error due to an exception, with the exception stacktrace if provided.
-     *
-     * <p>The error and exception message appear in the shared log, but the stacktrace is only
-     * logged in general log output (logcat). The log entry will be also added to the system log.
-     */
-    public void e(@NonNull String msg, @Nullable Throwable exception) {
-        if (exception == null) {
-            e(msg);
-            return;
-        }
-        Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
-    }
-
-    /**
-     * Log an informational message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void i(String msg) {
-        Log.i(mTag, record(Category.NONE, msg));
-    }
-
-    /**
-     * Log a warning message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void w(String msg) {
-        Log.w(mTag, record(Category.WARN, msg));
-    }
-
-    //////
-    // Methods that only log an entry (and do NOT emit to the system log).
-    //////
-
-    /**
-     * Log a general message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void log(String msg) {
-        record(Category.NONE, msg);
-    }
-
-    /**
-     * Log a general, formatted message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     * @see String#format(String, Object...)
-     */
-    public void logf(String fmt, Object... args) {
-        log(String.format(fmt, args));
-    }
-
-    /**
-     * Log a message with MARK level.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void mark(String msg) {
-        record(Category.MARK, msg);
-    }
-
-    private String record(Category category, String msg) {
-        final String entry = logLine(category, msg);
-        mLocalLog.log(entry);
-        return entry;
-    }
-
-    private String logLine(Category category, String msg) {
-        final StringJoiner sj = new StringJoiner(" ");
-        if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
-        if (category != Category.NONE) sj.add(category.toString());
-        return sj.add(msg).toString();
-    }
-
-    // Check whether this SharedLog instance is nominally the top level in
-    // a potential hierarchy of shared logs (the root of a tree),
-    // or is a subcomponent within the hierarchy.
-    private boolean isRootLogInstance() {
-        return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/Stopwatch.java b/packages/NetworkStack/src/android/net/util/Stopwatch.java
deleted file mode 100644
index c316699..0000000
--- a/packages/NetworkStack/src/android/net/util/Stopwatch.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.os.SystemClock;
-
-
-/**
- * @hide
- */
-public class Stopwatch {
-    private long mStartTimeMs;
-    private long mStopTimeMs;
-
-    public boolean isStarted() {
-        return (mStartTimeMs > 0);
-    }
-
-    public boolean isStopped() {
-        return (mStopTimeMs > 0);
-    }
-
-    public boolean isRunning() {
-        return (isStarted() && !isStopped());
-    }
-
-    /**
-     * Start the Stopwatch.
-     */
-    public Stopwatch start() {
-        if (!isStarted()) {
-            mStartTimeMs = SystemClock.elapsedRealtime();
-        }
-        return this;
-    }
-
-    /**
-     * Stop the Stopwatch.
-     * @return the total time recorded, in milliseconds, or 0 if not started.
-     */
-    public long stop() {
-        if (isRunning()) {
-            mStopTimeMs = SystemClock.elapsedRealtime();
-        }
-        // Return either the delta after having stopped, or 0.
-        return (mStopTimeMs - mStartTimeMs);
-    }
-
-    /**
-     * Return the total time recorded to date, in milliseconds.
-     * If the Stopwatch is not running, returns the same value as stop(),
-     * i.e. either the total time recorded before stopping or 0.
-     */
-    public long lap() {
-        if (isRunning()) {
-            return (SystemClock.elapsedRealtime() - mStartTimeMs);
-        } else {
-            return stop();
-        }
-    }
-
-    /**
-     * Reset the Stopwatch. It will be stopped when this method returns.
-     */
-    public void reset() {
-        mStartTimeMs = 0;
-        mStopTimeMs = 0;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
deleted file mode 100644
index 2523ecd..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2019 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.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.NetworkStackUtils;
-import android.net.wifi.WifiInfo;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.CellularData;
-import com.android.server.connectivity.nano.DataStallEventProto;
-import com.android.server.connectivity.nano.DnsEvent;
-import com.android.server.connectivity.nano.WifiData;
-
-import com.google.protobuf.nano.MessageNano;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Class to record the stats of detection level information for data stall.
- *
- * @hide
- */
-public final class DataStallDetectionStats {
-    private static final int UNKNOWN_SIGNAL_STRENGTH = -1;
-    @NonNull
-    final byte[] mCellularInfo;
-    @NonNull
-    final byte[] mWifiInfo;
-    @NonNull
-    final byte[] mDns;
-    final int mEvaluationType;
-    final int mNetworkType;
-
-    public DataStallDetectionStats(@Nullable byte[] cell, @Nullable byte[] wifi,
-                @NonNull int[] returnCode, @NonNull long[] dnsTime, int evalType, int netType) {
-        mCellularInfo = emptyCellDataIfNull(cell);
-        mWifiInfo = emptyWifiInfoIfNull(wifi);
-
-        DnsEvent dns = new DnsEvent();
-        dns.dnsReturnCode = returnCode;
-        dns.dnsTime = dnsTime;
-        mDns = MessageNano.toByteArray(dns);
-        mEvaluationType = evalType;
-        mNetworkType = netType;
-    }
-
-    private byte[] emptyCellDataIfNull(@Nullable byte[] cell) {
-        if (cell != null) return cell;
-
-        CellularData data  = new CellularData();
-        data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_UNKNOWN;
-        data.networkMccmnc = "";
-        data.simMccmnc = "";
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    private byte[] emptyWifiInfoIfNull(@Nullable byte[] wifi) {
-        if (wifi != null) return wifi;
-
-        WifiData data = new WifiData();
-        data.wifiBand = DataStallEventProto.AP_BAND_UNKNOWN;
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("type: ").append(mNetworkType)
-          .append(", evaluation type: ")
-          .append(mEvaluationType)
-          .append(", wifi info: ")
-          .append(HexDump.toHexString(mWifiInfo))
-          .append(", cell info: ")
-          .append(HexDump.toHexString(mCellularInfo))
-          .append(", dns: ")
-          .append(HexDump.toHexString(mDns));
-        return sb.toString();
-    }
-
-    @Override
-    public boolean equals(@Nullable final Object o) {
-        if (!(o instanceof DataStallDetectionStats)) return false;
-        final DataStallDetectionStats other = (DataStallDetectionStats) o;
-        return (mNetworkType == other.mNetworkType)
-            && (mEvaluationType == other.mEvaluationType)
-            && Arrays.equals(mWifiInfo, other.mWifiInfo)
-            && Arrays.equals(mCellularInfo, other.mCellularInfo)
-            && Arrays.equals(mDns, other.mDns);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns);
-    }
-
-    /**
-     * Utility to create an instance of {@Link DataStallDetectionStats}
-     *
-     * @hide
-     */
-    public static class Builder {
-        @Nullable
-        private byte[] mCellularInfo;
-        @Nullable
-        private byte[] mWifiInfo;
-        @NonNull
-        private final List<Integer> mDnsReturnCode = new ArrayList<Integer>();
-        @NonNull
-        private final List<Long> mDnsTimeStamp = new ArrayList<Long>();
-        private int mEvaluationType;
-        private int mNetworkType;
-
-        /**
-         * Add a dns event into Builder.
-         *
-         * @param code the return code of the dns event.
-         * @param timeMs the elapsedRealtime in ms that the the dns event was received from netd.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder addDnsEvent(int code, long timeMs) {
-            mDnsReturnCode.add(code);
-            mDnsTimeStamp.add(timeMs);
-            return this;
-        }
-
-        /**
-         * Set the dns evaluation type into Builder.
-         *
-         * @param type the return code of the dns event.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setEvaluationType(int type) {
-            mEvaluationType = type;
-            return this;
-        }
-
-        /**
-         * Set the network type into Builder.
-         *
-         * @param type the network type of the logged network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setNetworkType(int type) {
-            mNetworkType = type;
-            return this;
-        }
-
-        /**
-         * Set the wifi data into Builder.
-         *
-         * @param info a {@link WifiInfo} of the connected wifi network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setWiFiData(@Nullable final WifiInfo info) {
-            WifiData data = new WifiData();
-            data.wifiBand = getWifiBand(info);
-            data.signalStrength = (info != null) ? info.getRssi() : UNKNOWN_SIGNAL_STRENGTH;
-            mWifiInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        private static int getWifiBand(@Nullable final WifiInfo info) {
-            if (info == null) return DataStallEventProto.AP_BAND_UNKNOWN;
-
-            int freq = info.getFrequency();
-            // Refer to ScanResult.is5GHz() and ScanResult.is24GHz().
-            if (freq > 4900 && freq < 5900) {
-                return DataStallEventProto.AP_BAND_5GHZ;
-            } else if (freq > 2400 && freq < 2500) {
-                return DataStallEventProto.AP_BAND_2GHZ;
-            } else {
-                return DataStallEventProto.AP_BAND_UNKNOWN;
-            }
-        }
-
-        /**
-         * Set the cellular data into Builder.
-         *
-         * @param radioType the radio technology of the logged cellular network.
-         * @param roaming a boolean indicates if logged cellular network is roaming or not.
-         * @param networkMccmnc the mccmnc of the camped network.
-         * @param simMccmnc the mccmnc of the sim.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setCellData(int radioType, boolean roaming,
-                @NonNull String networkMccmnc, @NonNull String simMccmnc, int ss) {
-            CellularData data  = new CellularData();
-            data.ratType = radioType;
-            data.isRoaming = roaming;
-            data.networkMccmnc = networkMccmnc;
-            data.simMccmnc = simMccmnc;
-            data.signalStrength = ss;
-            mCellularInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        /**
-         * Create a new {@Link DataStallDetectionStats}.
-         */
-        public DataStallDetectionStats build() {
-            return new DataStallDetectionStats(mCellularInfo, mWifiInfo,
-                    NetworkStackUtils.convertToIntArray(mDnsReturnCode),
-                    NetworkStackUtils.convertToLongArray(mDnsTimeStamp),
-                    mEvaluationType, mNetworkType);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
deleted file mode 100644
index 9308901..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 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.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.DataStallEventProto;
-
-/**
- * Collection of utilities for data stall metrics.
- *
- * To see if the logs are properly sent to statsd, execute following command.
- *
- * $ adb shell cmd stats print-logs
- * $ adb logcat | grep statsd  OR $ adb logcat -b stats
- *
- * @hide
- */
-public class DataStallStatsUtils {
-    private static final String TAG = DataStallStatsUtils.class.getSimpleName();
-    private static final boolean DBG = false;
-
-    private static int probeResultToEnum(@Nullable final CaptivePortalProbeResult result) {
-        if (result == null) return DataStallEventProto.INVALID;
-
-        if (result.isSuccessful()) {
-            return DataStallEventProto.VALID;
-        } else if (result.isPortal()) {
-            return DataStallEventProto.PORTAL;
-        } else if (result.isPartialConnectivity()) {
-            return DataStallEventProto.PARTIAL;
-        } else {
-            return DataStallEventProto.INVALID;
-        }
-    }
-
-    /**
-     * Write the metric to {@link StatsLog}.
-     */
-    public static void write(@NonNull final DataStallDetectionStats stats,
-            @NonNull final CaptivePortalProbeResult result) {
-        int validationResult = probeResultToEnum(result);
-        if (DBG) {
-            Log.d(TAG, "write: " + stats + " with result: " + validationResult
-                    + ", dns: " + HexDump.toHexString(stats.mDns));
-        }
-        NetworkStackStatsLog.write(NetworkStackStatsLog.DATA_STALL_EVENT,
-                stats.mEvaluationType,
-                validationResult,
-                stats.mNetworkType,
-                stats.mWifiInfo,
-                stats.mCellularInfo,
-                stats.mDns);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java b/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
deleted file mode 100644
index 4767d55..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 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.networkstack.util;
-
-import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
-import static android.net.DnsResolver.TYPE_A;
-import static android.net.DnsResolver.TYPE_AAAA;
-
-import android.annotation.NonNull;
-import android.net.DnsResolver;
-import android.net.Network;
-import android.net.TrafficStats;
-import android.util.Log;
-
-import com.android.internal.util.TrafficStatsConstants;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Collection of utilities for dns query.
- */
-public class DnsUtils {
-    // Decide what queries to make depending on what IP addresses are on the system.
-    public static final int TYPE_ADDRCONFIG = -1;
-    private static final String TAG = DnsUtils.class.getSimpleName();
-
-    /**
-     * Return both A and AAAA query results regardless the ip address type of the giving network.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull String host, int timeout)
-            throws UnknownHostException {
-        final List<InetAddress> result = new ArrayList<InetAddress>();
-
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v4-only, still need to query TYPE_A
-        }
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_A, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v6-only, still need to return AAAA answers
-        }
-        if (result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-        return result.toArray(new InetAddress[0]);
-    }
-
-    /**
-     * Return dns query result based on the given QueryType(TYPE_A, TYPE_AAAA) or TYPE_ADDRCONFIG.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull final String host, int type, int flag,
-            int timeoutMs) throws UnknownHostException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final AtomicReference<List<InetAddress>> resultRef = new AtomicReference<>();
-
-        final DnsResolver.Callback<List<InetAddress>> callback =
-                new DnsResolver.Callback<List<InetAddress>>() {
-            @Override
-            public void onAnswer(List<InetAddress> answer, int rcode) {
-                if (rcode == 0) {
-                    resultRef.set(answer);
-                }
-                latch.countDown();
-            }
-
-            @Override
-            public void onError(@NonNull DnsResolver.DnsException e) {
-                Log.d(TAG, "DNS error resolving " + host + ": " + e.getMessage());
-                latch.countDown();
-            }
-        };
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-
-        if (type == TYPE_ADDRCONFIG) {
-            dnsResolver.query(network, host, flag, r -> r.run(), null /* cancellationSignal */,
-                    callback);
-        } else {
-            dnsResolver.query(network, host, type, flag, r -> r.run(),
-                    null /* cancellationSignal */, callback);
-        }
-
-        TrafficStats.setThreadStatsTag(oldTag);
-
-        try {
-            latch.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-        }
-
-        final List<InetAddress> result = resultRef.get();
-        if (result == null || result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-
-        return result.toArray(new InetAddress[0]);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserver.java b/packages/NetworkStack/src/com/android/server/NetworkObserver.java
deleted file mode 100644
index cccec0b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserver.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-
-/**
- * Observer for network events, to use with {@link NetworkObserverRegistry}.
- */
-public interface NetworkObserver {
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceChanged(java.lang.String, boolean)
-     */
-    default void onInterfaceChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceRemoved(String)
-     */
-    default void onInterfaceRemoved(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressUpdated(String, String, int, int)
-     */
-    default void onInterfaceAddressUpdated(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressRemoved(String, String, int, int)
-     */
-    default void onInterfaceAddressRemoved(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceLinkStateChanged(String, boolean)
-     */
-    default void onInterfaceLinkStateChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceAdded(String)
-     */
-    default void onInterfaceAdded(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceClassActivityChanged(boolean, int, long, int)
-     */
-    default void onInterfaceClassActivityChanged(
-            boolean isActive, int label, long timestamp, int uid) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onQuotaLimitReached(String, String)
-     */
-    default void onQuotaLimitReached(String alertName, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceDnsServerInfo(String, long, String[])
-     */
-    default void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteUpdated(RouteInfo route) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteRemoved(RouteInfo route) {}
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java b/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
deleted file mode 100644
index afe166b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-
-import android.annotation.NonNull;
-import android.net.INetd;
-import android.net.INetdUnsolicitedEventListener;
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A class for reporting network events to clients.
- *
- * Implements INetdUnsolicitedEventListener and registers with netd, and relays those events to
- * all INetworkManagementEventObserver objects that have registered with it.
- */
-public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub {
-    private static final String TAG = NetworkObserverRegistry.class.getSimpleName();
-
-    /**
-     * Constructs a new NetworkObserverRegistry.
-     *
-     * <p>Only one registry should be used per process since netd will silently ignore multiple
-     * registrations from the same process.
-     */
-    NetworkObserverRegistry() {}
-
-    /**
-     * Start listening for Netd events.
-     *
-     * <p>This should be called before allowing any observer to be registered.
-     */
-    void register(@NonNull INetd netd) throws RemoteException {
-        netd.registerUnsolicitedEventListener(this);
-    }
-
-    private final ConcurrentHashMap<NetworkObserver, Optional<Handler>> mObservers =
-            new ConcurrentHashMap<>();
-
-    /**
-     * Registers the specified observer and start sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void registerObserver(@NonNull NetworkObserver observer, @NonNull Handler handler) {
-        if (handler == null) {
-            throw new IllegalArgumentException("handler must be non-null");
-        }
-        mObservers.put(observer, Optional.of(handler));
-    }
-
-    /**
-     * Registers the specified observer, and start sending callbacks to it.
-     *
-     * <p>This method must only be called with callbacks that are nonblocking, such as callbacks
-     * that only send a message to a StateMachine.
-     */
-    public void registerObserverForNonblockingCallback(@NonNull NetworkObserver observer) {
-        mObservers.put(observer, Optional.empty());
-    }
-
-    /**
-     * Unregisters the specified observer and stop sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void unregisterObserver(@NonNull NetworkObserver observer) {
-        mObservers.remove(observer);
-    }
-
-    @FunctionalInterface
-    private interface NetworkObserverEventCallback {
-        void sendCallback(NetworkObserver o);
-    }
-
-    private void invokeForAllObservers(@NonNull final NetworkObserverEventCallback callback) {
-        // ConcurrentHashMap#entrySet is weakly consistent: observers that were in the map before
-        // creation will be processed, those added during traversal may or may not.
-        for (Map.Entry<NetworkObserver, Optional<Handler>> entry : mObservers.entrySet()) {
-            final NetworkObserver observer = entry.getKey();
-            final Optional<Handler> handler = entry.getValue();
-            if (handler.isPresent()) {
-                handler.get().post(() -> callback.sendCallback(observer));
-                return;
-            }
-
-            try {
-                callback.sendCallback(observer);
-            } catch (RuntimeException e) {
-                Log.e(TAG, "Error sending callback to observer", e);
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceClassActivityChanged(boolean isActive,
-            int label, long timestamp, int uid) {
-        invokeForAllObservers(o -> o.onInterfaceClassActivityChanged(
-                isActive, label, timestamp, uid));
-    }
-
-    /**
-     * Notify our observers of a limit reached.
-     */
-    @Override
-    public void onQuotaLimitReached(String alertName, String ifName) {
-        invokeForAllObservers(o -> o.onQuotaLimitReached(alertName, ifName));
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {
-        invokeForAllObservers(o -> o.onInterfaceDnsServerInfo(ifName, lifetime, servers));
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressUpdated(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(String addr,
-            String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressRemoved(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAdded(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceAdded(ifName));
-    }
-
-    @Override
-    public void onInterfaceRemoved(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceRemoved(ifName));
-    }
-
-    @Override
-    public void onInterfaceChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceChanged(ifName, up));
-    }
-
-    @Override
-    public void onInterfaceLinkStateChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceLinkStateChanged(ifName, up));
-    }
-
-    @Override
-    public void onRouteChanged(boolean updated, String route, String gateway, String ifName) {
-        final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
-                ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
-                ifName, RTN_UNICAST);
-        if (updated) {
-            invokeForAllObservers(o -> o.onRouteUpdated(processRoute));
-        } else {
-            invokeForAllObservers(o -> o.onRouteRemoved(processRoute));
-        }
-    }
-
-    @Override
-    public void onStrictCleartextDetected(int uid, String hex) {}
-
-    @Override
-    public int getInterfaceVersion() {
-        return INetdUnsolicitedEventListener.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
deleted file mode 100644
index c394d4c..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-
-import static com.android.server.util.PermissionUtil.checkDumpPermission;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.IIpMemoryStore;
-import android.net.IIpMemoryStoreCallbacks;
-import android.net.INetd;
-import android.net.INetworkMonitor;
-import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkStackConnector;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.PrivateDnsConfigParcel;
-import android.net.dhcp.DhcpServer;
-import android.net.dhcp.DhcpServingParams;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpServerCallbacks;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Android service used to start the network stack when bound to via an intent.
- *
- * <p>The service returns a binder for the system server to communicate with the network stack.
- */
-public class NetworkStackService extends Service {
-    private static final String TAG = NetworkStackService.class.getSimpleName();
-    private static NetworkStackConnector sConnector;
-
-    /**
-     * Create a binder connector for the system server to communicate with the network stack.
-     *
-     * <p>On platforms where the network stack runs in the system server process, this method may
-     * be called directly instead of obtaining the connector by binding to the service.
-     */
-    public static synchronized IBinder makeConnector(Context context) {
-        if (sConnector == null) {
-            sConnector = new NetworkStackConnector(context);
-        }
-        return sConnector;
-    }
-
-    @NonNull
-    @Override
-    public IBinder onBind(Intent intent) {
-        return makeConnector(this);
-    }
-
-    /**
-     * An interface for internal clients of the network stack service that can return
-     * or create inline instances of the service it manages.
-     */
-    public interface NetworkStackServiceManager {
-        /**
-         * Get an instance of the IpMemoryStoreService.
-         */
-        IIpMemoryStore getIpMemoryStoreService();
-    }
-
-    private static class NetworkStackConnector extends INetworkStackConnector.Stub
-            implements NetworkStackServiceManager {
-        private static final int NUM_VALIDATION_LOG_LINES = 20;
-        private final Context mContext;
-        private final INetd mNetd;
-        private final NetworkObserverRegistry mObserverRegistry;
-        private final ConnectivityManager mCm;
-        @GuardedBy("mIpClients")
-        private final ArrayList<WeakReference<IpClient>> mIpClients = new ArrayList<>();
-        private final IpMemoryStoreService mIpMemoryStoreService;
-
-        private static final int MAX_VALIDATION_LOGS = 10;
-        @GuardedBy("mValidationLogs")
-        private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
-
-        private static final int VERSION_UNKNOWN = 0;
-        private static final String DUMPSYS_ARG_VERSION = "version";
-
-        /** Version of the AIDL interfaces observed on the system */
-        private final AtomicInteger mSystemAidlVersion = new AtomicInteger(VERSION_UNKNOWN);
-
-        /** Whether different versions have been observed on interfaces provided by the system */
-        private volatile boolean mConflictingSystemAidlVersions = false;
-
-        private SharedLog addValidationLogs(Network network, String name) {
-            final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
-            synchronized (mValidationLogs) {
-                while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
-                    mValidationLogs.removeLast();
-                }
-                mValidationLogs.addFirst(log);
-            }
-            return log;
-        }
-
-        NetworkStackConnector(Context context) {
-            mContext = context;
-            mNetd = INetd.Stub.asInterface(
-                    (IBinder) context.getSystemService(Context.NETD_SERVICE));
-            mObserverRegistry = new NetworkObserverRegistry();
-            mCm = context.getSystemService(ConnectivityManager.class);
-            mIpMemoryStoreService = new IpMemoryStoreService(context);
-
-            try {
-                mObserverRegistry.register(mNetd);
-            } catch (RemoteException e) {
-                mLog.e("Error registering observer on Netd", e);
-            }
-        }
-
-        private void updateSystemAidlVersion(final int version) {
-            final int previousVersion = mSystemAidlVersion.getAndSet(version);
-            if (previousVersion != VERSION_UNKNOWN && previousVersion != version) {
-                mConflictingSystemAidlVersions = true;
-            }
-        }
-
-        @NonNull
-        private final SharedLog mLog = new SharedLog(TAG);
-
-        @Override
-        public void makeDhcpServer(@NonNull String ifName, @NonNull DhcpServingParamsParcel params,
-                @NonNull IDhcpServerCallbacks cb) throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final DhcpServer server;
-            try {
-                server = new DhcpServer(
-                        ifName,
-                        DhcpServingParams.fromParcelableObject(params),
-                        mLog.forSubComponent(ifName + ".DHCP"));
-            } catch (DhcpServingParams.InvalidParameterException e) {
-                mLog.e("Invalid DhcpServingParams", e);
-                cb.onDhcpServerCreated(STATUS_INVALID_ARGUMENT, null);
-                return;
-            } catch (Exception e) {
-                mLog.e("Unknown error starting DhcpServer", e);
-                cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
-                return;
-            }
-            cb.onDhcpServerCreated(STATUS_SUCCESS, server);
-        }
-
-        @Override
-        public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
-                throws RemoteException {
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final SharedLog log = addValidationLogs(network, name);
-            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, network, log);
-            cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
-        }
-
-        @Override
-        public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final IpClient ipClient = new IpClient(mContext, ifName, cb, mObserverRegistry, this);
-
-            synchronized (mIpClients) {
-                final Iterator<WeakReference<IpClient>> it = mIpClients.iterator();
-                while (it.hasNext()) {
-                    final IpClient ipc = it.next().get();
-                    if (ipc == null) {
-                        it.remove();
-                    }
-                }
-                mIpClients.add(new WeakReference<>(ipClient));
-            }
-
-            cb.onIpClientCreated(ipClient.makeConnector());
-        }
-
-        @Override
-        public IIpMemoryStore getIpMemoryStoreService() {
-            return mIpMemoryStoreService;
-        }
-
-        @Override
-        public void fetchIpMemoryStore(@NonNull final IIpMemoryStoreCallbacks cb)
-                throws RemoteException {
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            cb.onIpMemoryStoreFetched(mIpMemoryStoreService);
-        }
-
-        @Override
-        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
-                @Nullable String[] args) {
-            checkDumpPermission();
-            if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
-                dumpVersion(fout);
-                return;
-            }
-
-            final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
-            pw.println("NetworkStack logs:");
-            mLog.dump(fd, pw, args);
-
-            // Dump full IpClient logs for non-GCed clients
-            pw.println();
-            pw.println("Recently active IpClient logs:");
-            final ArrayList<IpClient> ipClients = new ArrayList<>();
-            final HashSet<String> dumpedIpClientIfaces = new HashSet<>();
-            synchronized (mIpClients) {
-                for (WeakReference<IpClient> ipcRef : mIpClients) {
-                    final IpClient ipc = ipcRef.get();
-                    if (ipc != null) {
-                        ipClients.add(ipc);
-                    }
-                }
-            }
-
-            for (IpClient ipc : ipClients) {
-                pw.println(ipc.getName());
-                pw.increaseIndent();
-                ipc.dump(fd, pw, args);
-                pw.decreaseIndent();
-                dumpedIpClientIfaces.add(ipc.getInterfaceName());
-            }
-
-            // State machine and connectivity metrics logs are kept for GCed IpClients
-            pw.println();
-            pw.println("Other IpClient logs:");
-            IpClient.dumpAllLogs(fout, dumpedIpClientIfaces);
-
-            pw.println();
-            pw.println("Validation logs (most recent first):");
-            synchronized (mValidationLogs) {
-                for (SharedLog p : mValidationLogs) {
-                    pw.println(p.getTag());
-                    pw.increaseIndent();
-                    p.dump(fd, pw, args);
-                    pw.decreaseIndent();
-                }
-            }
-        }
-
-        /**
-         * Dump version information of the module and detected system version.
-         */
-        private void dumpVersion(@NonNull PrintWriter fout) {
-            fout.println("NetworkStackConnector: " + this.VERSION);
-            fout.println("SystemServer: " + mSystemAidlVersion);
-            fout.println("SystemServerConflicts: " + mConflictingSystemAidlVersions);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    private static class NetworkMonitorImpl extends INetworkMonitor.Stub {
-        private final NetworkMonitor mNm;
-
-        NetworkMonitorImpl(NetworkMonitor nm) {
-            mNm = nm;
-        }
-
-        @Override
-        public void start() {
-            checkNetworkStackCallingPermission();
-            mNm.start();
-        }
-
-        @Override
-        public void launchCaptivePortalApp() {
-            checkNetworkStackCallingPermission();
-            mNm.launchCaptivePortalApp();
-        }
-
-        @Override
-        public void notifyCaptivePortalAppFinished(int response) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyCaptivePortalAppFinished(response);
-        }
-
-        @Override
-        public void setAcceptPartialConnectivity() {
-            checkNetworkStackCallingPermission();
-            mNm.setAcceptPartialConnectivity();
-        }
-
-        @Override
-        public void forceReevaluation(int uid) {
-            checkNetworkStackCallingPermission();
-            mNm.forceReevaluation(uid);
-        }
-
-        @Override
-        public void notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyPrivateDnsSettingsChanged(PrivateDnsConfig.fromParcel(config));
-        }
-
-        @Override
-        public void notifyDnsResponse(int returnCode) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyDnsResponse(returnCode);
-        }
-
-        @Override
-        public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkConnected(lp, nc);
-        }
-
-        @Override
-        public void notifyNetworkDisconnected() {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkDisconnected();
-        }
-
-        @Override
-        public void notifyLinkPropertiesChanged(LinkProperties lp) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyLinkPropertiesChanged(lp);
-        }
-
-        @Override
-        public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkCapabilitiesChanged(nc);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
deleted file mode 100644
index 4e40ba4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ /dev/null
@@ -1,2143 +0,0 @@
-/*
- * Copyright (C) 2014 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.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.CaptivePortal.APP_RETURN_UNWANTED;
-import static android.net.CaptivePortal.APP_RETURN_WANTED_AS_IS;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.DnsResolver.FLAG_EMPTY;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.captiveportal.CaptivePortalProbeSpec.parseCaptivePortalProbeSpecs;
-import static android.net.metrics.ValidationProbeEvent.DNS_FAILURE;
-import static android.net.metrics.ValidationProbeEvent.DNS_SUCCESS;
-import static android.net.metrics.ValidationProbeEvent.PROBE_FALLBACK;
-import static android.net.metrics.ValidationProbeEvent.PROBE_PRIVDNS;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.DataStallUtils.DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_EVALUATION_TYPES;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DNS_LOG_SIZE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-import static android.net.util.NetworkStackUtils.NAMESPACE_CONNECTIVITY;
-import static android.net.util.NetworkStackUtils.isEmpty;
-
-import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.ProxyInfo;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.NetworkEvent;
-import android.net.metrics.ValidationProbeEvent;
-import android.net.shared.NetworkMonitorUtils;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.Stopwatch;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CellSignalStrength;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.ArrayRes;
-import androidx.annotation.StringRes;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.RingBufferIndices;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-import com.android.networkstack.util.DnsUtils;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-
-/**
- * {@hide}
- */
-public class NetworkMonitor extends StateMachine {
-    private static final String TAG = NetworkMonitor.class.getSimpleName();
-    private static final boolean DBG  = true;
-    private static final boolean VDBG = false;
-    private static final boolean VDBG_STALL = Log.isLoggable(TAG, Log.DEBUG);
-    private static final String DEFAULT_USER_AGENT    = "Mozilla/5.0 (X11; Linux x86_64) "
-                                                      + "AppleWebKit/537.36 (KHTML, like Gecko) "
-                                                      + "Chrome/60.0.3112.32 Safari/537.36";
-
-    @VisibleForTesting
-    static final String CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT =
-            "captive_portal_dns_probe_timeout";
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    private static final int PROBE_TIMEOUT_MS  = 3000;
-
-    enum EvaluationResult {
-        VALIDATED(true),
-        CAPTIVE_PORTAL(false);
-        final boolean mIsValidated;
-        EvaluationResult(boolean isValidated) {
-            this.mIsValidated = isValidated;
-        }
-    }
-
-    enum ValidationStage {
-        FIRST_VALIDATION(true),
-        REVALIDATION(false);
-        final boolean mIsFirstValidation;
-        ValidationStage(boolean isFirstValidation) {
-            this.mIsFirstValidation = isFirstValidation;
-        }
-    }
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has connected.
-     * Initiates Network Validation.
-     */
-    private static final int CMD_NETWORK_CONNECTED = 1;
-
-    /**
-     * Message to self indicating it's time to evaluate a network's connectivity.
-     * arg1 = Token to ignore old messages.
-     */
-    private static final int CMD_REEVALUATE = 6;
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has disconnected.
-     */
-    private static final int CMD_NETWORK_DISCONNECTED = 7;
-
-    /**
-     * Force evaluation even if it has succeeded in the past.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     */
-    private static final int CMD_FORCE_REEVALUATION = 8;
-
-    /**
-     * Message to self indicating captive portal app finished.
-     * arg1 = one of: APP_RETURN_DISMISSED,
-     *                APP_RETURN_UNWANTED,
-     *                APP_RETURN_WANTED_AS_IS
-     * obj = mCaptivePortalLoggedInResponseToken as String
-     */
-    private static final int CMD_CAPTIVE_PORTAL_APP_FINISHED = 9;
-
-    /**
-     * Message indicating sign-in app should be launched.
-     * Sent by mLaunchCaptivePortalAppBroadcastReceiver when the
-     * user touches the sign in notification, or sent by
-     * ConnectivityService when the user touches the "sign into
-     * network" button in the wifi access point detail page.
-     */
-    private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = 11;
-
-    /**
-     * Retest network to see if captive portal is still in place.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     *        0 indicates self-initiated, so nobody to blame.
-     */
-    private static final int CMD_CAPTIVE_PORTAL_RECHECK = 12;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of settings changes to
-     * Private DNS. If a DNS resolution is required, e.g. for DNS-over-TLS in
-     * strict mode, then an event is sent back to ConnectivityService with the
-     * result of the resolution attempt.
-     *
-     * A separate message is used to trigger (re)evaluation of the Private DNS
-     * configuration, so that the message can be handled as needed in different
-     * states, including being ignored until after an ongoing captive portal
-     * validation phase is completed.
-     */
-    private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = 13;
-    private static final int CMD_EVALUATE_PRIVATE_DNS = 15;
-
-    /**
-     * Message to self indicating captive portal detection is completed.
-     * obj = CaptivePortalProbeResult for detection result;
-     */
-    private static final int CMD_PROBE_COMPLETE = 16;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of DNS query responses event.
-     * arg1 = returncode in OnDnsEvent which indicates the response code for the DNS query.
-     */
-    private static final int EVENT_DNS_NOTIFICATION = 17;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
-     * NetworkMonitor should ignore the https probe.
-     */
-    private static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of changed LinkProperties.
-     * obj = new LinkProperties.
-     */
-    private static final int EVENT_LINK_PROPERTIES_CHANGED = 19;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of changed NetworkCapabilities.
-     * obj = new NetworkCapabilities.
-     */
-    private static final int EVENT_NETWORK_CAPABILITIES_CHANGED = 20;
-
-    // Start mReevaluateDelayMs at this value and double.
-    private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
-    private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    // Before network has been evaluated this many times, ignore repeated reevaluate requests.
-    private static final int IGNORE_REEVALUATE_ATTEMPTS = 5;
-    private int mReevaluateToken = 0;
-    private static final int NO_UID = 0;
-    private static final int INVALID_UID = -1;
-    private int mUidResponsibleForReeval = INVALID_UID;
-    // Stop blaming UID that requested re-evaluation after this many attempts.
-    private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
-    // Delay between reevaluations once a captive portal has been found.
-    private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    private static final int NETWORK_VALIDATION_RESULT_INVALID = 0;
-    private String mPrivateDnsProviderHostname = "";
-
-    private final Context mContext;
-    private final INetworkMonitorCallbacks mCallback;
-    private final Network mCleartextDnsNetwork;
-    private final Network mNetwork;
-    private final TelephonyManager mTelephonyManager;
-    private final WifiManager mWifiManager;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog;
-    private final Dependencies mDependencies;
-    private final DataStallStatsUtils mDetectionStatsUtils;
-
-    // Configuration values for captive portal detection probes.
-    private final String mCaptivePortalUserAgent;
-    private final URL mCaptivePortalHttpsUrl;
-    private final URL mCaptivePortalHttpUrl;
-    private final URL[] mCaptivePortalFallbackUrls;
-    @Nullable
-    private final CaptivePortalProbeSpec[] mCaptivePortalFallbackSpecs;
-
-    private NetworkCapabilities mNetworkCapabilities;
-    private LinkProperties mLinkProperties;
-
-    @VisibleForTesting
-    protected boolean mIsCaptivePortalCheckEnabled;
-
-    private boolean mUseHttps;
-    // The total number of captive portal detection attempts for this NetworkMonitor instance.
-    private int mValidations = 0;
-
-    // Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
-    private boolean mUserDoesNotWant = false;
-    // Avoids surfacing "Sign in to network" notification.
-    private boolean mDontDisplaySigninNotification = false;
-
-    private final State mDefaultState = new DefaultState();
-    private final State mValidatedState = new ValidatedState();
-    private final State mMaybeNotifyState = new MaybeNotifyState();
-    private final State mEvaluatingState = new EvaluatingState();
-    private final State mCaptivePortalState = new CaptivePortalState();
-    private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
-    private final State mProbingState = new ProbingState();
-    private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
-
-    private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
-
-    private final SharedLog mValidationLogs;
-
-    private final Stopwatch mEvaluationTimer = new Stopwatch();
-
-    // This variable is set before transitioning to the mCaptivePortalState.
-    private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
-
-    // Random generator to select fallback URL index
-    private final Random mRandom;
-    private int mNextFallbackUrlIndex = 0;
-
-
-    private int mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-    private int mEvaluateAttempts = 0;
-    private volatile int mProbeToken = 0;
-    private final int mConsecutiveDnsTimeoutThreshold;
-    private final int mDataStallMinEvaluateTime;
-    private final int mDataStallValidDnsTimeThreshold;
-    private final int mDataStallEvaluationType;
-    private final DnsStallDetector mDnsStallDetector;
-    private long mLastProbeTime;
-    // Set to true if data stall is suspected and reset to false after metrics are sent to statsd.
-    private boolean mCollectDataStallMetrics;
-    private boolean mAcceptPartialConnectivity = false;
-    private final EvaluationState mEvaluationState = new EvaluationState();
-
-    public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            SharedLog validationLog) {
-        this(context, cb, network, new IpConnectivityLog(), validationLog,
-                Dependencies.DEFAULT, new DataStallStatsUtils());
-    }
-
-    @VisibleForTesting
-    protected NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            IpConnectivityLog logger, SharedLog validationLogs,
-            Dependencies deps, DataStallStatsUtils detectionStatsUtils) {
-        // Add suffix indicating which NetworkMonitor we're talking about.
-        super(TAG + "/" + network.toString());
-
-        // Logs with a tag of the form given just above, e.g.
-        //     <timestamp>   862  2402 D NetworkMonitor/NetworkAgentInfo [WIFI () - 100]: ...
-        setDbg(VDBG);
-
-        mContext = context;
-        mMetricsLog = logger;
-        mValidationLogs = validationLogs;
-        mCallback = cb;
-        mDependencies = deps;
-        mDetectionStatsUtils = detectionStatsUtils;
-        mNetwork = network;
-        mCleartextDnsNetwork = deps.getPrivateDnsBypassNetwork(network);
-        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mDefaultState);
-        addState(mMaybeNotifyState, mDefaultState);
-            addState(mEvaluatingState, mMaybeNotifyState);
-                addState(mProbingState, mEvaluatingState);
-                addState(mWaitingForNextProbeState, mEvaluatingState);
-            addState(mCaptivePortalState, mMaybeNotifyState);
-        addState(mEvaluatingPrivateDnsState, mDefaultState);
-        addState(mValidatedState, mDefaultState);
-        setInitialState(mDefaultState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled();
-        mUseHttps = getUseHttpsValidation();
-        mCaptivePortalUserAgent = getCaptivePortalUserAgent();
-        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl());
-        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl());
-        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls();
-        mCaptivePortalFallbackSpecs = makeCaptivePortalFallbackProbeSpecs();
-        mRandom = deps.getRandom();
-        // TODO: Evaluate to move data stall configuration to a specific class.
-        mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold();
-        mDnsStallDetector = new DnsStallDetector(mConsecutiveDnsTimeoutThreshold);
-        mDataStallMinEvaluateTime = getDataStallMinEvaluateTime();
-        mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold();
-        mDataStallEvaluationType = getDataStallEvaluationType();
-
-        // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null,
-        // even before notifyNetworkConnected.
-        mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities(null);
-    }
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user already accepted partial
-     * connectivity previously, so NetworkMonitor can validate the network even if it has partial
-     * connectivity.
-     */
-    public void setAcceptPartialConnectivity() {
-        sendMessage(EVENT_ACCEPT_PARTIAL_CONNECTIVITY);
-    }
-
-    /**
-     * Request the NetworkMonitor to reevaluate the network.
-     */
-    public void forceReevaluation(int responsibleUid) {
-        sendMessage(CMD_FORCE_REEVALUATION, responsibleUid, 0);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that there was a DNS query response event.
-     * @param returnCode the DNS return code of the response.
-     */
-    public void notifyDnsResponse(int returnCode) {
-        sendMessage(EVENT_DNS_NOTIFICATION, returnCode);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that private DNS settings have changed.
-     * @param newCfg The new private DNS configuration.
-     */
-    public void notifyPrivateDnsSettingsChanged(PrivateDnsConfig newCfg) {
-        // Cancel any outstanding resolutions.
-        removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED);
-        // Send the update to the proper thread.
-        sendMessage(CMD_PRIVATE_DNS_SETTINGS_CHANGED, newCfg);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now connected.
-     */
-    public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-        sendMessage(CMD_NETWORK_CONNECTED, new Pair<>(
-                new LinkProperties(lp), new NetworkCapabilities(nc)));
-    }
-
-    private void updateConnectedNetworkAttributes(Message connectedMsg) {
-        final Pair<LinkProperties, NetworkCapabilities> attrs =
-                (Pair<LinkProperties, NetworkCapabilities>) connectedMsg.obj;
-        mLinkProperties = attrs.first;
-        mNetworkCapabilities = attrs.second;
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now disconnected.
-     */
-    public void notifyNetworkDisconnected() {
-        sendMessage(CMD_NETWORK_DISCONNECTED);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that link properties have changed.
-     */
-    public void notifyLinkPropertiesChanged(final LinkProperties lp) {
-        sendMessage(EVENT_LINK_PROPERTIES_CHANGED, new LinkProperties(lp));
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that network capabilities have changed.
-     */
-    public void notifyNetworkCapabilitiesChanged(final NetworkCapabilities nc) {
-        sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilities(nc));
-    }
-
-    /**
-     * Request the captive portal application to be launched.
-     */
-    public void launchCaptivePortalApp() {
-        sendMessage(CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-    }
-
-    /**
-     * Notify that the captive portal app was closed with the provided response code.
-     */
-    public void notifyCaptivePortalAppFinished(int response) {
-        sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response);
-    }
-
-    @Override
-    protected void log(String s) {
-        if (DBG) Log.d(TAG + "/" + mCleartextDnsNetwork.toString(), s);
-    }
-
-    private void validationLog(int probeType, Object url, String msg) {
-        String probeName = ValidationProbeEvent.getProbeName(probeType);
-        validationLog(String.format("%s %s %s", probeName, url, msg));
-    }
-
-    private void validationLog(String s) {
-        if (DBG) log(s);
-        mValidationLogs.log(s);
-    }
-
-    private ValidationStage validationStage() {
-        return 0 == mValidations ? ValidationStage.FIRST_VALIDATION : ValidationStage.REVALIDATION;
-    }
-
-    private boolean isValidationRequired() {
-        return NetworkMonitorUtils.isValidationRequired(mNetworkCapabilities);
-    }
-
-    private boolean isPrivateDnsValidationRequired() {
-        return NetworkMonitorUtils.isPrivateDnsValidationRequired(mNetworkCapabilities);
-    }
-
-    private void notifyNetworkTested(int result, @Nullable String redirectUrl) {
-        try {
-            mCallback.notifyNetworkTested(result, redirectUrl);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error sending network test result", e);
-        }
-    }
-
-    private void showProvisioningNotification(String action) {
-        try {
-            mCallback.showProvisioningNotification(action, mContext.getPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error showing provisioning notification", e);
-        }
-    }
-
-    private void hideProvisioningNotification() {
-        try {
-            mCallback.hideProvisioningNotification();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error hiding provisioning notification", e);
-        }
-    }
-
-    // DefaultState is the parent of all States.  It exists only to handle CMD_* messages but
-    // does not entail any real state (hence no enter() or exit() routines).
-    private class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    logNetworkEvent(NetworkEvent.NETWORK_CONNECTED);
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_NETWORK_DISCONNECTED:
-                    logNetworkEvent(NetworkEvent.NETWORK_DISCONNECTED);
-                    quit();
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                case CMD_CAPTIVE_PORTAL_RECHECK:
-                    final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount();
-                    validationLog("Forcing reevaluation for UID " + message.arg1
-                            + ". Dns signal count: " + dnsCount);
-                    mUidResponsibleForReeval = message.arg1;
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_CAPTIVE_PORTAL_APP_FINISHED:
-                    log("CaptivePortal App responded with " + message.arg1);
-
-                    // If the user has seen and acted on a captive portal notification, and the
-                    // captive portal app is now closed, disable HTTPS probes. This avoids the
-                    // following pathological situation:
-                    //
-                    // 1. HTTP probe returns a captive portal, HTTPS probe fails or times out.
-                    // 2. User opens the app and logs into the captive portal.
-                    // 3. HTTP starts working, but HTTPS still doesn't work for some other reason -
-                    //    perhaps due to the network blocking HTTPS?
-                    //
-                    // In this case, we'll fail to validate the network even after the app is
-                    // dismissed. There is now no way to use this network, because the app is now
-                    // gone, so the user cannot select "Use this network as is".
-                    mUseHttps = false;
-
-                    switch (message.arg1) {
-                        case APP_RETURN_DISMISSED:
-                            sendMessage(CMD_FORCE_REEVALUATION, NO_UID, 0);
-                            break;
-                        case APP_RETURN_WANTED_AS_IS:
-                            mDontDisplaySigninNotification = true;
-                            // TODO: Distinguish this from a network that actually validates.
-                            // Displaying the "x" on the system UI icon may still be a good idea.
-                            transitionTo(mEvaluatingPrivateDnsState);
-                            break;
-                        case APP_RETURN_UNWANTED:
-                            mDontDisplaySigninNotification = true;
-                            mUserDoesNotWant = true;
-                            mEvaluationState.reportEvaluationResult(
-                                    NETWORK_VALIDATION_RESULT_INVALID, null);
-                            // TODO: Should teardown network.
-                            mUidResponsibleForReeval = 0;
-                            transitionTo(mEvaluatingState);
-                            break;
-                    }
-                    return HANDLED;
-                case CMD_PRIVATE_DNS_SETTINGS_CHANGED: {
-                    final PrivateDnsConfig cfg = (PrivateDnsConfig) message.obj;
-                    if (!isPrivateDnsValidationRequired() || cfg == null || !cfg.inStrictMode()) {
-                        // No DNS resolution required.
-                        //
-                        // We don't force any validation in opportunistic mode
-                        // here. Opportunistic mode nameservers are validated
-                        // separately within netd.
-                        //
-                        // Reset Private DNS settings state.
-                        mPrivateDnsProviderHostname = "";
-                        break;
-                    }
-
-                    mPrivateDnsProviderHostname = cfg.hostname;
-
-                    // DNS resolutions via Private DNS strict mode block for a
-                    // few seconds (~4.2) checking for any IP addresses to
-                    // arrive and validate. Initiating a (re)evaluation now
-                    // should not significantly alter the validation outcome.
-                    //
-                    // No matter what: enqueue a validation request; one of
-                    // three things can happen with this request:
-                    //     [1] ignored (EvaluatingState or CaptivePortalState)
-                    //     [2] transition to EvaluatingPrivateDnsState
-                    //         (DefaultState and ValidatedState)
-                    //     [3] handled (EvaluatingPrivateDnsState)
-                    //
-                    // The Private DNS configuration to be evaluated will:
-                    //     [1] be skipped (not in strict mode), or
-                    //     [2] validate (huzzah), or
-                    //     [3] encounter some problem (invalid hostname,
-                    //         no resolved IP addresses, IPs unreachable,
-                    //         port 853 unreachable, port 853 is not running a
-                    //         DNS-over-TLS server, et cetera).
-                    sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-                    break;
-                }
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    break;
-                // Set mAcceptPartialConnectivity to true and if network start evaluating or
-                // re-evaluating and get the result of partial connectivity, ProbingState will
-                // disable HTTPS probe and transition to EvaluatingPrivateDnsState.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    break;
-                case EVENT_LINK_PROPERTIES_CHANGED:
-                    mLinkProperties = (LinkProperties) message.obj;
-                    break;
-                case EVENT_NETWORK_CAPABILITIES_CHANGED:
-                    mNetworkCapabilities = (NetworkCapabilities) message.obj;
-                    break;
-                default:
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    // Being in the ValidatedState State indicates a Network is:
-    // - Successfully validated, or
-    // - Wanted "as is" by the user, or
-    // - Does not satisfy the default NetworkRequest and so validation has been skipped.
-    private class ValidatedState extends State {
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.VALIDATED));
-            // If the user has accepted partial connectivity and HTTPS probing is disabled, then
-            // mark the network as validated and partial so that settings can keep informing the
-            // user that the connection is limited.
-            int result = NETWORK_VALIDATION_RESULT_VALID;
-            if (!mUseHttps && mAcceptPartialConnectivity) {
-                result |= NETWORK_VALIDATION_RESULT_PARTIAL;
-            }
-            mEvaluationState.reportEvaluationResult(result, null /* redirectUrl */);
-            mValidations++;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    transitionTo(mValidatedState);
-                    break;
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    break;
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    if (isDataStall()) {
-                        mCollectDataStallMetrics = true;
-                        validationLog("Suspecting data stall, reevaluate");
-                        transitionTo(mEvaluatingState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private void writeDataStallStats(@NonNull final CaptivePortalProbeResult result) {
-        /*
-         * Collect data stall detection level information for each transport type. Collect type
-         * specific information for cellular and wifi only currently. Generate
-         * DataStallDetectionStats for each transport type. E.g., if a network supports both
-         * TRANSPORT_WIFI and TRANSPORT_VPN, two DataStallDetectionStats will be generated.
-         */
-        final int[] transports = mNetworkCapabilities.getTransportTypes();
-
-        for (int i = 0; i < transports.length; i++) {
-            DataStallStatsUtils.write(buildDataStallDetectionStats(transports[i]), result);
-        }
-        mCollectDataStallMetrics = false;
-    }
-
-    @VisibleForTesting
-    protected DataStallDetectionStats buildDataStallDetectionStats(int transport) {
-        final DataStallDetectionStats.Builder stats = new DataStallDetectionStats.Builder();
-        if (VDBG_STALL) log("collectDataStallMetrics: type=" + transport);
-        stats.setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        stats.setNetworkType(transport);
-        switch (transport) {
-            case NetworkCapabilities.TRANSPORT_WIFI:
-                // TODO: Update it if status query in dual wifi is supported.
-                final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-                stats.setWiFiData(wifiInfo);
-                break;
-            case NetworkCapabilities.TRANSPORT_CELLULAR:
-                final boolean isRoaming = !mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-                final SignalStrength ss = mTelephonyManager.getSignalStrength();
-                // TODO(b/120452078): Support multi-sim.
-                stats.setCellData(
-                        mTelephonyManager.getDataNetworkType(),
-                        isRoaming,
-                        mTelephonyManager.getNetworkOperator(),
-                        mTelephonyManager.getSimOperator(),
-                        (ss != null)
-                        ? ss.getLevel() : CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
-                break;
-            default:
-                // No transport type specific information for the other types.
-                break;
-        }
-        addDnsEvents(stats);
-
-        return stats.build();
-    }
-
-    @VisibleForTesting
-    protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-        final int size = mDnsStallDetector.mResultIndices.size();
-        for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) {
-            final int index = mDnsStallDetector.mResultIndices.indexOf(size - i);
-            stats.addDnsEvent(mDnsStallDetector.mDnsEvents[index].mReturnCode,
-                    mDnsStallDetector.mDnsEvents[index].mTimeStamp);
-        }
-    }
-
-
-    // Being in the MaybeNotifyState State indicates the user may have been notified that sign-in
-    // is required.  This State takes care to clear the notification upon exit from the State.
-    private class MaybeNotifyState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
-                    final Bundle appExtras = new Bundle();
-                    // OneAddressPerFamilyNetwork is not parcelable across processes.
-                    final Network network = new Network(mCleartextDnsNetwork);
-                    appExtras.putParcelable(ConnectivityManager.EXTRA_NETWORK, network);
-                    final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
-                    appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
-                    if (probeRes.probeSpec != null) {
-                        final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
-                        appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
-                    }
-                    appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
-                            mCaptivePortalUserAgent);
-                    mCm.startCaptivePortalApp(network, appExtras);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
-                mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
-                mLaunchCaptivePortalAppBroadcastReceiver = null;
-            }
-            hideProvisioningNotification();
-        }
-    }
-
-    // Being in the EvaluatingState State indicates the Network is being evaluated for internet
-    // connectivity, or that the user has indicated that this network is unwanted.
-    private class EvaluatingState extends State {
-        @Override
-        public void enter() {
-            // If we have already started to track time spent in EvaluatingState
-            // don't reset the timer due simply to, say, commands or events that
-            // cause us to exit and re-enter EvaluatingState.
-            if (!mEvaluationTimer.isStarted()) {
-                mEvaluationTimer.start();
-            }
-            sendMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            if (mUidResponsibleForReeval != INVALID_UID) {
-                TrafficStats.setThreadStatsUid(mUidResponsibleForReeval);
-                mUidResponsibleForReeval = INVALID_UID;
-            }
-            mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mEvaluateAttempts = 0;
-            // Reset all current probe results to zero, but retain current validation state until
-            // validation succeeds or fails.
-            mEvaluationState.clearProbeResults();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_REEVALUATE:
-                    if (message.arg1 != mReevaluateToken || mUserDoesNotWant) {
-                        return HANDLED;
-                    }
-                    // Don't bother validating networks that don't satisfy the default request.
-                    // This includes:
-                    //  - VPNs which can be considered explicitly desired by the user and the
-                    //    user's desire trumps whether the network validates.
-                    //  - Networks that don't provide Internet access.  It's unclear how to
-                    //    validate such networks.
-                    //  - Untrusted networks.  It's unsafe to prompt the user to sign-in to
-                    //    such networks and the user didn't express interest in connecting to
-                    //    such networks (an app did) so the user may be unhappily surprised when
-                    //    asked to sign-in to a network they didn't want to connect to in the
-                    //    first place.  Validation could be done to adjust the network scores
-                    //    however these networks are app-requested and may not be intended for
-                    //    general usage, in which case general validation may not be an accurate
-                    //    measure of the network's quality.  Only the app knows how to evaluate
-                    //    the network so don't bother validating here.  Furthermore sending HTTP
-                    //    packets over the network may be undesirable, for example an extremely
-                    //    expensive metered network, or unwanted leaking of the User Agent string.
-                    //
-                    // On networks that need to support private DNS in strict mode (e.g., VPNs, but
-                    // not networks that don't provide Internet access), we still need to perform
-                    // private DNS server resolution.
-                    if (!isValidationRequired()) {
-                        if (isPrivateDnsValidationRequired()) {
-                            validationLog("Network would not satisfy default request, "
-                                    + "resolving private DNS");
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            validationLog("Network would not satisfy default request, "
-                                    + "not validating");
-                            transitionTo(mValidatedState);
-                        }
-                        return HANDLED;
-                    }
-                    mEvaluateAttempts++;
-
-                    transitionTo(mProbingState);
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                    // Before IGNORE_REEVALUATE_ATTEMPTS attempts are made,
-                    // ignore any re-evaluation requests. After, restart the
-                    // evaluation process via EvaluatingState#enter.
-                    return (mEvaluateAttempts < IGNORE_REEVALUATE_ATTEMPTS) ? HANDLED : NOT_HANDLED;
-                // Disable HTTPS probe and transition to EvaluatingPrivateDnsState because:
-                // 1. Network is connected and finish the network validation.
-                // 2. NetworkMonitor detects network is partial connectivity and user accepts it.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            TrafficStats.clearThreadStatsUid();
-        }
-    }
-
-    // BroadcastReceiver that waits for a particular Intent and then posts a message.
-    private class CustomIntentReceiver extends BroadcastReceiver {
-        private final int mToken;
-        private final int mWhat;
-        private final String mAction;
-        CustomIntentReceiver(String action, int token, int what) {
-            mToken = token;
-            mWhat = what;
-            mAction = action + "_" + mCleartextDnsNetwork.getNetworkHandle() + "_" + token;
-            mContext.registerReceiver(this, new IntentFilter(mAction));
-        }
-        public PendingIntent getPendingIntent() {
-            final Intent intent = new Intent(mAction);
-            intent.setPackage(mContext.getPackageName());
-            return PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(mAction)) sendMessage(obtainMessage(mWhat, mToken));
-        }
-    }
-
-    // Being in the CaptivePortalState State indicates a captive portal was detected and the user
-    // has been shown a notification to sign-in.
-    private class CaptivePortalState extends State {
-        private static final String ACTION_LAUNCH_CAPTIVE_PORTAL_APP =
-                "android.net.netmon.launchCaptivePortalApp";
-
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.CAPTIVE_PORTAL));
-            // Don't annoy user with sign-in notifications.
-            if (mDontDisplaySigninNotification) return;
-            // Create a CustomIntentReceiver that sends us a
-            // CMD_LAUNCH_CAPTIVE_PORTAL_APP message when the user
-            // touches the notification.
-            if (mLaunchCaptivePortalAppBroadcastReceiver == null) {
-                // Wait for result.
-                mLaunchCaptivePortalAppBroadcastReceiver = new CustomIntentReceiver(
-                        ACTION_LAUNCH_CAPTIVE_PORTAL_APP, new Random().nextInt(),
-                        CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-                // Display the sign in notification.
-                // Only do this once for every time we enter MaybeNotifyState. b/122164725
-                showProvisioningNotification(mLaunchCaptivePortalAppBroadcastReceiver.mAction);
-            }
-            // Retest for captive portal occasionally.
-            sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
-                    CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
-            mValidations++;
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
-        }
-    }
-
-    private class EvaluatingPrivateDnsState extends State {
-        private int mPrivateDnsReevalDelayMs;
-        private PrivateDnsConfig mPrivateDnsConfig;
-
-        @Override
-        public void enter() {
-            mPrivateDnsReevalDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mPrivateDnsConfig = null;
-            sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    if (inStrictMode()) {
-                        if (!isStrictModeHostnameResolved()) {
-                            resolveStrictModeHostname();
-
-                            if (isStrictModeHostnameResolved()) {
-                                notifyPrivateDnsConfigResolved();
-                            } else {
-                                handlePrivateDnsEvaluationFailure();
-                                break;
-                            }
-                        }
-
-                        // Look up a one-time hostname, to bypass caching.
-                        //
-                        // Note that this will race with ConnectivityService
-                        // code programming the DNS-over-TLS server IP addresses
-                        // into netd (if invoked, above). If netd doesn't know
-                        // the IP addresses yet, or if the connections to the IP
-                        // addresses haven't yet been validated, netd will block
-                        // for up to a few seconds before failing the lookup.
-                        if (!sendPrivateDnsProbe()) {
-                            handlePrivateDnsEvaluationFailure();
-                            break;
-                        }
-                    }
-
-                    // All good!
-                    transitionTo(mValidatedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        private boolean inStrictMode() {
-            return !TextUtils.isEmpty(mPrivateDnsProviderHostname);
-        }
-
-        private boolean isStrictModeHostnameResolved() {
-            return (mPrivateDnsConfig != null)
-                    && mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname)
-                    && (mPrivateDnsConfig.ips.length > 0);
-        }
-
-        private void resolveStrictModeHostname() {
-            try {
-                // Do a blocking DNS resolution using the network-assigned nameservers.
-                final InetAddress[] ips = DnsUtils.getAllByName(mDependencies.getDnsResolver(),
-                        mCleartextDnsNetwork, mPrivateDnsProviderHostname, getDnsProbeTimeout());
-                mPrivateDnsConfig = new PrivateDnsConfig(mPrivateDnsProviderHostname, ips);
-                validationLog("Strict mode hostname resolved: " + mPrivateDnsConfig);
-            } catch (UnknownHostException uhe) {
-                mPrivateDnsConfig = null;
-                validationLog("Strict mode hostname resolution failed: " + uhe.getMessage());
-            }
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS,
-                    (mPrivateDnsConfig != null) /* succeeded */);
-        }
-
-        private void notifyPrivateDnsConfigResolved() {
-            try {
-                mCallback.notifyPrivateDnsConfigResolved(mPrivateDnsConfig.toParcel());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error sending private DNS config resolved notification", e);
-            }
-        }
-
-        private void handlePrivateDnsEvaluationFailure() {
-            mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                    null /* redirectUrl */);
-            // Queue up a re-evaluation with backoff.
-            //
-            // TODO: Consider abandoning this state after a few attempts and
-            // transitioning back to EvaluatingState, to perhaps give ourselves
-            // the opportunity to (re)detect a captive portal or something.
-            //
-            // TODO: distinguish between CMD_EVALUATE_PRIVATE_DNS messages that are caused by server
-            // lookup failures (which should continue to do exponential backoff) and
-            // CMD_EVALUATE_PRIVATE_DNS messages that are caused by user reconfiguration (which
-            // should be processed immediately.
-            sendMessageDelayed(CMD_EVALUATE_PRIVATE_DNS, mPrivateDnsReevalDelayMs);
-            mPrivateDnsReevalDelayMs *= 2;
-            if (mPrivateDnsReevalDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mPrivateDnsReevalDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        private boolean sendPrivateDnsProbe() {
-            // q.v. system/netd/server/dns/DnsTlsTransport.cpp
-            final String oneTimeHostnameSuffix = "-dnsotls-ds.metric.gstatic.com";
-            final String host = UUID.randomUUID().toString().substring(0, 8)
-                    + oneTimeHostnameSuffix;
-            final Stopwatch watch = new Stopwatch().start();
-            boolean success = false;
-            long time;
-            try {
-                final InetAddress[] ips = mNetwork.getAllByName(host);
-                time = watch.stop();
-                final String strIps = Arrays.toString(ips);
-                success = (ips != null && ips.length > 0);
-                validationLog(PROBE_PRIVDNS, host, String.format("%dms: %s", time, strIps));
-            } catch (UnknownHostException uhe) {
-                time = watch.stop();
-                validationLog(PROBE_PRIVDNS, host,
-                        String.format("%dms - Error: %s", time, uhe.getMessage()));
-            }
-            logValidationProbe(time, PROBE_PRIVDNS, success ? DNS_SUCCESS : DNS_FAILURE);
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS, success);
-            return success;
-        }
-    }
-
-    private class ProbingState extends State {
-        private Thread mThread;
-
-        @Override
-        public void enter() {
-            if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
-                //Don't continue to blame UID forever.
-                TrafficStats.clearThreadStatsUid();
-            }
-
-            final int token = ++mProbeToken;
-            mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
-                    isCaptivePortal())));
-            mThread.start();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_PROBE_COMPLETE:
-                    // Ensure that CMD_PROBE_COMPLETE from stale threads are ignored.
-                    if (message.arg1 != mProbeToken) {
-                        return HANDLED;
-                    }
-
-                    final CaptivePortalProbeResult probeResult =
-                            (CaptivePortalProbeResult) message.obj;
-                    mLastProbeTime = SystemClock.elapsedRealtime();
-
-                    if (mCollectDataStallMetrics) {
-                        writeDataStallStats(probeResult);
-                    }
-
-                    if (probeResult.isSuccessful()) {
-                        // Transit EvaluatingPrivateDnsState to get to Validated
-                        // state (even if no Private DNS validation required).
-                        transitionTo(mEvaluatingPrivateDnsState);
-                    } else if (probeResult.isPortal()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                probeResult.redirectUrl);
-                        mLastPortalProbeResult = probeResult;
-                        transitionTo(mCaptivePortalState);
-                    } else if (probeResult.isPartialConnectivity()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                                null /* redirectUrl */);
-                        // Check if disable https probing needed.
-                        maybeDisableHttpsProbing(mAcceptPartialConnectivity);
-                        if (mAcceptPartialConnectivity) {
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            transitionTo(mWaitingForNextProbeState);
-                        }
-                    } else {
-                        logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                null /* redirectUrl */);
-                        transitionTo(mWaitingForNextProbeState);
-                    }
-                    return HANDLED;
-                case EVENT_DNS_NOTIFICATION:
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    // Leave the event to DefaultState.
-                    return NOT_HANDLED;
-                default:
-                    // Wait for probe result and defer events to next state by default.
-                    deferMessage(message);
-                    return HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mThread.isAlive()) {
-                mThread.interrupt();
-            }
-            mThread = null;
-        }
-    }
-
-    // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is
-    // transited from ProbingState. This ensures that the state machine is only in ProbingState
-    // while a probe is in progress, not while waiting to perform the next probe. That allows
-    // ProbingState to defer most messages until the probe is complete, which keeps the code simple
-    // and matches the pre-Q behaviour where probes were a blocking operation performed on the state
-    // machine thread.
-    private class WaitingForNextProbeState extends State {
-        @Override
-        public void enter() {
-            scheduleNextProbe();
-        }
-
-        private void scheduleNextProbe() {
-            final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            sendMessageDelayed(msg, mReevaluateDelayMs);
-            mReevaluateDelayMs *= 2;
-            if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            return NOT_HANDLED;
-        }
-    }
-
-    // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
-    // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
-    // to complete, regardless of how many IP addresses a host has.
-    private static class OneAddressPerFamilyNetwork extends Network {
-        OneAddressPerFamilyNetwork(Network network) {
-            // Always bypass Private DNS.
-            super(network.getPrivateDnsBypassingCopy());
-        }
-
-        @Override
-        public InetAddress[] getAllByName(String host) throws UnknownHostException {
-            final List<InetAddress> addrs = Arrays.asList(super.getAllByName(host));
-
-            // Ensure the address family of the first address is tried first.
-            LinkedHashMap<Class, InetAddress> addressByFamily = new LinkedHashMap<>();
-            addressByFamily.put(addrs.get(0).getClass(), addrs.get(0));
-            Collections.shuffle(addrs);
-
-            for (InetAddress addr : addrs) {
-                addressByFamily.put(addr.getClass(), addr);
-            }
-
-            return addressByFamily.values().toArray(new InetAddress[addressByFamily.size()]);
-        }
-    }
-
-    private boolean getIsCaptivePortalCheckEnabled() {
-        String symbol = CAPTIVE_PORTAL_MODE;
-        int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT;
-        int mode = mDependencies.getSetting(mContext, symbol, defaultValue);
-        return mode != CAPTIVE_PORTAL_MODE_IGNORE;
-    }
-
-    private boolean getUseHttpsValidation() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
-    }
-
-    private String getCaptivePortalServerHttpsUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_https_url,
-                R.string.default_captive_portal_https_url, CAPTIVE_PORTAL_HTTPS_URL);
-    }
-
-    private int getDnsProbeTimeout() {
-        return getIntSetting(mContext, R.integer.config_captive_portal_dns_probe_timeout,
-                CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout);
-    }
-
-    /**
-     * Gets an integer setting from resources or device config
-     *
-     * configResource is used if set, followed by device config if set, followed by defaultResource.
-     * If none of these are set then an exception is thrown.
-     *
-     * TODO: move to a common location such as a ConfigUtils class.
-     * TODO(b/130324939): test that the resources can be overlayed by an RRO package.
-     */
-    @VisibleForTesting
-    int getIntSetting(@NonNull final Context context, @StringRes int configResource,
-            @NonNull String symbol, @StringRes int defaultResource) {
-        final Resources res = context.getResources();
-        try {
-            return res.getInteger(configResource);
-        } catch (Resources.NotFoundException e) {
-            return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                    symbol, res.getInteger(defaultResource));
-        }
-    }
-
-    /**
-     * Get the captive portal server HTTP URL that is configured on the device.
-     *
-     * NetworkMonitor does not use {@link ConnectivityManager#getCaptivePortalServerUrl()} as
-     * it has its own updatable strategies to detect captive portals. The framework only advises
-     * on one URL that can be used, while NetworkMonitor may implement more complex logic.
-     */
-    public String getCaptivePortalServerHttpUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_http_url,
-                R.string.default_captive_portal_http_url, CAPTIVE_PORTAL_HTTP_URL);
-    }
-
-    private int getConsecutiveDnsTimeoutThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD,
-                DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD);
-    }
-
-    private int getDataStallMinEvaluateTime() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL,
-                DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS);
-    }
-
-    private int getDataStallValidDnsTimeThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD,
-                DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS);
-    }
-
-    private int getDataStallEvaluationType() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_EVALUATION_TYPE,
-                DEFAULT_DATA_STALL_EVALUATION_TYPES);
-    }
-
-    private URL[] makeCaptivePortalFallbackUrls() {
-        try {
-            final String firstUrl = mDependencies.getSetting(mContext, CAPTIVE_PORTAL_FALLBACK_URL,
-                    null);
-
-            final URL[] settingProviderUrls;
-            if (!TextUtils.isEmpty(firstUrl)) {
-                final String otherUrls = mDependencies.getDeviceConfigProperty(
-                        NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, "");
-                // otherUrls may be empty, but .split() ignores trailing empty strings
-                final String separator = ",";
-                final String[] urls = (firstUrl + separator + otherUrls).split(separator);
-                settingProviderUrls = convertStrings(urls, this::makeURL, new URL[0]);
-            } else {
-                settingProviderUrls = new URL[0];
-            }
-
-            return getArrayConfig(settingProviderUrls, R.array.config_captive_portal_fallback_urls,
-                    R.array.default_captive_portal_fallback_urls, this::makeURL);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback URLs", e);
-            return new URL[0];
-        }
-    }
-
-    private CaptivePortalProbeSpec[] makeCaptivePortalFallbackProbeSpecs() {
-        try {
-            final String settingsValue = mDependencies.getDeviceConfigProperty(
-                    NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS, null);
-
-            final CaptivePortalProbeSpec[] emptySpecs = new CaptivePortalProbeSpec[0];
-            final CaptivePortalProbeSpec[] providerValue = TextUtils.isEmpty(settingsValue)
-                    ? emptySpecs
-                    : parseCaptivePortalProbeSpecs(settingsValue).toArray(emptySpecs);
-
-            return getArrayConfig(providerValue, R.array.config_captive_portal_fallback_probe_specs,
-                    R.array.default_captive_portal_fallback_probe_specs,
-                    CaptivePortalProbeSpec::parseSpecOrNull);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback probe specs", e);
-            return null;
-        }
-    }
-
-    /**
-     * Read a setting from a resource or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider value, then the default
-     * resource value.
-     * @param context The context
-     * @param configResource The resource id for the configuration parameter
-     * @param defaultResource The resource id for the default value
-     * @param symbol The symbol in the settings provider
-     * @return The best available value
-     */
-    @NonNull
-    private String getSettingFromResource(@NonNull final Context context,
-            @StringRes int configResource, @StringRes int defaultResource,
-            @NonNull String symbol) {
-        final Resources res = context.getResources();
-        String setting = res.getString(configResource);
-
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        setting = mDependencies.getSetting(context, symbol, null);
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        return res.getString(defaultResource);
-    }
-
-    /**
-     * Get an array configuration from resources or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider values, then the default
-     * resource values.
-     * @param providerValue Values obtained from the setting provider.
-     * @param configResId ID of the configuration resource.
-     * @param defaultResId ID of the default resource.
-     * @param resourceConverter Converter from the resource strings to stored setting class. Null
-     *                          return values are ignored.
-     */
-    private <T> T[] getArrayConfig(@NonNull T[] providerValue, @ArrayRes int configResId,
-            @ArrayRes int defaultResId, @NonNull Function<String, T> resourceConverter) {
-        final Resources res = mContext.getResources();
-        String[] configValue = res.getStringArray(configResId);
-
-        if (configValue.length == 0) {
-            if (providerValue.length > 0) {
-                return providerValue;
-            }
-
-            configValue = res.getStringArray(defaultResId);
-        }
-
-        return convertStrings(configValue, resourceConverter, Arrays.copyOf(providerValue, 0));
-    }
-
-    /**
-     * Convert a String array to an array of some other type using the specified converter.
-     *
-     * <p>Any null value, or value for which the converter throws a {@link RuntimeException}, will
-     * not be added to the output array, so the output array may be smaller than the input.
-     */
-    private <T> T[] convertStrings(
-            @NonNull String[] strings, Function<String, T> converter, T[] emptyArray) {
-        final ArrayList<T> convertedValues = new ArrayList<>(strings.length);
-        for (String configString : strings) {
-            T convertedValue = null;
-            try {
-                convertedValue = converter.apply(configString);
-            } catch (Exception e) {
-                Log.e(TAG, "Error parsing configuration", e);
-                // Fall through
-            }
-            if (convertedValue != null) {
-                convertedValues.add(convertedValue);
-            }
-        }
-        return convertedValues.toArray(emptyArray);
-    }
-
-    private String getCaptivePortalUserAgent() {
-        return mDependencies.getDeviceConfigProperty(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USER_AGENT, DEFAULT_USER_AGENT);
-    }
-
-    private URL nextFallbackUrl() {
-        if (mCaptivePortalFallbackUrls.length == 0) {
-            return null;
-        }
-        int idx = Math.abs(mNextFallbackUrlIndex) % mCaptivePortalFallbackUrls.length;
-        mNextFallbackUrlIndex += mRandom.nextInt(); // randomly change url without memory.
-        return mCaptivePortalFallbackUrls[idx];
-    }
-
-    private CaptivePortalProbeSpec nextFallbackSpec() {
-        if (isEmpty(mCaptivePortalFallbackSpecs)) {
-            return null;
-        }
-        // Randomly change spec without memory. Also randomize the first attempt.
-        final int idx = Math.abs(mRandom.nextInt()) % mCaptivePortalFallbackSpecs.length;
-        return mCaptivePortalFallbackSpecs[idx];
-    }
-
-    @VisibleForTesting
-    protected CaptivePortalProbeResult isCaptivePortal() {
-        if (!mIsCaptivePortalCheckEnabled) {
-            validationLog("Validation disabled.");
-            return CaptivePortalProbeResult.SUCCESS;
-        }
-
-        URL pacUrl = null;
-        URL httpsUrl = mCaptivePortalHttpsUrl;
-        URL httpUrl = mCaptivePortalHttpUrl;
-
-        // On networks with a PAC instead of fetching a URL that should result in a 204
-        // response, we instead simply fetch the PAC script.  This is done for a few reasons:
-        // 1. At present our PAC code does not yet handle multiple PACs on multiple networks
-        //    until something like https://android-review.googlesource.com/#/c/115180/ lands.
-        //    Network.openConnection() will ignore network-specific PACs and instead fetch
-        //    using NO_PROXY.  If a PAC is in place, the only fetch we know will succeed with
-        //    NO_PROXY is the fetch of the PAC itself.
-        // 2. To proxy the generate_204 fetch through a PAC would require a number of things
-        //    happen before the fetch can commence, namely:
-        //        a) the PAC script be fetched
-        //        b) a PAC script resolver service be fired up and resolve the captive portal
-        //           server.
-        //    Network validation could be delayed until these prerequisities are satisifed or
-        //    could simply be left to race them.  Neither is an optimal solution.
-        // 3. PAC scripts are sometimes used to block or restrict Internet access and may in
-        //    fact block fetching of the generate_204 URL which would lead to false negative
-        //    results for network validation.
-        final ProxyInfo proxyInfo = mLinkProperties.getHttpProxy();
-        if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
-            pacUrl = makeURL(proxyInfo.getPacFileUrl().toString());
-            if (pacUrl == null) {
-                return CaptivePortalProbeResult.FAILED;
-            }
-        }
-
-        if ((pacUrl == null) && (httpUrl == null || httpsUrl == null)) {
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        long startTime = SystemClock.elapsedRealtime();
-
-        final CaptivePortalProbeResult result;
-        if (pacUrl != null) {
-            result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        } else if (mUseHttps) {
-            // Probe results are reported inside sendParallelHttpProbes.
-            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
-        } else {
-            result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        }
-
-        long endTime = SystemClock.elapsedRealtime();
-
-        sendNetworkConditionsBroadcast(true /* response received */,
-                result.isPortal() /* isCaptivePortal */,
-                startTime, endTime);
-
-        log("isCaptivePortal: isSuccessful()=" + result.isSuccessful()
-                + " isPortal()=" + result.isPortal()
-                + " RedirectUrl=" + result.redirectUrl
-                + " isPartialConnectivity()=" + result.isPartialConnectivity()
-                + " Time=" + (endTime - startTime) + "ms");
-
-        return result;
-    }
-
-    /**
-     * Do a DNS resolution and URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    private CaptivePortalProbeResult sendDnsAndHttpProbes(ProxyInfo proxy, URL url, int probeType) {
-        // Pre-resolve the captive portal server host so we can log it.
-        // Only do this if HttpURLConnection is about to, to avoid any potentially
-        // unnecessary resolution.
-        final String host = (proxy != null) ? proxy.getHost() : url.getHost();
-        // This method cannot safely report probe results because it might not be running on the
-        // state machine thread. Reporting results here would cause races and potentially send
-        // information to callers that does not make sense because the state machine has already
-        // changed state.
-        sendDnsProbe(host);
-        return sendHttpProbe(url, probeType, null);
-    }
-
-    /** Do a DNS lookup for the given server, or throw UnknownHostException after timeoutMs */
-    @VisibleForTesting
-    protected InetAddress[] sendDnsProbeWithTimeout(String host, int timeoutMs)
-                throws UnknownHostException {
-        return DnsUtils.getAllByName(mDependencies.getDnsResolver(), mCleartextDnsNetwork, host,
-                TYPE_ADDRCONFIG, FLAG_EMPTY, timeoutMs);
-    }
-
-    /** Do a DNS resolution of the given server. */
-    private void sendDnsProbe(String host) {
-        if (TextUtils.isEmpty(host)) {
-            return;
-        }
-
-        final String name = ValidationProbeEvent.getProbeName(ValidationProbeEvent.PROBE_DNS);
-        final Stopwatch watch = new Stopwatch().start();
-        int result;
-        String connectInfo;
-        try {
-            InetAddress[] addresses = sendDnsProbeWithTimeout(host, getDnsProbeTimeout());
-            StringBuffer buffer = new StringBuffer();
-            for (InetAddress address : addresses) {
-                buffer.append(',').append(address.getHostAddress());
-            }
-            result = ValidationProbeEvent.DNS_SUCCESS;
-            connectInfo = "OK " + buffer.substring(1);
-        } catch (UnknownHostException e) {
-            result = ValidationProbeEvent.DNS_FAILURE;
-            connectInfo = "FAIL";
-        }
-        final long latency = watch.stop();
-        validationLog(ValidationProbeEvent.PROBE_DNS, host,
-                String.format("%dms %s", latency, connectInfo));
-        logValidationProbe(latency, ValidationProbeEvent.PROBE_DNS, result);
-    }
-
-    /**
-     * Do a URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    @VisibleForTesting
-    protected CaptivePortalProbeResult sendHttpProbe(URL url, int probeType,
-            @Nullable CaptivePortalProbeSpec probeSpec) {
-        HttpURLConnection urlConnection = null;
-        int httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-        String redirectUrl = null;
-        final Stopwatch probeTimer = new Stopwatch().start();
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-        try {
-            urlConnection = (HttpURLConnection) mCleartextDnsNetwork.openConnection(url);
-            urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
-            urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setRequestProperty("Connection", "close");
-            urlConnection.setUseCaches(false);
-            if (mCaptivePortalUserAgent != null) {
-                urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent);
-            }
-            // cannot read request header after connection
-            String requestHeader = urlConnection.getRequestProperties().toString();
-
-            // Time how long it takes to get a response to our request
-            long requestTimestamp = SystemClock.elapsedRealtime();
-
-            httpResponseCode = urlConnection.getResponseCode();
-            redirectUrl = urlConnection.getHeaderField("location");
-
-            // Time how long it takes to get a response to our request
-            long responseTimestamp = SystemClock.elapsedRealtime();
-
-            validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms"
-                    + " ret=" + httpResponseCode
-                    + " request=" + requestHeader
-                    + " headers=" + urlConnection.getHeaderFields());
-            // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
-            // portal.  The only example of this seen so far was a captive portal.  For
-            // the time being go with prior behavior of assuming it's not a captive
-            // portal.  If it is considered a captive portal, a different sign-in URL
-            // is needed (i.e. can't browse a 204).  This could be the result of an HTTP
-            // proxy server.
-            if (httpResponseCode == 200) {
-                long contentLength = urlConnection.getContentLengthLong();
-                if (probeType == ValidationProbeEvent.PROBE_PAC) {
-                    validationLog(
-                            probeType, url, "PAC fetch 200 response interpreted as 204 response.");
-                    httpResponseCode = CaptivePortalProbeResult.SUCCESS_CODE;
-                } else if (contentLength == -1) {
-                    // When no Content-length (default value == -1), attempt to read a byte
-                    // from the response. Do not use available() as it is unreliable.
-                    // See http://b/33498325.
-                    if (urlConnection.getInputStream().read() == -1) {
-                        validationLog(probeType, url,
-                                "Empty 200 response interpreted as failed response.");
-                        httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                    }
-                } else if (contentLength <= 4) {
-                    // Consider 200 response with "Content-length <= 4" to not be a captive
-                    // portal. There's no point in considering this a captive portal as the
-                    // user cannot sign-in to an empty page. Probably the result of a broken
-                    // transparent proxy. See http://b/9972012 and http://b/122999481.
-                    validationLog(probeType, url, "200 response with Content-length <= 4"
-                            + " interpreted as failed response.");
-                    httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                }
-            }
-        } catch (IOException e) {
-            validationLog(probeType, url, "Probe failed with exception " + e);
-            if (httpResponseCode == CaptivePortalProbeResult.FAILED_CODE) {
-                // TODO: Ping gateway and DNS server and log results.
-            }
-        } finally {
-            if (urlConnection != null) {
-                urlConnection.disconnect();
-            }
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);
-
-        if (probeSpec == null) {
-            return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
-        } else {
-            return probeSpec.getResult(httpResponseCode, redirectUrl);
-        }
-    }
-
-    private CaptivePortalProbeResult sendParallelHttpProbes(
-            ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
-        // Number of probes to wait for. If a probe completes with a conclusive answer
-        // it shortcuts the latch immediately by forcing the count to 0.
-        final CountDownLatch latch = new CountDownLatch(2);
-
-        final class ProbeThread extends Thread {
-            private final boolean mIsHttps;
-            private volatile CaptivePortalProbeResult mResult = CaptivePortalProbeResult.FAILED;
-
-            ProbeThread(boolean isHttps) {
-                mIsHttps = isHttps;
-            }
-
-            public CaptivePortalProbeResult result() {
-                return mResult;
-            }
-
-            @Override
-            public void run() {
-                if (mIsHttps) {
-                    mResult =
-                            sendDnsAndHttpProbes(proxy, httpsUrl, ValidationProbeEvent.PROBE_HTTPS);
-                } else {
-                    mResult = sendDnsAndHttpProbes(proxy, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-                }
-                if ((mIsHttps && mResult.isSuccessful()) || (!mIsHttps && mResult.isPortal())) {
-                    // Stop waiting immediately if https succeeds or if http finds a portal.
-                    while (latch.getCount() > 0) {
-                        latch.countDown();
-                    }
-                }
-                // Signal this probe has completed.
-                latch.countDown();
-            }
-        }
-
-        final ProbeThread httpsProbe = new ProbeThread(true);
-        final ProbeThread httpProbe = new ProbeThread(false);
-
-        try {
-            httpsProbe.start();
-            httpProbe.start();
-            latch.await(PROBE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            validationLog("Error: probes wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        final CaptivePortalProbeResult httpsResult = httpsProbe.result();
-        final CaptivePortalProbeResult httpResult = httpProbe.result();
-
-        // Look for a conclusive probe result first.
-        if (httpResult.isPortal()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpResult);
-            return httpResult;
-        }
-        // httpsResult.isPortal() is not expected, but check it nonetheless.
-        if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsResult);
-            return httpsResult;
-        }
-        // If a fallback method exists, use it to retry portal detection.
-        // If we have new-style probe specs, use those. Otherwise, use the fallback URLs.
-        final CaptivePortalProbeSpec probeSpec = nextFallbackSpec();
-        final URL fallbackUrl = (probeSpec != null) ? probeSpec.getUrl() : nextFallbackUrl();
-        CaptivePortalProbeResult fallbackProbeResult = null;
-        if (fallbackUrl != null) {
-            fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_FALLBACK, fallbackProbeResult);
-            if (fallbackProbeResult.isPortal()) {
-                return fallbackProbeResult;
-            }
-        }
-        // Otherwise wait until http and https probes completes and use their results.
-        try {
-            httpProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpProbe.result());
-
-            if (httpProbe.result().isPortal()) {
-                return httpProbe.result();
-            }
-
-            httpsProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsProbe.result());
-
-            final boolean isHttpSuccessful =
-                    (httpProbe.result().isSuccessful()
-                    || (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
-            if (httpsProbe.result().isFailed() && isHttpSuccessful) {
-                return CaptivePortalProbeResult.PARTIAL;
-            }
-            return httpsProbe.result();
-        } catch (InterruptedException e) {
-            validationLog("Error: http or https probe wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-    }
-
-    private URL makeURL(String url) {
-        if (url != null) {
-            try {
-                return new URL(url);
-            } catch (MalformedURLException e) {
-                validationLog("Bad URL: " + url);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param responseReceived - whether or not we received a valid HTTP response to our request.
-     * If false, isCaptivePortal and responseTimestampMs are ignored
-     * TODO: This should be moved to the transports.  The latency could be passed to the transports
-     * along with the captive portal result.  Currently the TYPE_MOBILE broadcasts appear unused so
-     * perhaps this could just be added to the WiFi transport only.
-     */
-    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
-            long requestTimestampMs, long responseTimestampMs) {
-        Intent latencyBroadcast =
-                new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED);
-        if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) {
-            if (!mWifiManager.isScanAlwaysAvailable()) {
-                return;
-            }
-
-            WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
-            if (currentWifiInfo != null) {
-                // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
-                // surrounded by double quotation marks (thus violating the Javadoc), but this
-                // was changed to match the Javadoc in API 17. Since clients may have started
-                // sanitizing the output of this method since API 17 was released, we should
-                // not change it here as it would become impossible to tell whether the SSID is
-                // simply being surrounded by quotes due to the API, or whether those quotes
-                // are actually part of the SSID.
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_SSID,
-                        currentWifiInfo.getSSID());
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_BSSID,
-                        currentWifiInfo.getBSSID());
-            } else {
-                if (VDBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
-                return;
-            }
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_WIFI);
-        } else if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
-            // TODO(b/123893112): Support multi-sim.
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_NETWORK_TYPE,
-                    mTelephonyManager.getNetworkType());
-            final ServiceState dataSs = mTelephonyManager.getServiceState();
-            if (dataSs == null) {
-                logw("failed to retrieve ServiceState");
-                return;
-            }
-            // See if the data sub is registered for PS services on cell.
-            final NetworkRegistrationInfo nri = dataSs.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS,
-                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            latencyBroadcast.putExtra(
-                    NetworkMonitorUtils.EXTRA_CELL_ID,
-                    nri == null ? null : nri.getCellIdentity());
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE);
-        } else {
-            return;
-        }
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_RECEIVED,
-                responseReceived);
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_REQUEST_TIMESTAMP_MS,
-                requestTimestampMs);
-
-        if (responseReceived) {
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_IS_CAPTIVE_PORTAL,
-                    isCaptivePortal);
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_TIMESTAMP_MS,
-                    responseTimestampMs);
-        }
-        mContext.sendBroadcastAsUser(latencyBroadcast, UserHandle.CURRENT,
-                NetworkMonitorUtils.PERMISSION_ACCESS_NETWORK_CONDITIONS);
-    }
-
-    private void logNetworkEvent(int evtype) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, new NetworkEvent(evtype));
-    }
-
-    private int networkEventType(ValidationStage s, EvaluationResult r) {
-        if (s.mIsFirstValidation) {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_PORTAL_FOUND;
-            }
-        } else {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_REVALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_REVALIDATION_PORTAL_FOUND;
-            }
-        }
-    }
-
-    private void maybeLogEvaluationResult(int evtype) {
-        if (mEvaluationTimer.isRunning()) {
-            int[] transports = mNetworkCapabilities.getTransportTypes();
-            mMetricsLog.log(mCleartextDnsNetwork, transports,
-                    new NetworkEvent(evtype, mEvaluationTimer.stop()));
-            mEvaluationTimer.reset();
-        }
-    }
-
-    private void logValidationProbe(long durationMs, int probeType, int probeResult) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        boolean isFirstValidation = validationStage().mIsFirstValidation;
-        ValidationProbeEvent ev = new ValidationProbeEvent.Builder()
-                .setProbeType(probeType, isFirstValidation)
-                .setReturnCode(probeResult)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, ev);
-    }
-
-    @VisibleForTesting
-    static class Dependencies {
-        public Network getPrivateDnsBypassNetwork(Network network) {
-            return new OneAddressPerFamilyNetwork(network);
-        }
-
-        public DnsResolver getDnsResolver() {
-            return DnsResolver.getInstance();
-        }
-
-        public Random getRandom() {
-            return new Random();
-        }
-
-        /**
-         * Get the value of a global integer setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public int getSetting(Context context, String symbol, int defaultValue) {
-            return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue);
-        }
-
-        /**
-         * Get the value of a global String setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public String getSetting(Context context, String symbol, String defaultValue) {
-            final String value = Settings.Global.getString(context.getContentResolver(), symbol);
-            return value != null ? value : defaultValue;
-        }
-
-        /**
-         * Look up the value of a property in DeviceConfig.
-         * @param namespace The namespace containing the property to look up.
-         * @param name The name of the property to look up.
-         * @param defaultValue The value to return if the property does not exist or has no non-null
-         *                     value.
-         * @return the corresponding value, or defaultValue if none exists.
-         */
-        @Nullable
-        public String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-                @Nullable String defaultValue) {
-            return NetworkStackUtils.getDeviceConfigProperty(namespace, name, defaultValue);
-        }
-
-        /**
-         * Look up the value of a property in DeviceConfig.
-         * @param namespace The namespace containing the property to look up.
-         * @param name The name of the property to look up.
-         * @param defaultValue The value to return if the property does not exist or has no non-null
-         *                     value.
-         * @return the corresponding value, or defaultValue if none exists.
-         */
-        public int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-                int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
-        }
-
-        public static final Dependencies DEFAULT = new Dependencies();
-    }
-
-    /**
-     * Methods in this class perform no locking because all accesses are performed on the state
-     * machine's thread. Need to consider the thread safety if it ever could be accessed outside the
-     * state machine.
-     */
-    @VisibleForTesting
-    protected class DnsStallDetector {
-        private int mConsecutiveTimeoutCount = 0;
-        private int mSize;
-        final DnsResult[] mDnsEvents;
-        final RingBufferIndices mResultIndices;
-
-        DnsStallDetector(int size) {
-            mSize = Math.max(DEFAULT_DNS_LOG_SIZE, size);
-            mDnsEvents = new DnsResult[mSize];
-            mResultIndices = new RingBufferIndices(mSize);
-        }
-
-        @VisibleForTesting
-        protected void accumulateConsecutiveDnsTimeoutCount(int code) {
-            final DnsResult result = new DnsResult(code);
-            mDnsEvents[mResultIndices.add()] = result;
-            if (result.isTimeout()) {
-                mConsecutiveTimeoutCount++;
-            } else {
-                // Keep the event in mDnsEvents without clearing it so that there are logs to do the
-                // simulation and analysis.
-                mConsecutiveTimeoutCount = 0;
-            }
-        }
-
-        private boolean isDataStallSuspected(int timeoutCountThreshold, int validTime) {
-            if (timeoutCountThreshold <= 0) {
-                Log.wtf(TAG, "Timeout count threshold should be larger than 0.");
-                return false;
-            }
-
-            // Check if the consecutive timeout count reach the threshold or not.
-            if (mConsecutiveTimeoutCount < timeoutCountThreshold) {
-                return false;
-            }
-
-            // Check if the target dns event index is valid or not.
-            final int firstConsecutiveTimeoutIndex =
-                    mResultIndices.indexOf(mResultIndices.size() - timeoutCountThreshold);
-
-            // If the dns timeout events happened long time ago, the events are meaningless for
-            // data stall evaluation. Thus, check if the first consecutive timeout dns event
-            // considered in the evaluation happened in defined threshold time.
-            final long now = SystemClock.elapsedRealtime();
-            final long firstTimeoutTime = now - mDnsEvents[firstConsecutiveTimeoutIndex].mTimeStamp;
-            return (firstTimeoutTime < validTime);
-        }
-
-        int getConsecutiveTimeoutCount() {
-            return mConsecutiveTimeoutCount;
-        }
-    }
-
-    private static class DnsResult {
-        // TODO: Need to move the DNS return code definition to a specific class once unify DNS
-        // response code is done.
-        private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-
-        private final long mTimeStamp;
-        private final int mReturnCode;
-
-        DnsResult(int code) {
-            mTimeStamp = SystemClock.elapsedRealtime();
-            mReturnCode = code;
-        }
-
-        private boolean isTimeout() {
-            return mReturnCode == RETURN_CODE_DNS_TIMEOUT;
-        }
-    }
-
-
-    @VisibleForTesting
-    protected DnsStallDetector getDnsStallDetector() {
-        return mDnsStallDetector;
-    }
-
-    private boolean dataStallEvaluateTypeEnabled(int type) {
-        return (mDataStallEvaluationType & type) != 0;
-    }
-
-    @VisibleForTesting
-    protected long getLastProbeTime() {
-        return mLastProbeTime;
-    }
-
-    @VisibleForTesting
-    protected boolean isDataStall() {
-        boolean result = false;
-        // Reevaluation will generate traffic. Thus, set a minimal reevaluation timer to limit the
-        // possible traffic cost in metered network.
-        if (!mNetworkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
-                && (SystemClock.elapsedRealtime() - getLastProbeTime()
-                < mDataStallMinEvaluateTime)) {
-            return false;
-        }
-
-        // Check dns signal. Suspect it may be a data stall if both :
-        // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold.
-        // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms.
-        if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) {
-            if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold,
-                    mDataStallValidDnsTimeThreshold)) {
-                result = true;
-                logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND);
-            }
-        }
-
-        if (VDBG_STALL) {
-            log("isDataStall: result=" + result + ", consecutive dns timeout count="
-                    + mDnsStallDetector.getConsecutiveTimeoutCount());
-        }
-
-        return result;
-    }
-
-    // Class to keep state of evaluation results and probe results.
-    // The main purpose is to ensure NetworkMonitor can notify ConnectivityService of probe results
-    // as soon as they happen, without triggering any other changes. This requires keeping state on
-    // the most recent evaluation result. Calling reportProbeResult will ensure that the results
-    // reported to ConnectivityService contain the previous evaluation result, and thus won't
-    // trigger a validation or partial connectivity state change.
-    @VisibleForTesting
-    protected class EvaluationState {
-        // The latest validation result for this network. This is a bitmask of
-        // INetworkMonitor.NETWORK_VALIDATION_RESULT_* constants.
-        private int mEvaluationResult = NETWORK_VALIDATION_RESULT_INVALID;
-        // Indicates which probes have completed since clearProbeResults was called.
-        // This is a bitmask of INetworkMonitor.NETWORK_VALIDATION_PROBE_* constants.
-        private int mProbeResults = 0;
-        // The latest redirect URL.
-        private String mRedirectUrl;
-
-        protected void clearProbeResults() {
-            mProbeResults = 0;
-        }
-
-        // Probe result for http probe should be updated from reportHttpProbeResult().
-        protected void reportProbeResult(int probeResult, boolean succeeded) {
-            if (succeeded) {
-                mProbeResults |= probeResult;
-            } else {
-                mProbeResults &= ~probeResult;
-            }
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected void reportEvaluationResult(int result, @Nullable String redirectUrl) {
-            mEvaluationResult = result;
-            mRedirectUrl = redirectUrl;
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected int getNetworkTestResult() {
-            return mEvaluationResult | mProbeResults;
-        }
-    }
-
-    @VisibleForTesting
-    protected EvaluationState getEvaluationState() {
-        return mEvaluationState;
-    }
-
-    private void maybeDisableHttpsProbing(boolean acceptPartial) {
-        mAcceptPartialConnectivity = acceptPartial;
-        // Ignore https probe in next validation if user accept partial connectivity on a partial
-        // connectivity network.
-        if (((mEvaluationState.getNetworkTestResult() & NETWORK_VALIDATION_RESULT_PARTIAL) != 0)
-                && mAcceptPartialConnectivity) {
-            mUseHttps = false;
-        }
-    }
-
-    // Report HTTP, HTTP or FALLBACK probe result.
-    @VisibleForTesting
-    protected void reportHttpProbeResult(int probeResult,
-                @NonNull final CaptivePortalProbeResult result) {
-        boolean succeeded = result.isSuccessful();
-        // The success of a HTTP probe does not tell us whether the DNS probe succeeded.
-        // The DNS and HTTP probes run one after the other in sendDnsAndHttpProbes, and that
-        // method cannot report the result of the DNS probe because that it could be running
-        // on a different thread which is racing with the main state machine thread. So, if
-        // an HTTP or HTTPS probe succeeded, assume that the DNS probe succeeded. But if an
-        // HTTP or HTTPS probe failed, don't assume that DNS is not working.
-        // TODO: fix this.
-        if (succeeded) {
-            probeResult |= NETWORK_VALIDATION_PROBE_DNS;
-        }
-        mEvaluationState.reportProbeResult(probeResult, succeeded);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
deleted file mode 100644
index a538a5b..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright (C) 2019 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.connectivity.ipmemorystore;
-
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteCursor;
-import android.database.sqlite.SQLiteCursorDriver;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQuery;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.Status;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-/**
- * Encapsulating class for using the SQLite database backing the memory store.
- *
- * This class groups together the contracts and the SQLite helper used to
- * use the database.
- *
- * @hide
- */
-public class IpMemoryStoreDatabase {
-    private static final String TAG = IpMemoryStoreDatabase.class.getSimpleName();
-    // A pair of NetworkAttributes objects is group-close if the confidence that they are
-    // the same is above this cutoff. See NetworkAttributes and SameL3NetworkResponse.
-    private static final float GROUPCLOSE_CONFIDENCE = 0.5f;
-
-    /**
-     * Contract class for the Network Attributes table.
-     */
-    public static class NetworkAttributesContract {
-        public static final String TABLENAME = "NetworkAttributes";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_EXPIRYDATE = "expiryDate";
-        // Milliseconds since the Epoch, in true Java style
-        public static final String COLTYPE_EXPIRYDATE = "BIGINT";
-
-        public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address";
-        public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER";
-
-        public static final String COLNAME_ASSIGNEDV4ADDRESSEXPIRY = "assignedV4AddressExpiry";
-        // The lease expiry timestamp in uint of milliseconds
-        public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT";
-
-        // Please note that the group hint is only a *hint*, hence its name. The client can offer
-        // this information to nudge the grouping in the decision it thinks is right, but it can't
-        // decide for the memory store what is the same L3 network.
-        public static final String COLNAME_GROUPHINT = "groupHint";
-        public static final String COLTYPE_GROUPHINT = "TEXT";
-
-        public static final String COLNAME_DNSADDRESSES = "dnsAddresses";
-        // Stored in marshalled form as is
-        public static final String COLTYPE_DNSADDRESSES = "BLOB";
-
-        public static final String COLNAME_MTU = "mtu";
-        public static final String COLTYPE_MTU = "INTEGER DEFAULT -1";
-
-        public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME                       + " ("
-                + COLNAME_L2KEY                   + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
-                + COLNAME_EXPIRYDATE              + " " + COLTYPE_EXPIRYDATE              + ", "
-                + COLNAME_ASSIGNEDV4ADDRESS       + " " + COLTYPE_ASSIGNEDV4ADDRESS       + ", "
-                + COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", "
-                + COLNAME_GROUPHINT               + " " + COLTYPE_GROUPHINT               + ", "
-                + COLNAME_DNSADDRESSES            + " " + COLTYPE_DNSADDRESSES            + ", "
-                + COLNAME_MTU                     + " " + COLTYPE_MTU                     + ")";
-        public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
-    }
-
-    /**
-     * Contract class for the Private Data table.
-     */
-    public static class PrivateDataContract {
-        public static final String TABLENAME = "PrivateData";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_CLIENT = "client";
-        public static final String COLTYPE_CLIENT = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATANAME = "dataName";
-        public static final String COLTYPE_DATANAME = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATA = "data";
-        public static final String COLTYPE_DATA = "BLOB NOT NULL";
-
-        public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME        + " ("
-                + COLNAME_L2KEY    + " " + COLTYPE_L2KEY    + ", "
-                + COLNAME_CLIENT   + " " + COLTYPE_CLIENT   + ", "
-                + COLNAME_DATANAME + " " + COLTYPE_DATANAME + ", "
-                + COLNAME_DATA     + " " + COLTYPE_DATA     + ", "
-                + "PRIMARY KEY ("
-                + COLNAME_L2KEY    + ", "
-                + COLNAME_CLIENT   + ", "
-                + COLNAME_DATANAME + "))";
-        public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
-    }
-
-    // To save memory when the DB is not used, close it after 30s of inactivity. This is
-    // determined manually based on what feels right.
-    private static final long IDLE_CONNECTION_TIMEOUT_MS = 30_000;
-
-    /** The SQLite DB helper */
-    public static class DbHelper extends SQLiteOpenHelper {
-        // Update this whenever changing the schema.
-        private static final int SCHEMA_VERSION = 4;
-        private static final String DATABASE_FILENAME = "IpMemoryStore.db";
-        private static final String TRIGGER_NAME = "delete_cascade_to_private";
-
-        public DbHelper(@NonNull final Context context) {
-            super(context, DATABASE_FILENAME, null, SCHEMA_VERSION);
-            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
-        }
-
-        /** Called when the database is created */
-        @Override
-        public void onCreate(@NonNull final SQLiteDatabase db) {
-            db.execSQL(NetworkAttributesContract.CREATE_TABLE);
-            db.execSQL(PrivateDataContract.CREATE_TABLE);
-            createTrigger(db);
-        }
-
-        /** Called when the database is upgraded */
-        @Override
-        public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
-                final int newVersion) {
-            try {
-                if (oldVersion < 2) {
-                    // upgrade from version 1 to version 2
-                    // since we starts from version 2, do nothing here
-                }
-
-                if (oldVersion < 3) {
-                    // upgrade from version 2 to version 3
-                    final String sqlUpgradeAddressExpiry = "alter table"
-                            + " " + NetworkAttributesContract.TABLENAME + " ADD"
-                            + " " + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY
-                            + " " + NetworkAttributesContract.COLTYPE_ASSIGNEDV4ADDRESSEXPIRY;
-                    db.execSQL(sqlUpgradeAddressExpiry);
-                }
-
-                if (oldVersion < 4) {
-                    createTrigger(db);
-                }
-            } catch (SQLiteException e) {
-                Log.e(TAG, "Could not upgrade to the new version", e);
-                // create database with new version
-                db.execSQL(NetworkAttributesContract.DROP_TABLE);
-                db.execSQL(PrivateDataContract.DROP_TABLE);
-                onCreate(db);
-            }
-        }
-
-        /** Called when the database is downgraded */
-        @Override
-        public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion,
-                final int newVersion) {
-            // Downgrades always nuke all data and recreate an empty table.
-            db.execSQL(NetworkAttributesContract.DROP_TABLE);
-            db.execSQL(PrivateDataContract.DROP_TABLE);
-            db.execSQL("DROP TRIGGER " + TRIGGER_NAME);
-            onCreate(db);
-        }
-
-        private void createTrigger(@NonNull final SQLiteDatabase db) {
-            final String createTrigger = "CREATE TRIGGER " + TRIGGER_NAME
-                    + " DELETE ON " + NetworkAttributesContract.TABLENAME
-                    + " BEGIN"
-                    + " DELETE FROM " + PrivateDataContract.TABLENAME + " WHERE OLD."
-                    + NetworkAttributesContract.COLNAME_L2KEY
-                    + "=" + PrivateDataContract.COLNAME_L2KEY
-                    + "; END;";
-            db.execSQL(createTrigger);
-        }
-    }
-
-    @NonNull
-    private static byte[] encodeAddressList(@NonNull final List<InetAddress> addresses) {
-        final ByteArrayOutputStream os = new ByteArrayOutputStream();
-        for (final InetAddress address : addresses) {
-            final byte[] b = address.getAddress();
-            os.write(b.length);
-            os.write(b, 0, b.length);
-        }
-        return os.toByteArray();
-    }
-
-    @NonNull
-    private static ArrayList<InetAddress> decodeAddressList(@NonNull final byte[] encoded) {
-        final ByteArrayInputStream is = new ByteArrayInputStream(encoded);
-        final ArrayList<InetAddress> addresses = new ArrayList<>();
-        int d = -1;
-        while ((d = is.read()) != -1) {
-            final byte[] bytes = new byte[d];
-            is.read(bytes, 0, d);
-            try {
-                addresses.add(InetAddress.getByAddress(bytes));
-            } catch (UnknownHostException e) { /* Hopefully impossible */ }
-        }
-        return addresses;
-    }
-
-    @NonNull
-    private static ContentValues toContentValues(@Nullable final NetworkAttributes attributes) {
-        final ContentValues values = new ContentValues();
-        if (null == attributes) return values;
-        if (null != attributes.assignedV4Address) {
-            values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS,
-                    inet4AddressToIntHTH(attributes.assignedV4Address));
-        }
-        if (null != attributes.assignedV4AddressExpiry) {
-            values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY,
-                    attributes.assignedV4AddressExpiry);
-        }
-        if (null != attributes.groupHint) {
-            values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint);
-        }
-        if (null != attributes.dnsAddresses) {
-            values.put(NetworkAttributesContract.COLNAME_DNSADDRESSES,
-                    encodeAddressList(attributes.dnsAddresses));
-        }
-        if (null != attributes.mtu) {
-            values.put(NetworkAttributesContract.COLNAME_MTU, attributes.mtu);
-        }
-        return values;
-    }
-
-    // Convert a NetworkAttributes object to content values to store them in a table compliant
-    // with the contract defined in NetworkAttributesContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @Nullable final NetworkAttributes attributes, final long expiry) {
-        final ContentValues values = toContentValues(attributes);
-        values.put(NetworkAttributesContract.COLNAME_L2KEY, key);
-        values.put(NetworkAttributesContract.COLNAME_EXPIRYDATE, expiry);
-        return values;
-    }
-
-    // Convert a byte array into content values to store it in a table compliant with the
-    // contract defined in PrivateDataContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name,
-            @NonNull final byte[] data) {
-        final ContentValues values = new ContentValues();
-        values.put(PrivateDataContract.COLNAME_L2KEY, key);
-        values.put(PrivateDataContract.COLNAME_CLIENT, clientId);
-        values.put(PrivateDataContract.COLNAME_DATANAME, name);
-        values.put(PrivateDataContract.COLNAME_DATA, data);
-        return values;
-    }
-
-    @Nullable
-    private static NetworkAttributes readNetworkAttributesLine(@NonNull final Cursor cursor) {
-        // Make sure the data hasn't expired
-        final long expiry = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, -1L);
-        if (expiry < System.currentTimeMillis()) return null;
-
-        final NetworkAttributes.Builder builder = new NetworkAttributes.Builder();
-        final int assignedV4AddressInt = getInt(cursor,
-                NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0);
-        final long assignedV4AddressExpiry = getLong(cursor,
-                NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0);
-        final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT);
-        final byte[] dnsAddressesBlob =
-                getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
-        final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1);
-        if (0 != assignedV4AddressInt) {
-            builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt));
-        }
-        if (0 != assignedV4AddressExpiry) {
-            builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
-        }
-        builder.setGroupHint(groupHint);
-        if (null != dnsAddressesBlob) {
-            builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));
-        }
-        if (mtu >= 0) {
-            builder.setMtu(mtu);
-        }
-        return builder.build();
-    }
-
-    private static final String[] EXPIRY_COLUMN = new String[] {
-        NetworkAttributesContract.COLNAME_EXPIRYDATE
-    };
-    static final int EXPIRY_ERROR = -1; // Legal values for expiry are positive
-
-    static final String SELECT_L2KEY = NetworkAttributesContract.COLNAME_L2KEY + " = ?";
-
-    // Returns the expiry date of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static long getExpiry(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                EXPIRY_COLUMN, // columns
-                SELECT_L2KEY, // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null // orderBy
-        );
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return EXPIRY_ERROR;
-        cursor.moveToFirst();
-        final long result = cursor.getLong(0); // index in the EXPIRY_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    static final int RELEVANCE_ERROR = -1; // Legal values for relevance are positive
-
-    // Returns the relevance of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static int getRelevance(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final long expiry = getExpiry(db, key);
-        return expiry < 0 ? (int) expiry : RelevanceUtils.computeRelevanceForNow(expiry);
-    }
-
-    // If the attributes are null, this will only write the expiry.
-    // Returns an int out of Status.{SUCCESS, ERROR_*}
-    static int storeNetworkAttributes(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            final long expiry, @Nullable final NetworkAttributes attributes) {
-        final ContentValues cv = toContentValues(key, attributes, expiry);
-        db.beginTransaction();
-        try {
-            // Unfortunately SQLite does not have any way to do INSERT OR UPDATE. Options are
-            // to either insert with on conflict ignore then update (like done here), or to
-            // construct a custom SQL INSERT statement with nested select.
-            final long resultId = db.insertWithOnConflict(NetworkAttributesContract.TABLENAME,
-                    null, cv, SQLiteDatabase.CONFLICT_IGNORE);
-            if (resultId < 0) {
-                db.update(NetworkAttributesContract.TABLENAME, cv, SELECT_L2KEY, new String[]{key});
-            }
-            db.setTransactionSuccessful();
-            return Status.SUCCESS;
-        } catch (SQLiteException e) {
-            // No space left on disk or something
-            Log.e(TAG, "Could not write to the memory store", e);
-        } finally {
-            db.endTransaction();
-        }
-        return Status.ERROR_STORAGE;
-    }
-
-    // Returns an int out of Status.{SUCCESS, ERROR_*}
-    static int storeBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name,
-            @NonNull final byte[] data) {
-        final long res = db.insertWithOnConflict(PrivateDataContract.TABLENAME, null,
-                toContentValues(key, clientId, name, data), SQLiteDatabase.CONFLICT_REPLACE);
-        return (res == -1) ? Status.ERROR_STORAGE : Status.SUCCESS;
-    }
-
-    @Nullable
-    static NetworkAttributes retrieveNetworkAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                NetworkAttributesContract.COLNAME_L2KEY + " = ?", // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final NetworkAttributes attributes = readNetworkAttributesLine(cursor);
-        cursor.close();
-        return attributes;
-    }
-
-    private static final String[] DATA_COLUMN = new String[] {
-            PrivateDataContract.COLNAME_DATA
-    };
-
-    @Nullable
-    static byte[] retrieveBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name) {
-        final Cursor cursor = db.query(PrivateDataContract.TABLENAME,
-                DATA_COLUMN, // columns
-                PrivateDataContract.COLNAME_L2KEY + " = ? AND " // selection
-                + PrivateDataContract.COLNAME_CLIENT + " = ? AND "
-                + PrivateDataContract.COLNAME_DATANAME + " = ?",
-                new String[] { key, clientId, name }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // The query above is querying by (composite) primary key, so it should not be possible to
-        // get more than one result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final byte[] result = cursor.getBlob(0); // index in the DATA_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    /**
-     * Wipe all data in tables when network factory reset occurs.
-     */
-    static void wipeDataUponNetworkReset(@NonNull final SQLiteDatabase db) {
-        for (int remainingRetries = 3; remainingRetries > 0; --remainingRetries) {
-            db.beginTransaction();
-            try {
-                db.delete(NetworkAttributesContract.TABLENAME, null, null);
-                db.delete(PrivateDataContract.TABLENAME, null, null);
-                final Cursor cursorNetworkAttributes = db.query(
-                        // table name
-                        NetworkAttributesContract.TABLENAME,
-                        // column name
-                        new String[] { NetworkAttributesContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorNetworkAttributes.getCount()) {
-                    cursorNetworkAttributes.close();
-                    continue;
-                }
-                cursorNetworkAttributes.close();
-                final Cursor cursorPrivateData = db.query(
-                        // table name
-                        PrivateDataContract.TABLENAME,
-                        // column name
-                        new String[] { PrivateDataContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorPrivateData.getCount()) {
-                    cursorPrivateData.close();
-                    continue;
-                }
-                cursorPrivateData.close();
-                db.setTransactionSuccessful();
-                return;
-            } catch (SQLiteException e) {
-                Log.e(TAG, "Could not wipe the data in database", e);
-            } finally {
-                db.endTransaction();
-            }
-        }
-    }
-
-    /**
-     * The following is a horrible hack that is necessary because the Android SQLite API does not
-     * have a way to query a binary blob. This, almost certainly, is an overlook.
-     *
-     * The Android SQLite API has two family of methods : one for query that returns data, and
-     * one for more general SQL statements that can execute any statement but may not return
-     * anything. All the query methods, however, take only String[] for the arguments.
-     *
-     * In principle it is simple to write a function that will encode the binary blob in the
-     * way SQLite expects it. However, because the API forces the argument to be coerced into a
-     * String, the SQLiteQuery object generated by the default query methods will bind all
-     * arguments as Strings and SQL will *sanitize* them. This works okay for numeric types,
-     * but the format for blobs is x'<hex string>'. Note the presence of quotes, which will
-     * be sanitized, changing the contents of the field, and the query will fail to match the
-     * blob.
-     *
-     * As far as I can tell, there are two possible ways around this problem. The first one
-     * is to put the data in the query string and eschew it being an argument. This would
-     * require doing the sanitizing by hand. The other is to call bindBlob directly on the
-     * generated SQLiteQuery object, which not only is a lot less dangerous than rolling out
-     * sanitizing, but also will do the right thing if the underlying format ever changes.
-     *
-     * But none of the methods that take an SQLiteQuery object can return data ; this *must*
-     * be called with SQLiteDatabase#query. This object is not accessible from outside.
-     * However, there is a #query version that accepts a CursorFactory and this is pretty
-     * straightforward to implement as all the arguments are coming in and the SQLiteCursor
-     * class is public API.
-     * With this, it's possible to intercept the SQLiteQuery object, and assuming the args
-     * are available, to bind them directly and work around the API's oblivious coercion into
-     * Strings.
-     *
-     * This is really sad, but I don't see another way of having this work than this or the
-     * hand-rolled sanitizing, and this is the lesser evil.
-     */
-    private static class CustomCursorFactory implements SQLiteDatabase.CursorFactory {
-        @NonNull
-        private final ArrayList<Object> mArgs;
-        CustomCursorFactory(@NonNull final ArrayList<Object> args) {
-            mArgs = args;
-        }
-        @Override
-        public Cursor newCursor(final SQLiteDatabase db, final SQLiteCursorDriver masterQuery,
-                final String editTable,
-                final SQLiteQuery query) {
-            int index = 1; // bind is 1-indexed
-            for (final Object arg : mArgs) {
-                if (arg instanceof String) {
-                    query.bindString(index++, (String) arg);
-                } else if (arg instanceof Long) {
-                    query.bindLong(index++, (Long) arg);
-                } else if (arg instanceof Integer) {
-                    query.bindLong(index++, Long.valueOf((Integer) arg));
-                } else if (arg instanceof byte[]) {
-                    query.bindBlob(index++, (byte[]) arg);
-                } else {
-                    throw new IllegalStateException("Unsupported type CustomCursorFactory "
-                            + arg.getClass().toString());
-                }
-            }
-            return new SQLiteCursor(masterQuery, editTable, query);
-        }
-    }
-
-    // Returns the l2key of the closest match, if and only if it matches
-    // closely enough (as determined by group-closeness).
-    @Nullable
-    static String findClosestAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final NetworkAttributes attr) {
-        if (attr.isEmpty()) return null;
-        final ContentValues values = toContentValues(attr);
-
-        // Build the selection and args. To cut down on the number of lines to search, limit
-        // the search to those with at least one argument equals to the requested attributes.
-        // This works only because null attributes match only will not result in group-closeness.
-        final StringJoiner sj = new StringJoiner(" OR ");
-        final ArrayList<Object> args = new ArrayList<>();
-        args.add(System.currentTimeMillis());
-        for (final String field : values.keySet()) {
-            sj.add(field + " = ?");
-            args.add(values.get(field));
-        }
-
-        final String selection = NetworkAttributesContract.COLNAME_EXPIRYDATE + " > ? AND ("
-                + sj.toString() + ")";
-        final Cursor cursor = db.queryWithFactory(new CustomCursorFactory(args),
-                false, // distinct
-                NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                selection, // selection
-                null, // selectionArgs, horrendously passed to the cursor factory instead
-                null, // groupBy
-                null, // having
-                null, // orderBy
-                null); // limit
-        if (cursor.getCount() <= 0) return null;
-        cursor.moveToFirst();
-        String bestKey = null;
-        float bestMatchConfidence = GROUPCLOSE_CONFIDENCE; // Never return a match worse than this.
-        while (!cursor.isAfterLast()) {
-            final NetworkAttributes read = readNetworkAttributesLine(cursor);
-            final float confidence = read.getNetworkGroupSamenessConfidence(attr);
-            if (confidence > bestMatchConfidence) {
-                bestKey = getString(cursor, NetworkAttributesContract.COLNAME_L2KEY);
-                bestMatchConfidence = confidence;
-            }
-            cursor.moveToNext();
-        }
-        cursor.close();
-        return bestKey;
-    }
-
-    // Drops all records that are expired. Relevance has decayed to zero of these records. Returns
-    // an int out of Status.{SUCCESS, ERROR_*}
-    static int dropAllExpiredRecords(@NonNull final SQLiteDatabase db) {
-        db.beginTransaction();
-        try {
-            // Deletes NetworkAttributes that have expired.
-            db.delete(NetworkAttributesContract.TABLENAME,
-                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " < ?",
-                    new String[]{Long.toString(System.currentTimeMillis())});
-            db.setTransactionSuccessful();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Could not delete data from memory store", e);
-            return Status.ERROR_STORAGE;
-        } finally {
-            db.endTransaction();
-        }
-
-        // Execute vacuuming here if above operation has no exception. If above operation got
-        // exception, vacuuming can be ignored for reducing unnecessary consumption.
-        try {
-            db.execSQL("VACUUM");
-        } catch (SQLiteException e) {
-            // Do nothing.
-        }
-        return Status.SUCCESS;
-    }
-
-    // Drops number of records that start from the lowest expiryDate. Returns an int out of
-    // Status.{SUCCESS, ERROR_*}
-    static int dropNumberOfRecords(@NonNull final SQLiteDatabase db, int number) {
-        if (number <= 0) {
-            return Status.ERROR_ILLEGAL_ARGUMENT;
-        }
-
-        // Queries number of NetworkAttributes that start from the lowest expiryDate.
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                new String[] {NetworkAttributesContract.COLNAME_EXPIRYDATE}, // columns
-                null, // selection
-                null, // selectionArgs
-                null, // groupBy
-                null, // having
-                NetworkAttributesContract.COLNAME_EXPIRYDATE, // orderBy
-                Integer.toString(number)); // limit
-        if (cursor == null || cursor.getCount() <= 0) return Status.ERROR_GENERIC;
-        cursor.moveToLast();
-
-        //Get the expiryDate from last record.
-        final long expiryDate = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, 0);
-        cursor.close();
-
-        db.beginTransaction();
-        try {
-            // Deletes NetworkAttributes that expiryDate are lower than given value.
-            db.delete(NetworkAttributesContract.TABLENAME,
-                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " <= ?",
-                    new String[]{Long.toString(expiryDate)});
-            db.setTransactionSuccessful();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Could not delete data from memory store", e);
-            return Status.ERROR_STORAGE;
-        } finally {
-            db.endTransaction();
-        }
-
-        // Execute vacuuming here if above operation has no exception. If above operation got
-        // exception, vacuuming can be ignored for reducing unnecessary consumption.
-        try {
-            db.execSQL("VACUUM");
-        } catch (SQLiteException e) {
-            // Do nothing.
-        }
-        return Status.SUCCESS;
-    }
-
-    static int getTotalRecordNumber(@NonNull final SQLiteDatabase db) {
-        // Query the total number of NetworkAttributes
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                new String[] {"COUNT(*)"}, // columns
-                null, // selection
-                null, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        cursor.moveToFirst();
-        return cursor == null ? 0 : cursor.getInt(0);
-    }
-
-    // Helper methods
-    private static String getString(final Cursor cursor, final String columnName) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getString(columnIndex) : null;
-    }
-    private static byte[] getBlob(final Cursor cursor, final String columnName) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getBlob(columnIndex) : null;
-    }
-    private static int getInt(final Cursor cursor, final String columnName,
-            final int defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getInt(columnIndex) : defaultValue;
-    }
-    private static long getLong(final Cursor cursor, final String columnName,
-            final long defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getLong(columnIndex) : defaultValue;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
deleted file mode 100644
index 55ab8d4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2018 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.connectivity.ipmemorystore;
-
-import static android.net.ipmemorystore.Status.ERROR_DATABASE_CANNOT_BE_OPENED;
-import static android.net.ipmemorystore.Status.ERROR_GENERIC;
-import static android.net.ipmemorystore.Status.ERROR_ILLEGAL_ARGUMENT;
-import static android.net.ipmemorystore.Status.SUCCESS;
-
-import static com.android.server.connectivity.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR;
-import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.IIpMemoryStore;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.File;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Implementation for the IP memory store.
- * This component offers specialized services for network components to store and retrieve
- * knowledge about networks, and provides intelligence that groups level 2 networks together
- * into level 3 networks.
- *
- * @hide
- */
-public class IpMemoryStoreService extends IIpMemoryStore.Stub {
-    private static final String TAG = IpMemoryStoreService.class.getSimpleName();
-    private static final int DATABASE_SIZE_THRESHOLD = 10 * 1024 * 1024; //10MB
-    private static final int MAX_DROP_RECORD_TIMES = 500;
-    private static final int MIN_DELETE_NUM = 5;
-    private static final boolean DBG = true;
-
-    // Error codes below are internal and used for notifying status beteween IpMemoryStore modules.
-    static final int ERROR_INTERNAL_BASE = -1_000_000_000;
-    // This error code is used for maintenance only to notify RegularMaintenanceJobService that
-    // full maintenance job has been interrupted.
-    static final int ERROR_INTERNAL_INTERRUPTED = ERROR_INTERNAL_BASE - 1;
-
-    @NonNull
-    final Context mContext;
-    @Nullable
-    final SQLiteDatabase mDb;
-    @NonNull
-    final ExecutorService mExecutor;
-
-    /**
-     * Construct an IpMemoryStoreService object.
-     * This constructor will block on disk access to open the database.
-     * @param context the context to access storage with.
-     */
-    public IpMemoryStoreService(@NonNull final Context context) {
-        // Note that constructing the service will access the disk and block
-        // for some time, but it should make no difference to the clients. Because
-        // the interface is one-way, clients fire and forget requests, and the callback
-        // will get called eventually in any case, and the framework will wait for the
-        // service to be created to deliver subsequent requests.
-        // Avoiding this would mean the mDb member can't be final, which means the service would
-        // have to test for nullity, care for failure, and allow for a wait at every single access,
-        // which would make the code a lot more complex and require all methods to possibly block.
-        mContext = context;
-        SQLiteDatabase db;
-        final IpMemoryStoreDatabase.DbHelper helper = new IpMemoryStoreDatabase.DbHelper(context);
-        try {
-            db = helper.getWritableDatabase();
-            if (null == db) Log.e(TAG, "Unexpected null return of getWriteableDatabase");
-        } catch (final SQLException e) {
-            Log.e(TAG, "Can't open the Ip Memory Store database", e);
-            db = null;
-        } catch (final Exception e) {
-            Log.wtf(TAG, "Impossible exception Ip Memory Store database", e);
-            db = null;
-        }
-        mDb = db;
-        // The single thread executor guarantees that all work is executed sequentially on the
-        // same thread, and no two tasks can be active at the same time. This is required to
-        // ensure operations from multiple clients don't interfere with each other (in particular,
-        // operations involving a transaction must not run concurrently with other operations
-        // as the other operations might be taken as part of the transaction). By default, the
-        // single thread executor runs off an unbounded queue.
-        // TODO : investigate replacing this scheme with a scheme where each thread has its own
-        // instance of the database, as it may be faster. It is likely however that IpMemoryStore
-        // operations are mostly IO-bound anyway, and additional contention is unlikely to bring
-        // benefits. Alternatively, a read-write lock might increase throughput.
-        mExecutor = Executors.newSingleThreadExecutor();
-        RegularMaintenanceJobService.schedule(mContext, this);
-    }
-
-    /**
-     * Shutdown the memory store service, cancelling running tasks and dropping queued tasks.
-     *
-     * This is provided to give a way to clean up, and is meant to be available in case of an
-     * emergency shutdown.
-     */
-    public void shutdown() {
-        // By contrast with ExecutorService#shutdown, ExecutorService#shutdownNow tries
-        // to cancel the existing tasks, and does not wait for completion. It does not
-        // guarantee the threads can be terminated in any given amount of time.
-        mExecutor.shutdownNow();
-        if (mDb != null) mDb.close();
-        RegularMaintenanceJobService.unschedule(mContext);
-    }
-
-    /** Helper function to make a status object */
-    private StatusParcelable makeStatus(final int code) {
-        return new Status(code).toParcelable();
-    }
-
-    /**
-     * Store network attributes for a given L2 key.
-     *
-     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
-     *              key and only care about grouping can pass a unique ID here like the ones
-     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
-     *              relevance of such a network will lead to it being evicted soon if it's not
-     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
-     * @param attributes The attributes for this network.
-     * @param listener A listener to inform of the completion of this call, or null if the client
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns the L2 key. This is useful if the L2 key was not specified.
-     * If the call failed, the L2 key will be null.
-     */
-    // Note that while l2Key and attributes are non-null in spirit, they are received from
-    // another process. If the remote process decides to ignore everything and send null, this
-    // process should still not crash.
-    @Override
-    public void storeNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnStatusListener listener) {
-        // Because the parcelable is 100% mutable, the thread may not see its members initialized.
-        // Therefore either an immutable object is created on this same thread before it's passed
-        // to the executor, or there need to be a write barrier here and a read barrier in the
-        // remote thread.
-        final NetworkAttributes na = null == attributes ? null : new NetworkAttributes(attributes);
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key, na,
-                        null /* clientId */, null /* name */, null /* data */);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Store a binary blob associated with an L2 key and a name.
-     *
-     * @param l2Key The L2 key for this network.
-     * @param clientId The ID of the client.
-     * @param name The name of this data.
-     * @param blob The data to store.
-     * @param listener The listener that will be invoked to return the answer, or null if the
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns a status to indicate success or failure.
-     */
-    @Override
-    public void storeBlob(@Nullable final String l2Key, @Nullable final String clientId,
-            @Nullable final String name, @Nullable final Blob blob,
-            @Nullable final IOnStatusListener listener) {
-        final byte[] data = null == blob ? null : blob.data;
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key,
-                        null /* NetworkAttributes */, clientId, name, data);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Helper method for storeNetworkAttributes and storeBlob.
-     *
-     * Either attributes or none of clientId, name and data may be null. This will write the
-     * passed data if non-null, and will write attributes if non-null, but in any case it will
-     * bump the relevance up.
-     * Returns a success code from Status.
-     */
-    private int storeNetworkAttributesAndBlobSync(@Nullable final String l2Key,
-            @Nullable final NetworkAttributes attributes,
-            @Nullable final String clientId,
-            @Nullable final String name, @Nullable final byte[] data) {
-        if (null == l2Key) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == attributes && null == data) return ERROR_ILLEGAL_ARGUMENT;
-        if (null != data && (null == clientId || null == name)) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == mDb) return ERROR_DATABASE_CANNOT_BE_OPENED;
-        try {
-            final long oldExpiry = IpMemoryStoreDatabase.getExpiry(mDb, l2Key);
-            final long newExpiry = RelevanceUtils.bumpExpiryDate(
-                    oldExpiry == EXPIRY_ERROR ? System.currentTimeMillis() : oldExpiry);
-            final int errorCode =
-                    IpMemoryStoreDatabase.storeNetworkAttributes(mDb, l2Key, newExpiry, attributes);
-            // If no blob to store, the client is interested in the result of storing the attributes
-            if (null == data) return errorCode;
-            // Otherwise it's interested in the result of storing the blob
-            return IpMemoryStoreDatabase.storeBlob(mDb, l2Key, clientId, name, data);
-        } catch (Exception e) {
-            if (DBG) {
-                Log.e(TAG, "Exception while storing for key {" + l2Key
-                        + "} ; NetworkAttributes {" + (null == attributes ? "null" : attributes)
-                        + "} ; clientId {" + (null == clientId ? "null" : clientId)
-                        + "} ; name {" + (null == name ? "null" : name)
-                        + "} ; data {" + Utils.byteArrayToString(data) + "}", e);
-            }
-        }
-        return ERROR_GENERIC;
-    }
-
-    /**
-     * Returns the best L2 key associated with the attributes.
-     *
-     * This will find a record that would be in the same group as the passed attributes. This is
-     * useful to choose the key for storing a sample or private data when the L2 key is not known.
-     * If multiple records are group-close to these attributes, the closest match is returned.
-     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
-     * order) L2 key is returned.
-     * If no record matches these attributes, null is returned.
-     *
-     * @param attributes The attributes of the network to find.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the L2 key if one matched, or null.
-     */
-    @Override
-    public void findL2Key(@Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnL2KeyResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == attributes) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                final String key = IpMemoryStoreDatabase.findClosestAttributes(mDb,
-                        new NetworkAttributes(attributes));
-                listener.onL2KeyResponse(makeStatus(SUCCESS), key);
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
-     * to the same L3 network. Group-closeness is used to determine this.
-     *
-     * @param l2Key1 The key for the first network.
-     * @param l2Key2 The key for the second network.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
-     */
-    @Override
-    public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
-            @Nullable final IOnSameL3NetworkResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key1 || null == l2Key2) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attr1 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key1);
-                    final NetworkAttributes attr2 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
-                    if (null == attr1 || null == attr2) {
-                        listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                                new SameL3NetworkResponse(l2Key1, l2Key2,
-                                        -1f /* never connected */).toParcelable());
-                        return;
-                    }
-                    final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
-                    listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                            new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
-                } catch (Exception e) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve the network attributes for a key.
-     * If no record is present for this key, this will return null attributes.
-     *
-     * @param l2Key The key of the network to query.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the network attributes and the L2 key associated with
-     *         the query.
-     */
-    @Override
-    public void retrieveNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final IOnNetworkAttributesRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attributes =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key);
-                    listener.onNetworkAttributesRetrieved(makeStatus(SUCCESS), l2Key,
-                            null == attributes ? null : attributes.toParcelable());
-                } catch (final Exception e) {
-                    listener.onNetworkAttributesRetrieved(makeStatus(ERROR_GENERIC), l2Key, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve previously stored private data.
-     * If no data was stored for this L2 key and name this will return null.
-     *
-     * @param l2Key The L2 key.
-     * @param clientId The id of the client that stored this data.
-     * @param name The name of the data.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the private data if any or null if none, with the L2 key
-     *         and the name of the data associated with the query.
-     */
-    @Override
-    public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, name, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key,
-                            name, null);
-                    return;
-                }
-                try {
-                    final Blob b = new Blob();
-                    b.data = IpMemoryStoreDatabase.retrieveBlob(mDb, l2Key, clientId, name);
-                    listener.onBlobRetrieved(makeStatus(SUCCESS), l2Key, name, b);
-                } catch (final Exception e) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_GENERIC), l2Key, name, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Wipe the data in IpMemoryStore database upon network factory reset.
-     */
-    @Override
-    public void factoryReset() {
-        mExecutor.execute(() -> IpMemoryStoreDatabase.wipeDataUponNetworkReset(mDb));
-    }
-
-    /** Get db size threshold. */
-    @VisibleForTesting
-    protected int getDbSizeThreshold() {
-        return DATABASE_SIZE_THRESHOLD;
-    }
-
-    private long getDbSize() {
-        final File dbFile = new File(mDb.getPath());
-        try {
-            return dbFile.length();
-        } catch (final SecurityException e) {
-            if (DBG) Log.e(TAG, "Read db size access deny.", e);
-            // Return zero value if can't get disk usage exactly.
-            return 0;
-        }
-    }
-
-    /** Check if db size is over the threshold. */
-    @VisibleForTesting
-    boolean isDbSizeOverThreshold() {
-        return getDbSize() > getDbSizeThreshold();
-    }
-
-    /**
-     * Full maintenance.
-     *
-     * @param listener A listener to inform of the completion of this call.
-     */
-    void fullMaintenance(@NonNull final IOnStatusListener listener,
-            @NonNull final InterruptMaintenance interrupt) {
-        mExecutor.execute(() -> {
-            try {
-                if (null == mDb) {
-                    listener.onComplete(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED));
-                    return;
-                }
-
-                // Interrupt maintenance because the scheduling job has been canceled.
-                if (checkForInterrupt(listener, interrupt)) return;
-
-                int result = SUCCESS;
-                // Drop all records whose relevance has decayed to zero.
-                // This is the first step to decrease memory store size.
-                result = IpMemoryStoreDatabase.dropAllExpiredRecords(mDb);
-
-                if (checkForInterrupt(listener, interrupt)) return;
-
-                // Aggregate historical data in passes
-                // TODO : Waiting for historical data implement.
-
-                // Check if db size meets the storage goal(10MB). If not, keep dropping records and
-                // aggregate historical data until the storage goal is met. Use for loop with 500
-                // times restriction to prevent infinite loop (Deleting records always fail and db
-                // size is still over the threshold)
-                for (int i = 0; isDbSizeOverThreshold() && i < MAX_DROP_RECORD_TIMES; i++) {
-                    if (checkForInterrupt(listener, interrupt)) return;
-
-                    final int totalNumber = IpMemoryStoreDatabase.getTotalRecordNumber(mDb);
-                    final long dbSize = getDbSize();
-                    final float decreaseRate = (dbSize == 0)
-                            ? 0 : (float) (dbSize - getDbSizeThreshold()) / (float) dbSize;
-                    final int deleteNumber = Math.max(
-                            (int) (totalNumber * decreaseRate), MIN_DELETE_NUM);
-
-                    result = IpMemoryStoreDatabase.dropNumberOfRecords(mDb, deleteNumber);
-
-                    if (checkForInterrupt(listener, interrupt)) return;
-
-                    // Aggregate historical data
-                    // TODO : Waiting for historical data implement.
-                }
-                listener.onComplete(makeStatus(result));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    private boolean checkForInterrupt(@NonNull final IOnStatusListener listener,
-            @NonNull final InterruptMaintenance interrupt) throws RemoteException {
-        if (!interrupt.isInterrupted()) return false;
-        listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED));
-        return true;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
deleted file mode 100644
index bea7052..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2019 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.connectivity.ipmemorystore;
-
-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.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Regular maintenance job service.
- * @hide
- */
-public final class RegularMaintenanceJobService extends JobService {
-    // Must be unique within the system server uid.
-    public static final int REGULAR_MAINTENANCE_ID = 3345678;
-
-    /**
-     * Class for interrupt check of maintenance job.
-     */
-    public static final class InterruptMaintenance {
-        private volatile boolean mIsInterrupted;
-        private final int mJobId;
-
-        public InterruptMaintenance(int jobId) {
-            mJobId = jobId;
-            mIsInterrupted = false;
-        }
-
-        public int getJobId() {
-            return mJobId;
-        }
-
-        public void setInterrupted(boolean interrupt) {
-            mIsInterrupted = interrupt;
-        }
-
-        public boolean isInterrupted() {
-            return mIsInterrupted;
-        }
-    }
-
-    private static final ArrayList<InterruptMaintenance> sInterruptList = new ArrayList<>();
-    private static IpMemoryStoreService sIpMemoryStoreService;
-
-    @Override
-    public boolean onStartJob(JobParameters params) {
-        if (sIpMemoryStoreService == null) {
-            Log.wtf("RegularMaintenanceJobService",
-                    "Can not start job because sIpMemoryStoreService is null.");
-            return false;
-        }
-        final InterruptMaintenance im = new InterruptMaintenance(params.getJobId());
-        sInterruptList.add(im);
-
-        sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
-                final Status result = new Status(statusParcelable);
-                if (!result.isSuccess()) {
-                    Log.e("RegularMaintenanceJobService", "Regular maintenance failed."
-                            + " Error is " + result.resultCode);
-                }
-                sInterruptList.remove(im);
-                jobFinished(params, !result.isSuccess());
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-        }, im);
-        return true;
-    }
-
-    @Override
-    public boolean onStopJob(JobParameters params) {
-        final int jobId = params.getJobId();
-        for (InterruptMaintenance im : sInterruptList) {
-            if (im.getJobId() == jobId) {
-                im.setInterrupted(true);
-            }
-        }
-        return true;
-    }
-
-    /** Schedule regular maintenance job */
-    static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) {
-        final JobScheduler jobScheduler =
-                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
-        final ComponentName maintenanceJobName =
-                new ComponentName(context, RegularMaintenanceJobService.class);
-
-        // Regular maintenance is scheduled for when the device is idle with access power and a
-        // minimum interval of one day.
-        final JobInfo regularMaintenanceJob =
-                new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName)
-                        .setRequiresDeviceIdle(true)
-                        .setRequiresCharging(true)
-                        .setRequiresBatteryNotLow(true)
-                        .setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
-
-        jobScheduler.schedule(regularMaintenanceJob);
-        sIpMemoryStoreService = ipMemoryStoreService;
-    }
-
-    /** Unschedule regular maintenance job */
-    static void unschedule(Context context) {
-        final JobScheduler jobScheduler =
-                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-        jobScheduler.cancel(REGULAR_MAINTENANCE_ID);
-        sIpMemoryStoreService = null;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
deleted file mode 100644
index 38d5544..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2018 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.connectivity.ipmemorystore;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * A class containing the logic around the relevance value for
- * IP Memory Store.
- *
- * @hide
- */
-public class RelevanceUtils {
-    /**
-     * The relevance is a decaying value that gets lower and lower until it
-     * reaches 0 after some time passes. It follows an exponential decay law,
-     * dropping slowly at first then faster and faster, because a network is
-     * likely to be visited again if it was visited not long ago, and the longer
-     * it hasn't been visited the more likely it is that it won't be visited
-     * again. For example, a network visited on holiday should stay fresh for
-     * the duration of the holiday and persist for a while, but after the venue
-     * hasn't been visited for a while it should quickly be discarded. What
-     * should accelerate forgetting the network is extended periods without
-     * visits, so that occasional venues get discarded but regular visits keep
-     * the network relevant, even if the visits are infrequent.
-     *
-     * This function must be stable by iteration, meaning that adjusting the same value
-     * for different dates iteratively multiple times should give the same result.
-     * Formally, if f is the decay function that associates a relevance x at a date d1
-     * to the value at ulterior date d3, then for any date d2 between d1 and d3 :
-     * f(x, d3 - d1) = f(f(x, d3 - d2), d2 - d1). Intuitively, this property simply
-     * means it should be the same to compute and store back the value after two months,
-     * or to do it once after one month, store it back, and do it again after another
-     * months has passed.
-     * The pair of the relevance and date define the entire curve, so any pair
-     * of values on the curve will define the same curve. Setting one of them to a
-     * constant, so as not to have to store it, means the other one will always suffice
-     * to describe the curve. For example, only storing the date for a known, constant
-     * value of the relevance is an efficient way of remembering this information (and
-     * to compare relevances together, as f is monotonically decreasing).
-     *
-     *** Choosing the function :
-     * Functions of the kind described above are standard exponential decay functions
-     * like the ones that govern atomic decay where the value at any given date can be
-     * computed uniformly from the value at a previous date and the time elapsed since
-     * that date. It is simple to picture this kind of function as one where after a
-     * given period of time called the half-life, the relevance value will have been
-     * halved. Decay of this kind is expressed in function of the previous value by
-     * functions like
-     * f(x, t) = x * F ^ (t / L)
-     * ...where x is the value, t is the elapsed time, L is the half-life (or more
-     * generally the F-th-life) and F the decay factor (typically 0.5, hence why L is
-     * usually called the half-life). The ^ symbol here is used for exponentiation.
-     * Or, starting at a given M for t = 0 :
-     * f(t) = M * F ^ (t / L)
-     *
-     * Because a line in the store needs to become irrelevant at some point but
-     * this class of functions never go to 0, a minimum cutoff has to be chosen to
-     * represent irrelevance. The simpler way of doing this is to simply add this
-     * minimum cutoff to the computation before and removing it after.
-     * Thus the function becomes :
-     * f(x, t) = ((x + K) * F ^ (t / L)) - K
-     * ...where K is the minimum cutoff, L the half-life, and F the factor between
-     * the original x and x after its half-life. Strictly speaking using the word
-     * "half-life" implies that F = 0.5, but the relation works for any value of F.
-     *
-     * It is easy enough to check that this function satisfies the stability
-     * relation that was given above for any value of F, L and K, which become
-     * parameters that can be defined at will.
-     *
-     * relevance
-     *  1.0 |
-     *      |\
-     *      | \
-     *      |  \            (this graph rendered with L = 75 days and K = 1/40)
-     *  0.75|   ',
-     *      |     \
-     *      |      '.
-     *      |        \.
-     *      |          \
-     *  0.5 |           '\
-     *      |             ''.
-     *      |                ''.
-     *      |                   ''.
-     *  0.25|                      '''..
-     *      |                           '''..
-     *      |                                ''''....
-     *      |                                        '''''..........
-     *    0 +-------------------------------------------------------''''''''''----
-     *      0       50       100      150     200      250     300      350     400 days
-     *
-     *** Choosing the parameters
-     * The maximum M is an arbitrary parameter that simply scales the curve.
-     * The tradeoff for M is pretty simple : if the relevance is going to be an
-     * integer, the bigger M is the more precision there is in the relevance.
-     * However, values of M that are easy for humans to read are preferable to
-     * help debugging, and a suitably low value may be enough to ensure there
-     * won't be integer overflows in intermediate computations.
-     * A value of 1_000_000 probably is plenty for precision, while still in the
-     * low range of what ints can represent.
-     *
-     * F and L are parameters to be chosen arbitrarily and have an impact on how
-     * fast the relevance will be decaying at first, keeping in mind that
-     * the 400 days value and the cap stay the same. In simpler words, F and L
-     * define the steepness of the curve.
-     * To keep things simple (and familiar) F is arbitrarily chosen to be 0.5, and
-     * L is set to 200 days visually to achieve the desired effect. Refer to the
-     * illustration above to get a feel of how that feels.
-     *
-     * Moreover, the memory store works on an assumption that the relevance should
-     * be capped, and that an entry with capped relevance should decay in 400 days.
-     * This is on premises that the networks a device will need to remember the
-     * longest should be networks visited about once a year.
-     * For this reason, the relevance is at the maximum M 400 days before expiry :
-     * f(M, 400 days) = 0
-     * From replacing this with the value of the function, K can then be derived
-     * from the values of M, F and L :
-     * (M + K) * F ^ (t / L) - K = 0
-     * K = M * F ^ (400 days / L) / (1 - F ^ (400 days / L))
-     * Replacing with actual values this gives :
-     * K = 1_000_000 * 0.5 ^ (400 / 200) / (1 - 0.5 ^ (400 / 200))
-     *   = 1_000_000 / 3 ≈ 333_333.3
-     * This ensures the function has the desired profile, the desired value at
-     * cap, and the desired value at expiry.
-     *
-     *** Useful relations
-     * Let's define the expiry time for any given relevance x as the interval of
-     * time such as :
-     * f(x, expiry) = 0
-     * which can be rewritten
-     * ((x + K) * F ^ (expiry / L)) = K
-     * ...giving an expression of the expiry in function of the relevance x as
-     * expiry = L * logF(K / (x + K))
-     * Conversely the relevance x can be expressed in function of the expiry as
-     * x = K / F ^ (expiry / L) - K
-     * These relations are useful in utility functions.
-     *
-     *** Bumping things up
-     * The last issue therefore is to decide how to bump up the relevance. The
-     * simple approach is to simply lift up the curve a little bit by a constant
-     * normalized amount, delaying the time of expiry. For example increasing
-     * the relevance by an amount I gives :
-     * x2 = x1 + I
-     * x2 and x1 correspond to two different expiry times expiry2 and expiry1,
-     * and replacing x1 and x2 in the relation above with their expression in
-     * function of the expiry comes :
-     * K / F ^ (expiry2 / L) - K = K / F ^ (expiry1 / L) - K + I
-     * which resolves to :
-     * expiry2 = L * logF(K / (I + K / F ^ (expiry1 / L)))
-     *
-     * In this implementation, the bump is defined as 1/25th of the cap for
-     * the relevance. This means a network will be remembered for the maximum
-     * period of 400 days if connected 25 times in succession not accounting
-     * for decay. Of course decay actually happens so it will take more than 25
-     * connections for any given network to actually reach the cap, but because
-     * decay is slow at first, it is a good estimate of how fast cap happens.
-     *
-     * Specifically, it gives the following four results :
-     * - A network that a device connects to once hits irrelevance about 32.7 days after
-     *   it was first registered if never connected again.
-     * - A network that a device connects to once a day at a fixed hour will hit the cap
-     *   on the 27th connection.
-     * - A network that a device connects to once a week at a fixed hour will hit the cap
-     *   on the 57th connection.
-     * - A network that a device connects to every day for 7 straight days then never again
-     *   expires 144 days after the last connection.
-     * These metrics tend to match pretty well the requirements.
-     */
-
-    // TODO : make these constants configurable at runtime. Don't forget to build it so that
-    // changes will wipe the database, migrate the values, or otherwise make sure the relevance
-    // values are still meaningful.
-
-    // How long, in milliseconds, is a capped relevance valid for, or in other
-    // words how many milliseconds after its relevance was set to RELEVANCE_CAP does
-    // any given line expire. 400 days.
-    @VisibleForTesting
-    public static final long CAPPED_RELEVANCE_LIFETIME_MS = 400L * 24 * 60 * 60 * 1000;
-
-    // The constant that represents a normalized 1.0 value for the relevance. In other words,
-    // the cap for the relevance. This is referred to as M in the explanation above.
-    @VisibleForTesting
-    public static final int CAPPED_RELEVANCE = 1_000_000;
-
-    // The decay factor. After a half-life, the relevance will have decayed by this value.
-    // This is referred to as F in the explanation above.
-    private static final double DECAY_FACTOR = 0.5;
-
-    // The half-life. After this time, the relevance will have decayed by a factor DECAY_FACTOR.
-    // This is referred to as L in the explanation above.
-    private static final long HALF_LIFE_MS = 200L * 24 * 60 * 60 * 1000;
-
-    // The value of the frame change. This is referred to as K in the explanation above.
-    private static final double IRRELEVANCE_FLOOR =
-            CAPPED_RELEVANCE * powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS)
-            / (1 - powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS));
-
-    // How much to bump the relevance by every time a line is written to.
-    @VisibleForTesting
-    public static final int RELEVANCE_BUMP = CAPPED_RELEVANCE / 25;
-
-    // Java doesn't include a function for the logarithm in an arbitrary base, so implement it
-    private static final double LOG_DECAY_FACTOR = Math.log(DECAY_FACTOR);
-    private static double logF(final double value) {
-        return Math.log(value) / LOG_DECAY_FACTOR;
-    }
-
-    // Utility function to get a power of the decay factor, to simplify the code.
-    private static double powF(final double value) {
-        return Math.pow(DECAY_FACTOR, value);
-    }
-
-    /**
-     * Compute the value of the relevance now given an expiry date.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @return the adjusted value of the relevance for this moment in time.
-     */
-    public static int computeRelevanceForNow(final long expiry) {
-        return computeRelevanceForTargetDate(expiry, System.currentTimeMillis());
-    }
-
-    /**
-     * Compute the value of the relevance at a given date from an expiry date.
-     *
-     * Because relevance decays with time, a relevance in the past corresponds to
-     * a different relevance later.
-     *
-     * Relevance is always a positive value. 0 means not relevant at all.
-     *
-     * See the explanation at the top of this file to get the justification for this
-     * computation.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @param target the target date to adjust the relevance to.
-     * @return the adjusted value of the relevance for the target moment.
-     */
-    public static int computeRelevanceForTargetDate(final long expiry, final long target) {
-        final long delay = expiry - target;
-        if (delay >= CAPPED_RELEVANCE_LIFETIME_MS) return CAPPED_RELEVANCE;
-        if (delay <= 0) return 0;
-        return (int) (IRRELEVANCE_FLOOR / powF((float) delay / HALF_LIFE_MS) - IRRELEVANCE_FLOOR);
-    }
-
-    /**
-     * Compute the expiry duration adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDate, this function uses a duration from now to expiry.
-     *
-     * See the explanation at the top of this file for a justification of this computation.
-     *
-     * @param oldExpiryDuration the old expiry duration in milliseconds from now.
-     * @return the expiry duration representing a bumped up relevance value.
-     */
-    public static long bumpExpiryDuration(final long oldExpiryDuration) {
-        // L * logF(K / (I + K / F ^ (expiry1 / L))), as documented above
-        final double divisionFactor = powF(((double) oldExpiryDuration) / HALF_LIFE_MS);
-        final double oldRelevance = IRRELEVANCE_FLOOR / divisionFactor;
-        final long newDuration =
-                (long) (HALF_LIFE_MS * logF(IRRELEVANCE_FLOOR / (RELEVANCE_BUMP + oldRelevance)));
-        return Math.min(newDuration, CAPPED_RELEVANCE_LIFETIME_MS);
-    }
-
-    /**
-     * Compute the new expiry date adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDuration, this function takes the old timestamp and returns the
-     * new timestamp.
-     *
-     * {@see bumpExpiryDuration}, and keep in mind that the bump depends on when this is called,
-     * because the relevance decays exponentially, therefore bumping up a high relevance (for a
-     * date far in the future) is less potent than bumping up a low relevance (for a date in
-     * a close future).
-     *
-     * @param oldExpiryDate the old date of expiration.
-     * @return the new expiration date after the relevance bump.
-     */
-    public static long bumpExpiryDate(final long oldExpiryDate) {
-        final long now = System.currentTimeMillis();
-        final long newDuration = bumpExpiryDuration(oldExpiryDate - now);
-        return now + newDuration;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
deleted file mode 100644
index 9cbf490..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.connectivity.ipmemorystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.ipmemorystore.Blob;
-
-/** {@hide} */
-public class Utils {
-    /** Pretty print */
-    public static String blobToString(@Nullable final Blob blob) {
-        return "Blob : " + byteArrayToString(null == blob ? null : blob.data);
-    }
-
-    /** Pretty print */
-    public static String byteArrayToString(@Nullable final byte[] data) {
-        if (null == data) return "null";
-        final StringBuilder sb = new StringBuilder("[");
-        if (data.length <= 24) {
-            appendByteArray(sb, data, 0, data.length);
-        } else {
-            appendByteArray(sb, data, 0, 16);
-            sb.append("...");
-            appendByteArray(sb, data, data.length - 8, data.length);
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    // Adds the hex representation of the array between the specified indices (inclusive, exclusive)
-    private static void appendByteArray(@NonNull final StringBuilder sb, @NonNull final byte[] ar,
-            final int from, final int to) {
-        for (int i = from; i < to; ++i) {
-            sb.append(String.format("%02X", ar[i]));
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
deleted file mode 100644
index 804765e..0000000
--- a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2018 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.util;
-
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import java.net.Inet4Address;
-
-/**
- * Network constants used by the network stack.
- */
-public final class NetworkStackConstants {
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_ADDR_BITS = 32;
-    public static final int IPV4_MIN_MTU = 68;
-    public static final int IPV4_MAX_MTU = 65_535;
-
-    /**
-     * Ethernet constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc894
-     *     - https://tools.ietf.org/html/rfc2464
-     *     - https://tools.ietf.org/html/rfc7042
-     *     - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
-     *     - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
-     */
-    public static final int ETHER_DST_ADDR_OFFSET = 0;
-    public static final int ETHER_SRC_ADDR_OFFSET = 6;
-    public static final int ETHER_ADDR_LEN = 6;
-    public static final int ETHER_TYPE_OFFSET = 12;
-    public static final int ETHER_TYPE_LENGTH = 2;
-    public static final int ETHER_TYPE_ARP  = 0x0806;
-    public static final int ETHER_TYPE_IPV4 = 0x0800;
-    public static final int ETHER_TYPE_IPV6 = 0x86dd;
-    public static final int ETHER_HEADER_LEN = 14;
-
-    /**
-     * ARP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc826
-     *     - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
-     */
-    public static final int ARP_PAYLOAD_LEN = 28;  // For Ethernet+IPv4.
-    public static final int ARP_REQUEST = 1;
-    public static final int ARP_REPLY   = 2;
-    public static final int ARP_HWTYPE_RESERVED_LO = 0;
-    public static final int ARP_HWTYPE_ETHER       = 1;
-    public static final int ARP_HWTYPE_RESERVED_HI = 0xffff;
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_HEADER_MIN_LEN = 20;
-    public static final int IPV4_IHL_MASK = 0xf;
-    public static final int IPV4_FLAGS_OFFSET = 6;
-    public static final int IPV4_FRAGMENT_MASK = 0x1fff;
-    public static final int IPV4_PROTOCOL_OFFSET = 9;
-    public static final int IPV4_SRC_ADDR_OFFSET = 12;
-    public static final int IPV4_DST_ADDR_OFFSET = 16;
-    public static final int IPV4_ADDR_LEN = 4;
-    public static final Inet4Address IPV4_ADDR_ALL = intToInet4AddressHTH(0xffffffff);
-    public static final Inet4Address IPV4_ADDR_ANY = intToInet4AddressHTH(0x0);
-
-    /**
-     * IPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2460
-     */
-    public static final int IPV6_ADDR_LEN = 16;
-    public static final int IPV6_HEADER_LEN = 40;
-    public static final int IPV6_PROTOCOL_OFFSET = 6;
-    public static final int IPV6_SRC_ADDR_OFFSET = 8;
-    public static final int IPV6_DST_ADDR_OFFSET = 24;
-
-    /**
-     * ICMPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc4443
-     *     - https://tools.ietf.org/html/rfc4861
-     */
-    public static final int ICMPV6_HEADER_MIN_LEN = 4;
-    public static final int ICMPV6_ECHO_REPLY_TYPE = 129;
-    public static final int ICMPV6_ECHO_REQUEST_TYPE = 128;
-    public static final int ICMPV6_ROUTER_SOLICITATION    = 133;
-    public static final int ICMPV6_ROUTER_ADVERTISEMENT   = 134;
-    public static final int ICMPV6_NEIGHBOR_SOLICITATION  = 135;
-    public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136;
-    public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8;
-    public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8;
-    public static final int ICMPV6_ND_OPTION_SLLA = 1;
-    public static final int ICMPV6_ND_OPTION_TLLA = 2;
-    public static final int ICMPV6_ND_OPTION_MTU  = 5;
-
-    /**
-     * UDP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc768
-     */
-    public static final int UDP_HEADER_LEN = 8;
-
-
-    /**
-     * DHCP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2131
-     */
-    public static final int INFINITE_LEASE = 0xffffffff;
-    public static final int DHCP4_CLIENT_PORT = 68;
-
-    private NetworkStackConstants() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java b/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
deleted file mode 100644
index 6fbeead..0000000
--- a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 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.util;
-
-import static android.os.Binder.getCallingUid;
-
-import android.os.Process;
-import android.os.UserHandle;
-
-/**
- * Utility class to check calling permissions on the network stack.
- */
-public final class PermissionUtil {
-
-    /**
-     * Check that the caller is allowed to communicate with the network stack.
-     * @throws SecurityException The caller is not allowed to communicate with the network stack.
-     */
-    public static void checkNetworkStackCallingPermission() {
-        // TODO: check that the calling PID is the system server.
-        final int caller = getCallingUid();
-        if (caller != Process.SYSTEM_UID
-                && UserHandle.getAppId(caller) != Process.BLUETOOTH_UID
-                && UserHandle.getAppId(caller) != Process.PHONE_UID) {
-            throw new SecurityException("Invalid caller: " + caller);
-        }
-    }
-
-    /**
-     * Check that the caller is allowed to dump the network stack, e.g. dumpsys.
-     * @throws SecurityException The caller is not allowed to dump the network stack.
-     */
-    public static void checkDumpPermission() {
-        final int caller = getCallingUid();
-        if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID
-                && caller != Process.SHELL_UID) {
-            throw new SecurityException("No dump permissions for caller: " + caller);
-        }
-    }
-
-    private PermissionUtil() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/tests/lib/Android.bp b/packages/NetworkStack/tests/lib/Android.bp
deleted file mode 100644
index f45a81c..0000000
--- a/packages/NetworkStack/tests/lib/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-java_library {
-    name: "net-tests-utils",
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
-    static_libs: [
-        "kotlin-test",
-    ],
-}
diff --git a/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt b/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt
deleted file mode 100644
index 3dce5a5..0000000
--- a/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 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.testutils
-
-import android.os.ConditionVariable
-import android.os.Handler
-import android.os.HandlerThread
-import java.util.concurrent.Executor
-import kotlin.test.fail
-
-/**
- * Block until the specified Handler or HandlerThread becomes idle, or until timeoutMs has passed.
- */
-fun Handler.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this, timeoutMs)
-fun HandlerThread.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this.threadHandler, timeoutMs)
-fun waitForIdleHandler(handler: HandlerThread, timeoutMs: Long) {
-    waitForIdleHandler(handler.threadHandler, timeoutMs)
-}
-fun waitForIdleHandler(handler: Handler, timeoutMs: Long) {
-    val cv = ConditionVariable(false)
-    handler.post(cv::open)
-    if (!cv.block(timeoutMs)) {
-        fail("Handler did not become idle after ${timeoutMs}ms")
-    }
-}
-
-/**
- * Block until the given Serial Executor becomes idle, or until timeoutMs has passed.
- */
-fun waitForIdleSerialExecutor(executor: Executor, timeoutMs: Long) {
-    val cv = ConditionVariable()
-    executor.execute(cv::open)
-    if (!cv.block(timeoutMs)) {
-        fail("Executor did not become idle after ${timeoutMs}ms")
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/Android.bp b/packages/NetworkStack/tests/unit/Android.bp
deleted file mode 100644
index 48b13b0..0000000
--- a/packages/NetworkStack/tests/unit/Android.bp
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// Copyright (C) 2018 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.
-//
-
-android_test {
-    name: "NetworkStackTests",
-    certificate: "platform",
-    srcs: ["src/**/*.java"],
-    test_suites: ["device-tests"],
-    resource_dirs: ["res"],
-    static_libs: [
-        "androidx.test.rules",
-        "mockito-target-extended-minus-junit4",
-        "net-tests-utils",
-        "NetworkStackBase",
-        "testables",
-    ],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        // For ApfTest
-        "libbacktrace",
-        "libbase",
-        "libbinder",
-        "libbinderthreadstate",
-        "libc++",
-        "libcgrouprc",
-        "libcrypto",
-        "libcutils",
-        "ld-android",
-        "libdl_android",
-        "libhidl-gen-utils",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "libjsoncpp",
-        "liblog",
-        "liblzma",
-        "libnativehelper",
-        "libnativehelper_compat_libc++",
-        "libnetworkstacktestsjni",
-        "libnetworkstackutilsjni",
-        "libpackagelistparser",
-        "libpcre2",
-        "libprocessgroup",
-        "libselinux",
-        "libui",
-        "libutils",
-        "libvintf",
-        "libvndksupport",
-        "libtinyxml2",
-        "libunwindstack",
-        "libutilscallstack",
-        "libziparchive",
-        "libz",
-        "netd_aidl_interface-V2-cpp",
-    ],
-}
-
-cc_library_shared {
-    name: "libnetworkstacktestsjni",
-    srcs: [
-        "jni/**/*.cpp"
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    include_dirs: [
-        "hardware/google/apf",
-    ],
-    shared_libs: [
-        "libbinder",
-        "liblog",
-        "libcutils",
-        "libnativehelper",
-        "netd_aidl_interface-V2-cpp",
-    ],
-    static_libs: [
-        "libapf",
-        "libpcap",
-    ],
-}
diff --git a/packages/NetworkStack/tests/unit/AndroidManifest.xml b/packages/NetworkStack/tests/unit/AndroidManifest.xml
deleted file mode 100644
index 5dcf6ff..0000000
--- a/packages/NetworkStack/tests/unit/AndroidManifest.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.networkstack.tests">
-
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
-    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
-    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
-    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
-    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
-    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
-    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
-    <uses-permission android:name="android.permission.NETWORK_STACK" />
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.server.networkstack.tests"
-        android:label="Networking service tests">
-    </instrumentation>
-</manifest>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/AndroidTest.xml b/packages/NetworkStack/tests/unit/AndroidTest.xml
deleted file mode 100644
index 047bc2e..0000000
--- a/packages/NetworkStack/tests/unit/AndroidTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs Tests for NetworkStack">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="NetworkStackTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="NetworkStackTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.server.networkstack.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp b/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
deleted file mode 100644
index 4222adf..0000000
--- a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2018, 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.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <jni.h>
-#include <pcap.h>
-#include <stdlib.h>
-#include <string>
-#include <utils/Log.h>
-#include <vector>
-
-#include "apf_interpreter.h"
-#include "nativehelper/scoped_primitive_array.h"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-// JNI function acting as simply call-through to native APF interpreter.
-static jint com_android_server_ApfTest_apfSimulate(
-        JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket,
-        jbyteArray jdata, jint filter_age) {
-
-    ScopedByteArrayRO packet(env, jpacket);
-    uint32_t packet_len = (uint32_t)packet.size();
-    uint32_t program_len = env->GetArrayLength(jprogram);
-    uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0;
-    std::vector<uint8_t> buf(program_len + data_len, 0);
-
-    env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data()));
-    if (jdata) {
-        // Merge program and data into a single buffer.
-        env->GetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    jint result =
-        accept_packet(buf.data(), program_len, program_len + data_len,
-                        reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age);
-
-    if (jdata) {
-        env->SetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    return result;
-}
-
-class ScopedPcap {
-  public:
-    explicit ScopedPcap(pcap_t* pcap) : pcap_ptr(pcap) {}
-    ~ScopedPcap() {
-        pcap_close(pcap_ptr);
-    }
-
-    pcap_t* get() const { return pcap_ptr; };
-  private:
-    pcap_t* const pcap_ptr;
-};
-
-class ScopedFILE {
-  public:
-    explicit ScopedFILE(FILE* fp) : file(fp) {}
-    ~ScopedFILE() {
-        fclose(file);
-    }
-
-    FILE* get() const { return file; };
-  private:
-    FILE* const file;
-};
-
-static void throwException(JNIEnv* env, const std::string& error) {
-    jclass newExcCls = env->FindClass("java/lang/IllegalStateException");
-    if (newExcCls == 0) {
-      abort();
-      return;
-    }
-    env->ThrowNew(newExcCls, error.c_str());
-}
-
-static jstring com_android_server_ApfTest_compileToBpf(JNIEnv* env, jclass, jstring jfilter) {
-    ScopedUtfChars filter(env, jfilter);
-    std::string bpf_string;
-    ScopedPcap pcap(pcap_open_dead(DLT_EN10MB, 65535));
-    if (pcap.get() == NULL) {
-        throwException(env, "pcap_open_dead failed");
-        return NULL;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return NULL;
-    }
-
-    // Translate BPF program to human-readable format
-    const struct bpf_insn* insn = bpf.bf_insns;
-    for (uint32_t i = 0; i < bpf.bf_len; i++) {
-        bpf_string += bpf_image(insn++, i);
-        bpf_string += "\n";
-    }
-
-    return env->NewStringUTF(bpf_string.c_str());
-}
-
-static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, jstring jfilter,
-        jstring jpcap_filename, jbyteArray japf_program) {
-    ScopedUtfChars filter(env, jfilter);
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, japf_program);
-
-    // Open pcap file for BPF filtering
-    ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    ScopedPcap bpf_pcap(pcap_fopen_offline(bpf_fp.get(), pcap_error));
-    if (bpf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Open pcap file for APF filtering
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(bpf_pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return false;
-    }
-
-    // Install BPF filter on bpf_pcap
-    if (pcap_setfilter(bpf_pcap.get(), &bpf)) {
-        throwException(env, "pcap_setfilter failed");
-        return false;
-    }
-
-    while (1) {
-        pcap_pkthdr bpf_header, apf_header;
-        // Run BPF filter to the next matching packet.
-        const uint8_t* bpf_packet = pcap_next(bpf_pcap.get(), &bpf_header);
-
-        // Run APF filter to the next matching packet.
-        const uint8_t* apf_packet;
-        do {
-            apf_packet = pcap_next(apf_pcap.get(), &apf_header);
-        } while (apf_packet != NULL && !accept_packet(
-                reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())),
-                apf_program.size(), 0 /* data_len */,
-                apf_packet, apf_header.len, 0 /* filter_age */));
-
-        // Make sure both filters matched the same packet.
-        if (apf_packet == NULL && bpf_packet == NULL)
-            break;
-        if (apf_packet == NULL || bpf_packet == NULL)
-            return false;
-        if (apf_header.len != bpf_header.len ||
-                apf_header.ts.tv_sec != bpf_header.ts.tv_sec ||
-                apf_header.ts.tv_usec != bpf_header.ts.tv_usec ||
-                memcmp(apf_packet, bpf_packet, apf_header.len))
-            return false;
-    }
-    return true;
-}
-
-static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram,
-        jbyteArray jdata, jstring jpcap_filename) {
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, jprogram);
-    uint32_t apf_program_len = (uint32_t)apf_program.size();
-    uint32_t data_len = env->GetArrayLength(jdata);
-    pcap_pkthdr apf_header;
-    const uint8_t* apf_packet;
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    std::vector<uint8_t> buf(apf_program_len + data_len, 0);
-
-    // Merge program and data into a single buffer.
-    env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data()));
-    env->GetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-
-    // Open pcap file
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) {
-        int result = accept_packet(buf.data(), apf_program_len,
-                                    apf_program_len + data_len, apf_packet, apf_header.len, 0);
-
-        // Return false once packet passes the filter
-        if (result) {
-            env->SetByteArrayRegion(jdata, 0, data_len,
-                                    reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-            return false;
-         }
-    }
-
-    env->SetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-    return true;
-}
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        ALOGE("ERROR: GetEnv failed");
-        return -1;
-    }
-
-    static JNINativeMethod gMethods[] = {
-            { "apfSimulate", "([B[B[BI)I",
-                    (void*)com_android_server_ApfTest_apfSimulate },
-            { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;",
-                    (void*)com_android_server_ApfTest_compileToBpf },
-            { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z",
-                    (void*)com_android_server_ApfTest_compareBpfApf },
-            { "dropsAllPackets", "([B[BLjava/lang/String;)Z",
-                    (void*)com_android_server_ApfTest_dropsAllPackets },
-    };
-
-    jniRegisterNativeMethods(env, "android/net/apf/ApfTest",
-            gMethods, ARRAY_SIZE(gMethods));
-
-    return JNI_VERSION_1_6;
-}
diff --git a/packages/NetworkStack/tests/unit/res/raw/apf.pcap b/packages/NetworkStack/tests/unit/res/raw/apf.pcap
deleted file mode 100644
index 963165f..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apf.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
deleted file mode 100644
index 6f69c4a..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
deleted file mode 100644
index 8f2b968..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
+++ /dev/null
@@ -1,2110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_STREAM;
-
-import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfFilter.ApfConfiguration;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-import com.android.server.networkstack.tests.R;
-import com.android.server.util.NetworkStackConstants;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Tests for APF program generator and interpreter.
- *
- * Build, install and run with:
- *  runtest frameworks-net -c android.net.apf.ApfTest
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ApfTest {
-    private static final int TIMEOUT_MS = 500;
-    private static final int MIN_APF_VERSION = 2;
-
-    @Mock IpConnectivityLog mLog;
-    @Mock Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        // Load up native shared library containing APF interpreter exposed via JNI.
-        System.loadLibrary("networkstacktestsjni");
-    }
-
-    private static final String TAG = "ApfTest";
-    // Expected return codes from APF interpreter.
-    private static final int PASS = 1;
-    private static final int DROP = 0;
-    // Interpreter will just accept packets without link layer headers, so pad fake packet to at
-    // least the minimum packet size.
-    private static final int MIN_PKT_SIZE = 15;
-
-    private static final ApfCapabilities MOCK_APF_CAPABILITIES =
-      new ApfCapabilities(2, 1700, ARPHRD_ETHER);
-
-    private static final boolean DROP_MULTICAST = true;
-    private static final boolean ALLOW_MULTICAST = false;
-
-    private static final boolean DROP_802_3_FRAMES = true;
-    private static final boolean ALLOW_802_3_FRAMES = false;
-
-    // Constants for opcode encoding
-    private static final byte LI_OP   = (byte)(13 << 3);
-    private static final byte LDDW_OP = (byte)(22 << 3);
-    private static final byte STDW_OP = (byte)(23 << 3);
-    private static final byte SIZE0   = (byte)(0 << 1);
-    private static final byte SIZE8   = (byte)(1 << 1);
-    private static final byte SIZE16  = (byte)(2 << 1);
-    private static final byte SIZE32  = (byte)(3 << 1);
-    private static final byte R1 = 1;
-
-    private static ApfConfiguration getDefaultConfig() {
-        ApfFilter.ApfConfiguration config = new ApfConfiguration();
-        config.apfCapabilities = MOCK_APF_CAPABILITIES;
-        config.multicastFilter = ALLOW_MULTICAST;
-        config.ieee802_3Filter = ALLOW_802_3_FRAMES;
-        config.ethTypeBlackList = new int[0];
-        return config;
-    }
-
-    private static String label(int code) {
-        switch (code) {
-            case PASS: return "PASS";
-            case DROP: return "DROP";
-            default:   return "UNKNOWN";
-        }
-    }
-
-    private static void assertReturnCodesEqual(int expected, int got) {
-        assertEquals(label(expected), label(got));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, filterAge));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, 0));
-    }
-
-    private void assertPass(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(PASS, program, packet, filterAge);
-    }
-
-    private void assertPass(byte[] program, byte[] packet) {
-        assertVerdict(PASS, program, packet);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(DROP, program, packet, filterAge);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet) {
-        assertVerdict(DROP, program, packet);
-    }
-
-    private void assertProgramEquals(byte[] expected, byte[] program) throws AssertionError {
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected, program)) {
-            throw new AssertionError(
-                    "\nexpected: " + HexDump.toHexString(expected) +
-                    "\nactual:   " + HexDump.toHexString(program));
-        }
-    }
-
-    private void assertDataMemoryContents(
-            int expected, byte[] program, byte[] packet, byte[] data, byte[] expected_data)
-            throws IllegalInstructionException, Exception {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, data, 0 /* filterAge */));
-
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected_data, data)) {
-            throw new Exception(
-                    "\nprogram:     " + HexDump.toHexString(program) +
-                    "\ndata memory: " + HexDump.toHexString(data) +
-                    "\nexpected:    " + HexDump.toHexString(expected_data));
-        }
-    }
-
-    private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, null,
-              filterAge));
-    }
-
-    private void assertPass(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, packet, filterAge);
-    }
-
-    private void assertDrop(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, packet, filterAge);
-    }
-
-    private void assertPass(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    private void assertDrop(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    /**
-     * Test each instruction by generating a program containing the instruction,
-     * generating bytecode for that program and running it through the
-     * interpreter to verify it functions correctly.
-     */
-    @Test
-    public void testApfInstructions() throws IllegalInstructionException {
-        // Empty program should pass because having the program counter reach the
-        // location immediately after the program indicates the packet should be
-        // passed to the AP.
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        assertPass(gen);
-
-        // Test jumping to pass label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.PASS_LABEL);
-        byte[] program = gen.generate();
-        assertEquals(1, program.length);
-        assertEquals((14 << 3) | (0 << 1) | 0, program[0]);
-        assertPass(program, new byte[MIN_PKT_SIZE], 0);
-
-        // Test jumping to drop label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(2, program.length);
-        assertEquals((14 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertDrop(program, new byte[15], 15);
-
-        // Test jumping if equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if not equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0EqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load immediate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(-1234567890);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addOr(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addAnd(123456789);
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLeftShift(1);
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addRightShift(1);
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addMul(2);
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addDiv(2);
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDiv(0);
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, -1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addOrR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 123456789);
-        gen.addAndR1();
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, -1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addMulR1();
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addDivR1();
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDivR1();
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test byte load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 1);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 16);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad16(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad32(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test byte indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad8Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 8);
-        gen.addLoad8Indexed(Register.R0, 8);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad16Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad32Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test jumping if greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 2);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set in register.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load from memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, 0);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test store to memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addStoreToMemory(Register.R1, 12);
-        gen.addLoadFromMemory(Register.R0, 12);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test filter age pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen, new byte[MIN_PKT_SIZE], 1234567890);
-
-        // Test packet size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test IPv4 header size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(20, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0);
-
-        // Test not.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNot(Register.R0);
-        gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test negate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNeg(Register.R0);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test move.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addMove(Register.R0);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addMove(Register.R1);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test swap.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jump if bytes not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(6, program.length);
-        assertEquals((13 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertEquals(((20 << 3) | (1 << 1) | 0) - 256, program[2]);
-        assertEquals(1, program[3]);
-        assertEquals(1, program[4]);
-        assertEquals(123, program[5]);
-        assertDrop(program, new byte[MIN_PKT_SIZE], 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0};
-        assertPass(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        assertDrop(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL);
-        byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0};
-        assertDrop(gen, packet12345, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,3,4,5}, gen.DROP_LABEL);
-        assertPass(gen, packet12345, 0);
-    }
-
-    @Test(expected = ApfGenerator.IllegalInstructionException.class)
-    public void testApfGeneratorWantsV2OrGreater() throws Exception {
-        // The minimum supported APF version is 2.
-        new ApfGenerator(1);
-    }
-
-    @Test
-    public void testApfDataOpcodesWantApfV3() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        try {
-            gen.addStoreData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-        try {
-            gen.addLoadData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-    }
-
-    /**
-     * Test that the generator emits immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 0-byte immediate: li R0, 0
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 0);
-        assertProgramEquals(new byte[]{LI_OP | SIZE0}, gen.generate());
-
-        // 1-byte immediate: li R0, 42
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, 42}, gen.generate());
-
-        // 2-byte immediate: li R1, 0x1234
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R1, 0x1234);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, 0x12, 0x34}, gen.generate());
-
-        // 4-byte immediate: li R0, 0x12345678
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x12345678);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, 0x12, 0x34, 0x56, 0x78},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator emits negative immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testNegativeImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 1-byte negative immediate: li R0, -42
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, -42}, gen.generate());
-
-        // 2-byte negative immediate: li R1, -0x1122
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // 4-byte negative immediate: li R0, -0x11223344
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -0x11223344);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator correctly emits positive and negative immediates for LDDW/STDW.
-     */
-    @Test
-    public void testLoadStoreDataEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // Load data with no offset: lddw R0, [0 + r1]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R0, 0);
-        assertProgramEquals(new byte[]{LDDW_OP | SIZE0}, gen.generate());
-
-        // Store data with 8bit negative offset: lddw r0, [-42 + r1]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R0, -42);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE8, -42}, gen.generate());
-
-        // Store data to R1 with 16bit negative offset: stdw r1, [-0x1122 + r0]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // Load data to R1 with 32bit negative offset: lddw r1, [0xDEADBEEF + r0]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R1, 0xDEADBEEF);
-        assertProgramEquals(
-                new byte[]{LDDW_OP | SIZE32 | R1, (byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF},
-                gen.generate());
-    }
-
-    /**
-     * Test that the interpreter correctly executes STDW with a negative 8bit offset
-     */
-    @Test
-    public void testApfDataWrite() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
-        byte[] expected_data = data.clone();
-
-        // No memory access instructions: should leave the data segment untouched.
-        ApfGenerator gen = new ApfGenerator(3);
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Expect value 0x87654321 to be stored starting from address -11 from the end of the
-        // data buffer, in big-endian order.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x87654321);
-        gen.addLoadImmediate(Register.R1, -5);
-        gen.addStoreData(Register.R0, -6);  // -5 + -6 = -11 (offset +5 with data_len=16)
-        expected_data[5] = (byte)0x87;
-        expected_data[6] = (byte)0x65;
-        expected_data[7] = (byte)0x43;
-        expected_data[8] = (byte)0x21;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW with a negative 16bit offset
-     */
-    @Test
-    public void testApfDataRead() throws IllegalInstructionException, Exception {
-        // Program that DROPs if address 10 (-6) contains 0x87654321.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, 1000);
-        gen.addLoadData(Register.R0, -1006);  // 1000 + -1006 = -6 (offset +10 with data_len=16)
-        gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
-        byte[] program = gen.generate();
-        byte[] packet = new byte[MIN_PKT_SIZE];
-
-        // Content is incorrect (last byte does not match) -> PASS
-        byte[] data = new byte[16];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x00;  // != 0x21
-        byte[] expected_data = data.clone();
-        assertDataMemoryContents(PASS, program, packet, data, expected_data);
-
-        // Fix the last byte -> conditional jump taken -> DROP
-        data[13] = (byte)0x21;
-        expected_data = data;
-        assertDataMemoryContents(DROP, program, packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW followed by a STDW.
-     * To cover a few more edge cases, LDDW has a 0bit offset, while STDW has a positive 8bit
-     * offset.
-     */
-    @Test
-    public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -22);
-        gen.addLoadData(Register.R0, 0);  // Load from address 32 -22 + 0 = 10
-        gen.addAdd(0x78453412);  // 87654321 + 78453412 = FFAA7733
-        gen.addStoreData(Register.R0, 4);  // Write back to address 32 -22 + 4 = 14
-
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x21;
-        byte[] expected_data = data.clone();
-        expected_data[14] = (byte)0xFF;
-        expected_data[15] = (byte)0xAA;
-        expected_data[16] = (byte)0x77;
-        expected_data[17] = (byte)0x33;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    @Test
-    public void testApfDataBoundChecking() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        byte[] expected_data = data;
-
-        // Program that DROPs unconditionally. This is our the baseline.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addLoadData(Register.R1, 7);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // Same program as before, but this time we're trying to load past the end of the data.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, 15);  // 20 + 15 > 32
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Subtracting an immediate should work...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -4);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...and underflowing simply wraps around to the end of the buffer...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -30);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...but doesn't allow accesses before the start of the buffer
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -1000);
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Generate some BPF programs, translate them to APF, then run APF and BPF programs
-     * over packet traces and verify both programs filter out the same packets.
-     */
-    @Test
-    public void testApfAgainstBpf() throws Exception {
-        String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
-                "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
-                "arp or icmp6 or portrange 53-54", "portrange 53-54 or portrange 100-50000",
-                "tcp[tcpflags] & (tcp-ack|tcp-fin) != 0 and (ip[2:2] > 57 or icmp)" };
-        String pcap_filename = stageFile(R.raw.apf);
-        for (String tcpdump_filter : tcpdump_filters) {
-            byte[] apf_program = Bpf2Apf.convert(compileToBpf(tcpdump_filter));
-            assertTrue("Failed to match for filter: " + tcpdump_filter,
-                    compareBpfApf(tcpdump_filter, pcap_filename, apf_program));
-        }
-    }
-
-    /**
-     * Generate APF program, run pcap file though APF filter, then check all the packets in the file
-     * should be dropped.
-     */
-    @Test
-    public void testApfFilterPcapFile() throws Exception {
-        final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151};
-        String pcapFilename = stageFile(R.raw.apfPcap);
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER);
-        config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES;
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        byte[] program = ipClientCallback.getApfProgram();
-        byte[] data = new byte[ApfFilter.Counter.totalSize()];
-        final boolean result;
-
-        result = dropsAllPackets(program, data, pcapFilename);
-        Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false));
-
-        assertTrue("Failed to drop all packets by filter. \nAPF counters:" +
-            HexDump.toHexString(data, false), result);
-    }
-
-    private class MockIpClientCallback extends IpClientCallbacksWrapper {
-        private final ConditionVariable mGotApfProgram = new ConditionVariable();
-        private byte[] mLastApfProgram;
-
-        MockIpClientCallback() {
-            super(mock(IIpClientCallbacks.class), mock(SharedLog.class));
-        }
-
-        @Override
-        public void installPacketFilter(byte[] filter) {
-            mLastApfProgram = filter;
-            mGotApfProgram.open();
-        }
-
-        public void resetApfProgramWait() {
-            mGotApfProgram.close();
-        }
-
-        public byte[] getApfProgram() {
-            assertTrue(mGotApfProgram.block(TIMEOUT_MS));
-            return mLastApfProgram;
-        }
-
-        public void assertNoProgramUpdate() {
-            assertFalse(mGotApfProgram.block(TIMEOUT_MS));
-        }
-    }
-
-    private static class TestApfFilter extends ApfFilter {
-        public static final byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
-
-        private FileDescriptor mWriteSocket;
-        private final long mFixedTimeMs = SystemClock.elapsedRealtime();
-
-        public TestApfFilter(Context context, ApfConfiguration config,
-                IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) throws Exception {
-            super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log);
-        }
-
-        // Pretend an RA packet has been received and show it to ApfFilter.
-        public void pretendPacketReceived(byte[] packet) throws IOException, ErrnoException {
-            // ApfFilter's ReceiveThread will be waiting to read this.
-            Os.write(mWriteSocket, packet, 0, packet.length);
-        }
-
-        @Override
-        protected long currentTimeSeconds() {
-            return mFixedTimeMs / DateUtils.SECOND_IN_MILLIS;
-        }
-
-        @Override
-        void maybeStartFilter() {
-            mHardwareAddress = MOCK_MAC_ADDR;
-            installNewProgramLocked();
-
-            // Create two sockets, "readSocket" and "mWriteSocket" and connect them together.
-            FileDescriptor readSocket = new FileDescriptor();
-            mWriteSocket = new FileDescriptor();
-            try {
-                Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mWriteSocket, readSocket);
-            } catch (ErrnoException e) {
-                fail();
-                return;
-            }
-            // Now pass readSocket to ReceiveThread as if it was setup to read raw RAs.
-            // This allows us to pretend RA packets have been recieved via pretendPacketReceived().
-            mReceiveThread = new ReceiveThread(readSocket);
-            mReceiveThread.start();
-        }
-
-        @Override
-        public void shutdown() {
-            super.shutdown();
-            IoUtils.closeQuietly(mWriteSocket);
-        }
-    }
-
-    private static final int ETH_HEADER_LEN               = 14;
-    private static final int ETH_DEST_ADDR_OFFSET         = 0;
-    private static final int ETH_ETHERTYPE_OFFSET         = 12;
-    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
-            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-    private static final int IPV4_HEADER_LEN          = 20;
-    private static final int IPV4_VERSION_IHL_OFFSET  = ETH_HEADER_LEN + 0;
-    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int IPV4_PROTOCOL_OFFSET     = ETH_HEADER_LEN + 9;
-    private static final int IPV4_SRC_ADDR_OFFSET     = ETH_HEADER_LEN + 12;
-    private static final int IPV4_DEST_ADDR_OFFSET    = ETH_HEADER_LEN + 16;
-
-    private static final int IPV4_TCP_HEADER_LEN           = 20;
-    private static final int IPV4_TCP_HEADER_OFFSET        = ETH_HEADER_LEN + IPV4_HEADER_LEN;
-    private static final int IPV4_TCP_SRC_PORT_OFFSET      = IPV4_TCP_HEADER_OFFSET + 0;
-    private static final int IPV4_TCP_DEST_PORT_OFFSET     = IPV4_TCP_HEADER_OFFSET + 2;
-    private static final int IPV4_TCP_SEQ_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 4;
-    private static final int IPV4_TCP_ACK_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 8;
-    private static final int IPV4_TCP_HEADER_LENGTH_OFFSET = IPV4_TCP_HEADER_OFFSET + 12;
-    private static final int IPV4_TCP_HEADER_FLAG_OFFSET   = IPV4_TCP_HEADER_OFFSET + 13;
-
-    private static final int IPV4_UDP_HEADER_OFFSET    = ETH_HEADER_LEN + IPV4_HEADER_LEN;;
-    private static final int IPV4_UDP_SRC_PORT_OFFSET  = IPV4_UDP_HEADER_OFFSET + 0;
-    private static final int IPV4_UDP_DEST_PORT_OFFSET = IPV4_UDP_HEADER_OFFSET + 2;
-    private static final int IPV4_UDP_LENGTH_OFFSET    = IPV4_UDP_HEADER_OFFSET + 4;
-    private static final int IPV4_UDP_PAYLOAD_OFFSET   = IPV4_UDP_HEADER_OFFSET + 8;
-    private static final byte[] IPV4_BROADCAST_ADDRESS =
-            {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
-
-    private static final int IPV6_HEADER_LEN             = 40;
-    private static final int IPV6_NEXT_HEADER_OFFSET     = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET        = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET       = ETH_HEADER_LEN + 24;
-    private static final int IPV6_TCP_HEADER_OFFSET      = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int IPV6_TCP_SRC_PORT_OFFSET    = IPV6_TCP_HEADER_OFFSET + 0;
-    private static final int IPV6_TCP_DEST_PORT_OFFSET   = IPV6_TCP_HEADER_OFFSET + 2;
-    private static final int IPV6_TCP_SEQ_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 4;
-    private static final int IPV6_TCP_ACK_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 8;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS   =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-    private static final byte[] IPV6_ALL_ROUTERS_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
-
-    private static final int ICMP6_TYPE_OFFSET           = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int ICMP6_ROUTER_SOLICITATION   = 133;
-    private static final int ICMP6_ROUTER_ADVERTISEMENT  = 134;
-    private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
-    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
-
-    private static final int ICMP6_RA_HEADER_LEN = 16;
-    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-    private static final int ICMP6_RA_CHECKSUM_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-    private static final int ICMP6_RA_OPTION_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-
-    private static final int ICMP6_PREFIX_OPTION_TYPE                      = 3;
-    private static final int ICMP6_PREFIX_OPTION_LEN                       = 32;
-    private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET     = 4;
-    private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-
-    // From RFC6106: Recursive DNS Server option
-    private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-    // From RFC6106: DNS Search List option
-    private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-    // From RFC4191: Route Information option
-    private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-    // Above three options all have the same format:
-    private static final int ICMP6_4_BYTE_OPTION_LEN      = 8;
-    private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-    private static final int ICMP6_4_BYTE_LIFETIME_LEN    = 4;
-
-    private static final int UDP_HEADER_LEN              = 8;
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 22;
-
-    private static final int DHCP_CLIENT_PORT       = 68;
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48;
-
-    private static final int ARP_HEADER_OFFSET          = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_REQUEST_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 1  // Opcode: request (1)
-    };
-    private static final byte[] ARP_IPV4_REPLY_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 2  // Opcode: reply (2)
-    };
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-
-    private static final byte[] MOCK_IPV4_ADDR           = {10, 0, 0, 1};
-    private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
-    private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
-    private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
-    private static final byte[] IPV4_SOURCE_ADDR         = {10, 0, 0, 3};
-    private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR1   = {0, 0, 1, 2};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR2   = {3, 4, 0, 0};
-    private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
-
-    // Helper to initialize a default apfFilter.
-    private ApfFilter setupApfFilter(
-            IpClientCallbacksWrapper ipClientCallback, ApfConfiguration config) throws Exception {
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        return apfFilter;
-    }
-
-    @Test
-    public void testApfFilterIPv4() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 packet is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify L2 unicast to IPv4 broadcast addresses is dropped (b/30231088)
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-
-        // Verify multicast/broadcast IPv4, not DHCP to us, is dropped
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP);
-        assertDrop(program, packet.array());
-        packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify broadcast IPv4 DHCP to us is passed
-        put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 DHCP to us is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterIPv6() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty IPv6 packet is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 packet is passed
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 NA packet is passed
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT);
-        assertPass(program, packet.array());
-
-        // Verify ICMPv6 NA to ff02::1 is dropped
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify ICMPv6 RS to any is dropped
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_SOLICITATION);
-        assertDrop(program, packet.array());
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_ROUTERS_ADDRESS);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticast() throws Exception {
-        final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
-        final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
-        final byte[] multicastIpv4Addr = {(byte)224,0,0,1};
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Construct IPv4 and IPv6 multicast packets.
-        ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]);
-        mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]);
-        mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
-        put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Construct IPv4 broadcast packet.
-        ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-
-        // Construct IPv4 broadcast with L2 unicast address packet (b/30231088).
-        ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]);
-        bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR);
-        bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr);
-
-        // Verify initially disabled multicast filter is off
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Turn on multicast filter and verify it works
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(true);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4packet2.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Turn off multicast filter and verify it's off
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(false);
-        program = ipClientCallback.getApfProgram();
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Verify it can be initialized to on
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Verify that ICMPv6 multicast is not dropped.
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, mcastv6packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticastPingWhileDozing() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, getDefaultConfig());
-
-        // Construct a multicast ICMPv6 ECHO request.
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMPV6_ECHO_REQUEST_TYPE);
-        put(packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Normally, we let multicast pings alone...
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...and even while dozing...
-        apfFilter.setDozeMode(true);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...but when the multicast filter is also enabled, drop the multicast pings to save power.
-        apfFilter.setMulticastFilter(true);
-        assertDrop(ipClientCallback.getApfProgram(), packet.array());
-
-        // However, we should still let through all other ICMPv6 types.
-        ByteBuffer raPacket = ByteBuffer.wrap(packet.array().clone());
-        raPacket.put(ICMP6_TYPE_OFFSET, (byte) NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT);
-        assertPass(ipClientCallback.getApfProgram(), raPacket.array());
-
-        // Now wake up from doze mode to ensure that we no longer drop the packets.
-        // (The multicast filter is still enabled at this point).
-        apfFilter.setDozeMode(false);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilter802_3() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now turn on the filter
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IEEE802.3 frame is dropped
-        // In this case ethtype is used for payload length
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)(100 - 14));
-        assertDrop(program, packet.array());
-
-        // Verify that IPv4 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify that IPv6 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterEthTypeBL() throws Exception {
-        final int[] emptyBlackList = {};
-        final int[] ipv4BlackList = {ETH_P_IP};
-        final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now add IPv4 to the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now let us have both IPv4 and IPv6 in the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4Ipv6BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    private byte[] getProgram(MockIpClientCallback cb, ApfFilter filter, LinkProperties lp) {
-        cb.resetApfProgramWait();
-        filter.setLinkProperties(lp);
-        return cb.getApfProgram();
-    }
-
-    private void verifyArpFilter(byte[] program, int filterResult) {
-        // Verify ARP request packet
-        assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR));
-        assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
-        assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
-
-        // Verify ARP reply packets from different source ip
-        assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
-
-        // Verify unicast ARP reply packet is always accepted.
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-
-        // Verify GARP reply packets are always filtered
-        assertDrop(program, garpReply());
-    }
-
-    @Test
-    public void testApfFilterArp() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-
-        // Verify initially ARP request filter is off, and GARP filter is on.
-        verifyArpFilter(ipClientCallback.getApfProgram(), PASS);
-
-        // Inform ApfFilter of our address and verify ARP filtering is on
-        LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24);
-        LinkProperties lp = new LinkProperties();
-        assertTrue(lp.addLinkAddress(linkAddress));
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, lp), DROP);
-
-        // Inform ApfFilter of loss of IP and verify ARP filtering is off
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, new LinkProperties()), PASS);
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] arpReply(byte[] sip, byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] arpRequestBroadcast(byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] garpReply() {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR);
-        return packet.array();
-    }
-
-    private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 5};
-    private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 6};
-    private static final byte[] IPV4_ANOTHER_ADDR = {10, 0 , 0, 7};
-    private static final byte[] IPV6_KEEPALIVE_SRC_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf1};
-    private static final byte[] IPV6_KEEPALIVE_DST_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf2};
-    private static final byte[] IPV6_ANOTHER_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf5};
-
-    @Test
-    public void testApfFilterKeepaliveAck() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 12345;
-        final int dstPort = 54321;
-        final int seqNum = 2123456789;
-        final int ackNum = 1234567890;
-        final int anotherSrcPort = 23456;
-        final int anotherDstPort = 65432;
-        final int anotherSeqNum = 2123456780;
-        final int anotherAckNum = 1123456789;
-        final int slot1 = 1;
-        final int slot2 = 2;
-        final int window = 14480;
-        final int windowScale = 4;
-
-        // src: 10.0.0.5, port: 12345
-        // dst: 10.0.0.6, port: 54321
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-        parcel.seq = seqNum;
-        parcel.ack = ackNum;
-
-        apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive ack packet is dropped
-        // src: 10.0.0.6, port: 54321
-        // dst: 10.0.0.5, port: 12345
-        assertDrop(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        // Verify IPv4 non-keepalive ack packet from the same source address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 10 /* dataLength */));
-        // Verify IPv4 packet from another address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                        anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-        // Remove IPv4 keepalive filter
-        apfFilter.removeKeepalivePacketFilter(slot1);
-
-        try {
-            // src: 2404:0:0:0:0:0:faf1, port: 12345
-            // dst: 2404:0:0:0:0:0:faf2, port: 54321
-            srcAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_SRC_ADDR);
-            dstAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_DST_ADDR);
-
-            final TcpKeepalivePacketDataParcelable ipv6Parcel =
-                    new TcpKeepalivePacketDataParcelable();
-            ipv6Parcel.srcAddress = srcAddr.getAddress();
-            ipv6Parcel.srcPort = srcPort;
-            ipv6Parcel.dstAddress = dstAddr.getAddress();
-            ipv6Parcel.dstPort = dstPort;
-            ipv6Parcel.seq = seqNum;
-            ipv6Parcel.ack = ackNum;
-
-            apfFilter.addTcpKeepalivePacketFilter(slot1, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove IPv6 keepalive filter
-            apfFilter.removeKeepalivePacketFilter(slot1);
-
-            // Verify multiple filters
-            apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-            apfFilter.addTcpKeepalivePacketFilter(slot2, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv4 keepalive ack packet is dropped
-            // src: 10.0.0.6, port: 54321
-            // dst: 10.0.0.5, port: 12345
-            assertDrop(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-            // Verify IPv4 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-            // Verify IPv4 packet from another address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove keepalive filters
-            apfFilter.removeKeepalivePacketFilter(slot1);
-            apfFilter.removeKeepalivePacketFilter(slot2);
-        } catch (UnsupportedOperationException e) {
-            // TODO: support V6 packets
-        }
-
-        program = cb.getApfProgram();
-
-        // Verify IPv4, IPv6 packets are passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1));
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum));
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4Packet(byte[] sip, byte[] dip, int sport,
-            int dport, int seq, int ack, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN;
-
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_TCP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV4_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV4_TCP_ACK_NUM_OFFSET, ack);
-
-        // TCP header length 5(20 bytes), reserved 3 bits, NS=0
-        packet.put(IPV4_TCP_HEADER_LENGTH_OFFSET, (byte) 0x50);
-        // TCP flags: ACK set
-        packet.put(IPV4_TCP_HEADER_FLAG_OFFSET, (byte) 0x10);
-        return packet.array();
-    }
-
-    private static byte[] ipv6Packet(byte[] sip, byte[] tip, int sport,
-            int dport, int seq, int ack) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IPV6);
-        put(packet, IPV6_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV6_DEST_ADDR_OFFSET, tip);
-        packet.putShort(IPV6_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV6_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV6_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV6_TCP_ACK_NUM_OFFSET, ack);
-        return packet.array();
-    }
-
-    @Test
-    public void testApfFilterNattKeepalivePacket() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 1024;
-        final int dstPort = 4500;
-        final int slot1 = 1;
-        // NAT-T keepalive
-        final byte[] kaPayload = {(byte) 0xff};
-        final byte[] nonKaPayload = {(byte) 0xfe};
-
-        // src: 10.0.0.5, port: 1024
-        // dst: 10.0.0.6, port: 4500
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-
-        apfFilter.addNattKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive packet is dropped
-        // src: 10.0.0.6, port: 4500
-        // dst: 10.0.0.5, port: 1024
-        byte[] pkt = ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR,
-                    IPV4_KEEPALIVE_SRC_ADDR, dstPort, srcPort, 1 /* dataLength */);
-        System.arraycopy(kaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, kaPayload.length);
-        assertDrop(program, pkt);
-
-        // Verify a packet with payload length 1 byte but it is not 0xff will pass the filter.
-        System.arraycopy(nonKaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, nonKaPayload.length);
-        assertPass(program, pkt);
-
-        // Verify IPv4 non-keepalive response packet from the same source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        // Verify IPv4 non-keepalive response packet from other source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        apfFilter.removeKeepalivePacketFilter(slot1);
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4UdpPacket(byte[] sip, byte[] dip, int sport,
-            int dport, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + UDP_HEADER_LEN;
-        final int udpLength = UDP_HEADER_LEN + dataLength;
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_UDP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_UDP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_UDP_DEST_PORT_OFFSET, (short) dport);
-        packet.putShort(IPV4_UDP_LENGTH_OFFSET, (short) udpLength);
-
-        return packet.array();
-    }
-
-    // Verify that the last program pushed to the IpClient.Callback properly filters the
-    // given packet for the given lifetime.
-    private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
-        final int FRACTION_OF_LIFETIME = 6;
-        final int ageLimit = lifetime / FRACTION_OF_LIFETIME;
-
-        // Verify new program should drop RA for 1/6th its lifetime and pass afterwards.
-        assertDrop(program, packet.array());
-        assertDrop(program, packet.array(), ageLimit);
-        assertPass(program, packet.array(), ageLimit + 1);
-        assertPass(program, packet.array(), lifetime);
-        // Verify RA checksum is ignored
-        final short originalChecksum = packet.getShort(ICMP6_RA_CHECKSUM_OFFSET);
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, originalChecksum);
-
-        // Verify other changes to RA make it not match filter
-        final byte originalFirstByte = packet.get(0);
-        packet.put(0, (byte)-1);
-        assertPass(program, packet.array());
-        packet.put(0, (byte)0);
-        assertDrop(program, packet.array());
-        packet.put(0, originalFirstByte);
-    }
-
-    // Test that when ApfFilter is shown the given packet, it generates a program to filter it
-    // for the given lifetime.
-    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
-        // Verify new program generated if ApfFilter witnesses RA
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        byte[] program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, packet, lifetime);
-    }
-
-    private void verifyRaEvent(RaEvent expected) {
-        ArgumentCaptor<IpConnectivityLog.Event> captor =
-                ArgumentCaptor.forClass(IpConnectivityLog.Event.class);
-        verify(mLog, atLeastOnce()).log(captor.capture());
-        RaEvent got = lastRaEvent(captor.getAllValues());
-        if (!raEventEquals(expected, got)) {
-            assertEquals(expected, got);  // fail for printing an assertion error message.
-        }
-    }
-
-    private RaEvent lastRaEvent(List<IpConnectivityLog.Event> events) {
-        RaEvent got = null;
-        for (Parcelable ev : events) {
-            if (ev instanceof RaEvent) {
-                got = (RaEvent) ev;
-            }
-        }
-        return got;
-    }
-
-    private boolean raEventEquals(RaEvent ev1, RaEvent ev2) {
-        return (ev1 != null) && (ev2 != null)
-                && (ev1.routerLifetime == ev2.routerLifetime)
-                && (ev1.prefixValidLifetime == ev2.prefixValidLifetime)
-                && (ev1.prefixPreferredLifetime == ev2.prefixPreferredLifetime)
-                && (ev1.routeInfoLifetime == ev2.routeInfoLifetime)
-                && (ev1.rdnssLifetime == ev2.rdnssLifetime)
-                && (ev1.dnsslLifetime == ev2.dnsslLifetime);
-    }
-
-    private void assertInvalidRa(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet) throws IOException, ErrnoException {
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        ipClientCallback.assertNoProgramUpdate();
-    }
-
-    @Test
-    public void testApfFilterRa() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        final int ROUTER_LIFETIME = 1000;
-        final int PREFIX_VALID_LIFETIME = 200;
-        final int PREFIX_PREFERRED_LIFETIME = 100;
-        final int RDNSS_LIFETIME  = 300;
-        final int ROUTE_LIFETIME  = 400;
-        // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000.
-        final int DNSSL_LIFETIME  = 2000;
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET = ETH_HEADER_LEN;
-        // IPv6, traffic class = 0, flow label = 0x12345
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;
-
-        // Verify RA is passed the first time
-        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
-        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
-        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
-        basePacket.position(IPV6_DEST_ADDR_OFFSET);
-        basePacket.put(IPV6_ALL_NODES_ADDRESS);
-        assertPass(program, basePacket.array());
-
-        verifyRaLifetime(apfFilter, ipClientCallback, basePacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
-
-        ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.clear();
-        newFlowLabelPacket.put(basePacket);
-        // Check that changes are ignored in every byte of the flow label.
-        newFlowLabelPacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL + 0x11111);
-
-        // Ensure zero-length options cause the packet to be silently skipped.
-        // Do this before we test other packets. http://b/29586253
-        ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        zeroLengthOptionPacket.put(basePacket);
-        zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        zeroLengthOptionPacket.put((byte)0);
-        assertInvalidRa(apfFilter, ipClientCallback, zeroLengthOptionPacket);
-
-        // Generate several RAs with different options and lifetimes, and verify when
-        // ApfFilter is shown these packets, it generates programs to filter them for the
-        // appropriate lifetime.
-        ByteBuffer prefixOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_LEN]);
-        basePacket.clear();
-        prefixOptionPacket.put(basePacket);
-        prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8));
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                PREFIX_PREFERRED_LIFETIME);
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                PREFIX_VALID_LIFETIME);
-        verifyRaLifetime(
-                apfFilter, ipClientCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaEvent(new RaEvent(
-                ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
-
-        ByteBuffer rdnssOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        rdnssOptionPacket.put(basePacket);
-        rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE);
-        rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        rdnssOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
-
-        ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        routeInfoOptionPacket.put(basePacket);
-        routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE);
-        routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        routeInfoOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
-
-        ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        dnsslOptionPacket.put(basePacket);
-        dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE);
-        dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        dnsslOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, dnsslOptionPacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
-
-        // Verify that current program filters all five RAs:
-        program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, basePacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, newFlowLabelPacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaLifetime(program, dnsslOptionPacket, ROUTER_LIFETIME);
-
-        apfFilter.shutdown();
-    }
-
-    /**
-     * Stage a file for testing, i.e. make it native accessible. Given a resource ID,
-     * copy that resource into the app's data directory and return the path to it.
-     */
-    private String stageFile(int rawId) throws Exception {
-        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
-        new File(file.getParent()).mkdirs();
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
-            out = new FileOutputStream(file);
-            Streams.copy(in, out);
-        } finally {
-            if (in != null) in.close();
-            if (out != null) out.close();
-        }
-        return file.getAbsolutePath();
-    }
-
-    private static void put(ByteBuffer buffer, int position, byte[] bytes) {
-        final int original = buffer.position();
-        buffer.position(position);
-        buffer.put(bytes);
-        buffer.position(original);
-    }
-
-    @Test
-    public void testRaParsing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.new Ra(packet, packet.length);
-            } catch (ApfFilter.InvalidRaException e) {
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    @Test
-    public void testRaProcessing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.processRa(packet, packet.length);
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    /**
-     * Call the APF interpreter to run {@code program} on {@code packet} with persistent memory
-     * segment {@data} pretending the filter was installed {@code filter_age} seconds ago.
-     */
-    private native static int apfSimulate(byte[] program, byte[] packet, byte[] data,
-        int filter_age);
-
-    /**
-     * Compile a tcpdump human-readable filter (e.g. "icmp" or "tcp port 54") into a BPF
-     * prorgam and return a human-readable dump of the BPF program identical to "tcpdump -d".
-     */
-    private native static String compileToBpf(String filter);
-
-    /**
-     * Open packet capture file {@code pcap_filename} and filter the packets using tcpdump
-     * human-readable filter (e.g. "icmp" or "tcp port 54") compiled to a BPF program and
-     * at the same time using APF program {@code apf_program}.  Return {@code true} if
-     * both APF and BPF programs filter out exactly the same packets.
-     */
-    private native static boolean compareBpfApf(String filter, String pcap_filename,
-            byte[] apf_program);
-
-
-    /**
-     * Open packet capture file {@code pcapFilename} and run it through APF filter. Then
-     * checks whether all the packets are dropped and populates data[] {@code data} with
-     * the APF counters.
-     */
-    private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename);
-
-    @Test
-    public void testBroadcastAddress() throws Exception {
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
-        assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
-        assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22));
-        assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8));
-
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0));
-        assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32));
-        assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24));
-        assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16));
-    }
-
-    public void assertEqualsIp(String expected, int got) throws Exception {
-        int want = bytesToBEInt(InetAddress.getByName(expected).getAddress());
-        assertEquals(want, got);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
deleted file mode 100644
index 5d57cde..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import android.net.apf.ApfGenerator;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * BPF to APF translator.
- *
- * Note: This is for testing purposes only and is not guaranteed to support
- *       translation of all BPF programs.
- *
- * Example usage:
- *   javac net/java/android/net/apf/ApfGenerator.java \
- *         tests/servicestests/src/android/net/apf/Bpf2Apf.java
- *   sudo tcpdump -i em1 -d icmp | java -classpath tests/servicestests/src:net/java \
- *                                      android.net.apf.Bpf2Apf
- */
-public class Bpf2Apf {
-    private static int parseImm(String line, String arg) {
-        if (!arg.startsWith("#0x")) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        final long val_long = Long.parseLong(arg.substring(3), 16);
-        if (val_long < 0 || val_long > Long.parseLong("ffffffff", 16)) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        return new Long((val_long << 32) >> 32).intValue();
-    }
-
-    /**
-     * Convert a single line of "tcpdump -d" (human readable BPF program dump) {@code line} into
-     * APF instruction(s) and append them to {@code gen}. Here's an example line:
-     * (001) jeq      #0x86dd          jt 2    jf 7
-     */
-    private static void convertLine(String line, ApfGenerator gen)
-            throws IllegalInstructionException {
-        if (line.indexOf("(") != 0 || line.indexOf(")") != 4 || line.indexOf(" ") != 5) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        int label = Integer.parseInt(line.substring(1, 4));
-        gen.defineLabel(Integer.toString(label));
-        String opcode = line.substring(6, 10).trim();
-        String arg = line.substring(15, Math.min(32, line.length())).trim();
-        switch (opcode) {
-            case "ld":
-            case "ldh":
-            case "ldb":
-            case "ldx":
-            case "ldxb":
-            case "ldxh":
-                Register dest = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (arg.equals("4*([14]&0xf)")) {
-                    if (!opcode.equals("ldxb")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.equals("#pktlen")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.PACKET_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.startsWith("#0x")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadImmediate(dest, parseImm(line, arg));
-                    break;
-                }
-                if (arg.startsWith("M[")) {
-                    if (!opcode.startsWith("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                    if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                            // Disallow use of pre-filled slots as BPF programs might
-                            // wrongfully assume they're initialized to 0.
-                            (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                    memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, memory_slot);
-                    break;
-                }
-                if (arg.startsWith("[x + ")) {
-                    int offset = Integer.parseInt(arg.substring(5, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32Indexed(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16Indexed(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8Indexed(dest, offset);
-                            break;
-                    }
-                } else {
-                    int offset = Integer.parseInt(arg.substring(1, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8(dest, offset);
-                            break;
-                    }
-                }
-                break;
-            case "st":
-            case "stx":
-                Register src = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (!arg.startsWith("M[")) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                        // Disallow overwriting pre-filled slots
-                        (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                gen.addStoreToMemory(src, memory_slot);
-                break;
-            case "add":
-            case "and":
-            case "or":
-            case "sub":
-                if (arg.equals("x")) {
-                    switch(opcode) {
-                        case "add":
-                            gen.addAddR1();
-                            break;
-                        case "and":
-                            gen.addAndR1();
-                            break;
-                        case "or":
-                            gen.addOrR1();
-                            break;
-                        case "sub":
-                            gen.addNeg(Register.R1);
-                            gen.addAddR1();
-                            gen.addNeg(Register.R1);
-                            break;
-                    }
-                } else {
-                    int imm = parseImm(line, arg);
-                    switch(opcode) {
-                        case "add":
-                            gen.addAdd(imm);
-                            break;
-                        case "and":
-                            gen.addAnd(imm);
-                            break;
-                        case "or":
-                            gen.addOr(imm);
-                            break;
-                        case "sub":
-                            gen.addAdd(-imm);
-                            break;
-                    }
-                }
-                break;
-            case "jeq":
-            case "jset":
-            case "jgt":
-            case "jge":
-                int val = 0;
-                boolean reg_compare;
-                if (arg.startsWith("x")) {
-                    reg_compare = true;
-                } else {
-                    reg_compare = false;
-                    val = parseImm(line, arg);
-                }
-                int jt_offset = line.indexOf("jt");
-                int jf_offset = line.indexOf("jf");
-                String true_label = line.substring(jt_offset + 2, jf_offset).trim();
-                String false_label = line.substring(jf_offset + 2).trim();
-                boolean true_label_is_fallthrough = Integer.parseInt(true_label) == label + 1;
-                boolean false_label_is_fallthrough = Integer.parseInt(false_label) == label + 1;
-                if (true_label_is_fallthrough && false_label_is_fallthrough)
-                    break;
-                switch (opcode) {
-                    case "jeq":
-                        if (!true_label_is_fallthrough) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0EqualsR1(true_label);
-                            } else {
-                                gen.addJumpIfR0Equals(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough) {
-                                gen.addJump(false_label);
-                            } else if (reg_compare) {
-                                gen.addJumpIfR0NotEqualsR1(false_label);
-                            } else {
-                                gen.addJumpIfR0NotEquals(val, false_label);
-                            }
-                        }
-                        break;
-                    case "jset":
-                        if (reg_compare) {
-                            gen.addJumpIfR0AnyBitsSetR1(true_label);
-                        } else {
-                            gen.addJumpIfR0AnyBitsSet(val, true_label);
-                        }
-                        if (!false_label_is_fallthrough) {
-                            gen.addJump(false_label);
-                        }
-                        break;
-                    case "jgt":
-                        if (!true_label_is_fallthrough ||
-                                // We have no less-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!false_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0GreaterThanR1(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough || reg_compare) {
-                                gen.addJump(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val + 1, false_label);
-                            }
-                        }
-                        break;
-                    case "jge":
-                        if (!false_label_is_fallthrough ||
-                                // We have no greater-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!true_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0LessThanR1(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val, false_label);
-                            }
-                        }
-                        if (!true_label_is_fallthrough) {
-                            if (!false_label_is_fallthrough || reg_compare) {
-                                gen.addJump(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val - 1, true_label);
-                            }
-                        }
-                        break;
-                }
-                break;
-            case "ret":
-                if (arg.equals("#0")) {
-                    gen.addJump(gen.DROP_LABEL);
-                } else {
-                    gen.addJump(gen.PASS_LABEL);
-                }
-                break;
-            case "tax":
-                gen.addMove(Register.R1);
-                break;
-            case "txa":
-                gen.addMove(Register.R0);
-                break;
-            default:
-                throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) {@code bpf} into an APF
-     * program and return it.
-     */
-    public static byte[] convert(String bpf) throws IllegalInstructionException {
-        ApfGenerator gen = new ApfGenerator(3);
-        for (String line : bpf.split("\\n")) convertLine(line, gen);
-        return gen.generate();
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) piped in stdin into an
-     * APF program and output it via stdout.
-     */
-    public static void main(String[] args) throws Exception {
-        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-        String line = null;
-        StringBuilder responseData = new StringBuilder();
-        ApfGenerator gen = new ApfGenerator(3);
-        while ((line = in.readLine()) != null) convertLine(line, gen);
-        System.out.write(gen.generate());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
deleted file mode 100644
index f948086..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2018 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.captiveportal;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.MalformedURLException;
-import java.text.ParseException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class CaptivePortalProbeSpecTest {
-
-    @Test
-    public void testGetResult_Regex() throws MalformedURLException, ParseException {
-        // 2xx status or 404, with an empty (match everything) location regex
-        CaptivePortalProbeSpec statusRegexSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://www.google.com@@/@@2[0-9]{2}|404@@/@@");
-
-        // 404, or 301/302 redirect to some HTTPS page under google.com
-        CaptivePortalProbeSpec redirectSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://google.com@@/@@404|30[12]@@/@@https://([0-9a-z]+\\.)*google\\.com.*");
-
-        assertSuccess(statusRegexSpec.getResult(200, null));
-        assertSuccess(statusRegexSpec.getResult(299, "qwer"));
-        assertSuccess(statusRegexSpec.getResult(404, null));
-        assertSuccess(statusRegexSpec.getResult(404, ""));
-
-        assertPortal(statusRegexSpec.getResult(300, null));
-        assertPortal(statusRegexSpec.getResult(399, "qwer"));
-        assertPortal(statusRegexSpec.getResult(500, null));
-
-        assertSuccess(redirectSpec.getResult(404, null));
-        assertSuccess(redirectSpec.getResult(404, ""));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com"));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com/test?q=3"));
-        assertSuccess(redirectSpec.getResult(302, "https://google.com/test?q=3"));
-
-        assertPortal(redirectSpec.getResult(299, "https://google.com/test?q=3"));
-        assertPortal(redirectSpec.getResult(299, ""));
-        assertPortal(redirectSpec.getResult(499, null));
-        assertPortal(redirectSpec.getResult(301, "http://login.portal.example.com/loginpage"));
-        assertPortal(redirectSpec.getResult(302, "http://www.google.com/test?q=3"));
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Empty() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Null() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec(null);
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_MissingParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_TooManyParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@456@@/@@extra");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidStatusRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@unmatched(parenthesis@@/@@456");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidLocationRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@unmatched[[]bracket");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_EmptyURL() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("@@/@@123@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_NoParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("invalid");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_RegexInvalidUrl() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("notaurl@@/@@123@@/@@123");
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesSpec() {
-        final String specUrl = "http://google.com/probe";
-        final String redirectUrl = "https://google.com/probe";
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(
-                specUrl + "@@/@@302@@/@@" + redirectUrl);
-        assertEquals(specUrl, spec.getUrl().toString());
-
-        assertPortal(spec.getResult(302, "http://portal.example.com"));
-        assertSuccess(spec.getResult(302, redirectUrl));
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesFallback() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(null);
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("@@/@@ @@/@@ @@/@@");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("invalid@@/@@123@@/@@456");
-        assertNull(spec);
-    }
-
-    @Test
-    public void testParseSpecOrUseStatusCodeFallback_EmptySpec() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-    }
-
-    private void assertIsStatusSpec(CaptivePortalProbeSpec spec) {
-        assertSuccess(spec.getResult(204, null));
-        assertSuccess(spec.getResult(204, "1234"));
-
-        assertPortal(spec.getResult(200, null));
-        assertPortal(spec.getResult(301, null));
-        assertPortal(spec.getResult(302, "1234"));
-        assertPortal(spec.getResult(399, ""));
-
-        assertFailed(spec.getResult(404, null));
-        assertFailed(spec.getResult(500, "1234"));
-    }
-
-    private void assertPortal(CaptivePortalProbeResult result) {
-        assertTrue(result.isPortal());
-    }
-
-    private void assertSuccess(CaptivePortalProbeResult result) {
-        assertTrue(result.isSuccessful());
-    }
-
-    private void assertFailed(CaptivePortalProbeResult result) {
-        assertTrue(result.isFailed());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
deleted file mode 100644
index 27d7255..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
-import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
-import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static java.lang.String.format;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpLeaseRepositoryTest {
-    private static final Inet4Address TEST_DEF_ROUTER = parseAddr4("192.168.42.247");
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr4("192.168.42.241");
-    private static final Inet4Address TEST_RESERVED_ADDR = parseAddr4("192.168.42.243");
-    private static final MacAddress TEST_MAC_1 = MacAddress.fromBytes(
-            new byte[] { 5, 4, 3, 2, 1, 0 });
-    private static final MacAddress TEST_MAC_2 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 5 });
-    private static final MacAddress TEST_MAC_3 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 6 });
-    private static final Inet4Address TEST_INETADDR_1 = parseAddr4("192.168.42.248");
-    private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
-    private static final String TEST_HOSTNAME_1 = "hostname1";
-    private static final String TEST_HOSTNAME_2 = "hostname2";
-    private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
-    private static final long TEST_TIME = 100L;
-    private static final int TEST_LEASE_TIME_MS = 3_600_000;
-    private static final Set<Inet4Address> TEST_EXCL_SET =
-            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-                TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
-
-    @NonNull
-    private SharedLog mLog;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull
-    private DhcpLeaseRepository mRepo;
-
-    private static Inet4Address parseAddr4(String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mLog = new SharedLog("DhcpLeaseRepositoryTest");
-        when(mClock.elapsedRealtime()).thenReturn(TEST_TIME);
-        mRepo = new DhcpLeaseRepository(
-                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, mLog, mClock);
-    }
-
-    /**
-     * Request a number of addresses through offer/request. Useful to test address exhaustion.
-     * @param nAddr Number of addresses to request.
-     */
-    private void requestAddresses(byte nAddr) throws Exception {
-        final HashSet<Inet4Address> addrs = new HashSet<>();
-        byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
-        for (byte i = 0; i < nAddr; i++) {
-            hwAddrBytes[5] = i;
-            MacAddress newMac = MacAddress.fromBytes(hwAddrBytes);
-            final String hostname = "host_" + i;
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, newMac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, hostname);
-
-            assertNotNull(lease);
-            assertEquals(newMac, lease.getHwAddr());
-            assertEquals(hostname, lease.getHostname());
-            assertTrue(format("Duplicate address allocated: %s in %s", lease.getNetAddr(), addrs),
-                    addrs.add(lease.getNetAddr()));
-
-            requestLeaseSelecting(newMac, lease.getNetAddr(), hostname);
-        }
-    }
-
-    @Test
-    public void testAddressExhaustion() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 11);
-
-        try {
-            mRepo.getOffer(null, TEST_MAC_2,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Should be out of addresses");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            // Expected
-        }
-    }
-
-    @Test
-    public void testUpdateParams_LeaseCleanup() throws Exception {
-        // Inside /28:
-        final Inet4Address reqAddrIn28 = parseAddr4("192.168.42.242");
-        final Inet4Address declinedAddrIn28 = parseAddr4("192.168.42.245");
-
-        // Inside /28, but not available there (first address of the range)
-        final Inet4Address declinedFirstAddrIn28 = parseAddr4("192.168.42.240");
-
-        final DhcpLease reqAddrIn28Lease = requestLeaseSelecting(TEST_MAC_1, reqAddrIn28);
-        mRepo.markLeaseDeclined(declinedAddrIn28);
-        mRepo.markLeaseDeclined(declinedFirstAddrIn28);
-
-        // Inside /22, but outside /28:
-        final Inet4Address reqAddrIn22 = parseAddr4("192.168.42.3");
-        final Inet4Address declinedAddrIn22 = parseAddr4("192.168.42.4");
-
-        final DhcpLease reqAddrIn22Lease = requestLeaseSelecting(TEST_MAC_3, reqAddrIn22);
-        mRepo.markLeaseDeclined(declinedAddrIn22);
-
-        // Address that will be reserved in the updateParams call below
-        final Inet4Address reservedAddr = parseAddr4("192.168.42.244");
-        final DhcpLease reservedAddrLease = requestLeaseSelecting(TEST_MAC_2, reservedAddr);
-
-        // Update from /22 to /28 and add another reserved address
-        Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
-        newReserved.add(reservedAddr);
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS);
-
-        assertHasLease(reqAddrIn28Lease);
-        assertDeclined(declinedAddrIn28);
-
-        assertNotDeclined(declinedFirstAddrIn28);
-
-        assertNoLease(reqAddrIn22Lease);
-        assertNotDeclined(declinedAddrIn22);
-
-        assertNoLease(reservedAddrLease);
-    }
-
-    @Test
-    public void testGetOffer_StableAddress() throws Exception {
-        for (final MacAddress macAddr : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            // Same lease is offered twice
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease, newLease);
-        }
-    }
-
-    @Test
-    public void testUpdateParams_UsesNewPrefix() throws Exception {
-        final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
-        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertTrue(newPrefix.contains(lease.getNetAddr()));
-    }
-
-    @Test
-    public void testGetOffer_ExistingLease() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1, TEST_HOSTNAME_1);
-
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_ClientIdHasExistingLease() throws Exception {
-        final byte[] clientId = new byte[] { 1, 2 };
-        mRepo.requestLease(clientId, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Different MAC, but same clientId
-        DhcpLease offer = mRepo.getOffer(clientId, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_DifferentClientId() throws Exception {
-        final byte[] clientId1 = new byte[] { 1, 2 };
-        final byte[] clientId2 = new byte[] { 3, 4 };
-        mRepo.requestLease(clientId1, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Same MAC, different client ID
-        DhcpLease offer = mRepo.getOffer(clientId2, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        // Obtains a different address
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(HOSTNAME_NONE, offer.getHostname());
-        assertEquals(TEST_MAC_1, offer.getHwAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddress() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, TEST_HOSTNAME_1);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressReserved() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_RESERVED_ADDR /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_RESERVED_ADDR, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInvalid() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.42.0");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressOutsideSubnet() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.254.2");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testGetOffer_RelayInInvalidSubnet() throws Exception {
-        mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, parseAddr4("192.168.254.2") /* relayAddr */,
-                INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_SelectingTwice() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1,
-                TEST_HOSTNAME_1);
-
-        // Second request from same client for a different address
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_2,
-                TEST_HOSTNAME_2);
-
-        assertEquals(TEST_INETADDR_1, lease1.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, lease1.getHostname());
-
-        assertEquals(TEST_INETADDR_2, lease2.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, lease2.getHostname());
-
-        // First address freed when client requested a different one: another client can request it
-        final DhcpLease lease3 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, lease3.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInvalid() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, parseAddr4("192.168.254.5"));
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingReserved() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_RESERVED_ADDR);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testRequestLease_SelectingRelayInInvalidSubnet() throws  Exception {
-        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                parseAddr4("192.168.128.1") /* relayAddr */, TEST_INETADDR_1 /* reqAddr */,
-                true /* sidSet */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_InitReboot() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        // init-reboot (sidSet == false): verify configuration
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongAddr() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        // init-reboot with different requested address
-        requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-    }
-
-    @Test
-    public void testRequestLease_InitRebootUnknownAddr() throws Exception {
-        // init-reboot with unknown requested address
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-        // RFC2131 says we should not reply to accommodate other servers, but since we are
-        // authoritative we allow creating the lease to avoid issues with lost lease DB (same as
-        // dnsmasq behavior)
-        assertEquals(TEST_INETADDR_2, lease.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongSubnet() throws Exception {
-        requestLeaseInitReboot(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testRequestLease_Renewing() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test
-    public void testRequestLease_RenewingUnknownAddr() throws Exception {
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-        // Allows renewing an unknown address if available
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingAddrInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingInvalidAddr() throws Exception {
-        requestLeaseRenewing(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testReleaseLease() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertHasLease(lease1);
-        assertTrue(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-        assertNoLease(lease1);
-
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease2.getNetAddr());
-    }
-
-    @Test
-    public void testReleaseLease_UnknownLease() {
-        assertFalse(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-    }
-
-    @Test
-    public void testReleaseLease_StableOffer() throws Exception {
-        for (MacAddress mac : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            requestLeaseSelecting(mac, lease.getNetAddr());
-            mRepo.releaseLease(CLIENTID_UNSPEC, mac, lease.getNetAddr());
-
-            // Same lease is offered after it was released
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease.getNetAddr(), newLease.getNetAddr());
-        }
-    }
-
-    @Test
-    public void testMarkLeaseDeclined() throws Exception {
-        final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-        mRepo.markLeaseDeclined(lease.getNetAddr());
-
-        // Same lease is not offered again
-        final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
-    }
-
-    @Test
-    public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        mRepo.markLeaseDeclined(TEST_INETADDR_1);
-        mRepo.markLeaseDeclined(TEST_INETADDR_2);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 9);
-
-        // Last 2 addresses: addresses marked declined should be used
-        final DhcpLease firstLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_1);
-        requestLeaseSelecting(TEST_MAC_1, firstLease.getNetAddr());
-
-        final DhcpLease secondLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_2);
-        requestLeaseSelecting(TEST_MAC_2, secondLease.getNetAddr());
-
-        // Now out of addresses
-        try {
-            mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_3, IPV4_ADDR_ANY /* relayAddr */,
-                    INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Repository should be out of addresses and throw");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) { /* expected */ }
-
-        assertEquals(TEST_INETADDR_1, firstLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, firstLease.getHostname());
-        assertEquals(TEST_INETADDR_2, secondLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
-    }
-
-    private DhcpLease requestLease(@NonNull MacAddress macAddr, @NonNull Inet4Address clientAddr,
-            @Nullable Inet4Address reqAddr, @Nullable String hostname, boolean sidSet)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return mRepo.requestLease(CLIENTID_UNSPEC, macAddr, clientAddr,
-                IPV4_ADDR_ANY /* relayAddr */,
-                reqAddr, sidSet, hostname);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr, @Nullable String hostname)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, hostname,
-                true /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLeaseSelecting(macAddr, reqAddr, HOSTNAME_NONE);
-    }
-
-    /**
-     * Request a lease simulating a client in the INIT-REBOOT state.
-     */
-    private DhcpLease requestLeaseInitReboot(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, HOSTNAME_NONE,
-                false /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the RENEWING state.
-     */
-    private DhcpLease requestLeaseRenewing(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address clientAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        // Renewing: clientAddr filled in, no reqAddr
-        return requestLease(macAddr, clientAddr, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE,
-                true /* sidSet */);
-    }
-
-    private void assertNoLease(DhcpLease lease) {
-        assertFalse("Leases contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertHasLease(DhcpLease lease) {
-        assertTrue("Leases do not contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertNotDeclined(Inet4Address addr) {
-        assertFalse("Address is declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-
-    private void assertDeclined(Inet4Address addr) {
-        assertTrue("Address is not declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
deleted file mode 100644
index a30d3e4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_ACK;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_OFFER;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.ENCAP_L2;
-import static android.net.dhcp.DhcpPacket.ENCAP_L3;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
-import static android.net.dhcp.DhcpPacket.ParseException;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.net.metrics.DhcpErrorEvent;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Random;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpPacketTest {
-
-    private static final Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
-    private static final Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
-    private static final int PREFIX_LENGTH = 22;
-    private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH);
-    private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
-            SERVER_ADDR, PREFIX_LENGTH);
-    private static final String HOSTNAME = "testhostname";
-    private static final short MTU = 1500;
-    // Use our own empty address instead of IPV4_ADDR_ANY or INADDR_ANY to ensure that the code
-    // doesn't use == instead of equals when comparing addresses.
-    private static final Inet4Address ANY = v4Address("0.0.0.0");
-
-    private static final byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
-
-    private static final Inet4Address v4Address(String addrString) throws IllegalArgumentException {
-        return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
-    }
-
-    @Before
-    public void setUp() {
-        DhcpPacket.testOverrideVendorId = "android-dhcp-???";
-        DhcpPacket.testOverrideHostname = "android-01234567890abcde";
-    }
-
-    class TestDhcpPacket extends DhcpPacket {
-        private byte mType;
-        // TODO: Make this a map of option numbers to bytes instead.
-        private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes, mNetmaskBytes;
-
-        public TestDhcpPacket(byte type, Inet4Address clientIp, Inet4Address yourIp) {
-            super(0xdeadbeef, (short) 0, clientIp, yourIp, INADDR_ANY, INADDR_ANY,
-                  CLIENT_MAC, true);
-            mType = type;
-        }
-
-        public TestDhcpPacket(byte type) {
-            this(type, INADDR_ANY, CLIENT_ADDR);
-        }
-
-        public TestDhcpPacket setDomainBytes(byte[] domainBytes) {
-            mDomainBytes = domainBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setVendorInfoBytes(byte[] vendorInfoBytes) {
-            mVendorInfoBytes = vendorInfoBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setLeaseTimeBytes(byte[] leaseTimeBytes) {
-            mLeaseTimeBytes = leaseTimeBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setNetmaskBytes(byte[] netmaskBytes) {
-            mNetmaskBytes = netmaskBytes;
-            return this;
-        }
-
-        public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
-            ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-            fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
-                         DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
-            return result;
-        }
-
-        public void finishPacket(ByteBuffer buffer) {
-            addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
-            if (mDomainBytes != null) {
-                addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
-            }
-            if (mVendorInfoBytes != null) {
-                addTlv(buffer, DHCP_VENDOR_INFO, mVendorInfoBytes);
-            }
-            if (mLeaseTimeBytes != null) {
-                addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes);
-            }
-            if (mNetmaskBytes != null) {
-                addTlv(buffer, DHCP_SUBNET_MASK, mNetmaskBytes);
-            }
-            addTlvEnd(buffer);
-        }
-
-        // Convenience method.
-        public ByteBuffer build() {
-            // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
-            ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
-            pkt.flip();
-            return pkt;
-        }
-    }
-
-    private void assertDomainAndVendorInfoParses(
-            String expectedDomain, byte[] domainBytes,
-            String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
-                .setDomainBytes(domainBytes)
-                .setVendorInfoBytes(vendorInfoBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertEquals(expectedDomain, offerPacket.mDomainName);
-        assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
-    }
-
-    @Test
-    public void testDomainName() throws Exception {
-        byte[] nullByte = new byte[] { 0x00 };
-        byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
-        byte[] nonNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
-        };
-        byte[] trailingNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
-        };
-        byte[] embeddedNullsDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
-        };
-        byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
-
-        byte[] meteredEmbeddedNull = metered.clone();
-        meteredEmbeddedNull[7] = (char) 0;
-
-        byte[] meteredTrailingNull = metered.clone();
-        meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
-
-        assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
-        assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
-        assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
-        assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
-                                        "ANDROID\u0000METERED", meteredEmbeddedNull);
-        assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
-                                        "ANDROID_METERE\u0000", meteredTrailingNull);
-    }
-
-    private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
-            long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
-        TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
-        if (leaseTimeBytes != null) {
-            testPacket.setLeaseTimeBytes(leaseTimeBytes);
-        }
-        ByteBuffer packet = testPacket.build();
-        DhcpPacket offerPacket = null;
-
-        if (!expectValid) {
-            try {
-                offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-                fail("Invalid packet parsed successfully: " + offerPacket);
-            } catch (ParseException expected) {
-            }
-            return;
-        }
-
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertNotNull(offerPacket);
-        assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();  // Just check this doesn't crash.
-        assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
-    }
-
-    @Test
-    public void testLeaseTime() throws Exception {
-        byte[] noLease = null;
-        byte[] tooShortLease = new byte[] { 0x00, 0x00 };
-        byte[] tooLongLease = new byte[] { 0x00, 0x00, 0x00, 60, 0x01 };
-        byte[] zeroLease = new byte[] { 0x00, 0x00, 0x00, 0x00 };
-        byte[] tenSecondLease = new byte[] { 0x00, 0x00, 0x00, 10 };
-        byte[] oneMinuteLease = new byte[] { 0x00, 0x00, 0x00, 60 };
-        byte[] fiveMinuteLease = new byte[] { 0x00, 0x00, 0x01, 0x2c };
-        byte[] oneDayLease = new byte[] { 0x00, 0x01, 0x51, (byte) 0x80 };
-        byte[] maxIntPlusOneLease = new byte[] { (byte) 0x80, 0x00, 0x00, 0x01 };
-        byte[] infiniteLease = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-        assertLeaseTimeParses(true, null, 0, noLease);
-        assertLeaseTimeParses(false, null, 0, tooShortLease);
-        assertLeaseTimeParses(false, null, 0, tooLongLease);
-        assertLeaseTimeParses(true, 0, 60 * 1000, zeroLease);
-        assertLeaseTimeParses(true, 10, 60 * 1000, tenSecondLease);
-        assertLeaseTimeParses(true, 60, 60 * 1000, oneMinuteLease);
-        assertLeaseTimeParses(true, 300, 300 * 1000, fiveMinuteLease);
-        assertLeaseTimeParses(true, 86400, 86400 * 1000, oneDayLease);
-        assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease);
-        assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease);
-    }
-
-    private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
-    }
-
-    private void checkIpAddress(String expected, byte type,
-                                Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
-                .setNetmaskBytes(netmaskBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        DhcpResults results = offerPacket.toDhcpResults();
-
-        if (expected != null) {
-            LinkAddress expectedAddress = new LinkAddress(expected);
-            assertEquals(expectedAddress, results.ipAddress);
-        } else {
-            assertNull(results);
-        }
-    }
-
-    @Test
-    public void testIpAddress() throws Exception {
-        byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
-        byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
-        byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 };
-        Inet4Address example1 = v4Address("192.0.2.1");
-        Inet4Address example2 = v4Address("192.0.2.43");
-
-        // A packet without any addresses is not valid.
-        checkIpAddress(null, ANY, ANY, slash24Netmask);
-
-        // ClientIP is used iff YourIP is not present.
-        checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask);
-        checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask);
-        checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask);
-
-        // Invalid netmasks are ignored.
-        checkIpAddress(null, example2, ANY, invalidNetmask);
-
-        // If there is no netmask, implicit netmasks are used.
-        checkIpAddress("192.0.2.43/24", ANY, example2, null);
-    }
-
-    private void assertDhcpResults(String ipAddress, String gateway, String dnsServersString,
-            String domains, String serverAddress, String serverHostName, String vendorInfo,
-            int leaseDuration, boolean hasMeteredHint, int mtu, DhcpResults dhcpResults)
-                    throws Exception {
-        assertEquals(new LinkAddress(ipAddress), dhcpResults.ipAddress);
-        assertEquals(v4Address(gateway), dhcpResults.gateway);
-
-        String[] dnsServerStrings = dnsServersString.split(",");
-        ArrayList dnsServers = new ArrayList();
-        for (String dnsServerString : dnsServerStrings) {
-            dnsServers.add(v4Address(dnsServerString));
-        }
-        assertEquals(dnsServers, dhcpResults.dnsServers);
-
-        assertEquals(domains, dhcpResults.domains);
-        assertEquals(v4Address(serverAddress), dhcpResults.serverAddress);
-        assertEquals(serverHostName, dhcpResults.serverHostName);
-        assertEquals(vendorInfo, dhcpResults.vendorInfo);
-        assertEquals(leaseDuration, dhcpResults.leaseDuration);
-        assertEquals(hasMeteredHint, dhcpResults.hasMeteredHint());
-        assertEquals(mtu, dhcpResults.mtu);
-    }
-
-    @Test
-    public void testOffer1() throws Exception {
-        // TODO: Turn all of these into golden files. This will probably require using
-        // androidx.test.InstrumentationRegistry for obtaining a Context object
-        // to read such golden files, along with an appropriate Android.mk.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testOffer2() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name ("dhcp.android.com" plus invalid "AAAA" after null terminator).
-            "646863702e616e64726f69642e636f6d00000000000000000000000000000000" +
-            "0000000000004141414100000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-
-        assertEquals(337, packet.limit());
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.43.247/24", "192.168.43.1", "192.168.43.1",
-                null, "192.168.43.1", "dhcp.android.com", "ANDROID_METERED", 3600, true, 0,
-                dhcpResults);
-        assertTrue(dhcpResults.hasMeteredHint());
-    }
-
-    @Test
-    public void testBadIpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadDhcpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadTruncatedOffer() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File, missing one byte
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "00000000000000000000000000000000000000000000000000000000000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadOfferWithoutACookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000"
-            // No options
-            );
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_NO_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testOfferWithBadCookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Bad cookie
-            "DEADBEEF3501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    private void assertDhcpErrorCodes(int expected, int got) {
-        assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
-    }
-
-    @Test
-    public void testTruncatedOfferPackets() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        for (int len = 0; len < packet.length; len++) {
-            try {
-                DhcpPacket.decodeFullPacket(packet, len, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail(String.format("bad truncated packet of length %d", len));
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testRandomPackets() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        for (int i = 0; i < 10000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail("bad packet: " + HexDump.toHexString(packet));
-                }
-            }
-        }
-    }
-
-    private byte[] mtuBytes(int mtu) {
-        // 0x1a02: option 26, length 2. 0xff: no more options.
-        if (mtu > Short.MAX_VALUE - Short.MIN_VALUE) {
-            throw new IllegalArgumentException(
-                String.format("Invalid MTU %d, must be 16-bit unsigned", mtu));
-        }
-        String hexString = String.format("1a02%04xff", mtu);
-        return HexDump.hexStringToByteArray(hexString);
-    }
-
-    private void checkMtu(ByteBuffer packet, int expectedMtu, byte[] mtuBytes) throws Exception {
-        if (mtuBytes != null) {
-            packet.position(packet.capacity() - mtuBytes.length);
-            packet.put(mtuBytes);
-            packet.clear();
-        }
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, expectedMtu, dhcpResults);
-    }
-
-    @Test
-    public void testMtu() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        checkMtu(packet, 0, null);
-        checkMtu(packet, 0, mtuBytes(1501));
-        checkMtu(packet, 1500, mtuBytes(1500));
-        checkMtu(packet, 1499, mtuBytes(1499));
-        checkMtu(packet, 1280, mtuBytes(1280));
-        checkMtu(packet, 0, mtuBytes(1279));
-        checkMtu(packet, 0, mtuBytes(576));
-        checkMtu(packet, 0, mtuBytes(68));
-        checkMtu(packet, 0, mtuBytes(Short.MIN_VALUE));
-        checkMtu(packet, 0, mtuBytes(Short.MAX_VALUE + 3));
-        checkMtu(packet, 0, mtuBytes(-1));
-    }
-
-    @Test
-    public void testBadHwaddrLength() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-        String expectedClientMac = "30766FF2A90C";
-
-        final int hwAddrLenOffset = 20 + 8 + 2;
-        assertEquals(6, packet.get(hwAddrLenOffset));
-
-        // Expect the expected.
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Reduce the hardware address length and verify that it shortens the client MAC.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 5);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(5, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 10),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 3);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(3, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 6),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
-        // and crash, and b) hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) -1);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to a positive invalid value (> 16) and verify that we
-        // hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 17);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-    }
-
-    @Test
-    public void testPadAndOverloadedOptionsOffer() throws Exception {
-        // A packet observed in the real world that is interesting for two reasons:
-        //
-        // 1. It uses pad bytes, which we previously didn't support correctly.
-        // 2. It uses DHCP option overloading, which we don't currently support (but it doesn't
-        //    store any information in the overloaded fields).
-        //
-        // For now, we just check that it parses correctly.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "b4cef6000000e80462236e300800" +
-            // IP header.
-            "4500014c00000000ff11741701010101ac119876" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "004300440138ae5a" +
-            // BOOTP header.
-            "020106000fa0059f0000000000000000ac1198760000000000000000" +
-            // MAC address.
-            "b4cef600000000000000000000000000" +
-            // Server name.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604010101010104ffff000033040000a8c03401030304ac1101010604ac110101" +
-            "0000000000000000000000000000000000000000000000ff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1",
-                null, "1.1.1.1", "", null, 43200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2111() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387464" +
-            // BOOTP header.
-            "0201060002554812000a0000000000000a3f5d040000000000000000" +
-            // MAC address.
-            "00904c00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" +
-            "0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2",
-                "domain123.co.uk", "192.0.2.254", "", null, 49094, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2136() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "bcf5ac000000d0c7890000000800" +
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387574" +
-            // BOOTP header.
-            "0201060163339a3000050000000000000a209ecd0000000000000000" +
-            // MAC address.
-            "bcf5ac00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" +
-            "0f0b6c616e63732e61632e756b000000000000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
-                "lancs.ac.uk", "10.32.255.128", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpServerAnySourcePort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The server source port is not the canonical port 67.
-            "C29F004401341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.15.122.242/16", "10.15.200.23",
-                "209.129.128.3,209.129.148.3,209.129.128.6",
-                "wvm.edu", "10.1.105.252", "", null, 86400, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpInvalidDstPort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The destination port is a non-DHCP port.
-            "0043aaaa01341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        try {
-            DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-            fail("Packet with invalid dst port did not throw ParseException");
-        } catch (ParseException expected) {}
-    }
-
-    @Test
-    public void testMultipleRouters() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "fc3d93000000" + "081735000000" + "0800" +
-            // IP header.
-            "45000148c2370000ff117ac2c0a8bd02ffffffff" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401343beb" +
-            // BOOTP header.
-            "0201060027f518e20000800000000000c0a8bd310000000000000000" +
-            // MAC address.
-            "fc3d9300000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
-            "0308c0a8bd01ffffff0006080808080808080404ff000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
-                null, "192.171.189.2", "", null, 28800, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testDiscoverPacket() throws Exception {
-        short secs = 7;
-        int transactionId = 0xdeadbeef;
-        byte[] hwaddr = {
-                (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a
-        };
-
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, transactionId, secs, hwaddr,
-                false /* do unicast */, DhcpClient.REQUESTED_PARAMS);
-
-        byte[] headers = new byte[] {
-            // Ethernet header.
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            (byte) 0x08, (byte) 0x00,
-            // IP header.
-            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x56,
-            (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00,
-            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x88,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            // UDP header.
-            (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43,
-            (byte) 0x01, (byte) 0x42, (byte) 0x6a, (byte) 0x4a,
-            // BOOTP.
-            (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-            (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-            (byte) 0x00, (byte) 0x07, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b,
-            (byte) 0xb1, (byte) 0x7a
-        };
-        byte[] options = new byte[] {
-            // Magic cookie 0x63825363.
-            (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-            // Message type DISCOVER.
-            (byte) 0x35, (byte) 0x01, (byte) 0x01,
-            // Client identifier Ethernet, da:01:19:5b:b1:7a.
-            (byte) 0x3d, (byte) 0x07,
-                    (byte) 0x01,
-                    (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            // Max message size 1500.
-            (byte) 0x39, (byte) 0x02, (byte) 0x05, (byte) 0xdc,
-            // Version "android-dhcp-???".
-            (byte) 0x3c, (byte) 0x10,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 'h', 'c', 'p', '-', '?', '?', '?',
-            // Hostname "android-01234567890abcde"
-            (byte) 0x0c, (byte) 0x18,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-',
-                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
-            // Requested parameter list.
-            (byte) 0x37, (byte) 0x0a,
-                DHCP_SUBNET_MASK,
-                DHCP_ROUTER,
-                DHCP_DNS_SERVER,
-                DHCP_DOMAIN_NAME,
-                DHCP_MTU,
-                DHCP_BROADCAST_ADDRESS,
-                DHCP_LEASE_TIME,
-                DHCP_RENEWAL_TIME,
-                DHCP_REBINDING_TIME,
-                DHCP_VENDOR_INFO,
-            // End options.
-            (byte) 0xff,
-            // Our packets are always of even length. TODO: find out why and possibly fix it.
-            (byte) 0x00
-        };
-        byte[] expected = new byte[DhcpPacket.MIN_PACKET_LENGTH_L2 + options.length];
-        assertTrue((expected.length & 1) == 0);
-        System.arraycopy(headers, 0, expected, 0, headers.length);
-        System.arraycopy(options, 0, expected, DhcpPacket.MIN_PACKET_LENGTH_L2, options.length);
-
-        byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        String msg =
-                "Expected:\n  " + Arrays.toString(expected) +
-                "\nActual:\n  " + Arrays.toString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    public void checkBuildOfferPacket(int leaseTimeSecs, @Nullable String hostname)
-            throws Exception {
-        final int renewalTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) / 2);
-        final int rebindingTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) * 875 / 1000);
-        final int transactionId = 0xdeadbeef;
-
-        final ByteBuffer packet = DhcpPacket.buildOfferPacket(
-                DhcpPacket.ENCAP_BOOTP, transactionId, false /* broadcast */,
-                SERVER_ADDR, INADDR_ANY /* relayIp */, CLIENT_ADDR /* yourIp */,
-                CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */,
-                BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */,
-                Collections.singletonList(SERVER_ADDR) /* dnsServers */,
-                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname,
-                false /* metered */, MTU);
-
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        // BOOTP headers
-        bos.write(new byte[] {
-                (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-                (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                // ciaddr
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        });
-        // yiaddr
-        bos.write(CLIENT_ADDR.getAddress());
-        // siaddr
-        bos.write(SERVER_ADDR.getAddress());
-        // giaddr
-        bos.write(INADDR_ANY.getAddress());
-        // chaddr
-        bos.write(CLIENT_MAC);
-
-        // Padding
-        bos.write(new byte[202]);
-
-        // Options
-        bos.write(new byte[]{
-                // Magic cookie 0x63825363.
-                (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-                // Message type OFFER.
-                (byte) 0x35, (byte) 0x01, (byte) 0x02,
-        });
-        // Server ID
-        bos.write(new byte[] { (byte) 0x36, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Lease time
-        bos.write(new byte[] { (byte) 0x33, (byte) 0x04 });
-        bos.write(intToByteArray(leaseTimeSecs));
-        if (leaseTimeSecs != INFINITE_LEASE) {
-            // Renewal time
-            bos.write(new byte[]{(byte) 0x3a, (byte) 0x04});
-            bos.write(intToByteArray(renewalTime));
-            // Rebinding time
-            bos.write(new byte[]{(byte) 0x3b, (byte) 0x04});
-            bos.write(intToByteArray(rebindingTime));
-        }
-        // Subnet mask
-        bos.write(new byte[] { (byte) 0x01, (byte) 0x04 });
-        bos.write(NETMASK.getAddress());
-        // Broadcast address
-        bos.write(new byte[] { (byte) 0x1c, (byte) 0x04 });
-        bos.write(BROADCAST_ADDR.getAddress());
-        // Router
-        bos.write(new byte[] { (byte) 0x03, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Nameserver
-        bos.write(new byte[] { (byte) 0x06, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Hostname
-        if (hostname != null) {
-            bos.write(new byte[]{(byte) 0x0c, (byte) hostname.length()});
-            bos.write(hostname.getBytes(Charset.forName("US-ASCII")));
-        }
-        // MTU
-        bos.write(new byte[] { (byte) 0x1a, (byte) 0x02 });
-        bos.write(shortToByteArray(MTU));
-        // End options.
-        bos.write(0xff);
-
-        if ((bos.size() & 1) != 0) {
-            bos.write(0x00);
-        }
-
-        final byte[] expected = bos.toByteArray();
-        final byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        final String msg = "Expected:\n  " + HexDump.dumpHexString(expected) +
-                "\nActual:\n  " + HexDump.dumpHexString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    @Test
-    public void testOfferPacket() throws Exception {
-        checkBuildOfferPacket(3600, HOSTNAME);
-        checkBuildOfferPacket(Integer.MAX_VALUE, HOSTNAME);
-        checkBuildOfferPacket(0x80000000, HOSTNAME);
-        checkBuildOfferPacket(INFINITE_LEASE, HOSTNAME);
-        checkBuildOfferPacket(3600, null);
-    }
-
-    private static byte[] intToByteArray(int val) {
-        return ByteBuffer.allocate(4).putInt(val).array();
-    }
-
-    private static byte[] shortToByteArray(short val) {
-        return ByteBuffer.allocate(2).putShort(val).array();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
deleted file mode 100644
index f0e2f1b..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.LinkAddress;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpLeaseRepository.InvalidAddressException;
-import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.SharedLog;
-import android.os.HandlerThread;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-@RunWithLooper
-public class DhcpServerTest {
-    private static final String TEST_IFACE = "testiface";
-
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final int TEST_MTU = 1500;
-    private static final String TEST_HOSTNAME = "testhostname";
-
-    private static final int TEST_TRANSACTION_ID = 123;
-    private static final byte[] TEST_CLIENT_MAC_BYTES = new byte [] { 1, 2, 3, 4, 5, 6 };
-    private static final MacAddress TEST_CLIENT_MAC = MacAddress.fromBytes(TEST_CLIENT_MAC_BYTES);
-    private static final Inet4Address TEST_CLIENT_ADDR = parseAddr("192.168.0.42");
-
-    private static final long TEST_CLOCK_TIME = 1234L;
-    private static final int TEST_LEASE_EXPTIME_SECS = 3600;
-    private static final DhcpLease TEST_LEASE = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME,
-            null /* hostname */);
-    private static final DhcpLease TEST_LEASE_WITH_HOSTNAME = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, TEST_HOSTNAME);
-
-    @NonNull @Mock
-    private Dependencies mDeps;
-    @NonNull @Mock
-    private DhcpLeaseRepository mRepository;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull @Mock
-    private DhcpPacketListener mPacketListener;
-
-    @NonNull @Captor
-    private ArgumentCaptor<ByteBuffer> mSentPacketCaptor;
-    @NonNull @Captor
-    private ArgumentCaptor<Inet4Address> mResponseDstAddrCaptor;
-
-    @NonNull
-    private HandlerThread mHandlerThread;
-    @NonNull
-    private TestableLooper mLooper;
-    @NonNull
-    private DhcpServer mServer;
-
-    @Nullable
-    private String mPrevShareClassloaderProp;
-
-    private final INetworkStackStatusCallback mAssertSuccessCallback =
-            new INetworkStackStatusCallback.Stub() {
-        @Override
-        public void onStatusAvailable(int statusCode) {
-            assertEquals(STATUS_SUCCESS, statusCode);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mDeps.makeLeaseRepository(any(), any(), any())).thenReturn(mRepository);
-        when(mDeps.makeClock()).thenReturn(mClock);
-        when(mDeps.makePacketListener()).thenReturn(mPacketListener);
-        doNothing().when(mDeps)
-                .sendPacket(any(), mSentPacketCaptor.capture(), mResponseDstAddrCaptor.capture());
-        when(mClock.elapsedRealtime()).thenReturn(TEST_CLOCK_TIME);
-
-        final DhcpServingParams servingParams = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_SERVER_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .build();
-
-        mLooper = TestableLooper.get(this);
-        mHandlerThread = spy(new HandlerThread("TestDhcpServer"));
-        when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
-        mServer = new DhcpServer(mHandlerThread, TEST_IFACE, servingParams,
-                new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
-
-        mServer.start(mAssertSuccessCallback);
-        mLooper.processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mServer.stop(mAssertSuccessCallback);
-        mLooper.processMessages(1);
-        verify(mPacketListener, times(1)).stop();
-        verify(mHandlerThread, times(1)).quitSafely();
-    }
-
-    @Test
-    public void testStart() throws Exception {
-        verify(mPacketListener, times(1)).start();
-    }
-
-    @Test
-    public void testDiscover() throws Exception {
-        // TODO: refactor packet construction to eliminate unnecessary/confusing/duplicate fields
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenReturn(TEST_LEASE);
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpOfferPacket packet = assertOffer(getPacket());
-        assertMatchesTestLease(packet);
-    }
-
-    @Test
-    public void testDiscover_OutOfAddresses() throws Exception {
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenThrow(new OutOfAddressesException("Test exception"));
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    private DhcpRequestPacket makeRequestSelectingPacket() {
-        final DhcpRequestPacket request = new DhcpRequestPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* clientIp */, INADDR_ANY /* relayIp */,
-                TEST_CLIENT_MAC_BYTES, false /* broadcast */);
-        request.mServerIdentifier = TEST_SERVER_ADDR;
-        request.mRequestedIp = TEST_CLIENT_ADDR;
-        return request;
-    }
-
-    @Test
-    public void testRequest_Selecting_Ack() throws Exception {
-        when(mRepository.requestLease(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, eq(TEST_HOSTNAME)))
-                .thenReturn(TEST_LEASE_WITH_HOSTNAME);
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        request.mHostName = TEST_HOSTNAME;
-        request.mRequestedParams = new byte[] { DHCP_HOST_NAME };
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpAckPacket packet = assertAck(getPacket());
-        assertMatchesTestLease(packet, TEST_HOSTNAME);
-    }
-
-    @Test
-    public void testRequest_Selecting_Nak() throws Exception {
-        when(mRepository.requestLease(isNull(), eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, isNull() /* hostname */))
-                .thenThrow(new InvalidAddressException("Test error"));
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    @Test
-    public void testRequest_Selecting_WrongClientPort() throws Exception {
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, 50000);
-
-        verify(mRepository, never())
-                .requestLease(any(), any(), any(), any(), any(), anyBoolean(), any());
-        verify(mDeps, never()).sendPacket(any(), any(), any());
-    }
-
-    @Test
-    public void testRelease() throws Exception {
-        final DhcpReleasePacket release = new DhcpReleasePacket(TEST_TRANSACTION_ID,
-                TEST_SERVER_ADDR, TEST_CLIENT_ADDR,
-                INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES);
-        mServer.processPacket(release, DHCP_CLIENT);
-
-        verify(mRepository, times(1))
-                .releaseLease(isNull(), eq(TEST_CLIENT_MAC), eq(TEST_CLIENT_ADDR));
-    }
-
-    /* TODO: add more tests once packet construction is refactored, including:
-     *  - usage of giaddr
-     *  - usage of broadcast bit
-     *  - other request states (init-reboot/renewing/rebinding)
-     */
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet, @Nullable String hostname) {
-        assertMatchesClient(packet);
-        assertFalse(packet.hasExplicitClientId());
-        assertEquals(TEST_SERVER_ADDR, packet.mServerIdentifier);
-        assertEquals(TEST_CLIENT_ADDR, packet.mYourIp);
-        assertNotNull(packet.mLeaseTime);
-        assertEquals(TEST_LEASE_EXPTIME_SECS, (int) packet.mLeaseTime);
-        assertEquals(hostname, packet.mHostName);
-    }
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet) {
-        assertMatchesTestLease(packet, null);
-    }
-
-    private void assertMatchesClient(@NonNull DhcpPacket packet) {
-        assertEquals(TEST_TRANSACTION_ID, packet.mTransId);
-        assertEquals(TEST_CLIENT_MAC, MacAddress.fromBytes(packet.mClientMac));
-    }
-
-    private void assertResponseSentTo(@NonNull Inet4Address addr) {
-        assertEquals(addr, mResponseDstAddrCaptor.getValue());
-    }
-
-    private static DhcpNakPacket assertNak(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpNakPacket);
-        return (DhcpNakPacket) packet;
-    }
-
-    private static DhcpAckPacket assertAck(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpAckPacket);
-        return (DhcpAckPacket) packet;
-    }
-
-    private static DhcpOfferPacket assertOffer(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpOfferPacket);
-        return (DhcpOfferPacket) packet;
-    }
-
-    private DhcpPacket getPacket() throws Exception {
-        verify(mDeps, times(1)).sendPacket(any(), any(), any());
-        return DhcpPacket.decodeFullPacket(mSentPacketCaptor.getValue(), ENCAP_BOOTP);
-    }
-
-    private static Inet4Address parseAddr(@Nullable String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
deleted file mode 100644
index 57a87a4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2018 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.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.LinkAddress;
-import android.net.dhcp.DhcpServingParams.InvalidParameterException;
-import android.net.shared.Inet4AddressUtils;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpServingParamsTest {
-    @NonNull
-    private DhcpServingParams.Builder mBuilder;
-
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final int TEST_MTU = 1500;
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final boolean TEST_METERED = true;
-
-    @Before
-    public void setUp() {
-        mBuilder = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .setMetered(TEST_METERED);
-    }
-
-    @Test
-    public void testBuild_Immutable() throws InvalidParameterException {
-        final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS);
-        final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS);
-        final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS);
-
-        final DhcpServingParams params = mBuilder
-                .setDefaultRouters(routers)
-                .setDnsServers(dnsServers)
-                .setExcludedAddrs(excludedAddrs)
-                .build();
-
-        // Modifications to source objects should not affect builder or final parameters
-        final Inet4Address addedAddr = parseAddr("192.168.0.223");
-        routers.add(addedAddr);
-        dnsServers.add(addedAddr);
-        excludedAddrs.add(addedAddr);
-
-        assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters);
-        assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
-        assertEquals(TEST_DNS_SERVERS, params.dnsServers);
-        assertEquals(TEST_LINKADDR, params.serverAddr);
-        assertEquals(TEST_MTU, params.linkMtu);
-        assertEquals(TEST_METERED, params.metered);
-
-        assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS);
-        assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS);
-        assertContains(params.excludedAddrs, TEST_DNS_SERVERS);
-        assertContains(params.excludedAddrs, TEST_SERVER_ADDR);
-
-        assertFalse("excludedAddrs should not contain " + addedAddr,
-                params.excludedAddrs.contains(addedAddr));
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_NegativeLeaseTime() throws InvalidParameterException {
-        mBuilder.setDhcpLeaseTimeSecs(-1).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException {
-        // Set lease time larger than max value for uint32
-        mBuilder.setDhcpLeaseTimeSecs(1L << 32).build();
-    }
-
-    @Test
-    public void testBuild_InfiniteLeaseTime() throws InvalidParameterException {
-        final long infiniteLeaseTime = 0xffffffffL;
-        final DhcpServingParams params = mBuilder
-                .setDhcpLeaseTimeSecs(infiniteLeaseTime).build();
-        assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs);
-        assertTrue(params.dhcpLeaseTimeSecs > 0L);
-    }
-
-    @Test
-    public void testBuild_UnsetMtu() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build();
-        assertEquals(MTU_UNSET, params.linkMtu);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooSmall() throws InvalidParameterException {
-        mBuilder.setLinkMtu(20).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooLarge() throws InvalidParameterException {
-        mBuilder.setLinkMtu(65_536).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_IPv6Addr() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooLarge() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooSmall() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.0.254"))
-                .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
-                .build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build();
-    }
-
-    @Test
-    public void testFromParcelableObject() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.build();
-        final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel();
-        parcel.defaultRouters = toIntArray(TEST_DEFAULT_ROUTERS);
-        parcel.dhcpLeaseTimeSecs = TEST_LEASE_TIME_SECS;
-        parcel.dnsServers = toIntArray(TEST_DNS_SERVERS);
-        parcel.serverAddr = inet4AddressToIntHTH(TEST_SERVER_ADDR);
-        parcel.serverAddrPrefixLength = TEST_LINKADDR.getPrefixLength();
-        parcel.linkMtu = TEST_MTU;
-        parcel.excludedAddrs = toIntArray(TEST_EXCLUDED_ADDRS);
-        parcel.metered = TEST_METERED;
-        final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel);
-
-        assertEquals(params.defaultRouters, parceled.defaultRouters);
-        assertEquals(params.dhcpLeaseTimeSecs, parceled.dhcpLeaseTimeSecs);
-        assertEquals(params.dnsServers, parceled.dnsServers);
-        assertEquals(params.serverAddr, parceled.serverAddr);
-        assertEquals(params.linkMtu, parceled.linkMtu);
-        assertEquals(params.excludedAddrs, parceled.excludedAddrs);
-        assertEquals(params.metered, parceled.metered);
-
-        // Ensure that we do not miss any field if added in the future
-        final long numFields = Arrays.stream(DhcpServingParams.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers()))
-                .count();
-        assertEquals(7, numFields);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testFromParcelableObject_NullArgument() throws InvalidParameterException {
-        DhcpServingParams.fromParcelableObject(null);
-    }
-
-    private static int[] toIntArray(Collection<Inet4Address> addrs) {
-        return addrs.stream().mapToInt(Inet4AddressUtils::inet4AddressToIntHTH).toArray();
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
-        for (final T elem : subset) {
-            assertContains(set, elem);
-        }
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) {
-        assertTrue("Set does not contain " + elem, set.contains(elem));
-    }
-
-    @NonNull
-    private static Inet4Address parseAddr(@NonNull String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
deleted file mode 100644
index 5f80006..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * 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.ip;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.RouteInfo;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.R;
-import com.android.server.NetworkObserver;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for IpClient.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpClientTest {
-    private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
-
-    private static final String VALID = "VALID";
-    private static final String INVALID = "INVALID";
-    private static final String TEST_IFNAME = "test_wlan0";
-    private static final int TEST_IFINDEX = 1001;
-    // See RFC 7042#section-2.1.2 for EUI-48 documentation values.
-    private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
-    private static final int TEST_TIMEOUT_MS = 400;
-    private static final String TEST_L2KEY = "some l2key";
-    private static final String TEST_GROUPHINT = "some grouphint";
-
-    @Mock private Context mContext;
-    @Mock private ConnectivityManager mCm;
-    @Mock private NetworkObserverRegistry mObserverRegistry;
-    @Mock private INetd mNetd;
-    @Mock private Resources mResources;
-    @Mock private IIpClientCallbacks mCb;
-    @Mock private AlarmManager mAlarm;
-    @Mock private IpClient.Dependencies mDependencies;
-    @Mock private ContentResolver mContentResolver;
-    @Mock private NetworkStackService.NetworkStackServiceManager mNetworkStackServiceManager;
-    @Mock private NetworkStackIpMemoryStore mIpMemoryStore;
-
-    private NetworkObserver mObserver;
-    private InterfaceParams mIfParams;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
-        when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mDependencies.getNetd(any())).thenReturn(mNetd);
-        when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
-                .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-
-        mIfParams = null;
-    }
-
-    private void setTestInterfaceParams(String ifname) {
-        mIfParams = (ifname != null)
-                ? new InterfaceParams(ifname, TEST_IFINDEX, TEST_MAC)
-                : null;
-        when(mDependencies.getInterfaceParams(anyString())).thenReturn(mIfParams);
-    }
-
-    private IpClient makeIpClient(String ifname) throws Exception {
-        setTestInterfaceParams(ifname);
-        final IpClient ipc = new IpClient(mContext, ifname, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname);
-        ArgumentCaptor<NetworkObserver> arg = ArgumentCaptor.forClass(NetworkObserver.class);
-        verify(mObserverRegistry, times(1)).registerObserverForNonblockingCallback(arg.capture());
-        mObserver = arg.getValue();
-        reset(mObserverRegistry);
-        reset(mNetd);
-        // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
-        verify(mCb, never()).onLinkPropertiesChange(any());
-        reset(mCb);
-        return ipc;
-    }
-
-    private static LinkProperties makeEmptyLinkProperties(String iface) {
-        final LinkProperties empty = new LinkProperties();
-        empty.setInterfaceName(iface);
-        return empty;
-    }
-
-    private void verifyNetworkAttributesStored(final String l2Key,
-            final NetworkAttributes attributes) {
-        // TODO : when storing is implemented, turn this on
-        // verify(mIpMemoryStore).storeNetworkAttributes(eq(l2Key), eq(attributes), any());
-    }
-
-    @Test
-    public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
-        setTestInterfaceParams(null);
-        try {
-            final IpClient ipc = new IpClient(mContext, null, mCb, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null interface names not allowed.
-        }
-    }
-
-    @Test
-    public void testNullCallbackMostDefinitelyThrows() throws Exception {
-        final String ifname = "lo";
-        setTestInterfaceParams(ifname);
-        try {
-            final IpClient ipc = new IpClient(mContext, ifname, null, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null callbacks not allowed.
-        }
-    }
-
-    @Test
-    public void testInvalidInterfaceDoesNotThrow() throws Exception {
-        setTestInterfaceParams(TEST_IFNAME);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verifyNoMoreInteractions(mIpMemoryStore);
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testInterfaceNotFoundFailsImmediately() throws Exception {
-        setTestInterfaceParams(null);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        ipc.startProvisioning(new ProvisioningConfiguration());
-        verify(mCb, times(1)).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testDefaultProvisioningConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                // TODO: mock IpReachabilityMonitor's dependencies (NetworkInterface, PowerManager)
-                // and enable it in this test
-                .withoutIpReachabilityMonitor()
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-    }
-
-    @Test
-    public void testProvisioningWithInitialConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-        final String l2Key = TEST_L2KEY;
-        final String groupHint = TEST_GROUPHINT;
-
-        String[] addresses = {
-            "fe80::a4be:f92:e1f7:22d1/64",
-            "fe80::f04a:8f6:6a32:d756/64",
-            "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"
-        };
-        String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" };
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                .withoutIpReachabilityMonitor()
-                .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips()))
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        ipc.setL2KeyAndGroupHint(l2Key, groupHint);
-
-        for (String addr : addresses) {
-            String[] parts = addr.split("/");
-            verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1))
-                    .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1]));
-        }
-
-        final int lastAddr = addresses.length - 1;
-
-        // Add N - 1 addresses
-        for (int i = 0; i < lastAddr; i++) {
-            mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[i]), iface);
-            verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any());
-            reset(mCb);
-        }
-
-        // Add Nth address
-        mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface);
-        LinkProperties want = linkproperties(links(addresses), routes(prefixes));
-        want.setInterfaceName(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want);
-        verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder()
-                .setGroupHint(groupHint)
-                .build());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-        verifyNoMoreInteractions(mIpMemoryStore);
-    }
-
-    @Test
-    public void testIsProvisioned() throws Exception {
-        InitialConfiguration empty = conf(links(), prefixes());
-        IsProvisionedTestCase[] testcases = {
-            // nothing
-            notProvisionedCase(links(), routes(), dns(), null),
-            notProvisionedCase(links(), routes(), dns(), empty),
-
-            // IPv4
-            provisionedCase(links("192.0.2.12/24"), routes(), dns(), empty),
-
-            // IPv6
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes(), dns(), empty),
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"), dns("fd00:1234:5678::1000"), empty),
-            provisionedCase(
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    routes("::/0"),
-                    dns("2001:db8:dead:beef:f00::02"), empty),
-
-            // Initial configuration
-            provisionedCase(
-                    links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"),
-                    dns(),
-                    conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                        prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
-        };
-
-        for (IsProvisionedTestCase testcase : testcases) {
-            if (IpClient.isProvisioned(testcase.lp, testcase.config) != testcase.isProvisioned) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class IsProvisionedTestCase {
-        boolean isProvisioned;
-        LinkProperties lp;
-        InitialConfiguration config;
-
-        String errorMessage() {
-            return String.format("expected %s with config %s to be %s, but was %s",
-                     lp, config, provisioned(isProvisioned), provisioned(!isProvisioned));
-        }
-
-        static String provisioned(boolean isProvisioned) {
-            return isProvisioned ? "provisioned" : "not provisioned";
-        }
-    }
-
-    static IsProvisionedTestCase provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes,
-            Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(true, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase notProvisionedCase(Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(false, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        IsProvisionedTestCase testcase = new IsProvisionedTestCase();
-        testcase.isProvisioned = isProvisioned;
-        testcase.lp = new LinkProperties();
-        testcase.lp.setLinkAddresses(lpAddrs);
-        for (RouteInfo route : lpRoutes) {
-            testcase.lp.addRoute(route);
-        }
-        for (InetAddress dns : lpDns) {
-            testcase.lp.addDnsServer(dns);
-        }
-        testcase.config = config;
-        return testcase;
-    }
-
-    @Test
-    public void testInitialConfigurations() throws Exception {
-        InitialConfigurationTestCase[] testcases = {
-            validConf("valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("192.0.2.2")),
-            validConf("another valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns()),
-            validConf("valid IPv6 configurations",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64", "fe80::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configurations",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns()),
-            validConf("valid IPv6/v4 configuration",
-                    links("2001:db8:dead:beef:f00::a0/48", "192.0.2.12/24"),
-                    prefixes("2001:db8:dead:beef::/64", "192.0.2.0/24"),
-                    dns("192.0.2.2", "2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configuration without any GUA.",
-                    links("fd00:1234:5678::1/48"),
-                    prefixes("fd00:1234:5678::/48"),
-                    dns("fd00:1234:5678::1000")),
-
-            invalidConf("empty configuration", links(), prefixes(), dns()),
-            invalidConf("v4 addr and dns not in any prefix",
-                    links("192.0.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 addr not in any prefix",
-                    links("198.51.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 dns addr not in any prefix",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("198.51.100.2")),
-            invalidConf("v6 addr not in any prefix",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("v6 dns addr not in any prefix",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("default ipv6 route and no GUA",
-                    links("fd01:1111:2222:3333::a0/128"), prefixes("::/0"), dns()),
-            invalidConf("invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/32"),
-                    dns()),
-            invalidConf("another invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/72"),
-                    dns())
-        };
-
-        for (InitialConfigurationTestCase testcase : testcases) {
-            if (testcase.config.isValid() != testcase.isValid) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class InitialConfigurationTestCase {
-        String descr;
-        boolean isValid;
-        InitialConfiguration config;
-        public String errorMessage() {
-            return String.format("%s: expected configuration %s to be %s, but was %s",
-                    descr, config, validString(isValid), validString(!isValid));
-        }
-        static String validString(boolean isValid) {
-            return isValid ? VALID : INVALID;
-        }
-    }
-
-    static InitialConfigurationTestCase validConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, true, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase invalidConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, false, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase confTestCase(
-            String descr, boolean isValid, InitialConfiguration config) {
-        InitialConfigurationTestCase testcase = new InitialConfigurationTestCase();
-        testcase.descr = descr;
-        testcase.isValid = isValid;
-        testcase.config = config;
-        return testcase;
-    }
-
-    static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) {
-        LinkProperties lp = new LinkProperties();
-        lp.setLinkAddresses(addresses);
-        for (RouteInfo route : routes) {
-            lp.addRoute(route);
-        }
-        return lp;
-    }
-
-    static InitialConfiguration conf(Set<LinkAddress> links, Set<IpPrefix> prefixes) {
-        return conf(links, prefixes, new HashSet<>());
-    }
-
-    static InitialConfiguration conf(
-            Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        InitialConfiguration conf = new InitialConfiguration();
-        conf.ipAddresses.addAll(links);
-        conf.directlyConnectedRoutes.addAll(prefixes);
-        conf.dnsServers.addAll(dns);
-        return conf;
-    }
-
-    static Set<RouteInfo> routes(String... routes) {
-        return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r)));
-    }
-
-    static Set<IpPrefix> prefixes(String... prefixes) {
-        return mapIntoSet(prefixes, IpPrefix::new);
-    }
-
-    static Set<LinkAddress> links(String... addresses) {
-        return mapIntoSet(addresses, LinkAddress::new);
-    }
-
-    static Set<InetAddress> ips(String... addresses) {
-        return mapIntoSet(addresses, InetAddress::getByName);
-    }
-
-    static Set<InetAddress> dns(String... addresses) {
-        return ips(addresses);
-    }
-
-    static <A, B> Set<B> mapIntoSet(A[] in, Fn<A, B> fn) {
-        Set<B> out = new HashSet<>(in.length);
-        for (A item : in) {
-            try {
-                out.add(fn.call(item));
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-        return out;
-    }
-
-    interface Fn<A,B> {
-        B call(A a) throws Exception;
-    }
-
-    @Test
-    public void testAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertTrue(InitialConfiguration.all(list1, (x) -> false));
-        assertFalse(InitialConfiguration.all(list2, (x) -> false));
-        assertTrue(InitialConfiguration.all(list3, (x) -> true));
-        assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testAny() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertFalse(InitialConfiguration.any(list1, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f'));
-        assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testFindAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("foo", "bar", "baz");
-
-        assertEquals(list1, IpClient.findAll(list1, (x) -> true));
-        assertEquals(list1, IpClient.findAll(list3, (x) -> false));
-        assertEquals(list3, IpClient.findAll(list3, (x) -> true));
-        assertEquals(list2, IpClient.findAll(list3, (x) -> x.charAt(0) == 'f'));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
deleted file mode 100644
index 64b168a..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.ip;
-
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for IpReachabilityMonitor.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpReachabilityMonitorTest {
-
-    @Mock IpReachabilityMonitor.Callback mCallback;
-    @Mock IpReachabilityMonitor.Dependencies mDependencies;
-    @Mock SharedLog mLog;
-    @Mock Context mContext;
-    Handler mHandler;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mLog.forSubComponent(anyString())).thenReturn(mLog);
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    IpReachabilityMonitor makeMonitor() {
-        final InterfaceParams ifParams = new InterfaceParams("fake0", 1, null);
-        return new IpReachabilityMonitor(
-                mContext, ifParams, mHandler, mLog, mCallback, false, mDependencies);
-    }
-
-    @Test
-    public void testNothing() {
-        IpReachabilityMonitor monitor = makeMonitor();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
deleted file mode 100644
index 71be8b3..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for ConnectivityPacketSummary.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ConnectivityPacketSummaryTest {
-    private static final MacAddress MYHWADDR = MacAddress.fromString("80:7a:bf:6f:48:f3");
-
-    private String getSummary(String hexBytes) {
-        hexBytes = hexBytes.replaceAll("\\s+", "");
-        final byte[] bytes = HexEncoding.decode(hexBytes.toCharArray(), false);
-        return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
-    }
-
-    @Test
-    public void testParseICMPv6DADProbe() {
-        final String packet =
-                // Ethernet
-                "3333FF6F48F3 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000018 3A FF" +
-                "00000000000000000000000000000000" +
-                "FF0200000000000000000001FF6F48F3" +
-                // ICMPv6
-                "87 00 A8E7" +
-                "00000000" +
-                "FE80000000000000827ABFFFFE6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:ff:6f:48:f3 ipv6" +
-                " :: > ff02::1:ff6f:48f3 icmp6" +
-                " ns fe80::827a:bfff:fe6f:48f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RS() {
-        final String packet =
-                // Ethernet
-                "333300000002 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000010 3A FF" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                "FF020000000000000000000000000002" +
-                // ICMPv6 RS
-                "85 00 6973" +
-                "00000000" +
-                "01 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:00:00:00:02 ipv6" +
-                " fe80::827a:bfff:fe6f:48f3 > ff02::2 icmp6" +
-                " rs slla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RA() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "05 01 0000000005DC" +
-                "19 05 000000000E10" +
-                "      20014860486000000000000000008844" +
-                "      20014860486000000000000000008888" +
-                "03 04 40 C0" +
-                "      00278D00" +
-                "      00093A80" +
-                "      00000000" +
-                "      2401FA000004FD000000000000000000";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 mtu 1500";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NS() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 100E7E263FC1 86DD" +
-                  // IPv6
-                  "6C0000000020 3A FF" +
-                  "FE80000000000000FA000004FD000001" +
-                  "FF0200000000000000000001FF01C146" +
-                  // ICMPv6 NS
-                  "87 00 8AD4" +
-                  "00000000" +
-                  "2401FA000004FD0015EA6A5C7B01C146" +
-                  "01 01 00005E000265";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > ff02::1:ff01:c146 icmp6" +
-                " ns 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 slla 00:00:5e:00:02:65";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testInvalidICMPv6NDLength() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "00 00 0102030405D6";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 <malformed>";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NA() {
-        final String packet =
-                // Ethernet
-                "00005E000265 807ABF6F48F3 86DD" +
-                "600000000020 3A FF" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "FE80000000000000FA000004FD000001" +
-                "88 00 E8126" +
-                "0000000" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "02 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 00:00:5e:00:02:65 ipv6" +
-                " 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 > fe80::fa00:4:fd00:1 icmp6" +
-                " na 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 tlla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPRequest() {
-        final String packet =
-                // Ethernet
-                  "FFFFFFFFFFFF 807ABF6F48F3 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Request
-                  "0001" +
-                  "807ABF6F48F3 64706ADB" +
-                  "000000000000 64706FFD";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff arp" +
-                " who-has 100.112.111.253";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPReply() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 288A1CA8DFC1 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Reply
-                  "0002" +
-                  "288A1CA8DFC1 64706FFD"+
-                  "807ABF6F48F3 64706ADB" +
-                  // Ethernet padding to packet min size.
-                  "0000000000000000000000000000";
-
-        final String expected =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 arp" +
-                " reply 100.112.111.253 28:8a:1c:a8:df:c1";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseDHCPv4Discover() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "451001580000400040113986" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0144 5559" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 01" +
-                "3D 07 01807ABF6F48F3" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 DISCOVER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Offer() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D2C0000401188CB" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 371D" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 02" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 OFFER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Request() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "45100164000040004011397A" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0150 E5C7" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 03" +
-                "3D 07 01807ABF6F48F3" +
-                "32 04 64706ADB" +
-                "36 04 AC188A0B" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 REQUEST";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Ack() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D3B0000401188BC" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 341C" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 05" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 ACK";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
deleted file mode 100644
index 289dcad..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.net.util.PacketReader.DEFAULT_RECV_BUF_SIZE;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for PacketReader.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PacketReaderTest {
-    static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
-    static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
-
-    protected CountDownLatch mLatch;
-    protected FileDescriptor mLocalSocket;
-    protected InetSocketAddress mLocalSockName;
-    protected byte[] mLastRecvBuf;
-    protected boolean mStopped;
-    protected HandlerThread mHandlerThread;
-    protected PacketReader mReceiver;
-
-    class UdpLoopbackReader extends PacketReader {
-        public UdpLoopbackReader(Handler h) {
-            super(h);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                Os.bind(s, LOOPBACK6, 0);
-                mLocalSockName = (InetSocketAddress) Os.getsockname(s);
-                Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
-            } catch (ErrnoException|SocketException e) {
-                closeFd(s);
-                fail();
-                return null;
-            }
-
-            mLocalSocket = s;
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            mLastRecvBuf = Arrays.copyOf(recvbuf, length);
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStart() {
-            mStopped = false;
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStop() {
-            mStopped = true;
-            mLatch.countDown();
-        }
-    };
-
-    @Before
-    public void setUp() {
-        resetLatch();
-        mLocalSocket = null;
-        mLocalSockName = null;
-        mLastRecvBuf = null;
-        mStopped = false;
-
-        mHandlerThread = new HandlerThread(PacketReaderTest.class.getSimpleName());
-        mHandlerThread.start();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mReceiver != null) {
-            mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
-            waitForActivity();
-        }
-        mReceiver = null;
-        mHandlerThread.quit();
-        mHandlerThread = null;
-    }
-
-    void resetLatch() { mLatch = new CountDownLatch(1); }
-
-    void waitForActivity() throws Exception {
-        try {
-            mLatch.await(1000, TimeUnit.MILLISECONDS);
-        } finally {
-            resetLatch();
-        }
-    }
-
-    void sendPacket(byte[] contents) throws Exception {
-        final DatagramSocket sender = new DatagramSocket();
-        sender.connect(mLocalSockName);
-        sender.send(new DatagramPacket(contents, contents.length));
-        sender.close();
-    }
-
-    @Test
-    public void testBasicWorking() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-        mReceiver = new UdpLoopbackReader(h);
-
-        h.post(() -> { mReceiver.start(); });
-        waitForActivity();
-        assertTrue(mLocalSockName != null);
-        assertEquals(LOOPBACK6, mLocalSockName.getAddress());
-        assertTrue(0 < mLocalSockName.getPort());
-        assertTrue(mLocalSocket != null);
-        assertFalse(mStopped);
-
-        final byte[] one = "one 1".getBytes("UTF-8");
-        sendPacket(one);
-        waitForActivity();
-        assertEquals(1, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(one, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        final byte[] two = "two 2".getBytes("UTF-8");
-        sendPacket(two);
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        mReceiver.stop();
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertTrue(mStopped);
-        mReceiver = null;
-    }
-
-    class NullPacketReader extends PacketReader {
-        public NullPacketReader(Handler h, int recvbufsize) {
-            super(h, recvbufsize);
-        }
-
-        @Override
-        public FileDescriptor createFd() { return null; }
-    }
-
-    @Test
-    public void testMinimalRecvBufSize() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-
-        for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) {
-            final PacketReader b = new NullPacketReader(h, i);
-            assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize());
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
deleted file mode 100644
index e4c1d17..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ /dev/null
@@ -1,1154 +0,0 @@
-/*
- * 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.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.InetAddresses;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.metrics.IpConnectivityLog;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.telephony.CellSignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-import com.android.testutils.HandlerUtilsKt;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.mockito.verification.VerificationWithTimeout;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.Executor;
-
-import javax.net.ssl.SSLHandshakeException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetworkMonitorTest {
-    private static final String LOCATION_HEADER = "location";
-
-    private @Mock Context mContext;
-    private @Mock Resources mResources;
-    private @Mock IpConnectivityLog mLogger;
-    private @Mock SharedLog mValidationLogger;
-    private @Mock NetworkInfo mNetworkInfo;
-    private @Mock DnsResolver mDnsResolver;
-    private @Mock ConnectivityManager mCm;
-    private @Mock TelephonyManager mTelephony;
-    private @Mock WifiManager mWifi;
-    private @Mock HttpURLConnection mHttpConnection;
-    private @Mock HttpURLConnection mHttpsConnection;
-    private @Mock HttpURLConnection mFallbackConnection;
-    private @Mock HttpURLConnection mOtherFallbackConnection;
-    private @Mock Random mRandom;
-    private @Mock NetworkMonitor.Dependencies mDependencies;
-    private @Mock INetworkMonitorCallbacks mCallbacks;
-    private @Spy Network mCleartextDnsNetwork = new Network(TEST_NETID);
-    private @Mock Network mNetwork;
-    private @Mock DataStallStatsUtils mDataStallStatsUtils;
-    private @Mock WifiInfo mWifiInfo;
-    private @Captor ArgumentCaptor<String> mNetworkTestedRedirectUrlCaptor;
-
-    private HashSet<WrappedNetworkMonitor> mCreatedNetworkMonitors;
-    private HashSet<BroadcastReceiver> mRegisteredReceivers;
-
-    private static final int TEST_NETID = 4242;
-    private static final String TEST_HTTP_URL = "http://www.google.com/gen_204";
-    private static final String TEST_HTTPS_URL = "https://www.google.com/gen_204";
-    private static final String TEST_FALLBACK_URL = "http://fallback.google.com/gen_204";
-    private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204";
-    private static final String TEST_MCCMNC = "123456";
-
-    private static final int VALIDATION_RESULT_INVALID = 0;
-    private static final int VALIDATION_RESULT_PORTAL = 0;
-    private static final String TEST_REDIRECT_URL = "android.com";
-    private static final int VALIDATION_RESULT_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTP
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_FALLBACK_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_FALLBACK
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_VALID = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTPS
-            | NETWORK_VALIDATION_RESULT_VALID;
-
-    private static final int RETURN_CODE_DNS_SUCCESS = 0;
-    private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-    private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
-
-    private static final int HANDLER_TIMEOUT_MS = 1000;
-
-    private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
-
-    private static final NetworkCapabilities METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET);
-
-    private static final NetworkCapabilities NOT_METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET)
-            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-
-    private static final NetworkCapabilities NO_INTERNET_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-
-    /**
-     * Fakes DNS responses.
-     *
-     * Allows test methods to configure the IP addresses that will be resolved by
-     * Network#getAllByName and by DnsResolver#query.
-     */
-    class FakeDns {
-        private final ArrayMap<String, List<InetAddress>> mAnswers = new ArrayMap<>();
-        private boolean mNonBypassPrivateDnsWorking = true;
-
-        /** Whether DNS queries on mNonBypassPrivateDnsWorking should succeed. */
-        private void setNonBypassPrivateDnsWorking(boolean working) {
-            mNonBypassPrivateDnsWorking = working;
-        }
-
-        /** Clears all DNS entries. */
-        private synchronized void clearAll() {
-            mAnswers.clear();
-        }
-
-        /** Returns the answer for a given name on the given mock network. */
-        private synchronized List<InetAddress> getAnswer(Object mock, String hostname) {
-            if (mock == mNetwork && !mNonBypassPrivateDnsWorking) {
-                return null;
-            }
-            if (mAnswers.containsKey(hostname)) {
-                return mAnswers.get(hostname);
-            }
-            return mAnswers.get("*");
-        }
-
-        /** Sets the answer for a given name. */
-        private synchronized void setAnswer(String hostname, String[] answer)
-                throws UnknownHostException {
-            if (answer == null) {
-                mAnswers.remove(hostname);
-            } else {
-                List<InetAddress> answerList = new ArrayList<>();
-                for (String addr : answer) {
-                    answerList.add(InetAddresses.parseNumericAddress(addr));
-                }
-                mAnswers.put(hostname, answerList);
-            }
-        }
-
-        /** Simulates a getAllByName call for the specified name on the specified mock network. */
-        private InetAddress[] getAllByName(Object mock, String hostname)
-                throws UnknownHostException {
-            List<InetAddress> answer = getAnswer(mock, hostname);
-            if (answer == null || answer.size() == 0) {
-                throw new UnknownHostException(hostname);
-            }
-            return answer.toArray(new InetAddress[0]);
-        }
-
-        /** Starts mocking DNS queries. */
-        private void startMocking() throws UnknownHostException {
-            // Queries on mNetwork using getAllByName.
-            doAnswer(invocation -> {
-                return getAllByName(invocation.getMock(), invocation.getArgument(0));
-            }).when(mNetwork).getAllByName(any());
-
-            // Queries on mCleartextDnsNetwork using DnsResolver#query.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(3);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(5);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), any(), any(), any());
-
-            // Queries on mCleartextDnsNetwork using using DnsResolver#query with QueryType.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(4);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(6);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), anyInt(), any(), any(), any());
-        }
-    }
-
-    private FakeDns mFakeDns;
-
-    @Before
-    public void setUp() throws IOException {
-        MockitoAnnotations.initMocks(this);
-        when(mDependencies.getPrivateDnsBypassNetwork(any())).thenReturn(mCleartextDnsNetwork);
-        when(mDependencies.getDnsResolver()).thenReturn(mDnsResolver);
-        when(mDependencies.getRandom()).thenReturn(mRandom);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt()))
-                .thenReturn(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
-        when(mDependencies.getDeviceConfigPropertyInt(any(), eq(CAPTIVE_PORTAL_USE_HTTPS),
-                anyInt())).thenReturn(1);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTP_URL), any()))
-                .thenReturn(TEST_HTTP_URL);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTPS_URL), any()))
-                .thenReturn(TEST_HTTPS_URL);
-
-        doReturn(mCleartextDnsNetwork).when(mNetwork).getPrivateDnsBypassingCopy();
-
-        when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mCm);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifi);
-        when(mContext.getResources()).thenReturn(mResources);
-
-        when(mResources.getString(anyInt())).thenReturn("");
-        when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
-
-        when(mNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_OTHER_FALLBACK_URL);
-        setFallbackSpecs(null); // Test with no fallback spec by default
-        when(mRandom.nextInt()).thenReturn(0);
-
-        // DNS probe timeout should not be defined more than half of HANDLER_TIMEOUT_MS. Otherwise,
-        // it will fail the test because of timeout expired for querying AAAA and A sequentially.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(200);
-
-        doAnswer((invocation) -> {
-            URL url = invocation.getArgument(0);
-            switch(url.toString()) {
-                case TEST_HTTP_URL:
-                    return mHttpConnection;
-                case TEST_HTTPS_URL:
-                    return mHttpsConnection;
-                case TEST_FALLBACK_URL:
-                    return mFallbackConnection;
-                case TEST_OTHER_FALLBACK_URL:
-                    return mOtherFallbackConnection;
-                default:
-                    fail("URL not mocked: " + url.toString());
-                    return null;
-            }
-        }).when(mCleartextDnsNetwork).openConnection(any());
-        when(mHttpConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-        when(mHttpsConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-
-        mFakeDns = new FakeDns();
-        mFakeDns.startMocking();
-        mFakeDns.setAnswer("*", new String[]{"2001:db8::1", "192.0.2.2"});
-
-        when(mContext.registerReceiver(any(BroadcastReceiver.class), any())).then((invocation) -> {
-            mRegisteredReceivers.add(invocation.getArgument(0));
-            return new Intent();
-        });
-
-        doAnswer((invocation) -> {
-            mRegisteredReceivers.remove(invocation.getArgument(0));
-            return null;
-        }).when(mContext).unregisterReceiver(any());
-
-        setMinDataStallEvaluateInterval(500);
-        setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        setValidDataStallDnsTimeThreshold(500);
-        setConsecutiveDnsTimeoutThreshold(5);
-
-        mCreatedNetworkMonitors = new HashSet<>();
-        mRegisteredReceivers = new HashSet<>();
-    }
-
-    @After
-    public void tearDown() {
-        mFakeDns.clearAll();
-        assertTrue(mCreatedNetworkMonitors.size() > 0);
-        // Make a local copy of mCreatedNetworkMonitors because during the iteration below,
-        // WrappedNetworkMonitor#onQuitting will delete elements from it on the handler threads.
-        WrappedNetworkMonitor[] networkMonitors = mCreatedNetworkMonitors.toArray(
-                new WrappedNetworkMonitor[0]);
-        for (WrappedNetworkMonitor nm : networkMonitors) {
-            nm.notifyNetworkDisconnected();
-            nm.awaitQuit();
-        }
-        assertEquals("NetworkMonitor still running after disconnect",
-                0, mCreatedNetworkMonitors.size());
-        assertEquals("BroadcastReceiver still registered after disconnect",
-                0, mRegisteredReceivers.size());
-    }
-
-    private class WrappedNetworkMonitor extends NetworkMonitor {
-        private long mProbeTime = 0;
-        private final ConditionVariable mQuitCv = new ConditionVariable(false);
-
-        WrappedNetworkMonitor() {
-            super(mContext, mCallbacks, mNetwork, mLogger, mValidationLogger,
-                    mDependencies, mDataStallStatsUtils);
-        }
-
-        @Override
-        protected long getLastProbeTime() {
-            return mProbeTime;
-        }
-
-        protected void setLastProbeTime(long time) {
-            mProbeTime = time;
-        }
-
-        @Override
-        protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-            generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        }
-
-        @Override
-        protected void onQuitting() {
-            assertTrue(mCreatedNetworkMonitors.remove(this));
-            mQuitCv.open();
-        }
-
-        protected void awaitQuit() {
-            assertTrue("NetworkMonitor did not quit after " + HANDLER_TIMEOUT_MS + "ms",
-                    mQuitCv.block(HANDLER_TIMEOUT_MS));
-        }
-    }
-
-    private WrappedNetworkMonitor makeMonitor(NetworkCapabilities nc) {
-        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor();
-        nm.start();
-        setNetworkCapabilities(nm, nc);
-        HandlerUtilsKt.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
-        mCreatedNetworkMonitors.add(nm);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeNotMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(NOT_METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private void setNetworkCapabilities(NetworkMonitor nm, NetworkCapabilities nc) {
-        nm.notifyNetworkCapabilitiesChanged(nc);
-        HandlerUtilsKt.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
-    }
-
-    @Test
-    public void testGetIntSetting() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-
-        // No config resource, no device config. Expect to get default resource.
-        doThrow(new Resources.NotFoundException())
-                .when(mResources).getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout));
-        doAnswer(invocation -> {
-            int defaultValue = invocation.getArgument(2);
-            return defaultValue;
-        }).when(mDependencies).getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT),
-                anyInt());
-        when(mResources.getInteger(eq(R.integer.default_captive_portal_dns_probe_timeout)))
-                .thenReturn(42);
-        assertEquals(42, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set device config. Expect to get device config.
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT), anyInt()))
-                        .thenReturn(1234);
-        assertEquals(1234, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set config resource. Expect to get config resource.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(5678);
-        assertEquals(5678, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_PORTAL);
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpsProbeIsNotPortal() throws IOException {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 500);
-
-        runNotPortalNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsNotPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-
-        // Fallback probe did not see portal, HTTPS failed -> inconclusive
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_OtherFallbackProbeIsPortal() throws IOException {
-        // Set all fallback probes but one to invalid URLs to verify they are being skipped
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_FALLBACK_URL + "," + TEST_OTHER_FALLBACK_URL);
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-
-        // TEST_OTHER_FALLBACK_URL is third
-        when(mRandom.nextInt()).thenReturn(2);
-
-        // First check always uses the first fallback URL: inconclusive
-        final NetworkMonitor monitor = runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-
-        // Second check uses the URL chosen by Random
-        final CaptivePortalProbeResult result = monitor.isCaptivePortal();
-        assertTrue(result.isPortal());
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_AllProbesFailed() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_InvalidUrlSkipped() throws IOException {
-        setFallbackUrl("invalid");
-        setOtherFallbackUrls("otherinvalid," + TEST_OTHER_FALLBACK_URL + ",yetanotherinvalid");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    private void setupFallbackSpec() throws IOException {
-        setFallbackSpecs("http://example.com@@/@@204@@/@@"
-                + "@@,@@"
-                + TEST_OTHER_FALLBACK_URL + "@@/@@30[12]@@/@@https://(www\\.)?google.com/?.*");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-
-        // Use the 2nd fallback spec
-        when(mRandom.nextInt()).thenReturn(1);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPartial() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
-
-        // HTTPS failed, fallback spec went through -> partial connectivity
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPortal() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "http://login.portal.example.com");
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_IgnorePortals() throws IOException {
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        runNoValidationNetworkTest();
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDisabled() {
-        setDataStallEvaluationType(0);
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeoutCount() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        // Reset consecutive timeout counts.
-        makeDnsSuccessEvent(wrappedMonitor, 1);
-        makeDnsTimeoutEvent(wrappedMonitor, 2);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Set the value to larger than the default dns log size.
-        setConsecutiveDnsTimeoutThreshold(51);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 50);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 1);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeThreshold() {
-        // Test dns events happened in valid dns time threshold.
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Test dns events happened before valid dns time threshold.
-        setValidDataStallDnsTimeThreshold(0);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testBrokenNetworkNotValidated() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testNoInternetCapabilityValidated() throws Exception {
-        runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID,
-                getGeneralVerification());
-        verify(mCleartextDnsNetwork, never()).openConnection(any());
-    }
-
-    @Test
-    public void testLaunchCaptivePortalApp() throws Exception {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES);
-
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .showProvisioningNotification(any(), any());
-
-        assertEquals(1, mRegisteredReceivers.size());
-
-        // Check that startCaptivePortalApp sends the expected intent.
-        nm.launchCaptivePortalApp();
-
-        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
-        verify(mCm, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .startCaptivePortalApp(networkCaptor.capture(), bundleCaptor.capture());
-        final Bundle bundle = bundleCaptor.getValue();
-        final Network bundleNetwork = bundle.getParcelable(ConnectivityManager.EXTRA_NETWORK);
-        assertEquals(TEST_NETID, bundleNetwork.netId);
-        // network is passed both in bundle and as parameter, as the bundle is opaque to the
-        // framework and only intended for the captive portal app, but the framework needs
-        // the network to identify the right NetworkMonitor.
-        assertEquals(TEST_NETID, networkCaptor.getValue().netId);
-
-        // Have the app report that the captive portal is dismissed, and check that we revalidate.
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        reset(mCallbacks);
-        nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
-                        | NETWORK_VALIDATION_RESULT_VALID), any());
-        assertEquals(0, mRegisteredReceivers.size());
-    }
-
-    @Test
-    public void testPrivateDnsSuccess() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::53"});
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-    }
-
-    @Test
-    public void testPrivateDnsResolutionRetryUpdate() throws Exception {
-        // Set a private DNS hostname that doesn't resolve and expect validation to fail.
-        mFakeDns.setAnswer("dns.google", new String[0]);
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Fix DNS and retry, expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"});
-
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-
-        // Change configuration to an invalid DNS name, expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.bad", new String[0]);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
-        // Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
-        // notification.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID), eq(null));
-
-        // Change configuration back to working again, but make private DNS not work.
-        // Expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(false);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
-                new InetAddress[0]));
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Make private DNS work again. Expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(true);
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null));
-    }
-
-    @Test
-    public void testDataStall_StallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 5);
-        assertTrue(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, times(1)).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testDataStall_NoStallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, never()).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testCollectDataStallMetrics() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-
-        when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
-        when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC);
-        when(mTelephony.getSimOperator()).thenReturn(TEST_MCCMNC);
-
-        DataStallDetectionStats.Builder stats =
-                new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                .setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */,
-                        true /* roaming */,
-                        TEST_MCCMNC /* networkMccmnc */,
-                        TEST_MCCMNC /* simMccmnc */,
-                        CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN /* signalStrength */);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(wrappedMonitor.buildDataStallDetectionStats(
-                 NetworkCapabilities.TRANSPORT_CELLULAR), stats.build());
-
-        when(mWifi.getConnectionInfo()).thenReturn(mWifiInfo);
-
-        stats = new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_WIFI)
-                .setWiFiData(mWifiInfo);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(
-                wrappedMonitor.buildDataStallDetectionStats(NetworkCapabilities.TRANSPORT_WIFI),
-                stats.build());
-    }
-
-    @Test
-    public void testIgnoreHttpsProbe() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTP, HTTPS, FALLBACK probe and evaluation result notifications to CS.
-        final NetworkMonitor nm = runNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        nm.setAcceptPartialConnectivity();
-        // Expect to update evaluation result notifications to CS.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null));
-    }
-
-    @Test
-    public void testIsPartialConnectivity() throws IOException {
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 204);
-        setStatus(mFallbackConnection, 500);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-    }
-
-    private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
-        String[] actualStrings = new String[actual.length];
-        for (int i = 0; i < actual.length; i++) {
-            actualStrings[i] = actual[i].getHostAddress();
-        }
-        assertArrayEquals("Array of IP addresses differs", expected, actualStrings);
-    }
-
-    @Test
-    public void testSendDnsProbeWithTimeout() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        final int shortTimeoutMs = 200;
-
-        // Clear the wildcard DNS response created in setUp.
-        mFakeDns.setAnswer("*", null);
-
-        String[] expected = new String[]{"2001:db8::"};
-        mFakeDns.setAnswer("www.google.com", expected);
-        InetAddress[] actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        expected = new String[]{"2001:db8::", "192.0.2.1"};
-        mFakeDns.setAnswer("www.googleapis.com", expected);
-        actual = wnm.sendDnsProbeWithTimeout("www.googleapis.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        mFakeDns.setAnswer("www.google.com", new String[0]);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("No DNS results, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-
-        mFakeDns.setAnswer("www.google.com", null);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("DNS query timed out, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-    }
-
-    @Test
-    public void testNotifyNetwork_WithforceReevaluation() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        // Verify forceReevalution will not reset the validation result but only probe result until
-        // getting the validation result.
-        reset(mCallbacks);
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        nm.forceReevaluation(Process.myUid());
-        final ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
-        // Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(4))
-            .notifyNetworkTested(intCaptor.capture(), any());
-        List<Integer> intArgs = intCaptor.getAllValues();
-
-        // None of these exact values can be known in advance except for intArgs.get(0) because the
-        // HTTP and HTTPS probes race and the order in which they complete is non-deterministic.
-        // Thus, check only exact value for intArgs.get(0) and only check the validation result for
-        // the rest ones.
-        assertEquals(Integer.valueOf(NETWORK_VALIDATION_PROBE_DNS
-                | NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_VALID),
-                intArgs.get(0));
-        assertTrue((intArgs.get(1) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(2) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_VALID) == 0);
-    }
-
-    @Test
-    public void testEvaluationState_clearProbeResults() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        nm.getEvaluationState().clearProbeResults();
-        // Verify probe results are all reset and only evaluation result left.
-        assertEquals(NETWORK_VALIDATION_RESULT_VALID,
-                nm.getEvaluationState().getNetworkTestResult());
-    }
-
-    @Test
-    public void testEvaluationState_reportProbeResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        reset(mCallbacks);
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.SUCCESS);
-        // Verify result should be appended and notifyNetworkTested callback is triggered once.
-        assertEquals(nm.getEvaluationState().getNetworkTestResult(),
-                VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP), any());
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.FAILED);
-        // Verify DNS probe result should not be cleared.
-        assertTrue((nm.getEvaluationState().getNetworkTestResult() & NETWORK_VALIDATION_PROBE_DNS)
-                == NETWORK_VALIDATION_PROBE_DNS);
-    }
-
-    @Test
-    public void testEvaluationState_reportEvaluationResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
-                | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(
-                NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
-                TEST_REDIRECT_URL);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                eq(TEST_REDIRECT_URL));
-    }
-
-    private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_TIMEOUT);
-        }
-    }
-
-    private void makeDnsSuccessEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_SUCCESS);
-        }
-    }
-
-    private DataStallDetectionStats makeEmptyDataStallDetectionStats() {
-        return new DataStallDetectionStats.Builder().build();
-    }
-
-    private void setDataStallEvaluationType(int type) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_EVALUATION_TYPE), anyInt())).thenReturn(type);
-    }
-
-    private void setMinDataStallEvaluateInterval(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL), anyInt())).thenReturn(time);
-    }
-
-    private void setValidDataStallDnsTimeThreshold(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD), anyInt())).thenReturn(time);
-    }
-
-    private void setConsecutiveDnsTimeoutThreshold(int num) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD), anyInt())).thenReturn(num);
-    }
-
-    private void setFallbackUrl(String url) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL), any())).thenReturn(url);
-    }
-
-    private void setOtherFallbackUrls(String urls) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_OTHER_FALLBACK_URLS), any())).thenReturn(urls);
-    }
-
-    private void setFallbackSpecs(String specs) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS), any())).thenReturn(specs);
-    }
-
-    private void setCaptivePortalMode(int mode) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
-    }
-
-    private void runPortalNetworkTest(int result) {
-        // The network test event will be triggered twice with the same result. Expect to capture
-        // the second one with direct url.
-        runPortalNetworkTest(result,
-                (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).times(2));
-    }
-
-    private void runPortalNetworkTest(int result, VerificationWithTimeout mode) {
-        runNetworkTest(result, mode);
-        assertEquals(1, mRegisteredReceivers.size());
-        assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNotPortalNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNoValidationNetworkTest() {
-        runNetworkTest(NETWORK_VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runFailedNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runPartialConnectivityNetworkTest(int result) {
-        runNetworkTest(result);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private NetworkMonitor runValidatedNetworkTest() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTPs and evaluation results.
-        return runNetworkTest(VALIDATION_RESULT_VALID);
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, getGeneralVerification());
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult, VerificationWithTimeout mode) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, mode);
-    }
-
-    private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult,
-            VerificationWithTimeout mode) {
-        final NetworkMonitor monitor = makeMonitor(nc);
-        monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
-        try {
-            verify(mCallbacks, mode)
-                    .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
-        } catch (RemoteException e) {
-            fail("Unexpected exception: " + e);
-        }
-        HandlerUtilsKt.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
-
-        return monitor;
-    }
-
-    private void setSslException(HttpURLConnection connection) throws IOException {
-        doThrow(new SSLHandshakeException("Invalid cert")).when(connection).getResponseCode();
-    }
-
-    private void set302(HttpURLConnection connection, String location) throws IOException {
-        setStatus(connection, 302);
-        doReturn(location).when(connection).getHeaderField(LOCATION_HEADER);
-    }
-
-    private void setPortal302(HttpURLConnection connection) throws IOException {
-        set302(connection, "http://login.example.com");
-    }
-
-    private void setStatus(HttpURLConnection connection, int status) throws IOException {
-        doReturn(status).when(connection).getResponseCode();
-    }
-
-    private void generateTimeoutDnsEvent(DataStallDetectionStats.Builder stats, int num) {
-        for (int i = 0; i < num; i++) {
-            stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */);
-        }
-    }
-
-    private VerificationWithTimeout getGeneralVerification() {
-        return (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).atLeastOnce();
-    }
-
-}
-
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
deleted file mode 100644
index 64fe3a6..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2018 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.connectivity.ipmemorystore;
-
-import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
-
-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 static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-
-import android.app.job.JobScheduler;
-import android.content.Context;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/** Unit tests for {@link IpMemoryStoreService}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IpMemoryStoreServiceTest {
-    private static final String TEST_CLIENT_ID = "testClientId";
-    private static final String TEST_DATA_NAME = "testData";
-
-    private static final int TEST_DATABASE_SIZE_THRESHOLD = 100 * 1024; //100KB
-    private static final int DEFAULT_TIMEOUT_MS = 5000;
-    private static final int LONG_TIMEOUT_MS = 30000;
-    private static final int FAKE_KEY_COUNT = 20;
-    private static final long LEASE_EXPIRY_NULL = -1L;
-    private static final int MTU_NULL = -1;
-    private static final String[] FAKE_KEYS;
-    private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12,
-            -128, 0, 89, 112, 91, -34 };
-    static {
-        FAKE_KEYS = new String[FAKE_KEY_COUNT];
-        for (int i = 0; i < FAKE_KEYS.length; ++i) {
-            FAKE_KEYS[i] = "fakeKey" + i;
-        }
-    }
-
-    @Mock
-    private Context mMockContext;
-    @Mock
-    private JobScheduler mMockJobScheduler;
-    private File mDbFile;
-
-    private IpMemoryStoreService mService;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getContext();
-        final File dir = context.getFilesDir();
-        mDbFile = new File(dir, "test.db");
-        doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString());
-        doReturn(mMockJobScheduler).when(mMockContext)
-                .getSystemService(Context.JOB_SCHEDULER_SERVICE);
-        mService = new IpMemoryStoreService(mMockContext) {
-            @Override
-            protected int getDbSizeThreshold() {
-                return TEST_DATABASE_SIZE_THRESHOLD;
-            }
-
-            @Override
-            boolean isDbSizeOverThreshold() {
-                // Add a 100ms delay here for pausing maintenance job a while. Interrupted flag can
-                // be set at this time.
-                waitForMs(100);
-                return super.isDbSizeOverThreshold();
-            }
-        };
-    }
-
-    @After
-    public void tearDown() {
-        mService.shutdown();
-        mDbFile.delete();
-    }
-
-    /** Helper method to build test network attributes */
-    private static NetworkAttributes.Builder buildTestNetworkAttributes(
-            final Inet4Address ipAddress, final long expiry, final String hint,
-            final List<InetAddress> dnsServers, final int mtu) {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        if (null != ipAddress) {
-            na.setAssignedV4Address(ipAddress);
-        }
-        if (LEASE_EXPIRY_NULL != expiry) {
-            na.setAssignedV4AddressExpiry(expiry);
-        }
-        if (null != hint) {
-            na.setGroupHint(hint);
-        }
-        if (null != dnsServers) {
-            na.setDnsAddresses(dnsServers);
-        }
-        if (MTU_NULL != mtu) {
-            na.setMtu(mtu);
-        }
-        return na;
-    }
-
-    /** Helper method to make a vanilla IOnStatusListener */
-    private IOnStatusListener onStatus(Consumer<Status> functor) {
-        return new IOnStatusListener() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
-                functor.accept(new Status(statusParcelable));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnBlobRetrievedListener */
-    private interface OnBlobRetrievedListener {
-        void onBlobRetrieved(Status status, String l2Key, String name, byte[] data);
-    }
-    private IOnBlobRetrievedListener onBlobRetrieved(final OnBlobRetrievedListener functor) {
-        return new IOnBlobRetrievedListener() {
-            @Override
-            public void onBlobRetrieved(final StatusParcelable statusParcelable,
-                    final String l2Key, final String name, final Blob blob) throws RemoteException {
-                functor.onBlobRetrieved(new Status(statusParcelable), l2Key, name,
-                        null == blob ? null : blob.data);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnNetworkAttributesRetrievedListener */
-    private interface OnNetworkAttributesRetrievedListener  {
-        void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
-    }
-    private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
-            final OnNetworkAttributesRetrievedListener functor) {
-        return new IOnNetworkAttributesRetrievedListener() {
-            @Override
-            public void onNetworkAttributesRetrieved(final StatusParcelable status,
-                    final String l2Key, final NetworkAttributesParcelable attributes)
-                    throws RemoteException {
-                functor.onNetworkAttributesRetrieved(new Status(status), l2Key,
-                        null == attributes ? null : new NetworkAttributes(attributes));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnSameNetworkResponseListener */
-    private interface OnSameL3NetworkResponseListener {
-        void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
-    }
-    private IOnSameL3NetworkResponseListener onSameResponse(
-            final OnSameL3NetworkResponseListener functor) {
-        return new IOnSameL3NetworkResponseListener() {
-            @Override
-            public void onSameL3NetworkResponse(final StatusParcelable status,
-                    final SameL3NetworkResponseParcelable sameL3Network)
-                    throws RemoteException {
-                functor.onSameL3NetworkResponse(new Status(status),
-                        null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnL2KeyResponseListener */
-    private interface OnL2KeyResponseListener {
-        void onL2KeyResponse(Status status, String key);
-    }
-    private IOnL2KeyResponseListener onL2KeyResponse(final OnL2KeyResponseListener functor) {
-        return new IOnL2KeyResponseListener() {
-            @Override
-            public void onL2KeyResponse(final StatusParcelable status, final String key)
-                    throws RemoteException {
-                functor.onL2KeyResponse(new Status(status), key);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    // Helper method to factorize some boilerplate
-    private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor) {
-        doLatched(timeoutMessage, functor, DEFAULT_TIMEOUT_MS);
-    }
-
-    private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor,
-            final int timeout) {
-        final CountDownLatch latch = new CountDownLatch(1);
-        functor.accept(latch);
-        try {
-            if (!latch.await(timeout, TimeUnit.MILLISECONDS)) {
-                fail(timeoutMessage);
-            }
-        } catch (InterruptedException e) {
-            fail("Thread was interrupted");
-        }
-    }
-
-    // Helper method to store network attributes to database
-    private void storeAttributes(final String l2Key, final NetworkAttributes na) {
-        storeAttributes("Did not complete storing attributes", l2Key, na);
-    }
-    private void storeAttributes(final String timeoutMessage, final String l2Key,
-            final NetworkAttributes na) {
-        doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(),
-                onStatus(status -> {
-                    assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    // Helper method to store blob data to database
-    private void storeBlobOrFail(final String l2Key, final Blob b, final byte[] data) {
-        storeBlobOrFail("Did not complete storing private data", l2Key, b, data);
-    }
-    private void storeBlobOrFail(final String timeoutMessage, final String l2Key, final Blob b,
-            final byte[] data) {
-        b.data = data;
-        doLatched(timeoutMessage, latch -> mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME,
-                b, onStatus(status -> {
-                    assertTrue("Store status not successful : " + status.resultCode,
-                            status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    /** Insert large data that db size will be over threshold for maintenance test usage. */
-    private void insertFakeDataAndOverThreshold() {
-        try {
-            final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                    (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                    "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                    219);
-            final long time = System.currentTimeMillis() - 1;
-            for (int i = 0; i < 1000; i++) {
-                int errorCode = IpMemoryStoreDatabase.storeNetworkAttributes(
-                        mService.mDb,
-                        "fakeKey" + i,
-                        // Let first 100 records get expiry.
-                        i < 100 ? time : time + TimeUnit.HOURS.toMillis(i),
-                        na.build());
-                assertEquals(errorCode, Status.SUCCESS);
-
-                errorCode = IpMemoryStoreDatabase.storeBlob(
-                        mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME,
-                        TEST_BLOB_DATA);
-                assertEquals(errorCode, Status.SUCCESS);
-            }
-
-            // After added 5000 records, db size is larger than fake threshold(100KB).
-            assertTrue(mService.isDbSizeOverThreshold());
-        } catch (final UnknownHostException e) {
-            fail("Insert fake data fail");
-        }
-    }
-
-    /** Wait for assigned time. */
-    private void waitForMs(long ms) {
-        try {
-            Thread.sleep(ms);
-        } catch (final InterruptedException e) {
-            fail("Thread was interrupted");
-        }
-    }
-
-    @Test
-    public void testNetworkAttributes() throws UnknownHostException {
-        final String l2Key = FAKE_KEYS[0];
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        NetworkAttributes attributes = na.build();
-        storeAttributes(l2Key, attributes);
-
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(attributes, attr);
-                            latch.countDown();
-                        })));
-
-        final NetworkAttributes.Builder na2 = new NetworkAttributes.Builder();
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        final NetworkAttributes attributes2 = na2.build();
-        storeAttributes("Did not complete storing attributes 2", l2Key, attributes2);
-
-        doLatched("Did not complete retrieving attributes 2", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
-                            assertEquals(attributes.assignedV4AddressExpiry,
-                                    attr.assignedV4AddressExpiry);
-                            assertEquals(attributes.groupHint, attr.groupHint);
-                            assertEquals(attributes.mtu, attr.mtu);
-                            assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
-                            latch.countDown();
-                        })));
-
-        doLatched("Did not complete retrieving attributes 3", latch ->
-                mService.retrieveNetworkAttributes(l2Key + "nonexistent",
-                        onNetworkAttributesRetrieved(
-                                (status, key, attr) -> {
-                                    assertTrue("Retrieve network attributes not successful : "
-                                            + status.resultCode, status.isSuccess());
-                                    assertEquals(l2Key + "nonexistent", key);
-                                    assertNull("Retrieved data not stored", attr);
-                                    latch.countDown();
-                                }
-                        )));
-
-        // Verify that this test does not miss any new field added later.
-        // If any field is added to NetworkAttributes it must be tested here for storing
-        // and retrieving.
-        assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
-    }
-
-    @Test
-    public void testInvalidAttributes() {
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes("key", null, onStatus(status -> {
-                    assertFalse("Success storing on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        final NetworkAttributes na = new NetworkAttributes.Builder().setMtu(2).build();
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, na.toParcelable(), onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, null, onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete retrieving bad attributes", latch ->
-                mService.retrieveNetworkAttributes(null, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertFalse("Success retrieving attributes for a null key",
-                                    status.isSuccess());
-                            assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                            assertNull(key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testPrivateData() {
-        final String l2Key = FAKE_KEYS[0];
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertTrue(Arrays.equals(b.data, data));
-                            latch.countDown();
-                        })));
-
-        // Most puzzling error message ever
-        doLatched("Did not complete retrieving nothing", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME + "2", onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME + "2");
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testFindL2Key() throws UnknownHostException {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        na.setGroupHint("hint0");
-        storeAttributes(FAKE_KEYS[0], na.build());
-
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("8D56:9AF1::08EE:20F1")}));
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[1], na.build());
-        na.setMtu(null);
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        na.setGroupHint("hint1");
-        storeAttributes(FAKE_KEYS[2], na.build());
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[3], na.build());
-        na.setMtu(240);
-        storeAttributes(FAKE_KEYS[4], na.build());
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("5.6.7.8"));
-        storeAttributes(FAKE_KEYS[5], na.build());
-
-        // Matches key 5 exactly
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // MTU matches key 4 but v4 address matches key 5. The latter is stronger.
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // Closest to key 3 (indeed, identical)
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setMtu(219);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Group hint alone must not be strong enough to override the rest
-        na.setGroupHint("hint0");
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Still closest to key 3, though confidence is lower
-        na.setGroupHint("hint1");
-        na.setDnsAddresses(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // But changing the MTU makes this closer to key 4
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[4], key);
-                    latch.countDown();
-                })));
-
-        // MTU alone not strong enough to make this group-close
-        na.setGroupHint(null);
-        na.setDnsAddresses(null);
-        na.setAssignedV4Address(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertNull(key);
-                    latch.countDown();
-                })));
-    }
-
-    private void assertNetworksSameness(final String key1, final String key2, final int sameness) {
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(key1, key2, onSameResponse((status, answer) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(sameness, answer.getNetworkSameness());
-                    latch.countDown();
-                })));
-    }
-
-    @Test
-    public void testIsSameNetwork() throws UnknownHostException {
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                219);
-
-        storeAttributes(FAKE_KEYS[0], na.build());
-        // 0 and 1 have identical attributes
-        storeAttributes(FAKE_KEYS[1], na.build());
-
-        // Hopefully only the MTU being different still means it's the same network
-        na.setMtu(200);
-        storeAttributes(FAKE_KEYS[2], na.build());
-
-        // Hopefully different MTU, assigned V4 address and grouphint make a different network,
-        // even with identical DNS addresses
-        na.setAssignedV4Address(null);
-        na.setGroupHint("hint2");
-        storeAttributes(FAKE_KEYS[3], na.build());
-
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[1], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[3], SameL3NetworkResponse.NETWORK_DIFFERENT);
-        assertNetworksSameness(FAKE_KEYS[0], "neverInsertedKey",
-                SameL3NetworkResponse.NETWORK_NEVER_CONNECTED);
-
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(null, null, onSameResponse((status, answer) -> {
-                    assertFalse("Retrieve network sameness suspiciously successful : "
-                            + status.resultCode, status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    assertNull(answer);
-                    latch.countDown();
-                })));
-    }
-
-    @Test
-    public void testFullMaintenance() {
-        insertFakeDataAndOverThreshold();
-
-        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
-        // Do full maintenance and then db size should go down and meet the threshold.
-        doLatched("Maintenance unexpectedly completed successfully", latch ->
-                mService.fullMaintenance(onStatus((status) -> {
-                    assertTrue("Execute full maintenance failed: "
-                            + status.resultCode, status.isSuccess());
-                    latch.countDown();
-                }), im), LONG_TIMEOUT_MS);
-
-        // Assume that maintenance is successful, db size shall meet the threshold.
-        assertFalse(mService.isDbSizeOverThreshold());
-    }
-
-    @Test
-    public void testInterruptMaintenance() {
-        insertFakeDataAndOverThreshold();
-
-        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
-
-        // Test interruption immediately.
-        im.setInterrupted(true);
-        // Do full maintenance and the expectation is not completed by interruption.
-        doLatched("Maintenance unexpectedly completed successfully", latch ->
-                mService.fullMaintenance(onStatus((status) -> {
-                    assertFalse(status.isSuccess());
-                    latch.countDown();
-                }), im), LONG_TIMEOUT_MS);
-
-        // Assume that no data are removed, db size shall be over the threshold.
-        assertTrue(mService.isDbSizeOverThreshold());
-
-        // Reset the flag and test interruption during maintenance.
-        im.setInterrupted(false);
-
-        final ConditionVariable latch = new ConditionVariable();
-        // Do full maintenance and the expectation is not completed by interruption.
-        mService.fullMaintenance(onStatus((status) -> {
-            assertFalse(status.isSuccess());
-            latch.open();
-        }), im);
-
-        // Give a little bit of time for maintenance to start up for realism
-        waitForMs(50);
-        // Interrupt maintenance job.
-        im.setInterrupted(true);
-
-        if (!latch.block(LONG_TIMEOUT_MS)) {
-            fail("Maintenance unexpectedly completed successfully");
-        }
-
-        // Assume that only do dropAllExpiredRecords method in previous maintenance, db size shall
-        // still be over the threshold.
-        assertTrue(mService.isDbSizeOverThreshold());
-    }
-
-    @Test
-    public void testFactoryReset() throws UnknownHostException {
-        final String l2Key = FAKE_KEYS[0];
-
-        // store network attributes
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        storeAttributes(l2Key, na.build());
-
-        // store private data blob
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        // wipe all data in Database
-        mService.factoryReset();
-
-        // retrieved network attributes should be null
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-
-        // retrieved private data blob should be null
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    public void testTasksAreSerial() {
-        final long sleepTimeMs = 1000;
-        final long startTime = System.currentTimeMillis();
-        mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                (status, key, attr) -> {
-                    assertTrue("Unexpected status : " + status.resultCode, status.isSuccess());
-                    try {
-                        Thread.sleep(sleepTimeMs);
-                    } catch (InterruptedException e) {
-                        fail("InterruptedException");
-                    }
-                }));
-        doLatched("Serial tasks timing out", latch ->
-                mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Unexpected status : " + status.resultCode,
-                                    status.isSuccess());
-                            assertTrue(System.currentTimeMillis() >= startTime + sleepTimeMs);
-                        })), DEFAULT_TIMEOUT_MS);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
deleted file mode 100644
index 3d3aabc..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 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.connectivity.ipmemorystore;
-
-import static com.android.server.connectivity.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link RelevanceUtils}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RelevanceUtilsTests {
-    @Test
-    public void testComputeRelevanceForTargetDate() {
-        final long dayInMillis = 24L * 60 * 60 * 1000;
-        final long base = 1_000_000L; // any given point in time
-        // Relevance when the network expires in 1000 years must be capped
-        assertEquals(CAPPED_RELEVANCE, RelevanceUtils.computeRelevanceForTargetDate(
-                base + 1000L * dayInMillis, base));
-        // Relevance when expiry is before the date must be 0
-        assertEquals(0, RelevanceUtils.computeRelevanceForTargetDate(base - 1, base));
-        // Make sure the relevance for a given target date is higher if the expiry is further
-        // in the future
-        assertTrue(RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base)
-                < RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base));
-
-        // Make sure the relevance falls slower as the expiry is closing in. This is to ensure
-        // the decay is indeed logarithmic.
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(base, base);
-        final int relevance50DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 50 * dayInMillis, base);
-        final int relevance100DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base);
-        final int relevance150DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base);
-        assertEquals(0, relevanceAtExpiry);
-        assertTrue(relevance50DaysBeforeExpiry - relevanceAtExpiry
-                < relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry);
-        assertTrue(relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry
-                < relevance150DaysBeforeExpiry - relevance100DaysBeforeExpiry);
-    }
-
-    @Test
-    public void testIncreaseRelevance() {
-        long expiry = System.currentTimeMillis();
-
-        final long firstBump = RelevanceUtils.bumpExpiryDate(expiry);
-        // Though a few milliseconds might have elapsed, the first bump should push the duration
-        // to days in the future, so unless this test takes literal days between these two lines,
-        // this should always pass.
-        assertTrue(firstBump > expiry);
-
-        expiry = 0;
-        long lastDifference = Long.MAX_VALUE;
-        // The relevance should be capped in at most this many steps. Otherwise, fail.
-        final int steps = 1000;
-        for (int i = 0; i < steps; ++i) {
-            final long newExpiry = RelevanceUtils.bumpExpiryDuration(expiry);
-            if (newExpiry == expiry) {
-                // The relevance should be capped. Make sure it is, then exit without failure.
-                assertEquals(newExpiry, RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-                return;
-            }
-            // Make sure the new expiry is further in the future than last time.
-            assertTrue(newExpiry > expiry);
-            // Also check that it was not bumped as much as the last bump, because the
-            // decay must be exponential.
-            assertTrue(newExpiry - expiry < lastDifference);
-            lastDifference = newExpiry - expiry;
-            expiry = newExpiry;
-        }
-        fail("Relevance failed to go to the maximum value after " + steps + " bumps");
-    }
-
-    @Test
-    public void testContinuity() {
-        final long expiry = System.currentTimeMillis();
-
-        // Relevance at expiry and after expiry should be the cap.
-        final int relevanceBeforeMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1_000_000));
-        assertEquals(relevanceBeforeMaxLifetime, CAPPED_RELEVANCE);
-        final int relevanceForMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-        assertEquals(relevanceForMaxLifetime, CAPPED_RELEVANCE);
-
-        // If the max relevance is reached at the cap lifetime, one millisecond less than this
-        // should be very close. Strictly speaking this is a bit brittle, but it should be
-        // good enough for the purposes of the memory store.
-        final int relevanceForOneMillisecLessThanCap = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1);
-        assertTrue(relevanceForOneMillisecLessThanCap <= CAPPED_RELEVANCE);
-        assertTrue(relevanceForOneMillisecLessThanCap >= CAPPED_RELEVANCE - 10);
-
-        // Likewise the relevance one millisecond before expiry should be very close to 0. It's
-        // fine if it rounds down to 0.
-        final int relevanceOneMillisecBeforeExpiry = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - 1);
-        assertTrue(relevanceOneMillisecBeforeExpiry <= 10);
-        assertTrue(relevanceOneMillisecBeforeExpiry >= 0);
-
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry, expiry);
-        assertEquals(relevanceAtExpiry, 0);
-        final int relevanceAfterExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry + 1_000_000);
-        assertEquals(relevanceAfterExpiry, 0);
-    }
-
-    // testIncreaseRelevance makes sure bumping the expiry continuously always yields a
-    // monotonically increasing date as a side effect, but this tests that the relevance (as
-    // opposed to the expiry date) increases monotonically with increasing periods.
-    @Test
-    public void testMonotonicity() {
-        // Hopefully the relevance is granular enough to give a different value for every one
-        // of this number of steps.
-        final int steps = 40;
-        final long expiry = System.currentTimeMillis();
-
-        int lastRelevance = -1;
-        for (int i = 0; i < steps; ++i) {
-            final long date = expiry - i * (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS / steps);
-            final int relevance = RelevanceUtils.computeRelevanceForTargetDate(expiry, date);
-            assertTrue(relevance > lastRelevance);
-            lastRelevance = relevance;
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
deleted file mode 100644
index b1db051..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SharedLogTest {
-    private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
-    private static final String TIMESTAMP = "HH:MM:SS";
-
-    @Test
-    public void testBasicOperation() {
-        final SharedLog logTop = new SharedLog("top");
-        logTop.mark("first post!");
-
-        final SharedLog logLevel2a = logTop.forSubComponent("twoA");
-        final SharedLog logLevel2b = logTop.forSubComponent("twoB");
-        logLevel2b.e("2b or not 2b");
-        logLevel2b.e("No exception", null);
-        logLevel2b.e("Wait, here's one", new Exception("Test"));
-        logLevel2a.w("second post?");
-
-        final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
-        logTop.log("still logging");
-        logLevel3.log("3 >> 2");
-        logLevel2a.mark("ok: last post");
-
-        final String[] expected = {
-            " - MARK first post!",
-            " - [twoB] ERROR 2b or not 2b",
-            " - [twoB] ERROR No exception",
-            // No stacktrace in shared log, only in logcat
-            " - [twoB] ERROR Wait, here's one: Test",
-            " - [twoA] WARN second post?",
-            " - still logging",
-            " - [twoA.three] 3 >> 2",
-            " - [twoA] MARK ok: last post",
-        };
-        // Verify the logs are all there and in the correct order.
-        verifyLogLines(expected, logTop);
-
-        // In fact, because they all share the same underlying LocalLog,
-        // every subcomponent SharedLog's dump() is identical.
-        verifyLogLines(expected, logLevel2a);
-        verifyLogLines(expected, logLevel2b);
-        verifyLogLines(expected, logLevel3);
-    }
-
-    private static void verifyLogLines(String[] expected, SharedLog log) {
-        final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
-        final PrintWriter pw = new PrintWriter(ostream, true);
-        log.dump(null, pw, null);
-
-        final String dumpOutput = ostream.toString();
-        assertTrue(dumpOutput != null);
-        assertTrue(!"".equals(dumpOutput));
-
-        final String[] lines = dumpOutput.split("\n");
-        assertEquals(expected.length, lines.length);
-
-        for (int i = 0; i < expected.length; i++) {
-            String got = lines[i];
-            String want = expected[i];
-            assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
-            assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
-                    got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
-        }
-    }
-}
