Merge "Expose the empty MmTelCapabilities constructor"
diff --git a/Android.bp b/Android.bp
index e2b432c..383f58f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -550,6 +550,7 @@
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
         "telephony/java/com/android/internal/telephony/ISms.aidl",
         "telephony/java/com/android/internal/telephony/ISub.aidl",
+        "telephony/java/com/android/internal/telephony/IAns.aidl",
         "telephony/java/com/android/internal/telephony/ITelephony.aidl",
         "telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl",
         "telephony/java/com/android/internal/telephony/IWapPushManager.aidl",
@@ -600,6 +601,7 @@
         ":netd_aidl",
         ":vold_aidl",
         ":installd_aidl",
+        ":dumpstate_aidl",
 
         "lowpan/java/android/net/lowpan/ILowpanEnergyScanCallback.aidl",
         "lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl",
@@ -646,6 +648,7 @@
         include_dirs: [
             "system/update_engine/binder_bindings",
             "frameworks/native/aidl/binder",
+            "frameworks/native/cmds/dumpstate/binder",
             "frameworks/av/camera/aidl",
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
@@ -668,9 +671,6 @@
 
     no_framework_libs: true,
     libs: [
-        "conscrypt",
-        "okhttp",
-        "bouncycastle",
         "ext",
     ],
 
@@ -689,7 +689,9 @@
         "android.hardware.vibrator-V1.2-java",
         "android.hardware.wifi-V1.0-java-constants",
         "android.hardware.radio-V1.0-java",
+        "android.hardware.radio-V1.3-java",
         "android.hardware.usb.gadget-V1.0-java",
+        "netd_aidl_interface-java",
     ],
 
     // Loaded with System.loadLibrary by android.view.textclassifier
@@ -1074,14 +1076,13 @@
      "-federationapi SupportLib $(location current/support-api.txt) "
 
 framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " +
+     "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " +
      "-overview $(location core/java/overview.html) " +
      // Federate Support Library references against local API file.
      "-federate SupportLib https://developer.android.com " +
      "-federationapi SupportLib $(location current/support-api.txt) "
 
 framework_docs_only_libs = [
-    "conscrypt",
-    "bouncycastle",
     "voip-common",
     "android.test.mock",
     "android-support-annotations",
@@ -1161,7 +1162,8 @@
 
 doc_defaults {
     name: "framework-docs-default",
-    libs: framework_docs_only_libs,
+    libs: framework_docs_only_libs +
+         ["stub-annotations"],
     html_dirs: [
         "docs/html",
     ],
@@ -1558,7 +1560,6 @@
         "core/java/org/apache/http/params/CoreConnectionPNames.java",
         "core/java/org/apache/http/params/HttpConnectionParams.java",
         "core/java/org/apache/http/params/HttpParams.java",
-        "core/java/android/net/http/HttpResponseCache.java",
         "core/java/android/net/http/SslCertificate.java",
         "core/java/android/net/http/SslError.java",
         "core/java/com/android/internal/util/HexDump.java",
diff --git a/Android.mk b/Android.mk
index d333074..770ec20 100644
--- a/Android.mk
+++ b/Android.mk
@@ -87,6 +87,7 @@
     frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
     frameworks/base/config/hiddenapi-light-greylist.txt \
     frameworks/base/config/hiddenapi-vendor-list.txt \
+    frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
     frameworks/base/config/hiddenapi-force-blacklist.txt \
     $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
     $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
@@ -98,6 +99,7 @@
 	    --input-greylists \
 	        frameworks/base/config/hiddenapi-light-greylist.txt \
 	        frameworks/base/config/hiddenapi-vendor-list.txt \
+	        frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
 	        <(comm -12 <(sort $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)) \
 	                   $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)) \
 	        $(PRIVATE_GREYLIST_INPUTS) \
@@ -111,6 +113,17 @@
 	$(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST))
 	$(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST))
 
+$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): \
+    frameworks/base/tools/hiddenapi/merge_csv.py \
+    $(PRIVATE_METADATA_INPUTS)
+	frameworks/base/tools/hiddenapi/merge_csv.py $(PRIVATE_METADATA_INPUTS) > $@
+
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA))
+
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2247e43..6deda0c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -247,6 +247,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.media.remotedisplay.jar)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index c1b0cdf..443116f 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -27167,6 +27167,7 @@
   public static class ConnectivityManager.NetworkCallback {
     ctor public ConnectivityManager.NetworkCallback();
     method public void onAvailable(android.net.Network);
+    method public void onBlockedStatusChanged(android.net.Network, boolean);
     method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
     method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
     method public void onLosing(android.net.Network, int);
@@ -27438,16 +27439,16 @@
 
   public class NetworkInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.NetworkInfo.DetailedState getDetailedState();
+    method public deprecated android.net.NetworkInfo.DetailedState getDetailedState();
     method public java.lang.String getExtraInfo();
     method public deprecated java.lang.String getReason();
     method public deprecated android.net.NetworkInfo.State getState();
-    method public int getSubtype();
-    method public java.lang.String getSubtypeName();
+    method public deprecated int getSubtype();
+    method public deprecated java.lang.String getSubtypeName();
     method public deprecated int getType();
     method public deprecated java.lang.String getTypeName();
     method public deprecated boolean isAvailable();
-    method public boolean isConnected();
+    method public deprecated boolean isConnected();
     method public deprecated boolean isConnectedOrConnecting();
     method public deprecated boolean isFailover();
     method public deprecated boolean isRoaming();
@@ -41999,6 +42000,7 @@
     field public static final java.lang.String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
     field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
     field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
+    field public static final java.lang.String KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL = "support_clir_network_default_bool";
     field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
@@ -42636,10 +42638,13 @@
     method public static int getDefaultSmsSubscriptionId();
     method public static int getDefaultSubscriptionId();
     method public static int getDefaultVoiceSubscriptionId();
+    method public java.util.List<android.telephony.SubscriptionInfo> getOpportunisticSubscriptions(int);
+    method public static int getSlotIndex(int);
     method public static int[] getSubscriptionIds(int);
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public boolean isActiveSubscriptionId(int);
     method public boolean isNetworkRoaming(int);
+    method public static boolean isUsableSubscriptionId(int);
     method public static boolean isValidSubscriptionId(int);
     method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
@@ -42653,7 +42658,9 @@
     field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
+    field public static final int DEFAULT_SUBSCRIPTION_ID = 2147483647; // 0x7fffffff
     field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
+    field public static final int INVALID_SIM_SLOT_INDEX = -1; // 0xffffffff
     field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
 
@@ -43025,6 +43032,37 @@
 
 }
 
+package android.telephony.emergency {
+
+  public final class EmergencyNumber implements java.lang.Comparable android.os.Parcelable {
+    method public int compareTo(android.telephony.emergency.EmergencyNumber);
+    method public int describeContents();
+    method public java.lang.String getCountryIso();
+    method public int getEmergencyNumberSourceBitmask();
+    method public java.util.List<java.lang.Integer> getEmergencyNumberSources();
+    method public java.util.List<java.lang.Integer> getEmergencyServiceCategories();
+    method public int getEmergencyServiceCategoryBitmask();
+    method public java.lang.String getNumber();
+    method public boolean isFromSources(int);
+    method public boolean isInEmergencyServiceCategories(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.emergency.EmergencyNumber> CREATOR;
+    field public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = 8; // 0x8
+    field public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = 4; // 0x4
+    field public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING = 1; // 0x1
+    field public static final int EMERGENCY_NUMBER_SOURCE_SIM = 2; // 0x2
+    field public static final int EMERGENCY_SERVICE_CATEGORY_AIEC = 64; // 0x40
+    field public static final int EMERGENCY_SERVICE_CATEGORY_AMBULANCE = 2; // 0x2
+    field public static final int EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE = 4; // 0x4
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD = 8; // 0x8
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MIEC = 32; // 0x20
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE = 16; // 0x10
+    field public static final int EMERGENCY_SERVICE_CATEGORY_POLICE = 1; // 0x1
+    field public static final int EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED = 0; // 0x0
+  }
+
+}
+
 package android.telephony.euicc {
 
   public final class DownloadableSubscription implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 4a41157..082e067 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -120,6 +120,7 @@
     field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
     field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
     field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
+    field public static final java.lang.String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -3074,6 +3075,7 @@
   public class ConnectivityManager {
     method public java.lang.String getCaptivePortalServerUrl();
     method public boolean isTetheringSupported();
+    method public void setAirplaneMode(boolean);
     method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
     method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
     method public void stopTethering(int);
@@ -4281,6 +4283,23 @@
     field public static final java.lang.String INSTANT_APPS_ENABLED = "instant_apps_enabled";
   }
 
+  public static final class Telephony.Carriers implements android.provider.BaseColumns {
+    field public static final java.lang.String APN_SET_ID = "apn_set_id";
+    field public static final int CARRIER_EDITED = 4; // 0x4
+    field public static final java.lang.String EDITED = "edited";
+    field public static final java.lang.String MAX_CONNS = "max_conns";
+    field public static final java.lang.String MAX_CONNS_TIME = "max_conns_time";
+    field public static final java.lang.String MODEM_COGNITIVE = "modem_cognitive";
+    field public static final java.lang.String MTU = "mtu";
+    field public static final int NO_SET_SET = 0; // 0x0
+    field public static final int UNEDITED = 0; // 0x0
+    field public static final int USER_DELETED = 2; // 0x2
+    field public static final java.lang.String USER_EDITABLE = "user_editable";
+    field public static final int USER_EDITED = 1; // 0x1
+    field public static final java.lang.String USER_VISIBLE = "user_visible";
+    field public static final java.lang.String WAIT_TIME = "wait_time";
+  }
+
   public final class TimeZoneRulesDataContract {
     field public static final java.lang.String AUTHORITY = "com.android.timezone";
   }
@@ -5095,6 +5114,7 @@
     method public int getRejectCause();
     method public int getTransportType();
     method public boolean isEmergencyEnabled();
+    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationState> CREATOR;
     field public static final int DOMAIN_CS = 1; // 0x1
@@ -5137,6 +5157,11 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public class PhoneStateListener {
+    method public void onRadioPowerStateChanged(int);
+    field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
+  }
+
   public class ServiceState implements android.os.Parcelable {
     method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int);
     method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates();
@@ -5182,6 +5207,8 @@
     method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
     field public static final java.lang.String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
     field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
+    field public static final android.net.Uri ENHANCED_4G_ENABLED_CONTENT_URI;
+    field public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
@@ -5262,6 +5289,7 @@
     method public boolean getEmergencyCallbackMode();
     method public java.lang.String getIsimDomain();
     method public int getPreferredNetworkType(int);
+    method public int getRadioPowerState();
     method public int getSimApplicationState();
     method public int getSimCardState();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
@@ -5276,6 +5304,7 @@
     method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean needsOtaServiceProvisioning();
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method public void setCarrierDataEnabled(boolean);
     method public void setDataActivationState(int);
     method public deprecated void setDataEnabled(int, boolean);
     method public void setDataRoamingEnabled(boolean);
@@ -5325,6 +5354,9 @@
     field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe
     field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2
     field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0
+    field public static final int RADIO_POWER_OFF = 0; // 0x0
+    field public static final int RADIO_POWER_ON = 1; // 0x1
+    field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
     field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
     field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
     field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
@@ -5391,17 +5423,12 @@
   }
 
   public final class DataProfile implements android.os.Parcelable {
-    ctor public DataProfile(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, int, int, int, int, boolean, int, java.lang.String, int, int, java.lang.String, java.lang.String, boolean);
-    ctor public DataProfile(android.os.Parcel);
-    method public int describeContents();
     method public java.lang.String getApn();
     method public int getAuthType();
     method public int getBearerBitmap();
     method public int getMaxConns();
     method public int getMaxConnsTime();
     method public int getMtu();
-    method public java.lang.String getMvnoMatchData();
-    method public java.lang.String getMvnoType();
     method public java.lang.String getPassword();
     method public int getProfileId();
     method public java.lang.String getProtocol();
@@ -5411,9 +5438,8 @@
     method public java.lang.String getUserName();
     method public int getWaitTime();
     method public boolean isEnabled();
-    method public boolean isModemCognitive();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR;
+    method public boolean isPersistent();
+    method public boolean isPreferred();
     field public static final int TYPE_3GPP = 1; // 0x1
     field public static final int TYPE_3GPP2 = 2; // 0x2
     field public static final int TYPE_COMMON = 0; // 0x0
@@ -5739,11 +5765,13 @@
   }
 
   public final class ImsExternalCallState implements android.os.Parcelable {
+    ctor public ImsExternalCallState(java.lang.String, android.net.Uri, android.net.Uri, boolean, int, int, boolean);
     method public int describeContents();
     method public android.net.Uri getAddress();
     method public int getCallId();
     method public int getCallState();
     method public int getCallType();
+    method public android.net.Uri getLocalAddress();
     method public boolean isCallHeld();
     method public boolean isCallPullable();
     method public void writeToParcel(android.os.Parcel, int);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c4824c0..e12b665 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -120,6 +120,8 @@
         AppCrashOccurred app_crash_occurred = 78;
         ANROccurred anr_occurred = 79;
         WTFOccurred wtf_occurred = 80;
+        PhoneServiceStateChanged phone_service_state_changed = 94;
+        PhoneStateChanged phone_state_changed = 95;
         LowMemReported low_mem_reported = 81;
 
 
@@ -1137,6 +1139,33 @@
     optional android.telephony.SignalStrengthEnum signal_strength = 1;
 }
 
+
+/**
+ * Logs when the phone state, sim state or signal strength changes
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ */
+message PhoneServiceStateChanged {
+    optional android.telephony.ServiceStateEnum state = 1;
+    optional android.telephony.SimStateEnum sim_state = 2;
+    optional android.telephony.SignalStrengthEnum signal_strength = 3;
+}
+
+/**
+ * Logs when the phone becomes on or off.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/TelephonyRegistry.java
+ */
+message PhoneStateChanged {
+    enum State {
+        OFF = 0;
+        ON = 1;
+    }
+    optional State state = 1;
+}
+
 /**
  * Logs that a setting was updated.
  * Logged from:
diff --git a/cmds/statsd/src/hash.cpp b/cmds/statsd/src/hash.cpp
index c501c9f..543a748 100644
--- a/cmds/statsd/src/hash.cpp
+++ b/cmds/statsd/src/hash.cpp
@@ -16,6 +16,10 @@
 
 #include "hash.h"
 
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED [[fallthrough]]
+#endif
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -67,8 +71,10 @@
   switch (n) {
     case 3:
       h ^= ByteAs32(data[2]) << 16;
+      FALLTHROUGH_INTENDED;
     case 2:
       h ^= ByteAs32(data[1]) << 8;
+      FALLTHROUGH_INTENDED;
     case 1:
       h ^= ByteAs32(data[0]);
       h *= m;
@@ -104,16 +110,22 @@
   switch (n) {
     case 7:
       h ^= ByteAs64(data[6]) << 48;
+      FALLTHROUGH_INTENDED;
     case 6:
       h ^= ByteAs64(data[5]) << 40;
+      FALLTHROUGH_INTENDED;
     case 5:
       h ^= ByteAs64(data[4]) << 32;
+      FALLTHROUGH_INTENDED;
     case 4:
       h ^= ByteAs64(data[3]) << 24;
+      FALLTHROUGH_INTENDED;
     case 3:
       h ^= ByteAs64(data[2]) << 16;
+      FALLTHROUGH_INTENDED;
     case 2:
       h ^= ByteAs64(data[1]) << 8;
+      FALLTHROUGH_INTENDED;
     case 1:
       h ^= ByteAs64(data[0]);
       h *= m;
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index fff909c..73ac968 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -489,6 +489,10 @@
                                                              {"AID_RESERVED_DISK", 1065},
                                                              {"AID_STATSD", 1066},
                                                              {"AID_INCIDENTD", 1067},
+                                                             {"AID_SECURE_ELEMENT", 1068},
+                                                             {"AID_LMKD", 1069},
+                                                             {"AID_LLKD", 1070},
+                                                             {"AID_IORAPD", 1071},
                                                              {"AID_SHELL", 2000},
                                                              {"AID_CACHE", 2001},
                                                              {"AID_DIAG", 2002}};
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index fbf5b52..f0bc3d6 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -573,7 +573,6 @@
 Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->reportInetCondition(II)V
-Landroid/net/IConnectivityManager;->setAirplaneMode(Z)V
 Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyListener$Stub;-><init>()V
@@ -2288,6 +2287,7 @@
 Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY;
 Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey;
 Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
@@ -2860,15 +2860,6 @@
 Ljavax/net/ssl/SSLSocketFactory;->createSocket(Ljava/net/Socket;Ljava/io/InputStream;Z)Ljava/net/Socket;
 Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
 Llibcore/icu/ICU;->addLikelySubtags(Ljava/util/Locale;)Ljava/util/Locale;
-Llibcore/io/Memory;->peekByte(J)B
-Llibcore/io/Memory;->peekByteArray(J[BII)V
-Llibcore/io/Memory;->peekInt(JZ)I
-Llibcore/io/Memory;->peekLong(JZ)J
-Llibcore/io/Memory;->pokeByte(JB)V
-Llibcore/io/Memory;->pokeByteArray(J[BII)V
-Llibcore/io/Memory;->pokeInt(JIZ)V
-Llibcore/io/Memory;->pokeLong(JJZ)V
-Llibcore/io/Streams;->copy(Ljava/io/InputStream;Ljava/io/OutputStream;)I
 Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
 Llibcore/util/ZoneInfo;->mTransitions:[J
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
diff --git a/config/hiddenapi-max-sdk-p-blacklist.txt b/config/hiddenapi-max-sdk-p-blacklist.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/config/hiddenapi-max-sdk-p-blacklist.txt
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 73e98cd..d9e6fa2 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -107,20 +107,6 @@
             "android.bluetooth.device.action.FOUND";
 
     /**
-     * Broadcast Action: Remote device disappeared.
-     * <p>Sent when a remote device that was found in the last discovery is not
-     * found in the current discovery.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
-     *
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage
-    public static final String ACTION_DISAPPEARED =
-            "android.bluetooth.device.action.DISAPPEARED";
-
-    /**
      * Broadcast Action: Bluetooth class of a remote device has changed.
      * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
      * #EXTRA_CLASS}.
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 78248ef..d8a7834 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -56,6 +56,7 @@
     private int mAuthRetryState;
     private int mConnState;
     private final Object mStateLock = new Object();
+    private final Object mDeviceBusyLock = new Object();
     @UnsupportedAppUsage
     private Boolean mDeviceBusy = false;
     @UnsupportedAppUsage
@@ -281,7 +282,7 @@
                         }
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
                 }
@@ -356,7 +357,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -412,7 +413,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -495,7 +496,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -546,7 +547,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -595,7 +596,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -1097,7 +1098,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1131,7 +1132,7 @@
         if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid);
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1177,7 +1178,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1220,7 +1221,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1261,7 +1262,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1329,7 +1330,7 @@
         if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0fc55b4..2b60770 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3946,6 +3946,12 @@
     public static final String EXTRA_LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
 
     /**
+     * An parcelable extra used with {@link #ACTION_SERVICE_STATE} representing the service state.
+     * @hide
+     */
+    public static final String EXTRA_SERVICE_STATE = "android.intent.extra.SERVICE_STATE";
+
+    /**
      * The name of the extra used to define the text to be processed, as a
      * CharSequence. Note that this may be a styled CharSequence, so you must use
      * {@link Bundle#getCharSequence(String) Bundle.getCharSequence()} to retrieve it.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5cbd185..35db667 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5132,6 +5132,7 @@
      * @param packageName The name of the package to query
      * @throws IllegalArgumentException if the given package name is not installed
      */
+    @Nullable
     public abstract String getInstallerPackageName(String packageName);
 
     /**
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index caa99d5..12c2149 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2082,7 +2082,7 @@
 
     /**
      * <p>Optimized for dim settings where the main light source
-     * is a flame.</p>
+     * is a candle.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8333b81..4714587 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -83,6 +83,7 @@
 @SystemService(Context.CONNECTIVITY_SERVICE)
 public class ConnectivityManager {
     private static final String TAG = "ConnectivityManager";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     /**
      * A change in network connectivity has occurred. A default connection has either
@@ -2493,6 +2494,7 @@
      * {@hide}
      */
     public void reportInetCondition(int networkType, int percentage) {
+        printStackTrace();
         try {
             mService.reportInetCondition(networkType, percentage);
         } catch (RemoteException e) {
@@ -2513,6 +2515,7 @@
      */
     @Deprecated
     public void reportBadNetwork(Network network) {
+        printStackTrace();
         try {
             // One of these will be ignored because it matches system's current state.
             // The other will trigger the necessary reevaluation.
@@ -2535,6 +2538,7 @@
      *                        Internet using {@code network} or {@code false} if not.
      */
     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
+        printStackTrace();
         try {
             mService.reportNetworkConnectivity(network, hasConnectivity);
         } catch (RemoteException e) {
@@ -2727,8 +2731,11 @@
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
-    @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD,
+            android.Manifest.permission.NETWORK_STACK})
+    @SystemApi
     public void setAirplaneMode(boolean enable) {
         try {
             mService.setAirplaneMode(enable);
@@ -2809,10 +2816,11 @@
          * @param network The {@link Network} of the satisfying network.
          * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
          * @param linkProperties The {@link LinkProperties} of the satisfying network.
+         * @param blocked Whether access to the {@link Network} is blocked due to system policy.
          * @hide
          */
         public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
-                LinkProperties linkProperties) {
+                LinkProperties linkProperties, boolean blocked) {
             // Internally only this method is called when a new network is available, and
             // it calls the callback in the same way and order that older versions used
             // to call so as not to change the behavior.
@@ -2823,6 +2831,7 @@
             }
             onCapabilitiesChanged(network, networkCapabilities);
             onLinkPropertiesChanged(network, linkProperties);
+            onBlockedStatusChanged(network, blocked);
         }
 
         /**
@@ -2830,7 +2839,8 @@
          * This callback may be called more than once if the {@link Network} that is
          * satisfying the request changes. This will always immediately be followed by a
          * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
-         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
+         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call to
+         * {@link #onBlockedStatusChanged(Network, boolean)}.
          *
          * @param network The {@link Network} of the satisfying network.
          */
@@ -2909,6 +2919,14 @@
          */
         public void onNetworkResumed(Network network) {}
 
+        /**
+         * Called when access to the specified network is blocked or unblocked.
+         *
+         * @param network The {@link Network} whose blocked status has changed.
+         * @param blocked The blocked status of this {@link Network}.
+         */
+        public void onBlockedStatusChanged(Network network, boolean blocked) {}
+
         private NetworkRequest networkRequest;
     }
 
@@ -2955,6 +2973,8 @@
     public static final int CALLBACK_SUSPENDED           = BASE + 9;
     /** @hide */
     public static final int CALLBACK_RESUMED             = BASE + 10;
+    /** @hide */
+    public static final int CALLBACK_BLK_CHANGED         = BASE + 11;
 
     /** @hide */
     public static String getCallbackName(int whichCallback) {
@@ -2969,6 +2989,7 @@
             case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
             case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
             case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
+            case CALLBACK_BLK_CHANGED:  return "CALLBACK_BLK_CHANGED";
             default:
                 return Integer.toString(whichCallback);
         }
@@ -3015,7 +3036,7 @@
                 case CALLBACK_AVAILABLE: {
                     NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
                     LinkProperties lp = getObject(message, LinkProperties.class);
-                    callback.onAvailable(network, cap, lp);
+                    callback.onAvailable(network, cap, lp, message.arg1 != 0);
                     break;
                 }
                 case CALLBACK_LOSING: {
@@ -3048,6 +3069,10 @@
                     callback.onNetworkResumed(network);
                     break;
                 }
+                case CALLBACK_BLK_CHANGED: {
+                    boolean blocked = message.arg1 != 0;
+                    callback.onBlockedStatusChanged(network, blocked);
+                }
             }
         }
 
@@ -3073,6 +3098,7 @@
 
     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
             int timeoutMs, int action, int legacyType, CallbackHandler handler) {
+        printStackTrace();
         checkCallbackNotNull(callback);
         Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
         final NetworkRequest request;
@@ -3332,6 +3358,7 @@
      *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
      */
     public void requestNetwork(NetworkRequest request, PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
@@ -3355,6 +3382,7 @@
      *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
      */
     public void releaseNetworkRequest(PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.releasePendingNetworkRequest(operation);
@@ -3439,6 +3467,7 @@
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.pendingListenForNetwork(request.networkCapabilities, operation);
@@ -3520,6 +3549,7 @@
      * @param networkCallback The {@link NetworkCallback} used when making the request.
      */
     public void unregisterNetworkCallback(NetworkCallback networkCallback) {
+        printStackTrace();
         checkCallbackNotNull(networkCallback);
         final List<NetworkRequest> reqs = new ArrayList<>();
         // Find all requests associated to this callback and stop callback triggers immediately.
@@ -3948,4 +3978,19 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    private void printStackTrace() {
+        if (DEBUG) {
+            final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+            final StringBuffer sb = new StringBuffer();
+            for (int i = 3; i < callStack.length; i++) {
+                final String stackTrace = callStack[i].toString();
+                if (stackTrace == null || stackTrace.contains("android.os")) {
+                    break;
+                }
+                sb.append(" [").append(stackTrace).append("]");
+            }
+            Log.d(TAG, "StackLog:" + sb.toString());
+        }
+    }
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index fd1e5f2..74cd143 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -1589,4 +1589,14 @@
         Preconditions.checkArgument(isValidCapability(capability),
                 "NetworkCapability " + capability + "out of range");
     }
+
+    /**
+     * Check if this {@code NetworkCapability} instance is metered.
+     *
+     * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
+     * @hide
+     */
+    public boolean isMetered() {
+        return !hasCapability(NET_CAPABILITY_NOT_METERED);
+    }
 }
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index d912dd10..1a1d2d334 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -202,7 +202,9 @@
      * Return a network-type-specific integer describing the subtype
      * of the network.
      * @return the network subtype
+     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
      */
+    @Deprecated
     public int getSubtype() {
         synchronized (this) {
             return mSubtype;
@@ -243,7 +245,9 @@
     /**
      * Return a human-readable name describing the subtype of the network.
      * @return the name of the network subtype
+     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
      */
+    @Deprecated
     public String getSubtypeName() {
         synchronized (this) {
             return mSubtypeName;
@@ -278,7 +282,15 @@
      * connections and pass data.
      * <p>Always call this before attempting to perform data transactions.
      * @return {@code true} if network connectivity exists, {@code false} otherwise.
+     * @deprecated Apps should instead use the
+     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
+     *             learn about connectivity changes. See
+     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
+     *             {@link ConnectivityManager#registerNetworkCallback}. These will
+     *             give a more accurate picture of the connectivity state of
+     *             the device and let apps react more easily and quickly to changes.
      */
+    @Deprecated
     public boolean isConnected() {
         synchronized (this) {
             return mState == State.CONNECTED;
@@ -411,7 +423,15 @@
     /**
      * Reports the current fine-grained state of the network.
      * @return the fine-grained state
+     * @deprecated Apps should instead use the
+     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
+     *             learn about connectivity changes. See
+     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
+     *             {@link ConnectivityManager#registerNetworkCallback}. These will
+     *             give a more accurate picture of the connectivity state of
+     *             the device and let apps react more easily and quickly to changes.
      */
+    @Deprecated
     public DetailedState getDetailedState() {
         synchronized (this) {
             return mDetailedState;
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 40465ce..d09f33b 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1102,19 +1102,18 @@
         public String getHost() {
             @SuppressWarnings("StringEquality")
             boolean cached = (host != NOT_CACHED);
-            return cached ? host
-                    : (host = parseHost());
+            return cached ? host : (host = parseHost());
         }
 
         private String parseHost() {
-            String authority = getEncodedAuthority();
+            final String authority = getEncodedAuthority();
             if (authority == null) {
                 return null;
             }
 
             // Parse out user info and then port.
             int userInfoSeparator = authority.lastIndexOf('@');
-            int portSeparator = authority.indexOf(':', userInfoSeparator);
+            int portSeparator = findPortSeparator(authority);
 
             String encodedHost = portSeparator == NOT_FOUND
                     ? authority.substring(userInfoSeparator + 1)
@@ -1132,16 +1131,8 @@
         }
 
         private int parsePort() {
-            String authority = getEncodedAuthority();
-            if (authority == null) {
-                return -1;
-            }
-
-            // Make sure we look for the port separtor *after* the user info
-            // separator. We have URLs with a ':' in the user info.
-            int userInfoSeparator = authority.lastIndexOf('@');
-            int portSeparator = authority.indexOf(':', userInfoSeparator);
-
+            final String authority = getEncodedAuthority();
+            int portSeparator = findPortSeparator(authority);
             if (portSeparator == NOT_FOUND) {
                 return -1;
             }
@@ -1154,6 +1145,24 @@
                 return -1;
             }
         }
+
+        private int findPortSeparator(String authority) {
+            if (authority == null) {
+                return NOT_FOUND;
+            }
+
+            // Reverse search for the ':' character that breaks as soon as a char that is neither
+            // a colon nor an ascii digit is encountered. Thanks to the goodness of UTF-16 encoding,
+            // it's not possible that a surrogate matches one of these, so this loop can just
+            // look for characters rather than care about code points.
+            for (int i = authority.length() - 1; i >= 0; --i) {
+                final int character = authority.charAt(i);
+                if (':' == character) return i;
+                // Character.isDigit would include non-ascii digits
+                if (character < '0' || character > '9') return NOT_FOUND;
+            }
+            return NOT_FOUND;
+        }
     }
 
     /**
diff --git a/core/java/android/os/DumpstateOptions.java b/core/java/android/os/DumpstateOptions.java
new file mode 100644
index 0000000..53037b24
--- /dev/null
+++ b/core/java/android/os/DumpstateOptions.java
@@ -0,0 +1,57 @@
+/*
+ * 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.os;
+
+/**
+ * Options passed to dumpstate service.
+ *
+ * @hide
+ */
+public final class DumpstateOptions implements Parcelable {
+    // If true the caller can get callbacks with per-section
+    // progress details.
+    private final boolean mGetSectionDetails;
+    // Name of the caller.
+    private final String mName;
+
+    public DumpstateOptions(Parcel in) {
+        mGetSectionDetails = in.readBoolean();
+        mName = in.readString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+     public void writeToParcel(Parcel out, int flags) {
+        out.writeBoolean(mGetSectionDetails);
+        out.writeString(mName);
+    }
+
+    public static final Parcelable.Creator<DumpstateOptions> CREATOR =
+            new Parcelable.Creator<DumpstateOptions>() {
+        public DumpstateOptions createFromParcel(Parcel in) {
+            return new DumpstateOptions(in);
+        }
+
+        public DumpstateOptions[] newArray(int size) {
+            return new DumpstateOptions[size];
+        }
+    };
+}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 20ca19b..c9c4205 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -388,10 +388,10 @@
 
     /**
      * Setup a new physical network.
-     * @param permission null if no permissions required to access this network.  PERMISSION_NETWORK
-     *                   or PERMISSION_SYSTEM to set respective permission.
+     * @param permission PERMISSION_NONE if no permissions required to access this network.
+     *                   PERMISSION_NETWORK or PERMISSION_SYSTEM to set respective permission.
      */
-    void createPhysicalNetwork(int netId, String permission);
+    void createPhysicalNetwork(int netId, int permission);
 
     /**
      * Setup a new VPN.
@@ -420,10 +420,10 @@
 
     /**
      * Set permission for a network.
-     * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
-     *                   permission.
+     * @param permission PERMISSION_NONE to clear permissions.
+     *                   PERMISSION_NETWORK or PERMISSION_SYSTEM to set permission.
      */
-    void setNetworkPermission(int netId, String permission);
+    void setNetworkPermission(int netId, int permission);
 
     void setPermission(String permission, in int[] uids);
     void clearPermission(in int[] uids);
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index b303e10..c3f60a3 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -366,7 +366,7 @@
      * the <em>target</em> {@link Handler} that is receiving this Message to
      * dispatch it.  If
      * not set, the message will be dispatched to the receiving Handler's
-     * {@link Handler#handleMessage(Message Handler.handleMessage())}.
+     * {@link Handler#handleMessage(Message)}.
      */
     public Runnable getCallback() {
         return callback;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 29dbb83..7370029 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7299,6 +7299,15 @@
         public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application";
 
         /**
+         * Specifies the package name currently configured to be the default application to perform
+         * the user-defined call redirection service with Telecom.
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public static final String CALL_REDIRECTION_DEFAULT_APPLICATION =
+                "call_redirection_default_application";
+
+        /**
          * Specifies the package name currently configured to be the emergency assistance application
          *
          * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index cec0df0..959534d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -34,6 +34,8 @@
     public static final String FFLAG_PREFIX = "sys.fflag.";
     public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
     public static final String EMERGENCY_DIAL_SHORTCUTS = "settings_emergency_dial_shortcuts";
+    public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
+    public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
 
     private static final Map<String, String> DEFAULT_FLAGS;
     static {
@@ -46,6 +48,7 @@
         DEFAULT_FLAGS.put("settings_audio_switcher", "true");
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
         DEFAULT_FLAGS.put(EMERGENCY_DIAL_SHORTCUTS, "false");
+        DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "true");
     }
 
     /**
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index c388148..fee8345 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -171,8 +171,7 @@
             boolean debuggable);
 
     private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
-            String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge,
-            boolean debuggable);
+            String abiToCopy, boolean extractNativeLibs, boolean debuggable);
 
     private static long sumNativeBinaries(Handle handle, String abi) {
         long sum = 0;
@@ -193,7 +192,7 @@
     public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
         for (long apkHandle : handle.apkHandles) {
             int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
-                    handle.extractNativeLibs, HAS_NATIVE_BRIDGE, handle.debuggable);
+                    handle.extractNativeLibs, handle.debuggable);
             if (res != INSTALL_SUCCEEDED) {
                 return res;
             }
@@ -448,9 +447,6 @@
     // We don't care about the other return values for now.
     private static final int BITCODE_PRESENT = 1;
 
-    private static final boolean HAS_NATIVE_BRIDGE =
-            !"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0"));
-
     private static native int hasRenderscriptBitcode(long apkHandle);
 
     public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 10c32a3..486c836 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5369,6 +5369,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
                 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
+                StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin);
             }
         }
 
@@ -5380,6 +5381,7 @@
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
                 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
+                StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin);
             }
         }
 
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index bf31c7d..1ee4269 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -29,7 +29,6 @@
 import com.android.internal.util.FastPrintWriter;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/core/java/com/android/internal/widget/AlertDialogLayout.java b/core/java/com/android/internal/widget/AlertDialogLayout.java
index 9bf0948..7a01749 100644
--- a/core/java/com/android/internal/widget/AlertDialogLayout.java
+++ b/core/java/com/android/internal/widget/AlertDialogLayout.java
@@ -18,6 +18,7 @@
 
 import android.annotation.AttrRes;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.annotation.StyleRes;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -50,6 +51,7 @@
         super(context);
     }
 
+    @UnsupportedAppUsage
     public AlertDialogLayout(@Nullable Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java
index ab8be33..0ca6743 100644
--- a/core/java/com/android/internal/widget/ButtonBarLayout.java
+++ b/core/java/com/android/internal/widget/ButtonBarLayout.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -40,6 +41,7 @@
 
     private int mMinimumHeight = 0;
 
+    @UnsupportedAppUsage
     public ButtonBarLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
 
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index 7ea3d6b..405436c 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.text.Layout;
@@ -37,6 +38,7 @@
         super(context, attrs, defStyleAttr);
     }
 
+    @UnsupportedAppUsage
     public DialogTitle(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java
index c029bb2..3ea873b 100644
--- a/core/java/com/google/android/collect/Lists.java
+++ b/core/java/com/google/android/collect/Lists.java
@@ -16,6 +16,7 @@
 
 package com.google.android.collect;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Collections;
 
@@ -33,6 +34,7 @@
      *
      * @return a newly-created, initially-empty {@code ArrayList}
      */
+    @UnsupportedAppUsage
     public static <E> ArrayList<E> newArrayList() {
         return new ArrayList<E>();
     }
diff --git a/core/java/com/google/android/collect/Maps.java b/core/java/com/google/android/collect/Maps.java
index fc2c9fe..6ba3320 100644
--- a/core/java/com/google/android/collect/Maps.java
+++ b/core/java/com/google/android/collect/Maps.java
@@ -16,6 +16,7 @@
 
 package com.google.android.collect;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 
 import java.util.HashMap;
@@ -29,6 +30,7 @@
      *
      * @return a newly-created, initially-empty {@code HashMap}
      */
+    @UnsupportedAppUsage
     public static <K, V> HashMap<K, V> newHashMap() {
         return new HashMap<K, V>();
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 08c9678..d1a7d70 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -233,6 +233,7 @@
 
     shared_libs: [
         "libbpf",
+        "libnetdbpf",
         "libnetdutils",
         "libmemtrack",
         "libandroidfw",
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index c3ba9ba..9341d9a 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -23,6 +23,7 @@
 #include <atomic>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <mutex>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -69,6 +70,7 @@
     // Class state.
     jclass mClass;
     jmethodID mExecTransact;
+    jmethodID mGetInterfaceDescriptor;
 
     // Object state.
     jfieldID mObject;
@@ -328,8 +330,32 @@
         env->DeleteGlobalRef(mObject);
     }
 
-    virtual status_t onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
+    const String16& getInterfaceDescriptor() const override
+    {
+        call_once(mPopulateDescriptor, [this] {
+            JNIEnv* env = javavm_to_jnienv(mVM);
+
+            ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
+
+            jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
+
+            if (descriptor == nullptr) {
+                return;
+            }
+
+            static_assert(sizeof(jchar) == sizeof(char16_t), "");
+            const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
+            const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
+            jsize rawDescriptorLen = env->GetStringLength(descriptor);
+            mDescriptor = String16(rawDescriptor, rawDescriptorLen);
+            env->ReleaseStringChars(descriptor, descriptorChars);
+        });
+
+        return mDescriptor;
+    }
+
+    status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
     {
         JNIEnv* env = javavm_to_jnienv(mVM);
 
@@ -378,7 +404,7 @@
         return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
     }
 
-    virtual status_t dump(int fd, const Vector<String16>& args)
+    status_t dump(int fd, const Vector<String16>& args) override
     {
         return 0;
     }
@@ -386,6 +412,9 @@
 private:
     JavaVM* const   mVM;
     jobject const   mObject;  // GlobalRef to Java Binder
+
+    mutable std::once_flag mPopulateDescriptor;
+    mutable String16 mDescriptor;
 };
 
 // ----------------------------------------------------------------------------
@@ -939,6 +968,8 @@
 
     gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
     gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
+    gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
+        "()Ljava/lang/String;");
     gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
 
     return RegisterMethodsOrDie(
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index dc04269..5eefc81 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -176,7 +176,6 @@
     void** args = reinterpret_cast<void**>(arg);
     jstring* javaNativeLibPath = (jstring*) args[0];
     jboolean extractNativeLibs = *(jboolean*) args[1];
-    jboolean hasNativeBridge = *(jboolean*) args[2];
 
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
 
@@ -206,9 +205,7 @@
             return INSTALL_FAILED_INVALID_APK;
         }
 
-        if (!hasNativeBridge) {
-          return INSTALL_SUCCEEDED;
-        }
+        return INSTALL_SUCCEEDED;
     }
 
     // Build local file path
@@ -489,9 +486,9 @@
 static jint
 com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
         jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
-        jboolean extractNativeLibs, jboolean hasNativeBridge, jboolean debuggable)
+        jboolean extractNativeLibs, jboolean debuggable)
 {
-    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
+    void* args[] = { &javaNativeLibPath, &extractNativeLibs };
     return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable,
             copyFileIfChanged, reinterpret_cast<void*>(args));
 }
@@ -597,7 +594,7 @@
             "(J)V",
             (void *)com_android_internal_content_NativeLibraryHelper_close},
     {"nativeCopyNativeBinaries",
-            "(JLjava/lang/String;Ljava/lang/String;ZZZ)I",
+            "(JLjava/lang/String;Ljava/lang/String;ZZ)I",
             (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
     {"nativeSumNativeBinaries",
             "(JLjava/lang/String;Z)J",
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 109e65c..b3ff4db 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -32,8 +32,8 @@
 #include <utils/misc.h>
 
 #include "android-base/unique_fd.h"
-#include "bpf/BpfNetworkStats.h"
 #include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
 
 using android::bpf::hasBpfSupport;
 using android::bpf::parseBpfNetworkStatsDetail;
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index ed42e2e..30a9a01 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -7,6 +7,8 @@
 joeo@google.com
 kwekua@google.com
 singhtejinder@google.com
+yanglu@google.com
+yaochen@google.com
 
 # Frameworks
 ogunwale@google.com
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
index 32975a5..fba2e51 100644
--- a/core/proto/android/telephony/enums.proto
+++ b/core/proto/android/telephony/enums.proto
@@ -61,3 +61,64 @@
     SIGNAL_STRENGTH_GOOD = 3;
     SIGNAL_STRENGTH_GREAT = 4;
 }
+
+
+enum ServiceStateEnum {
+    /**
+     * Normal operation condition, the phone is registered
+     * with an operator either in home network or in roaming.
+     */
+    SERVICE_STATE_IN_SERVICE = 0;
+
+    /**
+     * Phone is not registered with any operator, the phone
+     * can be currently searching a new operator to register to, or not
+     * searching to registration at all, or registration is denied, or radio
+     * signal is not available.
+     */
+    SERVICE_STATE_OUT_OF_SERVICE = 1;
+
+    /**
+     * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
+     */
+    SERVICE_STATE_EMERGENCY_ONLY = 2;
+
+    /**
+     * Radio of telephony is explicitly powered off.
+     */
+    SERVICE_STATE_POWER_OFF = 3;
+}
+
+enum SimStateEnum {
+    SIM_STATE_UNKNOWN = 0;
+    /** SIM card state: no SIM card is available in the device */
+    SIM_STATE_ABSENT = 1;
+    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
+    SIM_STATE_PIN_REQUIRED = 2;
+    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
+    SIM_STATE_PUK_REQUIRED = 3;
+    /** SIM card state: Locked: requires a network PIN to unlock */
+    SIM_STATE_NETWORK_LOCKED = 4;
+    /** SIM card state: Ready */
+    SIM_STATE_READY = 5;
+    /** SIM card state: SIM Card is NOT READY */
+    SIM_STATE_NOT_READY = 6;
+    /** SIM card state: SIM Card Error, permanently disabled */
+    SIM_STATE_PERM_DISABLED = 7;
+    /** SIM card state: SIM Card Error, present but faulty */
+    SIM_STATE_CARD_IO_ERROR = 8;
+    /** SIM card state: SIM Card restricted, present but not usable due to
+     * carrier restrictions.
+     */
+    SIM_STATE_CARD_RESTRICTED = 9;
+    /**
+     * SIM card state: Loaded: SIM card applications have been loaded
+     * @hide
+     */
+    SIM_STATE_LOADED = 10;
+    /**
+     * SIM card state: SIM Card is present
+     * @hide
+     */
+    SIM_STATE_PRESENT = 11;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 73bb1fc..0dabcd7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -138,7 +138,6 @@
     <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
     <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
-    <protected-broadcast android:name="android.bluetooth.device.action.DISAPPEARED" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
@@ -1441,6 +1440,7 @@
 
     <!-- Allows SetupWizard to call methods in Networking services
          <p>Not for use by any other third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by SetupWizard.
     -->
     <permission android:name="android.permission.NETWORK_SETUP_WIZARD"
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index fb78b3b..7b3d940 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -109,12 +109,12 @@
     <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
          http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
          visual voicemail code for Orange: 21101 -->
-    <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366" />
+    <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051" />
 
     <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
          http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
          visual voicemail code for EE: 887 -->
-    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|2020|35890|61002|61202|887|83669|34664|40406|60174|7726|37726" />
+    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|2020|35890|61002|61202|887|83669|34664|40406|60174|7726|37726|88555|9017|9018" />
 
     <!-- Georgia: 4 digits, known premium codes listed -->
     <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
@@ -189,11 +189,14 @@
     <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
     <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223" />
 
+    <!-- Nigeria -->
+    <shortcode country="ng" pattern="\\d{1,5}" free="2441" />
+
     <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
 
     <!-- New Zealand: 3-4 digits, known premium codes listed -->
-    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="3067|3068|4053" />
+    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" />
 
     <!-- Peru: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="pe" pattern="\\d{4,5}" free="9963" />
@@ -209,7 +212,7 @@
 
     <!-- Portugal: 5 digits, plus EU:
          http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
-    <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}|1262" />
+    <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}|1262|12666" />
 
     <!-- Qatar: 1-5 digits (standard system default, not country specific) -->
     <shortcode country="qa" pattern="\\d{1,5}" free="92451" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index e0d5393..041fb7e 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -47,7 +47,6 @@
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.runner \
-    conscrypt \
     telephony-common \
     org.apache.http.legacy \
     android.test.base \
@@ -67,10 +66,6 @@
 
 # Disable AAPT2 because the hacks below depend on the AAPT rules implementation
 LOCAL_USE_AAPT2 := false
-# When AAPT2 is enabled it will need --warn-manifest-validation to fix:
-# frameworks/base/core/tests/coretests/AndroidManifest.xml:26: error: unknown element <meta-data> found.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-# LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 # Rules to copy all the test apks to the intermediate raw resource directory
diff --git a/core/tests/coretests/apks/install_multi_package/Android.mk b/core/tests/coretests/apks/install_multi_package/Android.mk
index 9727593..3f163de 100644
--- a/core/tests/coretests/apks/install_multi_package/Android.mk
+++ b/core/tests/coretests/apks/install_multi_package/Android.mk
@@ -8,10 +8,6 @@
 LOCAL_PACKAGE_NAME := install_multi_package
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml:46: error: unexpected element <package> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
 #include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_verifier_bad/Android.mk b/core/tests/coretests/apks/install_verifier_bad/Android.mk
index 679327c..745b4d3 100644
--- a/core/tests/coretests/apks/install_verifier_bad/Android.mk
+++ b/core/tests/coretests/apks/install_verifier_bad/Android.mk
@@ -6,9 +6,5 @@
 LOCAL_PACKAGE_NAME := install_verifier_bad
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_verifier_bad/AndroidManifest.xml:19: error: unexpected element <package-verifier> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_verifier_good/Android.mk b/core/tests/coretests/apks/install_verifier_good/Android.mk
index 7d621b3..150fd8d 100644
--- a/core/tests/coretests/apks/install_verifier_good/Android.mk
+++ b/core/tests/coretests/apks/install_verifier_good/Android.mk
@@ -6,9 +6,5 @@
 LOCAL_PACKAGE_NAME := install_verifier_good
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_verifier_good/AndroidManifest.xml:19: error: unexpected element <package-verifier> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
index 584257b..e248a77 100644
--- a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
+++ b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
@@ -45,7 +45,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -63,7 +63,7 @@
 
     @Before
     public void setUp() {
-        mTmpDir = IoUtils.createTemporaryDirectory("DexMetadataHelperTest");
+        mTmpDir = TestIoUtils.createTemporaryDirectory("DexMetadataHelperTest");
     }
 
     @After
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 0bc3a2d..17e34be 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -32,7 +32,6 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 
-import libcore.io.IoUtils;
 import libcore.io.Streams;
 
 import com.google.android.collect.Sets;
@@ -79,7 +78,7 @@
 
     @After
     public void tearDown() throws Exception {
-        IoUtils.deleteContents(mDir);
+        FileUtils.deleteContents(mDir);
         FileUtils.deleteContents(mTarget);
     }
 
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 23be634..32790e5 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -527,6 +527,7 @@
                  Settings.Secure.BACKUP_ENABLED,
                  Settings.Secure.BACKUP_PROVISIONED,
                  Settings.Secure.BACKUP_TRANSPORT,
+                 Settings.Secure.CALL_REDIRECTION_DEFAULT_APPLICATION,
                  Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
                  Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index f8e3b4d..872b71a 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -117,7 +117,7 @@
     @Test
     public void testFormatSameDayTime() {
         // This test assumes a default DateFormat.is24Hour setting.
-        DateFormat.is24Hour = null;
+        DateFormat.set24HourTimePref(null);
         Date date = new Date(109, 0, 19, 3, 30, 15);
         long fixedTime = date.getTime();
 
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
index edad4b2..97a3d00 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
index 3fae8e1..a347025 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
index c352c05..e4819e1 100644
--- a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index ab3faf0..8656781 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -21,6 +21,8 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
 
 my_package_prefix := com.android.server.om.hosttest.framework_overlay
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 82b6a22..0082f4b 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -316,6 +316,7 @@
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
         <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
         <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
         <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 5814df5..8fd02c0 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -472,8 +472,8 @@
          *     <tr>
          *         <td>Electro-optical transfer function (EOTF)</td>
          *         <td colspan="4">\(\begin{equation}
-         *             C_{linear} = \begin{cases}\frac{C_{DisplayP3}}{12.92} & C_{sRGB} \lt 0.039 \\
-         *             \left( \frac{C_{DisplayP3} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.039 \end{cases}
+         *             C_{linear} = \begin{cases}\frac{C_{DisplayP3}}{12.92} & C_{sRGB} \lt 0.04045 \\
+         *             \left( \frac{C_{DisplayP3} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.04045 \end{cases}
          *             \end{equation}\)
          *         </td>
          *     </tr>
@@ -1484,7 +1484,7 @@
                 "Display P3",
                 new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f },
                 ILLUMINANT_D65,
-                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.039, 2.4),
+                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4),
                 Named.DISPLAY_P3.ordinal()
         );
         sNamedColorSpaces[Named.NTSC_1953.ordinal()] = new ColorSpace.Rgb(
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 3821bc7..21ce1b8 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -27,7 +27,6 @@
 import android.system.OsConstants;
 import dalvik.system.CloseGuard;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.IOException;
 
diff --git a/keystore/OWNERS b/keystore/OWNERS
new file mode 100644
index 0000000..a63ca46
--- /dev/null
+++ b/keystore/OWNERS
@@ -0,0 +1,4 @@
+jbires@google.com
+jdanis@google.com
+robbarnes@google.com
+swillden@google.com
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index e39926b..140001d 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -43,11 +43,14 @@
         "AssetManager2.cpp",
         "AttributeResolution.cpp",
         "ChunkIterator.cpp",
+        "ConfigDescription.cpp",
         "Idmap.cpp",
         "LoadedArsc.cpp",
+        "Locale.cpp",
         "LocaleData.cpp",
         "misc.cpp",
         "ObbFile.cpp",
+        "PosixUtils.cpp",
         "ResourceTypes.cpp",
         "ResourceUtils.cpp",
         "StreamingZipInflater.cpp",
@@ -135,9 +138,11 @@
         "tests/AttributeResolution_test.cpp",
         "tests/ByteBucketArray_test.cpp",
         "tests/Config_test.cpp",
+        "tests/ConfigDescription_test.cpp",
         "tests/ConfigLocale_test.cpp",
         "tests/Idmap_test.cpp",
         "tests/LoadedArsc_test.cpp",
+        "tests/Locale_test.cpp",
         "tests/ResourceUtils_test.cpp",
         "tests/ResTable_test.cpp",
         "tests/Split_test.cpp",
@@ -152,6 +157,7 @@
             srcs: [
                 "tests/BackupData_test.cpp",
                 "tests/ObbFile_test.cpp",
+                "tests/PosixUtils_test.cpp",
             ],
             shared_libs: common_test_libs + ["libui"],
         },
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 8f58f74..66a5477 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -39,7 +39,7 @@
 
 static const std::string kResourcesArsc("resources.arsc");
 
-ApkAssets::ApkAssets(void* unmanaged_handle, const std::string& path)
+ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path)
     : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) {
 }
 
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 9c1629b..04cc5bb 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -67,10 +67,10 @@
 }
 
 bool AssetManager2::SetApkAssets(const std::vector<const ApkAssets*>& apk_assets,
-                                 bool invalidate_caches) {
+                                 bool invalidate_caches, bool filter_incompatible_configs) {
   apk_assets_ = apk_assets;
   BuildDynamicRefTable();
-  RebuildFilterList();
+  RebuildFilterList(filter_incompatible_configs);
   if (invalidate_caches) {
     InvalidateCaches(static_cast<uint32_t>(-1));
   }
@@ -825,7 +825,7 @@
   return 0u;
 }
 
-void AssetManager2::RebuildFilterList() {
+void AssetManager2::RebuildFilterList(bool filter_incompatible_configs) {
   for (PackageGroup& group : package_groups_) {
     for (ConfiguredPackage& impl : group.packages_) {
       // Destroy it.
@@ -841,7 +841,7 @@
         for (auto iter = spec->types; iter != iter_end; ++iter) {
           ResTable_config this_config;
           this_config.copyFromDtoH((*iter)->config);
-          if (this_config.match(configuration_)) {
+          if (!filter_incompatible_configs || this_config.match(configuration_)) {
             group.configurations.push_back(this_config);
             group.types.push_back(*iter);
           }
diff --git a/tools/aapt2/ConfigDescription.cpp b/libs/androidfw/ConfigDescription.cpp
similarity index 98%
rename from tools/aapt2/ConfigDescription.cpp
rename to libs/androidfw/ConfigDescription.cpp
index f621660..1f3a89e 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/libs/androidfw/ConfigDescription.cpp
@@ -14,22 +14,16 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/Locale.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+#include "androidfw/Util.h"
 
 #include <string>
 #include <vector>
 
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/StringPiece.h"
-
-#include "Locale.h"
-#include "SdkConstants.h"
-#include "util/Util.h"
-
-using android::ResTable_config;
-using android::StringPiece;
-
-namespace aapt {
+namespace android {
 
 static const char* kWildcardName = "any";
 
@@ -883,7 +877,7 @@
 }
 
 std::string ConfigDescription::to_string() const {
-  const android::String8 str = toString();
+  const String8 str = toString();
   return std::string(str.string(), str.size());
 }
 
@@ -996,4 +990,4 @@
   return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 04d506a..21f023d 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -203,6 +203,39 @@
   return true;
 }
 
+LoadedPackage::iterator::iterator(const LoadedPackage* lp, size_t ti, size_t ei)
+    : loadedPackage_(lp),
+      typeIndex_(ti),
+      entryIndex_(ei),
+      typeIndexEnd_(lp->resource_ids_.size() + 1) {
+  while (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] == 0) {
+    typeIndex_++;
+  }
+}
+
+LoadedPackage::iterator& LoadedPackage::iterator::operator++() {
+  while (typeIndex_ < typeIndexEnd_) {
+    if (entryIndex_ + 1 < loadedPackage_->resource_ids_[typeIndex_]) {
+      entryIndex_++;
+      break;
+    }
+    entryIndex_ = 0;
+    typeIndex_++;
+    if (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] != 0) {
+      break;
+    }
+  }
+  return *this;
+}
+
+uint32_t LoadedPackage::iterator::operator*() const {
+  if (typeIndex_ >= typeIndexEnd_) {
+    return 0;
+  }
+  return make_resid(loadedPackage_->package_id_, typeIndex_ + loadedPackage_->type_id_offset_,
+          entryIndex_);
+}
+
 const ResTable_entry* LoadedPackage::GetEntry(const ResTable_type* type_chunk,
                                               uint16_t entry_index) {
   uint32_t entry_offset = GetEntryOffset(type_chunk, entry_index);
@@ -488,6 +521,7 @@
         std::unique_ptr<TypeSpecPtrBuilder>& builder_ptr = type_builder_map[type_spec->id - 1];
         if (builder_ptr == nullptr) {
           builder_ptr = util::make_unique<TypeSpecPtrBuilder>(type_spec, idmap_entry_header);
+          loaded_package->resource_ids_.set(type_spec->id, entry_count);
         } else {
           LOG(WARNING) << StringPrintf("RES_TABLE_TYPE_SPEC_TYPE already defined for ID %02x",
                                        type_spec->id);
diff --git a/tools/aapt2/Locale.cpp b/libs/androidfw/Locale.cpp
similarity index 98%
rename from tools/aapt2/Locale.cpp
rename to libs/androidfw/Locale.cpp
index d81921f..2870066 100644
--- a/tools/aapt2/Locale.cpp
+++ b/libs/androidfw/Locale.cpp
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include "Locale.h"
+#include "androidfw/Locale.h"
+#include "androidfw/Util.h"
 
 #include <ctype.h>
 
@@ -22,12 +23,10 @@
 #include <string>
 #include <vector>
 
-#include "util/Util.h"
-
 using ::android::ResTable_config;
 using ::android::StringPiece;
 
-namespace aapt {
+namespace android {
 
 void LocaleValue::set_language(const char* language_chars) {
   size_t i = 0;
@@ -258,4 +257,4 @@
   }
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/PosixUtils.cpp b/libs/androidfw/PosixUtils.cpp
new file mode 100644
index 0000000..df0dd7c
--- /dev/null
+++ b/libs/androidfw/PosixUtils.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+// nothing to see here
+#else
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "android-base/logging.h"
+
+#include "androidfw/PosixUtils.h"
+
+namespace {
+
+std::unique_ptr<std::string> ReadFile(int fd) {
+  std::unique_ptr<std::string> str(new std::string());
+  char buf[1024];
+  ssize_t r;
+  while ((r = read(fd, buf, sizeof(buf))) > 0) {
+    str->append(buf, r);
+  }
+  if (r != 0) {
+    return nullptr;
+  }
+  return str;
+}
+
+}
+
+namespace android {
+namespace util {
+
+std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv) {
+  int stdout[2];  // stdout[0] read, stdout[1] write
+  if (pipe(stdout) != 0) {
+    PLOG(ERROR) << "pipe";
+    return nullptr;
+  }
+
+  int stderr[2];  // stdout[0] read, stdout[1] write
+  if (pipe(stderr) != 0) {
+    PLOG(ERROR) << "pipe";
+    close(stdout[0]);
+    close(stdout[1]);
+    return nullptr;
+  }
+
+  char const** argv0 = (char const**)malloc(sizeof(char*) * (argv.size() + 1));
+  for (size_t i = 0; i < argv.size(); i++) {
+    argv0[i] = argv[i].c_str();
+  }
+  argv0[argv.size()] = nullptr;
+  switch (fork()) {
+    case -1: // error
+      free(argv0);
+      PLOG(ERROR) << "fork";
+      return nullptr;
+    case 0: // child
+      close(stdout[0]);
+      if (dup2(stdout[1], STDOUT_FILENO) == -1) {
+        abort();
+      }
+      close(stderr[0]);
+      if (dup2(stderr[1], STDERR_FILENO) == -1) {
+        abort();
+      }
+      execvp(argv0[0], const_cast<char* const*>(argv0));
+      PLOG(ERROR) << "execv";
+      abort();
+    default: // parent
+      free(argv0);
+      close(stdout[1]);
+      close(stderr[1]);
+      int status;
+      wait(&status);
+      if (!WIFEXITED(status)) {
+          return nullptr;
+      }
+      std::unique_ptr<ProcResult> result(new ProcResult());
+      result->status = status;
+      const auto out = ReadFile(stdout[0]);
+      result->stdout = out ? *out : "";
+      close(stdout[0]);
+      const auto err = ReadFile(stderr[0]);
+      result->stderr = err ? *err : "";
+      close(stderr[0]);
+      return result;
+  }
+}
+
+} // namespace util
+} // namespace android
+#endif
diff --git a/libs/androidfw/Util.cpp b/libs/androidfw/Util.cpp
index 575cd18..59c9d64 100644
--- a/libs/androidfw/Util.cpp
+++ b/libs/androidfw/Util.cpp
@@ -16,6 +16,7 @@
 
 #include "androidfw/Util.h"
 
+#include <algorithm>
 #include <string>
 
 #include "utils/ByteOrder.h"
@@ -67,5 +68,28 @@
   return utf8;
 }
 
+static std::vector<std::string> SplitAndTransform(
+    const StringPiece& str, char sep, const std::function<char(char)>& f) {
+  std::vector<std::string> parts;
+  const StringPiece::const_iterator end = std::end(str);
+  StringPiece::const_iterator start = std::begin(str);
+  StringPiece::const_iterator current;
+  do {
+    current = std::find(start, end, sep);
+    parts.emplace_back(str.substr(start, current).to_string());
+    if (f) {
+      std::string& part = parts.back();
+      std::transform(part.begin(), part.end(), part.begin(), f);
+    }
+    start = current + 1;
+  } while (current != end);
+  return parts;
+}
+
+std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) {
+  return SplitAndTransform(str, sep, ::tolower);
+}
+
+
 } // namespace util
 } // namespace android
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 69702e3..db2d038 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -27,6 +27,9 @@
 #include "androidfw/LoadedArsc.h"
 #include "androidfw/misc.h"
 
+struct ZipArchive;
+typedef ZipArchive* ZipArchiveHandle;
+
 namespace android {
 
 class LoadedIdmap;
@@ -88,9 +91,9 @@
   // Creates an Asset from any file on the file system.
   static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path);
 
-  ApkAssets(void* unmanaged_handle, const std::string& path);
+  ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path);
 
-  using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>;
+  using ZipArchivePtr = std::unique_ptr<ZipArchive, void(*)(ZipArchiveHandle)>;
 
   ZipArchivePtr zip_handle_;
   const std::string path_;
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index ad31f69..2f0ee01 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -96,7 +96,12 @@
   // Only pass invalidate_caches=false when it is known that the structure
   // change in ApkAssets is due to a safe addition of resources with completely
   // new resource IDs.
-  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true);
+  //
+  // Only pass in filter_incompatible_configs=false when you want to load all
+  // configurations (including incompatible ones) such as when constructing an
+  // idmap.
+  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true,
+          bool filter_incompatible_configs = true);
 
   inline const std::vector<const ApkAssets*> GetApkAssets() const {
     return apk_assets_;
@@ -274,7 +279,7 @@
 
   // Triggers the re-construction of lists of types that match the set configuration.
   // This should always be called when mutating the AssetManager's configuration or ApkAssets set.
-  void RebuildFilterList();
+  void RebuildFilterList(bool filter_incompatible_configs = true);
 
   // AssetManager2::GetBag(resid) wraps this function to track which resource ids have already
   // been seen while traversing bag parents.
diff --git a/tools/aapt2/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
similarity index 87%
rename from tools/aapt2/ConfigDescription.h
rename to libs/androidfw/include/androidfw/ConfigDescription.h
index b46a503..29424c4 100644
--- a/tools/aapt2/ConfigDescription.h
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -14,21 +14,52 @@
  * limitations under the License.
  */
 
-#ifndef AAPT_CONFIG_DESCRIPTION_H
-#define AAPT_CONFIG_DESCRIPTION_H
+#ifndef ANDROIDFW_CONFIG_DESCRIPTION_H
+#define ANDROIDFW_CONFIG_DESCRIPTION_H
 
 #include <ostream>
 
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
-namespace aapt {
+namespace android {
+
+using ApiVersion = int;
+
+enum : ApiVersion {
+  SDK_CUPCAKE = 3,
+  SDK_DONUT = 4,
+  SDK_ECLAIR = 5,
+  SDK_ECLAIR_0_1 = 6,
+  SDK_ECLAIR_MR1 = 7,
+  SDK_FROYO = 8,
+  SDK_GINGERBREAD = 9,
+  SDK_GINGERBREAD_MR1 = 10,
+  SDK_HONEYCOMB = 11,
+  SDK_HONEYCOMB_MR1 = 12,
+  SDK_HONEYCOMB_MR2 = 13,
+  SDK_ICE_CREAM_SANDWICH = 14,
+  SDK_ICE_CREAM_SANDWICH_MR1 = 15,
+  SDK_JELLY_BEAN = 16,
+  SDK_JELLY_BEAN_MR1 = 17,
+  SDK_JELLY_BEAN_MR2 = 18,
+  SDK_KITKAT = 19,
+  SDK_KITKAT_WATCH = 20,
+  SDK_LOLLIPOP = 21,
+  SDK_LOLLIPOP_MR1 = 22,
+  SDK_MARSHMALLOW = 23,
+  SDK_NOUGAT = 24,
+  SDK_NOUGAT_MR1 = 25,
+  SDK_O = 26,
+  SDK_O_MR1 = 27,
+  SDK_P = 28,
+};
 
 /*
  * Subclass of ResTable_config that adds convenient
  * initialization and comparison methods.
  */
-struct ConfigDescription : public android::ResTable_config {
+struct ConfigDescription : public ResTable_config {
   /**
    * Returns an immutable default config.
    */
@@ -180,6 +211,6 @@
   return out << o.toString().string();
 }
 
-}  // namespace aapt
+}  // namespace android
 
-#endif  // AAPT_CONFIG_DESCRIPTION_H
+#endif  // ANDROIDFW_CONFIG_DESCRIPTION_H
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 35ae5fc..349b379 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -78,6 +78,55 @@
 
 class LoadedPackage {
  public:
+  class iterator {
+   public:
+    iterator& operator=(const iterator& rhs) {
+      loadedPackage_ = rhs.loadedPackage_;
+      typeIndex_ = rhs.typeIndex_;
+      entryIndex_ = rhs.entryIndex_;
+      return *this;
+    }
+
+    bool operator==(const iterator& rhs) const {
+      return loadedPackage_ == rhs.loadedPackage_ &&
+             typeIndex_ == rhs.typeIndex_ &&
+             entryIndex_ == rhs.entryIndex_;
+    }
+
+    bool operator!=(const iterator& rhs) const {
+      return !(*this == rhs);
+    }
+
+    iterator operator++(int) {
+      size_t prevTypeIndex_ = typeIndex_;
+      size_t prevEntryIndex_ = entryIndex_;
+      operator++();
+      return iterator(loadedPackage_, prevTypeIndex_, prevEntryIndex_);
+    }
+
+    iterator& operator++();
+
+    uint32_t operator*() const;
+
+   private:
+    friend class LoadedPackage;
+
+    iterator(const LoadedPackage* lp, size_t ti, size_t ei);
+
+    const LoadedPackage* loadedPackage_;
+    size_t typeIndex_;
+    size_t entryIndex_;
+    const size_t typeIndexEnd_;  // STL style end, so one past the last element
+  };
+
+  iterator begin() const {
+    return iterator(this, 0, 0);
+  }
+
+  iterator end() const {
+    return iterator(this, resource_ids_.size() + 1, 0);
+  }
+
   static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
                                                    const LoadedIdmap* loaded_idmap, bool system,
                                                    bool load_as_shared_library);
@@ -182,6 +231,7 @@
   bool overlay_ = false;
 
   ByteBucketArray<TypeSpecPtr> type_specs_;
+  ByteBucketArray<uint32_t> resource_ids_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
 };
 
diff --git a/tools/aapt2/Locale.h b/libs/androidfw/include/androidfw/Locale.h
similarity index 94%
rename from tools/aapt2/Locale.h
rename to libs/androidfw/include/androidfw/Locale.h
index 6d8b598..484ed79 100644
--- a/tools/aapt2/Locale.h
+++ b/libs/androidfw/include/androidfw/Locale.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef AAPT_LOCALE_VALUE_H
-#define AAPT_LOCALE_VALUE_H
+#ifndef ANDROIDFW_LOCALE_VALUE_H
+#define ANDROIDFW_LOCALE_VALUE_H
 
 #include <string>
 #include <vector>
@@ -23,7 +23,7 @@
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
-namespace aapt {
+namespace android {
 
 /**
  * A convenience class to build and parse locales.
@@ -112,6 +112,6 @@
   return compare(o) > 0;
 }
 
-}  // namespace aapt
+}  // namespace android
 
-#endif  // AAPT_LOCALE_VALUE_H
+#endif  // ANDROIDFW_LOCALE_VALUE_H
diff --git a/libs/androidfw/include/androidfw/PosixUtils.h b/libs/androidfw/include/androidfw/PosixUtils.h
new file mode 100644
index 0000000..8fc3ee2
--- /dev/null
+++ b/libs/androidfw/include/androidfw/PosixUtils.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace util {
+
+struct ProcResult {
+  int status;
+  std::string stdout;
+  std::string stderr;
+};
+
+// Fork, exec and wait for an external process. Return nullptr if the process could not be launched,
+// otherwise a ProcResult containing the external process' exit status and captured stdout and
+// stderr.
+std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv);
+
+} // namespace util
+} // namespace android
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index 6c9eee0..10d088e 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -19,6 +19,7 @@
 
 #include <cstdlib>
 #include <memory>
+#include <vector>
 
 #include "android-base/macros.h"
 
@@ -116,6 +117,8 @@
 // Converts a UTF-16 string to a UTF-8 string.
 std::string Utf16ToUtf8(const StringPiece16& utf16);
 
+std::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep);
+
 }  // namespace util
 }  // namespace android
 
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index 03154d0..c221e3b 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -41,7 +41,8 @@
 #include <unistd.h>
 #include <time.h>
 
-typedef void* ZipArchiveHandle;
+struct ZipArchive;
+typedef ZipArchive* ZipArchiveHandle;
 
 namespace android {
 
diff --git a/tools/aapt2/ConfigDescription_test.cpp b/libs/androidfw/tests/ConfigDescription_test.cpp
similarity index 93%
rename from tools/aapt2/ConfigDescription_test.cpp
rename to libs/androidfw/tests/ConfigDescription_test.cpp
index 1f351bf..ce7f805 100644
--- a/tools/aapt2/ConfigDescription_test.cpp
+++ b/libs/androidfw/tests/ConfigDescription_test.cpp
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/StringPiece.h"
+
+#include "android-base/logging.h"
+
+#include "gtest/gtest.h"
 
 #include <string>
 
-#include "androidfw/StringPiece.h"
-
-#include "SdkConstants.h"
-#include "test/Test.h"
-
-using android::StringPiece;
-
-namespace aapt {
+namespace android {
 
 static ::testing::AssertionResult TestParse(
     const StringPiece& input, ConfigDescription* config = nullptr) {
@@ -140,9 +138,13 @@
   EXPECT_EQ(std::string("vrheadset-v26"), config.toString().string());
 }
 
-TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) {
-  using test::ParseConfigOrDie;
+static inline ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
+  ConfigDescription config;
+  CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
+  return config;
+}
 
+TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) {
   EXPECT_FALSE(ParseConfigOrDie("large").ConflictsWith(ParseConfigOrDie("normal-land")));
   EXPECT_FALSE(ParseConfigOrDie("long-hdpi").ConflictsWith(ParseConfigOrDie("xhdpi")));
   EXPECT_FALSE(ParseConfigOrDie("sw600dp").ConflictsWith(ParseConfigOrDie("sw700dp")));
@@ -152,4 +154,4 @@
   EXPECT_FALSE(ParseConfigOrDie("600x400").ConflictsWith(ParseConfigOrDie("300x200")));
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index cae632d..ffa4836 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -278,4 +278,52 @@
 // sizeof(Res_value) might not be backwards compatible.
 TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
 
+TEST(LoadedArscTest, ResourceIdentifierIterator) {
+  std::string contents;
+  ASSERT_TRUE(
+      ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
+
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
+  ASSERT_NE(nullptr, loaded_arsc);
+
+  const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
+  ASSERT_EQ(1u, packages.size());
+  EXPECT_EQ(std::string("com.android.basic"), packages[0]->GetPackageName());
+
+  const auto& loaded_package = packages[0];
+  auto iter = loaded_package->begin();
+  auto end = loaded_package->end();
+
+  ASSERT_NE(end, iter);
+  ASSERT_EQ(0x7f010000u, *iter++);
+  ASSERT_EQ(0x7f010001u, *iter++);
+  ASSERT_EQ(0x7f020000u, *iter++);
+  ASSERT_EQ(0x7f020001u, *iter++);
+  ASSERT_EQ(0x7f030000u, *iter++);
+  ASSERT_EQ(0x7f030001u, *iter++);
+  ASSERT_EQ(0x7f030002u, *iter++);  // note: string without default, excluded by aapt2 dump
+  ASSERT_EQ(0x7f040000u, *iter++);
+  ASSERT_EQ(0x7f040001u, *iter++);
+  ASSERT_EQ(0x7f040002u, *iter++);
+  ASSERT_EQ(0x7f040003u, *iter++);
+  ASSERT_EQ(0x7f040004u, *iter++);
+  ASSERT_EQ(0x7f040005u, *iter++);
+  ASSERT_EQ(0x7f040006u, *iter++);
+  ASSERT_EQ(0x7f040007u, *iter++);
+  ASSERT_EQ(0x7f040008u, *iter++);
+  ASSERT_EQ(0x7f040009u, *iter++);
+  ASSERT_EQ(0x7f04000au, *iter++);
+  ASSERT_EQ(0x7f04000bu, *iter++);
+  ASSERT_EQ(0x7f04000cu, *iter++);
+  ASSERT_EQ(0x7f04000du, *iter++);
+  ASSERT_EQ(0x7f050000u, *iter++);
+  ASSERT_EQ(0x7f050001u, *iter++);
+  ASSERT_EQ(0x7f060000u, *iter++);
+  ASSERT_EQ(0x7f070000u, *iter++);
+  ASSERT_EQ(0x7f070001u, *iter++);
+  ASSERT_EQ(0x7f070002u, *iter++);
+  ASSERT_EQ(0x7f070003u, *iter++);
+  ASSERT_EQ(end, iter);
+}
+
 }  // namespace android
diff --git a/tools/aapt2/Locale_test.cpp b/libs/androidfw/tests/Locale_test.cpp
similarity index 96%
rename from tools/aapt2/Locale_test.cpp
rename to libs/androidfw/tests/Locale_test.cpp
index 68b4cae..6b2ef5f 100644
--- a/tools/aapt2/Locale_test.cpp
+++ b/libs/androidfw/tests/Locale_test.cpp
@@ -14,15 +14,14 @@
  * limitations under the License.
  */
 
-#include "Locale.h"
+#include "androidfw/Locale.h"
+#include "androidfw/Util.h"
 
 #include <string>
 
 #include "gtest/gtest.h"
 
-#include "util/Util.h"
-
-namespace aapt {
+namespace android {
 
 static ::testing::AssertionResult TestLanguage(const char* input,
                                                const char* lang) {
@@ -93,4 +92,4 @@
   EXPECT_TRUE(TestLanguageRegion("fr-rCA", "fr", "CA"));
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/tests/PosixUtils_test.cpp b/libs/androidfw/tests/PosixUtils_test.cpp
new file mode 100644
index 0000000..cf97f87
--- /dev/null
+++ b/libs/androidfw/tests/PosixUtils_test.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#include <utility>
+
+#include "androidfw/PosixUtils.h"
+
+#include "TestHelpers.h"
+
+using ::testing::IsNull;
+using ::testing::NotNull;
+
+namespace android {
+namespace util {
+
+TEST(PosixUtilsTest, AbsolutePathToBinary) {
+  const auto result = ExecuteBinary({"/bin/date", "--help"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_EQ(result->status, 0);
+  ASSERT_EQ(result->stdout.find("usage: date "), 0);
+}
+
+TEST(PosixUtilsTest, RelativePathToBinary) {
+  const auto result = ExecuteBinary({"date", "--help"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_EQ(result->status, 0);
+  ASSERT_EQ(result->stdout.find("usage: date "), 0);
+}
+
+TEST(PosixUtilsTest, BadParameters) {
+  const auto result = ExecuteBinary({"/bin/date", "--this-parameter-is-not-supported"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_NE(result->status, 0);
+}
+
+TEST(PosixUtilsTest, NoSuchBinary) {
+  const auto result = ExecuteBinary({"/this/binary/does/not/exist"});
+  ASSERT_THAT(result, IsNull());
+}
+
+} // android
+} // util
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index 447195d..b09335c 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -18,4 +18,5 @@
     name: "com.android.location.provider",
     srcs: ["java/**/*.java"],
     api_packages: ["com.android.location.provider"],
+    metalava_enabled: false,
 }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index bbc51ce..aec4520 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3932,18 +3932,31 @@
     }
 
      /**
-     * Indicate Hearing Aid connection state change.
+     * Indicate Hearing Aid connection state change and eventually suppress
+     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
      * @param device Bluetooth device connected/disconnected
      * @param state new connection state (BluetoothProfile.STATE_xxx)
+     * @param musicDevice Default get system volume for the connecting device.
+     * (either {@link android.bluetooth.BluetoothProfile.hearingaid} or
+     * {@link android.bluetooth.BluetoothProfile.HEARING_AID})
+     * @param suppressNoisyIntent if true the
+     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+     * @return a delay in ms that the caller should wait before broadcasting
+     * BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED intent.
      * {@hide}
      */
-    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state) {
+    public int setBluetoothHearingAidDeviceConnectionState(
+                BluetoothDevice device, int state, boolean suppressNoisyIntent,
+                int musicDevice) {
         final IAudioService service = getService();
+        int delay = 0;
         try {
-            service.setHearingAidDeviceConnectionState(device, state);
+            delay = service.setBluetoothHearingAidDeviceConnectionState(device,
+                state, suppressNoisyIntent, musicDevice);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+        return delay;
     }
 
      /**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 569db16..abd6411 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -151,8 +151,6 @@
     void setWiredDeviceConnectionState(int type, int state, String address, String name,
             String caller);
 
-    void setHearingAidDeviceConnectionState(in BluetoothDevice device, int state);
-
     int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);
 
     void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);
@@ -210,6 +208,9 @@
 
     oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);
 
+    int setBluetoothHearingAidDeviceConnectionState(in BluetoothDevice device,
+            int state, boolean suppressNoisyIntent, int musicDevice);
+
     int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
             int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
 
diff --git a/media/lib/remotedisplay/Android.bp b/media/lib/remotedisplay/Android.bp
index 1e9320d..5f4b930 100644
--- a/media/lib/remotedisplay/Android.bp
+++ b/media/lib/remotedisplay/Android.bp
@@ -14,22 +14,8 @@
 // limitations under the License.
 //
 
-droiddoc {
-    name: "com.android.media.remotedisplay.stubs-gen-docs",
-    srcs: [
-        "java/**/*.java",
-    ],
-    args: " -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " +
-          " -stubpackages com.android.media.remotedisplay " +
-          " -nodocs ",
-    custom_template: "droiddoc-templates-sdk",
-    installable: false,
-}
-
-java_library_static {
-    name: "com.android.media.remotedisplay.stubs",
-    srcs: [
-        ":com.android.media.remotedisplay.stubs-gen-docs",
-    ],
-    sdk_version: "current",
+java_sdk_library {
+    name: "com.android.media.remotedisplay",
+    srcs: ["java/**/*.java"],
+    api_packages: ["com.android.media.remotedisplay"],
 }
diff --git a/media/lib/remotedisplay/Android.mk b/media/lib/remotedisplay/Android.mk
deleted file mode 100644
index e88c0f1..0000000
--- a/media/lib/remotedisplay/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-# the remotedisplay library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.media.remotedisplay
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ====  com.android.media.remotedisplay.xml lib def  ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.media.remotedisplay.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
diff --git a/media/lib/remotedisplay/api/current.txt b/media/lib/remotedisplay/api/current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/current.txt
diff --git a/media/lib/remotedisplay/api/removed.txt b/media/lib/remotedisplay/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/removed.txt
diff --git a/media/lib/remotedisplay/api/system-current.txt b/media/lib/remotedisplay/api/system-current.txt
new file mode 100644
index 0000000..69bbd35
--- /dev/null
+++ b/media/lib/remotedisplay/api/system-current.txt
@@ -0,0 +1,52 @@
+package com.android.media.remotedisplay {
+
+  public class RemoteDisplay {
+    ctor public RemoteDisplay(java.lang.String, java.lang.String);
+    method public java.lang.String getDescription();
+    method public java.lang.String getId();
+    method public java.lang.String getName();
+    method public int getPresentationDisplayId();
+    method public int getStatus();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
+    method public void setDescription(java.lang.String);
+    method public void setName(java.lang.String);
+    method public void setPresentationDisplayId(int);
+    method public void setStatus(int);
+    method public void setVolume(int);
+    method public void setVolumeHandling(int);
+    method public void setVolumeMax(int);
+    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_CONNECTED = 4; // 0x4
+    field public static final int STATUS_CONNECTING = 3; // 0x3
+    field public static final int STATUS_IN_USE = 1; // 0x1
+    field public static final int STATUS_NOT_AVAILABLE = 0; // 0x0
+  }
+
+  public abstract class RemoteDisplayProvider {
+    ctor public RemoteDisplayProvider(android.content.Context);
+    method public void addDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    method public com.android.media.remotedisplay.RemoteDisplay findRemoteDisplay(java.lang.String);
+    method public android.os.IBinder getBinder();
+    method public final android.content.Context getContext();
+    method public int getDiscoveryMode();
+    method public java.util.Collection<com.android.media.remotedisplay.RemoteDisplay> getDisplays();
+    method public android.app.PendingIntent getSettingsPendingIntent();
+    method public void onAdjustVolume(com.android.media.remotedisplay.RemoteDisplay, int);
+    method public void onConnect(com.android.media.remotedisplay.RemoteDisplay);
+    method public void onDisconnect(com.android.media.remotedisplay.RemoteDisplay);
+    method public void onDiscoveryModeChanged(int);
+    method public void onSetVolume(com.android.media.remotedisplay.RemoteDisplay, int);
+    method public void removeDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    method public void updateDisplay(com.android.media.remotedisplay.RemoteDisplay);
+    field public static final int DISCOVERY_MODE_ACTIVE = 2; // 0x2
+    field public static final int DISCOVERY_MODE_NONE = 0; // 0x0
+    field public static final int DISCOVERY_MODE_PASSIVE = 1; // 0x1
+    field public static final java.lang.String SERVICE_INTERFACE = "com.android.media.remotedisplay.RemoteDisplayProvider";
+  }
+
+}
+
diff --git a/media/lib/remotedisplay/api/system-removed.txt b/media/lib/remotedisplay/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/system-removed.txt
diff --git a/media/lib/remotedisplay/api/test-current.txt b/media/lib/remotedisplay/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/test-current.txt
diff --git a/media/lib/remotedisplay/api/test-removed.txt b/media/lib/remotedisplay/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/remotedisplay/api/test-removed.txt
diff --git a/media/lib/remotedisplay/com.android.media.remotedisplay.xml b/media/lib/remotedisplay/com.android.media.remotedisplay.xml
deleted file mode 100644
index 77a91d2..0000000
--- a/media/lib/remotedisplay/com.android.media.remotedisplay.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<permissions>
-    <library name="com.android.media.remotedisplay"
-            file="/system/framework/com.android.media.remotedisplay.jar" />
-</permissions>
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
index dc9dd79..8de414b 100644
--- a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplay.java
@@ -16,6 +16,7 @@
 
 package com.android.media.remotedisplay;
 
+import android.annotation.SystemApi;
 import android.media.RemoteDisplayState.RemoteDisplayInfo;
 import android.text.TextUtils;
 
@@ -23,7 +24,10 @@
 
 /**
  * Represents a remote display that has been discovered.
+ *
+ * @hide
  */
+@SystemApi
 public class RemoteDisplay {
     private final RemoteDisplayInfo mMutableInfo;
     private RemoteDisplayInfo mImmutableInfo;
diff --git a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
index 4d3edb8..7017e44 100644
--- a/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
+++ b/media/lib/remotedisplay/java/com/android/media/remotedisplay/RemoteDisplayProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.media.remotedisplay;
 
+import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
@@ -88,7 +89,10 @@
  * IMPORTANT: This class is effectively a public API for unbundled applications, and
  * must remain API stable. See README.txt in the root of this package for more information.
  * </p>
+ *
+ * @hide
  */
+@SystemApi
 public abstract class RemoteDisplayProvider {
     private static final int MSG_SET_CALLBACK = 1;
     private static final int MSG_SET_DISCOVERY_MODE = 2;
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 3b25787..8c43683 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -18,4 +18,5 @@
     name: "com.android.mediadrm.signer",
     srcs: ["java/**/*.java"],
     api_packages: ["com.android.mediadrm.signer"],
+    metalava_enabled: false,
 }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 33cb5964..4518d79 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -30,7 +30,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.carrierdefaultapp.R;
+
 /**
  * This util class provides common logic for carrier actions
  */
@@ -102,7 +102,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onDisableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, !ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(!ENABLE);
     }
 
     private static void onEnableAllMeteredApns(Intent intent, Context context) {
@@ -110,7 +110,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onEnableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(ENABLE);
     }
 
     private static void onEnableDefaultURLHandler(Context context) {
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
index f9dbcd4..5d84d64 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
@@ -104,6 +104,6 @@
         assertNotNull(pendingIntent);
 
         Rlog.d(TAG, "verify carrier action: disable all metered apns");
-        verify(mTelephonyMgr).carrierActionSetMeteredApnsEnabled(eq(subId), eq(false));
+        verify(mTelephonyMgr).setCarrierDataEnabled(eq(false));
     }
 }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index cdaabdc..d0ca04b 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -184,7 +184,6 @@
         if (shouldScan(mBluetoothFilters)) {
             final IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
-            intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
 
             mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
             registerReceiver(mBluetoothBroadcastReceiver, intentFilter);
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index e645adc..03eb0d9 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -67,10 +67,6 @@
 LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# out/target/common/obj/APPS/CtsShimPriv_intermediates/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 
@@ -113,10 +109,6 @@
 LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/packages/CtsShim/build/shim/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/PrintSpooler/Android.bp b/packages/PrintSpooler/Android.bp
new file mode 100644
index 0000000..c40a817
--- /dev/null
+++ b/packages/PrintSpooler/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 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: "PrintSpooler",
+
+    resource_dirs: ["res"],
+
+    srcs: [
+        "src/**/*.java",
+        "src/com/android/printspooler/renderer/IPdfRenderer.aidl",
+        "src/com/android/printspooler/renderer/IPdfEditor.aidl",
+    ],
+
+    platform_apis: true,
+
+    jni_libs: ["libprintspooler_jni"],
+    static_libs: [
+        "android-support-v7-recyclerview",
+        "android-support-compat",
+        "android-support-media-compat",
+        "android-support-core-utils",
+        "android-support-core-ui",
+        "android-support-fragment",
+        "android-support-annotations",
+    ],
+}
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
deleted file mode 100644
index e356f38..0000000
--- a/packages/PrintSpooler/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2013 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_USE_AAPT2 := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += \
-    src/com/android/printspooler/renderer/IPdfRenderer.aidl \
-    src/com/android/printspooler/renderer/IPdfEditor.aidl
-
-LOCAL_PACKAGE_NAME := PrintSpooler
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_JNI_SHARED_LIBRARIES := libprintspooler_jni
-LOCAL_STATIC_ANDROID_LIBRARIES := \
-    android-support-v7-recyclerview \
-    android-support-compat \
-    android-support-media-compat \
-    android-support-core-utils \
-    android-support-core-ui \
-    android-support-fragment
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-annotations
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/PrintSpooler/tests/Android.mk b/packages/PrintSpooler/tests/Android.mk
deleted file mode 100644
index 83e00ce..0000000
--- a/packages/PrintSpooler/tests/Android.mk
+++ /dev/null
@@ -1,19 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.bp b/packages/PrintSpooler/tests/outofprocess/Android.bp
new file mode 100644
index 0000000..e88074e
--- /dev/null
+++ b/packages/PrintSpooler/tests/outofprocess/Android.bp
@@ -0,0 +1,30 @@
+// 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_test {
+    name: "PrintSpoolerOutOfProcessTests",
+
+    srcs: ["src/**/*.java"],
+
+    libs: ["android.test.runner.stubs"],
+    static_libs: [
+        "android-support-test",
+        "ub-uiautomator",
+        "mockito-target-minus-junit4",
+        "print-test-util-lib",
+    ],
+
+    sdk_version: "test_current",
+    test_suites: ["device-tests"],
+}
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.mk b/packages/PrintSpooler/tests/outofprocess/Android.mk
deleted file mode 100644
index 161a600..0000000
--- a/packages/PrintSpooler/tests/outofprocess/Android.mk
+++ /dev/null
@@ -1,30 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4 print-test-util-lib
-
-LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
-LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 0b58c9d..9d8336f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -97,7 +97,6 @@
         addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
         addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
         addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
-        addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
         addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
         addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler());
 
@@ -280,24 +279,6 @@
         }
     }
 
-    private class DeviceDisappearedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
-            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
-            if (cachedDevice == null) {
-                Log.w(TAG, "received ACTION_DISAPPEARED for an unknown device: " + device);
-                return;
-            }
-            if (CachedBluetoothDeviceManager.onDeviceDisappeared(cachedDevice)) {
-                synchronized (mCallbacks) {
-                    for (BluetoothCallback callback : mCallbacks) {
-                        callback.onDeviceDeleted(cachedDevice);
-                    }
-                }
-            }
-        }
-    }
-
     private class NameChangedHandler implements Handler {
         public void onReceive(Context context, Intent intent,
                 BluetoothDevice device) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 8fa9597..d267ead 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -110,6 +110,10 @@
         mHiSyncId = id;
     }
 
+    public boolean isHearingAidDevice() {
+        return mHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID;
+    }
+
     /**
      * Last time a bt profile auto-connect was attempted.
      * If an ACTION_UUID intent comes in within
@@ -144,8 +148,8 @@
 
     void onProfileStateChanged(LocalBluetoothProfile profile, int newProfileState) {
         if (Utils.D) {
-            Log.d(TAG, "onProfileStateChanged: profile " + profile +
-                    " newProfileState " + newProfileState);
+            Log.d(TAG, "onProfileStateChanged: profile " + profile + ", device=" + mDevice
+                    + ", newProfileState " + newProfileState);
         }
         if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF)
         {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index b360faab..3a56627 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -162,14 +162,14 @@
      */
     public synchronized String getHearingAidPairDeviceSummary(CachedBluetoothDevice device) {
         String pairDeviceSummary = null;
-        if (device.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
-            for (CachedBluetoothDevice hearingAidDevice : mHearingAidDevicesNotAddedInCache) {
-                if (hearingAidDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
-                    && hearingAidDevice.getHiSyncId() == device.getHiSyncId()) {
-                    pairDeviceSummary = hearingAidDevice.getConnectionSummary();
-                }
-            }
+        CachedBluetoothDevice otherHearingAidDevice =
+            getHearingAidOtherDevice(device, device.getHiSyncId());
+        if (otherHearingAidDevice != null) {
+            pairDeviceSummary = otherHearingAidDevice.getConnectionSummary();
         }
+        log("getHearingAidPairDeviceSummary: pairDeviceSummary=" + pairDeviceSummary
+            + ", otherHearingAidDevice=" + otherHearingAidDevice);
+ 
         return pairDeviceSummary;
     }
 
@@ -358,7 +358,7 @@
         }
     }
 
-    private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
+    public CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
                                                            long hiSyncId) {
         if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
             return null;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 75cbb65..a993306 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -128,6 +128,14 @@
 
         ParcelUuid[] uuids = adapter.getUuids();
 
+        List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
+        if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
+            mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
+                                                       this);
+            addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+                       BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+        }
+
         // uuids may be null if Bluetooth is turned off
         if (uuids != null) {
             updateLocalProfiles(uuids);
@@ -164,13 +172,6 @@
         addProfile(mPbapProfile, PbapServerProfile.NAME,
              BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
 
-        List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
-        if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
-            mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
-                                                       this);
-            addProfile(mHearingAidProfile, HearingAidProfile.NAME,
-                       BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
-        }
         if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
     }
 
@@ -378,9 +379,10 @@
                 Log.i(TAG, "Failed to connect " + mProfile + " device");
             }
 
-            if (getHearingAidProfile() != null &&
-                mProfile instanceof HearingAidProfile &&
-                (newState == BluetoothProfile.STATE_CONNECTED)) {
+            boolean isHearingAidProfile = (getHearingAidProfile() != null) &&
+                (mProfile instanceof HearingAidProfile);
+
+            if (isHearingAidProfile && (newState == BluetoothProfile.STATE_CONNECTED)) {
                 // Check if the HiSyncID has being initialized
                 if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
 
@@ -393,10 +395,22 @@
                 }
             }
 
-            mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
-                    mProfile.getProfileId());
             cachedDevice.onProfileStateChanged(mProfile, newState);
             cachedDevice.refresh();
+
+            if (isHearingAidProfile) {
+                CachedBluetoothDevice otherDevice =
+                    mDeviceManager.getHearingAidOtherDevice(cachedDevice, cachedDevice.getHiSyncId());
+                if (otherDevice != null) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Refreshing other hearing aid=" + otherDevice
+                               + ", newState=" + newState);
+                    }
+                    otherDevice.refresh();
+                }
+            }
+            mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
+                    mProfile.getProfileId());
         }
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 6d6a132..a3d10a2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -828,4 +828,20 @@
         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
     }
+
+    /**
+     * Test to verify getHearingAidOtherDevice() for hearing aid devices with same HiSyncId.
+     */
+    @Test
+    public void testGetHearingAidOtherDevice_bothHearingAidsPaired_returnsOtherDevice() {
+        mCachedDevice1.setHiSyncId(HISYNCID1);
+        mCachedDevice2.setHiSyncId(HISYNCID1);
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+        mCachedDeviceManager.mHearingAidDevicesNotAddedInCache.add(mCachedDevice2);
+        doAnswer((invocation) -> DEVICE_SUMMARY_1).when(mCachedDevice1).getConnectionSummary();
+        doAnswer((invocation) -> DEVICE_SUMMARY_2).when(mCachedDevice2).getConnectionSummary();
+
+        assertThat(mCachedDeviceManager.getHearingAidOtherDevice(mCachedDevice1, HISYNCID1))
+            .isEqualTo(mCachedDevice2);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 927a94f..16a292b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -28,6 +28,7 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.media.AudioManager;
@@ -572,4 +573,16 @@
 
         assertThat(mCachedDevice.isHfpDevice()).isFalse();
     }
+
+    @Test
+    public void testIsHearingAidDevice_isHearingAidDevice() {
+        mCachedDevice.setHiSyncId(0x1234);
+        assertThat(mCachedDevice.isHearingAidDevice()).isTrue();
+    }
+
+    @Test
+    public void testIsHearingAidDevice_isNotHearingAidDevice() {
+        mCachedDevice.setHiSyncId(BluetoothHearingAid.HI_SYNC_ID_INVALID);
+        assertThat(mCachedDevice.isHearingAidDevice()).isFalse();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index ca997bf8..17af429 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -51,6 +52,7 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(resourceDir = "../../res")
 public class LocalBluetoothProfileManagerTest {
+    private final static long HI_SYNC_ID = 0x1234;
     @Mock
     private CachedBluetoothDeviceManager mDeviceManager;
     @Mock
@@ -61,6 +63,8 @@
     private BluetoothDevice mDevice;
     @Mock
     private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private CachedBluetoothDevice mHearingAidOtherDevice;
 
     private Context mContext;
     private LocalBluetoothProfileManager mProfileManager;
@@ -199,6 +203,32 @@
     }
 
     /**
+     * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+     * refresh both sides devices.
+     */
+    @Test
+    public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldRefreshBothSides() {
+        ArrayList<Integer> supportProfiles = new ArrayList<>();
+        supportProfiles.add(BluetoothProfile.HEARING_AID);
+        when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
+        when(mCachedBluetoothDevice.getHiSyncId()).thenReturn(HI_SYNC_ID);
+        when(mDeviceManager.getHearingAidOtherDevice(mCachedBluetoothDevice, HI_SYNC_ID))
+            .thenReturn(mHearingAidOtherDevice);
+
+        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+                mEventManager);
+        mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+        mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+        mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+        mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+        mContext.sendBroadcast(mIntent);
+
+        verify(mCachedBluetoothDevice).refresh();
+        verify(mHearingAidOtherDevice).refresh();
+    }
+
+    /**
      * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to
      * profile connection state changed callback
      */
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 8a5cb4a..abce8cf 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -26,6 +26,7 @@
     <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.READ_CALENDAR" />
@@ -54,6 +55,7 @@
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.MANAGE_ACCESSIBILITY" />
     <!-- Development tool permissions granted to the shell. -->
     <uses-permission android:name="android.permission.SET_DEBUG_APP" />
     <uses-permission android:name="android.permission.SET_PROCESS_LIMIT" />
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index f0436de..d033057 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -49,11 +49,6 @@
         android:paddingEnd="@dimen/status_bar_padding_end"
         android:orientation="horizontal"
         >
-        <ViewStub
-            android:id="@+id/operator_name"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout="@layout/operator_name" />
         <FrameLayout
             android:layout_height="match_parent"
             android:layout_width="0dp"
@@ -70,6 +65,12 @@
                 android:layout_width="match_parent"
                 android:clipChildren="false"
             >
+                <ViewStub
+                    android:id="@+id/operator_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout="@layout/operator_name" />
+
                 <com.android.systemui.statusbar.policy.Clock
                     android:id="@+id/clock"
                     android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5c0d5dd..f5397b5 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -141,15 +141,9 @@
     <integer name="quick_settings_brightness_dialog_short_timeout">2000</integer>
     <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
 
-    <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
-    <bool name="config_show4GForLTE">true</bool>
-
     <!-- Show indicator for Wifi on but not connected. -->
     <bool name="config_showWifiIndicatorWhenEnabled">false</bool>
 
-    <!-- Should "LTE"/"4G" be shown instead of "LTE+"/"4G+" when on NETWORK_TYPE_LTE_CA? -->
-    <bool name="config_hideLtePlus">false</bool>
-
     <!-- milliseconds before the heads up notification auto-dismisses. -->
     <integer name="heads_up_notification_decay">5000</integer>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 409a783..118f1e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -47,6 +47,7 @@
     private final NotificationStackScrollLayout mStackScroller;
     private final HeadsUpStatusBarView mHeadsUpStatusBarView;
     private final View mClockView;
+    private final View mOperatorNameView;
     private final DarkIconDispatcher mDarkIconDispatcher;
     private final NotificationPanelView mPanelView;
     private final Consumer<ExpandableNotificationRow>
@@ -61,8 +62,10 @@
     private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
             (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
                     -> updatePanelTranslation();
+    private boolean mAnimationsEnabled = true;
     Point mPoint;
 
+
     public HeadsUpAppearanceController(
             NotificationIconAreaController notificationIconAreaController,
             HeadsUpManagerPhone headsUpManager,
@@ -71,7 +74,8 @@
                 statusbarView.findViewById(R.id.heads_up_status_bar_view),
                 statusbarView.findViewById(R.id.notification_stack_scroller),
                 statusbarView.findViewById(R.id.notification_panel),
-                statusbarView.findViewById(R.id.clock));
+                statusbarView.findViewById(R.id.clock),
+                statusbarView.findViewById(R.id.operator_name_frame));
     }
 
     @VisibleForTesting
@@ -81,7 +85,8 @@
             HeadsUpStatusBarView headsUpStatusBarView,
             NotificationStackScrollLayout stackScroller,
             NotificationPanelView panelView,
-            View clockView) {
+            View clockView,
+            View operatorNameView) {
         mNotificationIconAreaController = notificationIconAreaController;
         mHeadsUpManager = headsUpManager;
         mHeadsUpManager.addListener(this);
@@ -97,6 +102,7 @@
         mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
         mStackScroller.setHeadsUpAppearanceController(this);
         mClockView = clockView;
+        mOperatorNameView = operatorNameView;
         mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
         mDarkIconDispatcher.addDarkReceiver(this);
     }
@@ -205,20 +211,52 @@
             mShown = isShown;
             if (isShown) {
                 mHeadsUpStatusBarView.setVisibility(View.VISIBLE);
-                CrossFadeHelper.fadeIn(mHeadsUpStatusBarView, CONTENT_FADE_DURATION /* duration */,
-                        CONTENT_FADE_DELAY /* delay */);
-                CrossFadeHelper.fadeOut(mClockView, CONTENT_FADE_DURATION/* duration */,
-                        0 /* delay */, () -> mClockView.setVisibility(View.INVISIBLE));
+                show(mHeadsUpStatusBarView);
+                hide(mClockView, View.INVISIBLE);
+                if (mOperatorNameView != null) {
+                    hide(mOperatorNameView, View.INVISIBLE);
+                }
             } else {
-                CrossFadeHelper.fadeIn(mClockView, CONTENT_FADE_DURATION /* duration */,
-                        CONTENT_FADE_DELAY /* delay */);
-                CrossFadeHelper.fadeOut(mHeadsUpStatusBarView, CONTENT_FADE_DURATION/* duration */,
-                        0 /* delay */, () -> mHeadsUpStatusBarView.setVisibility(View.GONE));
-
+                show(mClockView);
+                if (mOperatorNameView != null) {
+                    show(mOperatorNameView);
+                }
+                hide(mHeadsUpStatusBarView, View.GONE);
             }
         }
     }
 
+    /**
+     * Hides the view and sets the state to endState when finished.
+     *
+     * @param view The view to hide.
+     * @param endState One of {@link View#INVISIBLE} or {@link View#GONE}.
+     * @see View#setVisibility(int)
+     *
+     */
+    private void hide(View view, int endState) {
+        if (mAnimationsEnabled) {
+            CrossFadeHelper.fadeOut(view, CONTENT_FADE_DURATION /* duration */,
+                    0 /* delay */, () -> view.setVisibility(endState));
+        } else {
+            view.setVisibility(endState);
+        }
+    }
+
+    private void show(View view) {
+        if (mAnimationsEnabled) {
+            CrossFadeHelper.fadeIn(view, CONTENT_FADE_DURATION /* duration */,
+                    CONTENT_FADE_DELAY /* delay */);
+        } else {
+            view.setVisibility(View.VISIBLE);
+        }
+    }
+
+    @VisibleForTesting
+    void setAnimationsEnabled(boolean enabled) {
+        mAnimationsEnabled = enabled;
+    }
+
     @VisibleForTesting
     public boolean isShown() {
         return mShown;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index c984579..330ee8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -458,6 +458,8 @@
                     MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                     controller.handleBroadcast(intent);
                 }
+                mConfig = Config.readConfig(mContext);
+                mReceiverHandler.post(this::handleConfigurationChanged);
                 break;
             case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
                 // Avoid rebroadcast because SysUI is direct boot aware.
@@ -1038,18 +1040,23 @@
             config.showAtLeast3G = res.getBoolean(R.bool.config_showMin3G);
             config.alwaysShowCdmaRssi =
                     res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
-            config.show4gForLte = res.getBoolean(R.bool.config_show4GForLTE);
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
-            config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
             config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
 
             CarrierConfigManager configMgr = (CarrierConfigManager)
                     context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configMgr.getConfig();
+            // Handle specific carrier config values for the default data SIM
+            int defaultDataSubId = SubscriptionManager.from(context)
+                    .getDefaultDataSubscriptionId();
+            PersistableBundle b = configMgr.getConfigForSubId(defaultDataSubId);
             if (b != null) {
                 config.alwaysShowDataRatIcon = b.getBoolean(
                         CarrierConfigManager.KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL);
+                config.show4gForLte = b.getBoolean(
+                        CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
+                config.hideLtePlus = b.getBoolean(
+                        CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL);
             }
             return config;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 2031b27..1fefa18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -53,6 +53,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+    private final Object mCallbacksLock = new Object();
     private final Context mContext;
     private final GlobalSetting mModeSetting;
     private final GlobalSetting mConfigSetting;
@@ -113,16 +114,20 @@
 
     @Override
     public void addCallback(Callback callback) {
-        if (callback == null) {
-            Slog.e(TAG, "Attempted to add a null callback.");
-            return;
+        synchronized (mCallbacksLock) {
+            if (callback == null) {
+                Slog.e(TAG, "Attempted to add a null callback.");
+                return;
+            }
+            mCallbacks.add(callback);
         }
-        mCallbacks.add(callback);
     }
 
     @Override
     public void removeCallback(Callback callback) {
-        mCallbacks.remove(callback);
+        synchronized (mCallbacksLock) {
+            mCallbacks.remove(callback);
+        }
     }
 
     @Override
@@ -186,28 +191,40 @@
     }
 
     private void fireNextAlarmChanged() {
-        Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
+        }
     }
 
     private void fireEffectsSuppressorChanged() {
-        Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
+        }
     }
 
     private void fireZenChanged(int zen) {
-        Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
+        }
     }
 
     private void fireZenAvailableChanged(boolean available) {
-        Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
+        }
     }
 
     private void fireManualRuleChanged(ZenRule rule) {
-        Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
+        }
     }
 
     @VisibleForTesting
     protected void fireConfigChanged(ZenModeConfig config) {
-        Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
+        synchronized (mCallbacksLock) {
+            Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
index af99236..e85dee8 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
@@ -51,7 +51,9 @@
     public void onTuningChanged(String key, String newValue) {
         int dimen = mDefaultSize;
         if (newValue != null) {
-            dimen = (int) (Integer.parseInt(newValue) * mDensity);
+            try {
+                dimen = (int) (Integer.parseInt(newValue) * mDensity);
+            } catch (NumberFormatException ex) {}
         }
         int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
         int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 537bfd4..3c5c0b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -61,6 +61,7 @@
     private ExpandableNotificationRow mFirst;
     private HeadsUpStatusBarView mHeadsUpStatusBarView;
     private HeadsUpManagerPhone mHeadsUpManager;
+    private View mOperatorNameView;
 
     @Before
     public void setUp() throws Exception {
@@ -70,13 +71,15 @@
         mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class),
                 mock(TextView.class));
         mHeadsUpManager = mock(HeadsUpManagerPhone.class);
+        mOperatorNameView = new View(mContext);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
                 mHeadsUpStatusBarView,
                 mStackScroller,
                 mPanelView,
-                new View(mContext));
+                new View(mContext),
+                mOperatorNameView);
         mHeadsUpAppearanceController.setExpandedHeight(0.0f, 0.0f);
     }
 
@@ -123,6 +126,22 @@
     }
 
     @Test
+    public void testOperatorNameViewUpdated() {
+        mHeadsUpAppearanceController.setAnimationsEnabled(false);
+
+        mFirst.setPinned(true);
+        when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
+        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst);
+        Assert.assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
+
+        mFirst.setPinned(false);
+        when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst);
+        Assert.assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
+    }
+
+    @Test
     public void testDestroy() {
         reset(mHeadsUpManager);
         reset(mDarkIconDispatcher);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index cae15ba..8cfbda2 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -4,6 +4,7 @@
     aidl: {
         include_dirs: [
             "frameworks/native/aidl/binder",
+            "frameworks/native/cmds/dumpstate/binder",
             "system/core/storaged/binder",
             "system/netd/server/binder",
             "system/vold/binder",
@@ -11,6 +12,7 @@
     },
     srcs: [
         "java/**/*.java",
+        ":dumpstate_aidl",
         ":netd_aidl",
         ":netd_metrics_aidl",
         ":installd_aidl",
@@ -43,6 +45,7 @@
         "android.hardware.configstore-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.0-java",
+        "netd_aidl_interface-java",
     ],
 }
 
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 99e0056..49de4b1 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -53,12 +53,16 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
 import android.util.Slog;
 import android.util.StatsLog;
 
@@ -386,6 +390,15 @@
         mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
         mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
 
+        // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
+        boolean isHearingAidEnabled;
+        String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
+        if (!TextUtils.isEmpty(value)) {
+            isHearingAidEnabled = Boolean.parseBoolean(value);
+            Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
+            FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
+        }
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
         filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 953c99f..1c8d99a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -35,6 +35,8 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
@@ -189,6 +191,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.ConcurrentModificationException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -257,6 +260,14 @@
     @GuardedBy("mVpns")
     private LockdownVpnTracker mLockdownTracker;
 
+    /**
+     * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
+     * handler thread, they don't need a lock.
+     */
+    private SparseIntArray mUidRules = new SparseIntArray();
+    /** Flag indicating if background data is restricted. */
+    private boolean mRestrictBackground;
+
     final private Context mContext;
     // 0 is full bad, 100 is full good
     private int mDefaultInetConditionPublished = 0;
@@ -419,6 +430,16 @@
     // Handle private DNS validation status updates.
     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
 
+    /**
+     * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
+     */
+    private static final int EVENT_UID_RULES_CHANGED = 39;
+
+    /**
+     * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
+     */
+    private static final int EVENT_DATA_SAVER_CHANGED = 40;
+
     private static String eventName(int what) {
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
@@ -780,6 +801,9 @@
         mKeyStore = KeyStore.getInstance();
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
 
+        // To ensure uid rules are synchronized with Network Policy, register for
+        // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
+        // reading existing policy from disk.
         try {
             mPolicyManager.registerListener(mPolicyListener);
         } catch (RemoteException e) {
@@ -910,7 +934,8 @@
         registerPrivateDnsSettingsCallbacks();
     }
 
-    private Tethering makeTethering() {
+    @VisibleForTesting
+    protected Tethering makeTethering() {
         // TODO: Move other elements into @Overridden getters.
         final TetheringDependencies deps = new TetheringDependencies() {
             @Override
@@ -1116,11 +1141,6 @@
         if (ignoreBlocked) {
             return false;
         }
-        // Networks are never blocked for system services
-        // TODO: consider moving this check to NetworkPolicyManagerInternal.isUidNetworkingBlocked.
-        if (isSystem(uid)) {
-            return false;
-        }
         synchronized (mVpns) {
             final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
             if (vpn != null && vpn.isBlockingUid(uid)) {
@@ -1150,6 +1170,17 @@
         mNetworkInfoBlockingLogs.log(action + " " + uid);
     }
 
+    private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
+            boolean blocked) {
+        if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
+            return;
+        }
+        String action = blocked ? "BLOCKED" : "UNBLOCKED";
+        log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked,
+                nri.mUid, nri.request.requestId, net.netId));
+        mNetworkInfoBlockingLogs.log(action + " " + nri.mUid);
+    }
+
     /**
      * Apply any relevant filters to {@link NetworkState} for the given UID. For
      * example, this may mark the network as {@link DetailedState#BLOCKED} based
@@ -1651,10 +1682,17 @@
     private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
-            // TODO: notify UID when it has requested targeted updates
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
         }
         @Override
         public void onRestrictBackgroundChanged(boolean restrictBackground) {
+            // caller is NPMS, since we only register with them
+            if (LOGD_BLOCKED_NETWORKINFO) {
+                log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
+            }
+            mHandler.sendMessage(mHandler.obtainMessage(
+                    EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
+
             // TODO: relocate this specific callback in Tethering.
             if (restrictBackground) {
                 log("onRestrictBackgroundChanged(true): disabling tethering");
@@ -1663,6 +1701,50 @@
         }
     };
 
+    void handleUidRulesChanged(int uid, int newRules) {
+        // skip update when we've already applied rules
+        final int oldRules = mUidRules.get(uid, RULE_NONE);
+        if (oldRules == newRules) return;
+
+        maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
+
+        if (newRules == RULE_NONE) {
+            mUidRules.delete(uid);
+        } else {
+            mUidRules.put(uid, newRules);
+        }
+    }
+
+    void handleRestrictBackgroundChanged(boolean restrictBackground) {
+        if (mRestrictBackground == restrictBackground) return;
+
+        for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+            final boolean curMetered = nai.networkCapabilities.isMetered();
+            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
+                    restrictBackground);
+        }
+
+        mRestrictBackground = restrictBackground;
+    }
+
+    private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted) {
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
+            // Because the return value of this function depends on the list of UIDs the
+            // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
+            // list all state depending on the return value of this function has to be recomputed.
+            // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
+            // send the necessary onBlockedStatusChanged callbacks.
+            if (vpn != null && vpn.isBlockingUid(uid)) {
+                return true;
+            }
+        }
+
+        return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
+                isNetworkMetered, isBackgroundRestricted);
+    }
+
     /**
      * Require that the caller is either in the same user or has appropriate permission to interact
      * across users.
@@ -1679,6 +1761,16 @@
                 "ConnectivityService");
     }
 
+    private void enforceAnyPermissionOf(String... permissions) {
+        for (String permission : permissions) {
+            if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+                return;
+            }
+        }
+        throw new SecurityException(
+            "Requires one of the following permissions: " + String.join(", ", permissions) + ".");
+    }
+
     private void enforceInternetPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.INTERNET,
@@ -1723,6 +1815,13 @@
                 "ConnectivityService");
     }
 
+    private void enforceNetworkStackSettingsOrSetup() {
+        enforceAnyPermissionOf(
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD,
+            android.Manifest.permission.NETWORK_STACK);
+    }
+
     private boolean checkNetworkStackPermission() {
         return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.NETWORK_STACK);
@@ -1798,7 +1897,8 @@
 
     private void sendStickyBroadcast(Intent intent) {
         synchronized (this) {
-            if (!mSystemReady) {
+            if (!mSystemReady
+                    && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                 mInitialBroadcast = new Intent(intent);
             }
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1837,7 +1937,7 @@
     }
 
     void systemReady() {
-        loadGlobalProxy();
+        mProxyTracker.loadGlobalProxy();
         registerNetdEventCallback();
 
         synchronized (this) {
@@ -1847,8 +1947,6 @@
                 mInitialBroadcast = null;
             }
         }
-        // load the global proxy at startup
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
 
         // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
         // for user to unlock device too.
@@ -2102,6 +2200,28 @@
         pw.decreaseIndent();
         pw.println();
 
+        pw.print("Restrict background: ");
+        pw.println(mRestrictBackground);
+        pw.println();
+
+        pw.println("Status for known UIDs:");
+        pw.increaseIndent();
+        final int size = mUidRules.size();
+        for (int i = 0; i < size; i++) {
+            // Don't crash if the array is modified while dumping in bugreports.
+            try {
+                final int uid = mUidRules.keyAt(i);
+                final int uidRules = mUidRules.get(uid, RULE_NONE);
+                pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
+            } catch (ArrayIndexOutOfBoundsException e) {
+                pw.println("  ArrayIndexOutOfBoundsException");
+            } catch (ConcurrentModificationException e) {
+                pw.println("  ConcurrentModificationException");
+            }
+        }
+        pw.println();
+        pw.decreaseIndent();
+
         pw.println("Network Requests:");
         pw.increaseIndent();
         dumpNetworkRequests(pw);
@@ -3089,7 +3209,7 @@
                     break;
                 }
                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
-                    handleDeprecatedGlobalHttpProxy();
+                    mProxyTracker.loadDeprecatedGlobalHttpProxy();
                     break;
                 }
                 case EVENT_PROXY_HAS_CHANGED: {
@@ -3179,6 +3299,12 @@
                     handlePrivateDnsValidationUpdate(
                             (PrivateDnsValidationUpdate) msg.obj);
                     break;
+                case EVENT_UID_RULES_CHANGED:
+                    handleUidRulesChanged(msg.arg1, msg.arg2);
+                    break;
+                case EVENT_DATA_SAVER_CHANGED:
+                    handleRestrictBackgroundChanged(toBool(msg.arg1));
+                    break;
             }
         }
     }
@@ -3455,31 +3581,6 @@
         mProxyTracker.setGlobalProxy(proxyProperties);
     }
 
-    private void loadGlobalProxy() {
-        ContentResolver res = mContext.getContentResolver();
-        String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
-        int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
-        String exclList = Settings.Global.getString(res,
-                Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
-        String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
-        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
-            ProxyInfo proxyProperties;
-            if (!TextUtils.isEmpty(pacFileUrl)) {
-                proxyProperties = new ProxyInfo(pacFileUrl);
-            } else {
-                proxyProperties = new ProxyInfo(host, port, exclList);
-            }
-            if (!proxyProperties.isValid()) {
-                if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
-                return;
-            }
-
-            synchronized (mProxyTracker.mProxyLock) {
-                mProxyTracker.mGlobalProxy = proxyProperties;
-            }
-        }
-    }
-
     @Override
     @Nullable
     public ProxyInfo getGlobalProxy() {
@@ -3504,30 +3605,7 @@
         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
 
         if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
-            mProxyTracker.sendProxyBroadcast(mProxyTracker.getDefaultProxy());
-        }
-    }
-
-    private void handleDeprecatedGlobalHttpProxy() {
-        final String proxy = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.HTTP_PROXY);
-        if (!TextUtils.isEmpty(proxy)) {
-            String data[] = proxy.split(":");
-            if (data.length == 0) {
-                return;
-            }
-
-            final String proxyHost = data[0];
-            int proxyPort = 8080;
-            if (data.length > 1) {
-                try {
-                    proxyPort = Integer.parseInt(data[1]);
-                } catch (NumberFormatException e) {
-                    return;
-                }
-            }
-            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
-            setGlobalProxy(p);
+            mProxyTracker.sendProxyBroadcast();
         }
     }
 
@@ -3815,6 +3893,8 @@
     private void setLockdownTracker(LockdownVpnTracker tracker) {
         // Shutdown any existing tracker
         final LockdownVpnTracker existing = mLockdownTracker;
+        // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
+        // necessary onBlockedStatusChanged callbacks.
         mLockdownTracker = null;
         if (existing != null) {
             existing.shutdown();
@@ -4033,7 +4113,7 @@
 
     @Override
     public void setAirplaneMode(boolean enable) {
-        enforceConnectivityInternalPermission();
+        enforceNetworkStackSettingsOrSetup();
         final long ident = Binder.clearCallingIdentity();
         try {
             final ContentResolver cr = mContext.getContentResolver();
@@ -4814,15 +4894,14 @@
         }
     }
 
-    private String getNetworkPermission(NetworkCapabilities nc) {
-        // TODO: make these permission strings AIDL constants instead.
+    private int getNetworkPermission(NetworkCapabilities nc) {
         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
-            return NetworkManagementService.PERMISSION_SYSTEM;
+            return INetd.PERMISSION_SYSTEM;
         }
         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
-            return NetworkManagementService.PERMISSION_NETWORK;
+            return INetd.PERMISSION_NETWORK;
         }
-        return null;
+        return INetd.PERMISSION_NONE;
     }
 
     /**
@@ -4895,9 +4974,9 @@
 
         if (Objects.equals(nai.networkCapabilities, newNc)) return;
 
-        final String oldPermission = getNetworkPermission(nai.networkCapabilities);
-        final String newPermission = getNetworkPermission(newNc);
-        if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
+        final int oldPermission = getNetworkPermission(nai.networkCapabilities);
+        final int newPermission = getNetworkPermission(newNc);
+        if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
             try {
                 mNMS.setNetworkPermission(nai.network.netId, newPermission);
             } catch (RemoteException e) {
@@ -4926,12 +5005,20 @@
             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
 
-        // Report changes that are interesting for network statistics tracking.
         if (prevNc != null) {
-            final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
-                    newNc.hasCapability(NET_CAPABILITY_NOT_METERED);
+            final boolean oldMetered = prevNc.isMetered();
+            final boolean newMetered = newNc.isMetered();
+            final boolean meteredChanged = oldMetered != newMetered;
+
+            if (meteredChanged) {
+                maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
+                        mRestrictBackground);
+            }
+
             final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
                     newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+
+            // Report changes that are interesting for network statistics tracking.
             if (meteredChanged || roamingChanged) {
                 notifyIfacesChangedForNetworkStats();
             }
@@ -5061,6 +5148,8 @@
             case ConnectivityManager.CALLBACK_AVAILABLE: {
                 putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
+                // For this notification, arg1 contains the blocked status.
+                msg.arg1 = arg1;
                 break;
             }
             case ConnectivityManager.CALLBACK_LOSING: {
@@ -5078,6 +5167,10 @@
                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
                 break;
             }
+            case ConnectivityManager.CALLBACK_BLK_CHANGED: {
+                msg.arg1 = arg1;
+                break;
+            }
         }
         msg.what = notificationType;
         msg.setData(bundle);
@@ -5562,15 +5655,7 @@
 
             if (networkAgent.isVPN()) {
                 // Temporarily disable the default proxy (not global).
-                synchronized (mProxyTracker.mProxyLock) {
-                    if (!mProxyTracker.mDefaultProxyDisabled) {
-                        mProxyTracker.mDefaultProxyDisabled = true;
-                        if (mProxyTracker.mGlobalProxy == null
-                                && mProxyTracker.mDefaultProxy != null) {
-                            mProxyTracker.sendProxyBroadcast(null);
-                        }
-                    }
-                }
+                mProxyTracker.setDefaultProxyEnabled(false);
                 // TODO: support proxy per network.
             }
 
@@ -5592,15 +5677,7 @@
         } else if (state == NetworkInfo.State.DISCONNECTED) {
             networkAgent.asyncChannel.disconnect();
             if (networkAgent.isVPN()) {
-                synchronized (mProxyTracker.mProxyLock) {
-                    if (mProxyTracker.mDefaultProxyDisabled) {
-                        mProxyTracker.mDefaultProxyDisabled = false;
-                        if (mProxyTracker.mGlobalProxy == null
-                                && mProxyTracker.mDefaultProxy != null) {
-                            mProxyTracker.sendProxyBroadcast(mProxyTracker.mDefaultProxy);
-                        }
-                    }
-                }
+                mProxyTracker.setDefaultProxyEnabled(true);
                 updateUids(networkAgent, networkAgent.networkCapabilities, null);
             }
             disconnectAndDestroyNetwork(networkAgent);
@@ -5649,7 +5726,76 @@
             return;
         }
 
-        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
+        final boolean metered = nai.networkCapabilities.isMetered();
+        final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
+                metered, mRestrictBackground);
+        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
+    }
+
+    /**
+     * Notify of the blocked state apps with a registered callback matching a given NAI.
+     *
+     * Unlike other callbacks, blocked status is different between each individual uid. So for
+     * any given nai, all requests need to be considered according to the uid who filed it.
+     *
+     * @param nai The target NetworkAgentInfo.
+     * @param oldMetered True if the previous network capabilities is metered.
+     * @param newRestrictBackground True if data saver is enabled.
+     */
+    private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
+            boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
+
+        for (int i = 0; i < nai.numNetworkRequests(); i++) {
+            NetworkRequest nr = nai.requestAt(i);
+            NetworkRequestInfo nri = mNetworkRequests.get(nr);
+            final int uidRules = mUidRules.get(nri.mUid);
+            final boolean oldBlocked, newBlocked;
+            // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
+            // between these two calls.
+            synchronized (mVpns) {
+                oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
+                        oldRestrictBackground);
+                newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
+                        newRestrictBackground);
+            }
+            if (oldBlocked != newBlocked) {
+                callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
+                        encodeBool(newBlocked));
+            }
+        }
+    }
+
+    /**
+     * Notify apps with a given UID of the new blocked state according to new uid rules.
+     * @param uid The uid for which the rules changed.
+     * @param newRules The new rules to apply.
+     */
+    private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
+        for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+            final boolean metered = nai.networkCapabilities.isMetered();
+            final boolean oldBlocked, newBlocked;
+            // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
+            // rules changed event. And this function actually loop through all connected nai and
+            // its requests. It seems that mVpns lock will be grabbed frequently in this case.
+            // Reduce the number of locking or optimize the use of lock are likely needed in future.
+            synchronized (mVpns) {
+                oldBlocked = isUidNetworkingWithVpnBlocked(
+                        uid, mUidRules.get(uid), metered, mRestrictBackground);
+                newBlocked = isUidNetworkingWithVpnBlocked(
+                        uid, newRules, metered, mRestrictBackground);
+            }
+            if (oldBlocked == newBlocked) {
+                return;
+            }
+            final int arg = encodeBool(newBlocked);
+            for (int i = 0; i < nai.numNetworkRequests(); i++) {
+                NetworkRequest nr = nai.requestAt(i);
+                NetworkRequestInfo nri = mNetworkRequests.get(nr);
+                if (nri != null && nri.mUid == uid) {
+                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
+                }
+            }
+        }
     }
 
     private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index a69d416..8c25917 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -19,6 +19,8 @@
 import static android.Manifest.permission.DUMP;
 import static android.net.IpSecManager.INVALID_RESOURCE_ID;
 import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
 import static android.system.OsConstants.EINVAL;
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.SOCK_DGRAM;
@@ -63,6 +65,8 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
@@ -1426,6 +1430,17 @@
                         + "or Encryption algorithms");
     }
 
+    private int getFamily(String inetAddress) {
+        int family = AF_UNSPEC;
+        InetAddress checkAddress = NetworkUtils.numericToInetAddress(inetAddress);
+        if (checkAddress instanceof Inet4Address) {
+            family = AF_INET;
+        } else if (checkAddress instanceof Inet6Address) {
+            family = AF_INET6;
+        }
+        return family;
+    }
+
     /**
      * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an
      * IllegalArgumentException if they are not.
@@ -1479,6 +1494,26 @@
         // Require a valid source address for all transforms.
         checkInetAddress(config.getSourceAddress());
 
+        // Check to ensure source and destination have the same address family.
+        String sourceAddress = config.getSourceAddress();
+        String destinationAddress = config.getDestinationAddress();
+        int sourceFamily = getFamily(sourceAddress);
+        int destinationFamily = getFamily(destinationAddress);
+        if (sourceFamily != destinationFamily) {
+            throw new IllegalArgumentException(
+                    "Source address ("
+                            + sourceAddress
+                            + ") and destination address ("
+                            + destinationAddress
+                            + ") have different address families.");
+        }
+
+        // Throw an error if UDP Encapsulation is not used in IPv4.
+        if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) {
+            throw new IllegalArgumentException(
+                    "UDP Encapsulation is not supported for this address family");
+        }
+
         switch (config.getMode()) {
             case IpSecTransform.MODE_TRANSPORT:
                 break;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index ab0a565..ab50059 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -57,6 +57,7 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetd;
+import android.net.TetherStatsParcel;
 import android.net.INetworkManagementEventObserver;
 import android.net.ITetheringStatsProvider;
 import android.net.InterfaceConfiguration;
@@ -168,19 +169,6 @@
      */
     public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
 
-    /**
-     * String to pass to netd to indicate that a network is only accessible
-     * to apps that have the CHANGE_NETWORK_STATE permission.
-     */
-    public static final String PERMISSION_NETWORK = "NETWORK";
-
-    /**
-     * String to pass to netd to indicate that a network is only
-     * accessible to system apps and those with the CONNECTIVITY_INTERNAL
-     * permission.
-     */
-    public static final String PERMISSION_SYSTEM = "SYSTEM";
-
     static class NetdResponseCode {
         /* Keep in sync with system/netd/server/ResponseCode.h */
         public static final int InterfaceListResult       = 110;
@@ -221,6 +209,9 @@
 
     static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
 
+    static final boolean MODIFY_OPERATION_ADD = true;
+    static final boolean MODIFY_OPERATION_REMOVE = false;
+
     /**
      * Binder context for this service
      */
@@ -1116,41 +1107,47 @@
 
     @Override
     public void addRoute(int netId, RouteInfo route) {
-        modifyRoute("add", "" + netId, route);
+        modifyRoute(MODIFY_OPERATION_ADD, netId, route);
     }
 
     @Override
     public void removeRoute(int netId, RouteInfo route) {
-        modifyRoute("remove", "" + netId, route);
+        modifyRoute(MODIFY_OPERATION_REMOVE, netId, route);
     }
 
-    private void modifyRoute(String action, String netId, RouteInfo route) {
+    private void modifyRoute(boolean add, int netId, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final Command cmd = new Command("network", "route", action, netId);
-
-        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        cmd.appendArg(route.getInterface());
-        cmd.appendArg(route.getDestination().toString());
+        final String ifName = route.getInterface();
+        final String dst = route.getDestination().toString();
+        final String nextHop;
 
         switch (route.getType()) {
             case RouteInfo.RTN_UNICAST:
                 if (route.hasGateway()) {
-                    cmd.appendArg(route.getGateway().getHostAddress());
+                    nextHop = route.getGateway().getHostAddress();
+                } else {
+                    nextHop = INetd.NEXTHOP_NONE;
                 }
                 break;
             case RouteInfo.RTN_UNREACHABLE:
-                cmd.appendArg("unreachable");
+                nextHop = INetd.NEXTHOP_UNREACHABLE;
                 break;
             case RouteInfo.RTN_THROW:
-                cmd.appendArg("throw");
+                nextHop = INetd.NEXTHOP_THROW;
+                break;
+            default:
+                nextHop = INetd.NEXTHOP_NONE;
                 break;
         }
-
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            if (add) {
+                mNetdService.networkAddRoute(netId, ifName, dst, nextHop);
+            } else {
+                mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop);
+            }
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1839,31 +1836,30 @@
                 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
             }
 
-            final PersistableBundle bundle;
+            final TetherStatsParcel[] tetherStatsVec;
             try {
-                bundle = mNetdService.tetherGetStats();
+                tetherStatsVec = mNetdService.tetherGetStats();
             } catch (RemoteException | ServiceSpecificException e) {
                 throw new IllegalStateException("problem parsing tethering stats: ", e);
             }
 
             final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
-                    bundle.size());
+                tetherStatsVec.length);
             final NetworkStats.Entry entry = new NetworkStats.Entry();
 
-            for (String iface : bundle.keySet()) {
-                long[] statsArray = bundle.getLongArray(iface);
+            for (TetherStatsParcel tetherStats : tetherStatsVec) {
                 try {
-                    entry.iface = iface;
+                    entry.iface = tetherStats.iface;
                     entry.uid = UID_TETHERING;
                     entry.set = SET_DEFAULT;
                     entry.tag = TAG_NONE;
-                    entry.rxBytes   = statsArray[INetd.TETHER_STATS_RX_BYTES];
-                    entry.rxPackets = statsArray[INetd.TETHER_STATS_RX_PACKETS];
-                    entry.txBytes   = statsArray[INetd.TETHER_STATS_TX_BYTES];
-                    entry.txPackets = statsArray[INetd.TETHER_STATS_TX_PACKETS];
+                    entry.rxBytes   = tetherStats.rxBytes;
+                    entry.rxPackets = tetherStats.rxPackets;
+                    entry.txBytes   = tetherStats.txBytes;
+                    entry.txPackets = tetherStats.txPackets;
                     stats.combineValues(entry);
                 } catch (ArrayIndexOutOfBoundsException e) {
-                    throw new IllegalStateException("invalid tethering stats for " + iface, e);
+                    throw new IllegalStateException("invalid tethering stats " + e);
                 }
             }
 
@@ -1911,44 +1907,21 @@
     @Override
     public void addVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "users";
-        argv[1] = "add";
-        argv[2] = netId;
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UID ranges per command.
-        for (int i = 0; i < ranges.length; i++) {
-            argv[argc++] = ranges[i].toString();
-            if (i == (ranges.length - 1) || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+
+        try {
+            mNetdService.networkAddUidRanges(netId, ranges);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
     public void removeVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "users";
-        argv[1] = "remove";
-        argv[2] = netId;
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UID ranges per command.
-        for (int i = 0; i < ranges.length; i++) {
-            argv[argc++] = ranges[i].toString();
-            if (i == (ranges.length - 1) || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+        try {
+            mNetdService.networkRemoveUidRanges(netId, ranges);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2406,17 +2379,13 @@
     }
 
     @Override
-    public void createPhysicalNetwork(int netId, String permission) {
+    public void createPhysicalNetwork(int netId, int permission) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            if (permission != null) {
-                mConnector.execute("network", "create", netId, permission);
-            } else {
-                mConnector.execute("network", "create", netId);
-            }
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkCreatePhysical(netId, permission);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2425,10 +2394,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "create", netId, "vpn", hasDNS ? "1" : "0",
-                    secure ? "1" : "0");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkCreateVpn(netId, hasDNS, secure);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2449,20 +2417,24 @@
 
     @Override
     public void addInterfaceToNetwork(String iface, int netId) {
-        modifyInterfaceInNetwork("add", "" + netId, iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
     }
 
     @Override
     public void removeInterfaceFromNetwork(String iface, int netId) {
-        modifyInterfaceInNetwork("remove", "" + netId, iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
     }
 
-    private void modifyInterfaceInNetwork(String action, String netId, String iface) {
+    private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            mConnector.execute("network", "interface", action, netId, iface);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            if (add) {
+                mNetdService.networkAddInterface(netId, iface);
+            } else {
+                mNetdService.networkRemoveInterface(netId, iface);
+            }
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2470,20 +2442,20 @@
     public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final Command cmd = new Command("network", "route", "legacy", uid, "add", netId);
-
-        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
         final LinkAddress la = routeInfo.getDestinationLinkAddress();
-        cmd.appendArg(routeInfo.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
-        if (routeInfo.hasGateway()) {
-            cmd.appendArg(routeInfo.getGateway().getHostAddress());
-        }
+        final String ifName = routeInfo.getInterface();
+        final String dst = la.toString();
+        final String nextHop;
 
+        if (routeInfo.hasGateway()) {
+            nextHop = routeInfo.getGateway().getHostAddress();
+        } else {
+            nextHop = "";
+        }
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2492,9 +2464,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "default", "set", netId);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetDefault(netId);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2503,49 +2475,41 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "default", "clear");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkClearDefault();
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
-    public void setNetworkPermission(int netId, String permission) {
+    public void setNetworkPermission(int netId, int permission) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            if (permission != null) {
-                mConnector.execute("network", "permission", "network", "set", permission, netId);
-            } else {
-                mConnector.execute("network", "permission", "network", "clear", netId);
-            }
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetPermissionForNetwork(netId, permission);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
+    private int parsePermission(String permission) {
+        if (permission.equals("NETWORK")) {
+            return INetd.PERMISSION_NETWORK;
+        }
+        if (permission.equals("SYSTEM")) {
+            return INetd.PERMISSION_SYSTEM;
+        }
+        return INetd.PERMISSION_NONE;
+    }
 
     @Override
     public void setPermission(String permission, int[] uids) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        Object[] argv = new Object[4 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "permission";
-        argv[1] = "user";
-        argv[2] = "set";
-        argv[3] = permission;
-        int argc = 4;
-        // Avoid overly long commands by limiting number of UIDs per command.
-        for (int i = 0; i < uids.length; ++i) {
-            argv[argc++] = uids[i];
-            if (i == uids.length - 1 || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 4;
-            }
+        try {
+            mNetdService.networkSetPermissionForUser(parsePermission(permission), uids);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2553,22 +2517,10 @@
     public void clearPermission(int[] uids) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "permission";
-        argv[1] = "user";
-        argv[2] = "clear";
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UIDs per command.
-        for (int i = 0; i < uids.length; ++i) {
-            argv[argc++] = uids[i];
-            if (i == uids.length - 1 || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+        try {
+            mNetdService.networkClearPermissionForUser(uids);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2577,9 +2529,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "protect", "allow", uid);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetProtectAllow(uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2588,26 +2540,26 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "protect", "deny", uid);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetProtectDeny(uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
     public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
-        modifyInterfaceInNetwork("add", "local", iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.NETID_LOCAL, iface);
 
         for (RouteInfo route : routes) {
             if (!route.isDefaultRoute()) {
-                modifyRoute("add", "local", route);
+                modifyRoute(MODIFY_OPERATION_ADD, INetd.NETID_LOCAL, route);
             }
         }
     }
 
     @Override
     public void removeInterfaceFromLocalNetwork(String iface) {
-        modifyInterfaceInNetwork("remove", "local", iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.NETID_LOCAL, iface);
     }
 
     @Override
@@ -2616,7 +2568,7 @@
 
         for (RouteInfo route : routes) {
             try {
-                modifyRoute("remove", "local", route);
+                modifyRoute(MODIFY_OPERATION_REMOVE, INetd.NETID_LOCAL, route);
             } catch (IllegalStateException e) {
                 failures++;
             }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0f9fe83..ca74adc 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -49,7 +49,9 @@
 import android.telephony.TelephonyManager;
 import android.telephony.VoLteServiceState;
 import android.util.LocalLog;
+import android.util.StatsLog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 import com.android.internal.telephony.IPhoneStateListener;
@@ -82,7 +84,8 @@
  * Eventually we may want to remove the notion of dummy value but for now this
  * looks like the best approach.
  */
-class TelephonyRegistry extends ITelephonyRegistry.Stub {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public class TelephonyRegistry extends ITelephonyRegistry.Stub {
     private static final String TAG = "TelephonyRegistry";
     private static final boolean DBG = false; // STOPSHIP if true
     private static final boolean DBG_LOC = false; // STOPSHIP if true
@@ -211,6 +214,9 @@
 
     private PhoneCapability mPhoneCapability = null;
 
+    @TelephonyManager.RadioPowerState
+    private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
+
     private final LocalLog mLocalLog = new LocalLog(100);
 
     private PreciseDataConnectionState mPreciseDataConnectionState =
@@ -324,7 +330,8 @@
     // calls go through a oneway interface and local calls going through a
     // handler before they get to app code.
 
-    TelephonyRegistry(Context context) {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public TelephonyRegistry(Context context) {
         CellLocation  location = CellLocation.getEmpty();
 
         mContext = context;
@@ -749,6 +756,13 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
+                        try {
+                            r.callback.onRadioPowerStateChanged(mRadioPowerState);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -1570,6 +1584,32 @@
         }
     }
 
+    public void notifyRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+        if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) {
+            return;
+        }
+
+        if (VDBG) {
+            log("notifyRadioPowerStateChanged: state= " + state);
+        }
+
+        synchronized (mRecords) {
+            mRadioPowerState = state;
+
+            for (Record r : mRecords) {
+                if (r.matchPhoneStateListenerEvent(
+                        PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)) {
+                    try {
+                        r.callback.onRadioPowerStateChanged(state);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -1607,6 +1647,7 @@
             pw.println("mBackgroundCallState=" + mBackgroundCallState);
             pw.println("mVoLteServiceState=" + mVoLteServiceState);
             pw.println("mPhoneCapability=" + mPhoneCapability);
+            pw.println("mRadioPowerState=" + mRadioPowerState);
 
             pw.decreaseIndent();
 
@@ -1681,8 +1722,12 @@
         try {
             if (state == TelephonyManager.CALL_STATE_IDLE) {
                 mBatteryStats.notePhoneOff();
+                StatsLog.write(StatsLog.PHONE_STATE_CHANGED,
+                        StatsLog.PHONE_STATE_CHANGED__STATE__OFF);
             } else {
                 mBatteryStats.notePhoneOn();
+                StatsLog.write(StatsLog.PHONE_STATE_CHANGED,
+                        StatsLog.PHONE_STATE_CHANGED__STATE__ON);
             }
         } catch (RemoteException e) {
             /* The remote entity disappeared, we can safely ignore the exception. */
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 784d62e..302e195 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -157,9 +157,11 @@
     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
     // LMK_PROCPRIO <pid> <uid> <prio>
     // LMK_PROCREMOVE <pid>
+    // LMK_PROCPURGE
     static final byte LMK_TARGET = 0;
     static final byte LMK_PROCPRIO = 1;
     static final byte LMK_PROCREMOVE = 2;
+    static final byte LMK_PROCPURGE = 3;
 
     // These are the various interesting memory levels that we will give to
     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
@@ -808,31 +810,46 @@
         return true;
     }
 
+    // Never call directly, use writeLmkd() instead
+    private static boolean writeLmkdCommand(ByteBuffer buf) {
+        try {
+            sLmkdOutputStream.write(buf.array(), 0, buf.position());
+        } catch (IOException ex) {
+            Slog.w(TAG, "Error writing to lowmemorykiller socket");
+
+            try {
+                sLmkdSocket.close();
+            } catch (IOException ex2) {
+            }
+
+            sLmkdSocket = null;
+            return false;
+        }
+        return true;
+    }
+
     private static void writeLmkd(ByteBuffer buf) {
 
         for (int i = 0; i < 3; i++) {
             if (sLmkdSocket == null) {
-                    if (openLmkdSocket() == false) {
-                        try {
-                            Thread.sleep(1000);
-                        } catch (InterruptedException ie) {
-                        }
-                        continue;
+                if (openLmkdSocket() == false) {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException ie) {
                     }
-            }
-
-            try {
-                sLmkdOutputStream.write(buf.array(), 0, buf.position());
-                return;
-            } catch (IOException ex) {
-                Slog.w(TAG, "Error writing to lowmemorykiller socket");
-
-                try {
-                    sLmkdSocket.close();
-                } catch (IOException ex2) {
+                    continue;
                 }
 
-                sLmkdSocket = null;
+                // Purge any previously registered pids
+                ByteBuffer purge_buf = ByteBuffer.allocate(4);
+                purge_buf.putInt(LMK_PROCPURGE);
+                if (writeLmkdCommand(purge_buf) == false) {
+                    // Write failed, skip the rest and retry
+                    continue;
+                }
+            }
+            if (writeLmkdCommand(buf)) {
+                return;
             }
         }
     }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6fa17d8..40f1437 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -236,7 +236,6 @@
     private static final int MSG_PERSIST_RINGER_MODE = 3;
     private static final int MSG_AUDIO_SERVER_DIED = 4;
     private static final int MSG_PLAY_SOUND_EFFECT = 5;
-    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
     private static final int MSG_SET_FORCE_USE = 8;
     private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
@@ -268,6 +267,7 @@
     private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
     private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
     private static final int MSG_SET_HEARING_AID_CONNECTION_STATE = 105;
+    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 106;
     // end of messages handled under wakelock
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -3835,6 +3835,10 @@
                             int delay = checkSendBecomingNoisyIntent(
                                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState,
                                     AudioSystem.DEVICE_NONE);
+                            final String addr = btDevice == null ? "null" : btDevice.getAddress();
+                            mDeviceLogger.log(new AudioEventLogger.StringEvent(
+                                    "A2DP service connected: device addr=" + addr
+                                    + " state=" + state));
                             queueMsgUnderWakeLock(mAudioHandler,
                                     MSG_SET_A2DP_SINK_CONNECTION_STATE,
                                     state,
@@ -4545,13 +4549,21 @@
         }
         synchronized (mLastDeviceConnectMsgTime) {
             long time = SystemClock.uptimeMillis() + delay;
-            handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
-            if (msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
-                    msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
-                    msg == MSG_SET_A2DP_SINK_CONNECTION_STATE ||
-                    msg == MSG_SET_HEARING_AID_CONNECTION_STATE) {
+
+            if (msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
+                msg == MSG_SET_A2DP_SINK_CONNECTION_STATE ||
+                msg == MSG_SET_HEARING_AID_CONNECTION_STATE ||
+                msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
+                msg == MSG_A2DP_DEVICE_CONFIG_CHANGE ||
+                msg == MSG_BTA2DP_DOCK_TIMEOUT) {
+                if (mLastDeviceConnectMsgTime >= time) {
+                  // add a little delay to make sure messages are ordered as expected
+                  time = mLastDeviceConnectMsgTime + 30;
+                }
                 mLastDeviceConnectMsgTime = time;
             }
+
+            handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
         }
     }
 
@@ -4649,20 +4661,15 @@
         }
     }
 
-    @Override
-    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state)
-    {
-        Log.i(TAG, "setBluetoothHearingAidDeviceConnectionState");
-
-        setBluetoothHearingAidDeviceConnectionState(
-                device, state,  false /* suppressNoisyIntent */, AudioSystem.DEVICE_NONE);
-    }
-
     public int setBluetoothHearingAidDeviceConnectionState(
             BluetoothDevice device, int state, boolean suppressNoisyIntent,
             int musicDevice)
     {
         int delay;
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "setHearingAidDeviceConnectionState state=" + state
+                            + " addr=" + device.getAddress()
+                            + " supprNoisy=" + suppressNoisyIntent)).printLog(TAG));
         synchronized (mConnectedDevices) {
             if (!suppressNoisyIntent) {
                 int intState = (state == BluetoothHearingAid.STATE_CONNECTED) ? 1 : 0;
@@ -4690,7 +4697,14 @@
     public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice device,
                 int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
     {
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent state=" + state
+                // only querying address as this is the only readily available field on the device
+                + " addr=" + device.getAddress()
+                + " prof=" + profile + " supprNoisy=" + suppressNoisyIntent
+                + " vol=" + a2dpVolume)).printLog(TAG));
         if (mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE, device)) {
+            mDeviceLogger.log(new AudioEventLogger.StringEvent("A2DP connection state ignored"));
             return 0;
         }
         return setBluetoothA2dpDeviceConnectionStateInt(
@@ -4713,6 +4727,13 @@
             } else {
                 delay = 0;
             }
+
+            if (DEBUG_DEVICES) {
+                Log.d(TAG, "setBluetoothA2dpDeviceConnectionStateInt device: " + device
+                      + " state: " + state + " delay(ms): " + delay
+                      + " suppressNoisyIntent: " + suppressNoisyIntent);
+            }
+
             queueMsgUnderWakeLock(mAudioHandler,
                     (profile == BluetoothProfile.A2DP ?
                         MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
@@ -5615,6 +5636,7 @@
                     synchronized (mConnectedDevices) {
                         makeA2dpDeviceUnavailableNow( (String) msg.obj );
                     }
+                    mAudioEventWakeLock.release();
                     break;
 
                 case MSG_SET_FORCE_USE:
@@ -5629,7 +5651,7 @@
                 case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
                     {   WiredDeviceConnectionState connectState =
                             (WiredDeviceConnectionState)msg.obj;
-                        mWiredDevLogger.log(new WiredDevConnectEvent(connectState));
+                        mDeviceLogger.log(new WiredDevConnectEvent(connectState));
                         onSetWiredDeviceConnectionState(connectState.mType, connectState.mState,
                                 connectState.mAddress, connectState.mName, connectState.mCaller);
                         mAudioEventWakeLock.release();
@@ -5837,14 +5859,20 @@
                                    address));
         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
                 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, null, 0);
+        setCurrentAudioRouteNameIfPossible(name);
     }
 
     private void onSendBecomingNoisyIntent() {
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "broadcast ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
         sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
     }
 
     // must be called synchronized on mConnectedDevices
     private void makeA2dpDeviceUnavailableNow(String address) {
+        if (address == null) {
+            return;
+        }
         synchronized (mA2dpAvrcpLock) {
             mAvrcpAbsVolSupported = false;
         }
@@ -5853,7 +5881,10 @@
         mConnectedDevices.remove(
                 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
         // Remove A2DP routes as well
-        setCurrentAudioRouteName(null);
+        setCurrentAudioRouteNameIfPossible(null);
+        if (mDockAddress == address) {
+            mDockAddress = null;
+        }
     }
 
     // must be called synchronized on mConnectedDevices
@@ -5865,9 +5896,12 @@
         mConnectedDevices.remove(
                 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
         // send the delayed message to make the device unavailable later
-        Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address);
-        mAudioHandler.sendMessageDelayed(msg, delayMs);
-
+        queueMsgUnderWakeLock(mAudioHandler,
+            MSG_BTA2DP_DOCK_TIMEOUT,
+            0,
+            0,
+            address,
+            delayMs);
     }
 
     // must be called synchronized on mConnectedDevices
@@ -5914,6 +5948,10 @@
                                    address));
         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
                 AudioSystem.DEVICE_OUT_HEARING_AID, 0, null, 0);
+        sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
+                            AudioSystem.DEVICE_OUT_HEARING_AID, 0,
+                            mStreamStates[AudioSystem.STREAM_MUSIC], 0);
+        setCurrentAudioRouteNameIfPossible(name);
     }
 
     // must be called synchronized on mConnectedDevices
@@ -5923,7 +5961,7 @@
         mConnectedDevices.remove(
                 makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
         // Remove Hearing Aid routes as well
-        setCurrentAudioRouteName(null);
+        setCurrentAudioRouteNameIfPossible(null);
     }
 
     // must be called synchronized on mConnectedDevices
@@ -5939,7 +5977,8 @@
     private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state, int a2dpVolume)
     {
         if (DEBUG_DEVICES) {
-            Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice+"state=" + state);
+            Log.d(TAG, "onSetA2dpSinkConnectionState btDevice= " + btDevice+" state= " + state
+                + " is dock: "+btDevice.isBluetoothDock());
         }
         if (btDevice == null) {
             return;
@@ -5967,7 +6006,6 @@
                 } else {
                     makeA2dpDeviceUnavailableNow(address);
                 }
-                setCurrentAudioRouteName(null);
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                 if (btDevice.isBluetoothDock()) {
                     // this could be a reconnection after a transient disconnection
@@ -5976,7 +6014,7 @@
                 } else {
                     // this could be a connection of another A2DP device before the timeout of
                     // a dock: cancel the dock timeout, and make the dock unavailable now
-                    if(hasScheduledA2dpDockTimeout()) {
+                    if (hasScheduledA2dpDockTimeout() && mDockAddress != null) {
                         cancelA2dpDeviceTimeout();
                         makeA2dpDeviceUnavailableNow(mDockAddress);
                     }
@@ -5991,7 +6029,6 @@
                 }
                 makeA2dpDeviceAvailable(address, btDevice.getName(),
                         "onSetA2dpSinkConnectionState");
-                setCurrentAudioRouteName(btDevice.getAliasName());
             }
         }
     }
@@ -6043,25 +6080,35 @@
 
             if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
                 makeHearingAidDeviceUnavailable(address);
-                setCurrentAudioRouteName(null);
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                 makeHearingAidDeviceAvailable(address, btDevice.getName(),
                         "onSetHearingAidConnectionState");
-                setCurrentAudioRouteName(btDevice.getAliasName());
             }
         }
     }
 
-    private void setCurrentAudioRouteName(String name){
+    private void setCurrentAudioRouteNameIfPossible(String name) {
         synchronized (mCurAudioRoutes) {
             if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
-                mCurAudioRoutes.bluetoothName = name;
-                sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
-                        SENDMSG_NOOP, 0, 0, null, 0);
+                if (name != null || !isCurrentDeviceConnected()) {
+                    mCurAudioRoutes.bluetoothName = name;
+                    sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                            SENDMSG_NOOP, 0, 0, null, 0);
+                }
             }
         }
     }
 
+    private boolean isCurrentDeviceConnected() {
+        for (int i = 0; i < mConnectedDevices.size(); i++) {
+            DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
+            if (TextUtils.equals(deviceSpec.mDeviceName, mCurAudioRoutes.bluetoothName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void onBluetoothA2dpDeviceConfigChange(BluetoothDevice btDevice)
     {
         if (DEBUG_DEVICES) {
@@ -6074,10 +6121,14 @@
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             address = "";
         }
+        mDeviceLogger.log(new AudioEventLogger.StringEvent(
+                "onBluetoothA2dpDeviceConfigChange addr=" + address));
 
         int device = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
         synchronized (mConnectedDevices) {
             if (mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE, btDevice)) {
+                mDeviceLogger.log(new AudioEventLogger.StringEvent(
+                        "A2dp config change ignored"));
                 return;
             }
             final String key = makeDeviceListKey(device, address);
@@ -6195,17 +6246,6 @@
             }
         }
 
-        if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
-                mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
-                mAudioHandler.hasMessages(MSG_SET_HEARING_AID_CONNECTION_STATE) ||
-                mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
-            synchronized (mLastDeviceConnectMsgTime) {
-                long time = SystemClock.uptimeMillis();
-                if (mLastDeviceConnectMsgTime > time) {
-                    delay = (int)(mLastDeviceConnectMsgTime - time) + 30;
-                }
-            }
-        }
         return delay;
     }
 
@@ -7184,19 +7224,20 @@
     //==========================================================================================
     // AudioService logging and dumpsys
     //==========================================================================================
-    final int LOG_NB_EVENTS_PHONE_STATE = 20;
-    final int LOG_NB_EVENTS_WIRED_DEV_CONNECTION = 30;
-    final int LOG_NB_EVENTS_FORCE_USE = 20;
-    final int LOG_NB_EVENTS_VOLUME = 40;
-    final int LOG_NB_EVENTS_DYN_POLICY = 10;
+    static final int LOG_NB_EVENTS_PHONE_STATE = 20;
+    static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30;
+    static final int LOG_NB_EVENTS_FORCE_USE = 20;
+    static final int LOG_NB_EVENTS_VOLUME = 40;
+    static final int LOG_NB_EVENTS_DYN_POLICY = 10;
 
     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
             "phone state (logged after successfull call to AudioSystem.setPhoneState(int))");
 
-    final private AudioEventLogger mWiredDevLogger = new AudioEventLogger(
-            LOG_NB_EVENTS_WIRED_DEV_CONNECTION,
-            "wired device connection (logged before onSetWiredDeviceConnectionState() is executed)"
-            );
+    // logs for wired + A2DP device connections:
+    // - wired: logged before onSetWiredDeviceConnectionState() is executed
+    // - A2DP: logged at reception of method call
+    final private AudioEventLogger mDeviceLogger = new AudioEventLogger(
+            LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
 
     final private AudioEventLogger mForceUseLogger = new AudioEventLogger(
             LOG_NB_EVENTS_FORCE_USE,
@@ -7285,7 +7326,7 @@
         pw.println("\nEvent logs:");
         mModeLogger.dump(pw);
         pw.println("\n");
-        mWiredDevLogger.dump(pw);
+        mDeviceLogger.dump(pw);
         pw.println("\n");
         mForceUseLogger.dump(pw);
         pw.println("\n");
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index ca9b256..30659c1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -1031,6 +1031,11 @@
                 result.isPortal() /* isCaptivePortal */,
                 startTime, endTime);
 
+        log("isCaptivePortal: isSuccessful()=" + result.isSuccessful() +
+                " isPortal()=" + result.isPortal() +
+                " RedirectUrl=" + result.redirectUrl +
+                " StartTime=" + startTime + " EndTime=" + endTime);
+
         return result;
     }
 
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index dc65e1e..15468ff 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -16,6 +16,12 @@
 
 package com.android.server.connectivity;
 
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_HOST;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PAC;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PORT;
+import static android.provider.Settings.Global.HTTP_PROXY;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
@@ -47,16 +53,14 @@
     @NonNull
     private final Context mContext;
 
-    // TODO : make this private and import as much managing logic from ConnectivityService as
-    // possible
     @NonNull
-    public final Object mProxyLock = new Object();
+    private final Object mProxyLock = new Object();
     // The global proxy is the proxy that is set device-wide, overriding any network-specific
     // proxy. Note however that proxies are hints ; the system does not enforce their use. Hence
     // this value is only for querying.
     @Nullable
     @GuardedBy("mProxyLock")
-    public ProxyInfo mGlobalProxy = null;
+    private ProxyInfo mGlobalProxy = null;
     // The default proxy is the proxy that applies to no particular network if the global proxy
     // is not set. Individual networks have their own settings that override this. This member
     // is set through setDefaultProxy, which is called when the default network changes proxies
@@ -64,10 +68,10 @@
     // when PacManager resolves the proxy.
     @Nullable
     @GuardedBy("mProxyLock")
-    public volatile ProxyInfo mDefaultProxy = null;
-    // Whether the default proxy is disabled. TODO : make this mDefaultProxyEnabled
+    private volatile ProxyInfo mDefaultProxy = null;
+    // Whether the default proxy is enabled.
     @GuardedBy("mProxyLock")
-    public boolean mDefaultProxyDisabled = false;
+    private boolean mDefaultProxyEnabled = true;
 
     // The object responsible for Proxy Auto Configuration (PAC).
     @NonNull
@@ -85,7 +89,7 @@
     @Nullable
     private static ProxyInfo canonicalizeProxyInfo(@Nullable final ProxyInfo proxy) {
         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
-                && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
+                && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
             return null;
         }
         return proxy;
@@ -122,9 +126,9 @@
     public ProxyInfo getDefaultProxy() {
         // This information is already available as a world read/writable jvm property.
         synchronized (mProxyLock) {
-            final ProxyInfo ret = mGlobalProxy;
-            if ((ret == null) && !mDefaultProxyDisabled) return mDefaultProxy;
-            return ret;
+            if (mGlobalProxy != null) return mGlobalProxy;
+            if (mDefaultProxyEnabled) return mDefaultProxy;
+            return null;
         }
     }
 
@@ -142,15 +146,68 @@
     }
 
     /**
+     * Read the global proxy settings and cache them in memory.
+     */
+    public void loadGlobalProxy() {
+        ContentResolver res = mContext.getContentResolver();
+        String host = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_HOST);
+        int port = Settings.Global.getInt(res, GLOBAL_HTTP_PROXY_PORT, 0);
+        String exclList = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
+        String pacFileUrl = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_PAC);
+        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
+            ProxyInfo proxyProperties;
+            if (!TextUtils.isEmpty(pacFileUrl)) {
+                proxyProperties = new ProxyInfo(pacFileUrl);
+            } else {
+                proxyProperties = new ProxyInfo(host, port, exclList);
+            }
+            if (!proxyProperties.isValid()) {
+                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
+                return;
+            }
+
+            synchronized (mProxyLock) {
+                mGlobalProxy = proxyProperties;
+            }
+        }
+        loadDeprecatedGlobalHttpProxy();
+        // TODO : shouldn't this function call mPacManager.setCurrentProxyScriptUrl ?
+    }
+
+    /**
+     * Read the global proxy from the deprecated Settings.Global.HTTP_PROXY setting and apply it.
+     */
+    public void loadDeprecatedGlobalHttpProxy() {
+        final String proxy = Settings.Global.getString(mContext.getContentResolver(), HTTP_PROXY);
+        if (!TextUtils.isEmpty(proxy)) {
+            String data[] = proxy.split(":");
+            if (data.length == 0) {
+                return;
+            }
+
+            final String proxyHost = data[0];
+            int proxyPort = 8080;
+            if (data.length > 1) {
+                try {
+                    proxyPort = Integer.parseInt(data[1]);
+                } catch (NumberFormatException e) {
+                    return;
+                }
+            }
+            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
+            setGlobalProxy(p);
+        }
+    }
+
+    /**
      * Sends the system broadcast informing apps about a new proxy configuration.
      *
      * Confusingly this method also sets the PAC file URL. TODO : separate this, it has nothing
      * to do in a "sendProxyBroadcast" method.
-     * @param proxyInfo the proxy spec, or null for no proxy.
      */
-    // TODO : make the argument NonNull final and the method private
-    public void sendProxyBroadcast(@Nullable ProxyInfo proxyInfo) {
-        if (proxyInfo == null) proxyInfo = new ProxyInfo("", 0, "");
+    public void sendProxyBroadcast() {
+        final ProxyInfo defaultProxy = getDefaultProxy();
+        final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
         if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return;
         if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
@@ -203,16 +260,15 @@
             final ContentResolver res = mContext.getContentResolver();
             final long token = Binder.clearCallingIdentity();
             try {
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
-                Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
-                        exclList);
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_HOST, host);
+                Settings.Global.putInt(res, GLOBAL_HTTP_PROXY_PORT, port);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclList);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
 
-            sendProxyBroadcast(mGlobalProxy == null ? mDefaultProxy : proxyInfo);
+            sendProxyBroadcast();
         }
     }
 
@@ -224,10 +280,7 @@
      */
     public void setDefaultProxy(@Nullable ProxyInfo proxyInfo) {
         synchronized (mProxyLock) {
-            if (mDefaultProxy != null && mDefaultProxy.equals(proxyInfo)) {
-                return;
-            }
-            if (mDefaultProxy == proxyInfo) return; // catches repeated nulls
+            if (Objects.equals(mDefaultProxy, proxyInfo)) return;
             if (proxyInfo != null &&  !proxyInfo.isValid()) {
                 if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                 return;
@@ -242,14 +295,32 @@
                     && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
                     && proxyInfo.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
                 mGlobalProxy = proxyInfo;
-                sendProxyBroadcast(mGlobalProxy);
+                sendProxyBroadcast();
                 return;
             }
             mDefaultProxy = proxyInfo;
 
             if (mGlobalProxy != null) return;
-            if (!mDefaultProxyDisabled) {
-                sendProxyBroadcast(proxyInfo);
+            if (mDefaultProxyEnabled) {
+                sendProxyBroadcast();
+            }
+        }
+    }
+
+    /**
+     * Enable or disable the default proxy.
+     *
+     * This sets the flag for enabling/disabling the default proxy and sends the broadcast
+     * if applicable.
+     * @param enabled whether the default proxy should be enabled.
+     */
+    public void setDefaultProxyEnabled(final boolean enabled) {
+        synchronized (mProxyLock) {
+            if (mDefaultProxyEnabled != enabled) {
+                mDefaultProxyEnabled = enabled;
+                if (mGlobalProxy == null && mDefaultProxy != null) {
+                    sendProxyBroadcast();
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b06dba9..268e844 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -303,19 +303,19 @@
     private final class CecMessageBuffer {
         private List<HdmiCecMessage> mBuffer = new ArrayList<>();
 
-        public void bufferMessage(HdmiCecMessage message) {
+        public boolean bufferMessage(HdmiCecMessage message) {
             switch (message.getOpcode()) {
                 case Constants.MESSAGE_ACTIVE_SOURCE:
                     bufferActiveSource(message);
-                    break;
+                    return true;
                 case Constants.MESSAGE_IMAGE_VIEW_ON:
                 case Constants.MESSAGE_TEXT_VIEW_ON:
                     bufferImageOrTextViewOn(message);
-                    break;
+                    return true;
                     // Add here if new message that needs to buffer
                 default:
                     // Do not need to buffer messages other than above
-                    break;
+                    return false;
             }
         }
 
@@ -869,10 +869,6 @@
     @ServiceThreadOnly
     boolean handleCecCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if (!mAddressAllocated) {
-            mCecMessageBuffer.bufferMessage(message);
-            return true;
-        }
         int errorCode = mMessageValidator.isValid(message);
         if (errorCode != HdmiCecMessageValidator.OK) {
             // We'll not response on the messages with the invalid source or destination
@@ -882,7 +878,12 @@
             }
             return true;
         }
-        return dispatchMessageToLocalDevice(message);
+
+        if (dispatchMessageToLocalDevice(message)) {
+            return true;
+        }
+
+        return (!mAddressAllocated) ? mCecMessageBuffer.bufferMessage(message) : false;
     }
 
     void enableAudioReturnChannel(int portId, boolean enabled) {
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index d347a91..f7e871d 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -50,8 +50,7 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != SendMessageResult.SUCCESS) {
-                    tv().setSystemAudioMode(false);
-                    finish();
+                    handleSystemAudioModeStatusTimeout();
                 }
             }
         });
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index b4bc7f5..31fdc01 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -72,6 +72,7 @@
     static final int NTWK_ALLOWED_TMP_WHITELIST = 4;
     static final int NTWK_BLOCKED_BG_RESTRICT = 5;
     static final int NTWK_ALLOWED_DEFAULT = 6;
+    static final int NTWK_ALLOWED_SYSTEM = 7;
 
     private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
     private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 61d67b7..099671d 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -16,6 +16,8 @@
 
 package com.android.server.net;
 
+import static com.android.server.net.NetworkPolicyManagerService.isUidNetworkingBlockedInternal;
+
 import android.net.Network;
 import android.net.NetworkTemplate;
 import android.telephony.SubscriptionPlan;
@@ -46,6 +48,28 @@
     public abstract boolean isUidNetworkingBlocked(int uid, String ifname);
 
     /**
+     * Figure out if networking is blocked for a given set of conditions.
+     *
+     * This is used by ConnectivityService via passing stale copies of conditions, so it must not
+     * take any locks.
+     *
+     * @param uid The target uid.
+     * @param uidRules The uid rules which are obtained from NetworkPolicyManagerService.
+     * @param isNetworkMetered True if the network is metered.
+     * @param isBackgroundRestricted True if data saver is enabled.
+     *
+     * @return true if networking is blocked for the UID under the specified conditions.
+     */
+    public static boolean isUidNetworkingBlocked(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted) {
+        // Log of invoking internal function is disabled because it will be called very
+        // frequently. And metrics are unlikely needed on this method because the callers are
+        // external and this method doesn't take any locks or perform expensive operations.
+        return isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                isBackgroundRestricted, null);
+    }
+
+    /**
      * Informs that an appId has been added or removed from the temp-powersave-whitelist so that
      * that network rules for that appId can be updated.
      *
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ab482bb..9fa42ab 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -99,6 +99,7 @@
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED;
+import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_SYSTEM;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT;
@@ -4786,46 +4787,75 @@
         final long startTime = mStatLogger.getTime();
 
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-        final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
-
-        mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
-
-        return ret;
-    }
-
-    private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
         final int uidRules;
         final boolean isBackgroundRestricted;
         synchronized (mUidRulesFirstLock) {
             uidRules = mUidRules.get(uid, RULE_NONE);
             isBackgroundRestricted = mRestrictBackground;
         }
-        if (hasRule(uidRules, RULE_REJECT_ALL)) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_POWER);
-            return true;
+        final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                isBackgroundRestricted, mLogger);
+
+        mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
+
+        return ret;
+    }
+
+    private static boolean isSystem(int uid) {
+        return uid < Process.FIRST_APPLICATION_UID;
+    }
+
+    static boolean isUidNetworkingBlockedInternal(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted, @Nullable NetworkPolicyLogger logger) {
+        final int reason;
+        // Networks are never blocked for system components
+        if (isSystem(uid)) {
+            reason = NTWK_ALLOWED_SYSTEM;
         }
-        if (!isNetworkMetered) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_NON_METERED);
-            return false;
+        else if (hasRule(uidRules, RULE_REJECT_ALL)) {
+            reason = NTWK_BLOCKED_POWER;
         }
-        if (hasRule(uidRules, RULE_REJECT_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_BLACKLIST);
-            return true;
+        else if (!isNetworkMetered) {
+            reason = NTWK_ALLOWED_NON_METERED;
         }
-        if (hasRule(uidRules, RULE_ALLOW_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_WHITELIST);
-            return false;
+        else if (hasRule(uidRules, RULE_REJECT_METERED)) {
+            reason = NTWK_BLOCKED_BLACKLIST;
         }
-        if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_TMP_WHITELIST);
-            return false;
+        else if (hasRule(uidRules, RULE_ALLOW_METERED)) {
+            reason = NTWK_ALLOWED_WHITELIST;
         }
-        if (isBackgroundRestricted) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_BG_RESTRICT);
-            return true;
+        else if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
+            reason = NTWK_ALLOWED_TMP_WHITELIST;
         }
-        mLogger.networkBlocked(uid, NTWK_ALLOWED_DEFAULT);
-        return false;
+        else if (isBackgroundRestricted) {
+            reason = NTWK_BLOCKED_BG_RESTRICT;
+        }
+        else {
+            reason = NTWK_ALLOWED_DEFAULT;
+        }
+
+        final boolean blocked;
+        switch(reason) {
+            case NTWK_ALLOWED_DEFAULT:
+            case NTWK_ALLOWED_NON_METERED:
+            case NTWK_ALLOWED_TMP_WHITELIST:
+            case NTWK_ALLOWED_WHITELIST:
+            case NTWK_ALLOWED_SYSTEM:
+                blocked = false;
+                break;
+            case NTWK_BLOCKED_POWER:
+            case NTWK_BLOCKED_BLACKLIST:
+            case NTWK_BLOCKED_BG_RESTRICT:
+                blocked = true;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        if (logger != null) {
+            logger.networkBlocked(uid, reason);
+        }
+
+        return blocked;
     }
 
     private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
@@ -4867,11 +4897,18 @@
         public boolean isUidNetworkingBlocked(int uid, String ifname) {
             final long startTime = mStatLogger.getTime();
 
+            final int uidRules;
+            final boolean isBackgroundRestricted;
+            synchronized (mUidRulesFirstLock) {
+                uidRules = mUidRules.get(uid, RULE_NONE);
+                isBackgroundRestricted = mRestrictBackground;
+            }
             final boolean isNetworkMetered;
             synchronized (mNetworkPoliciesSecondLock) {
                 isNetworkMetered = mMeteredIfaces.contains(ifname);
             }
-            final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
+            final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                    isBackgroundRestricted, mLogger);
 
             mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 390c0cc..1fcb37f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -60,8 +60,6 @@
 import dalvik.system.VMRuntime;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.Streams;
 
 import java.io.BufferedReader;
 import java.io.File;
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 833cc5b..1fb51b7 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.pm.dex;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -57,8 +59,6 @@
 import dalvik.system.VMRuntime;
 
 import libcore.io.IoUtils;
-import libcore.util.NonNull;
-import libcore.util.Nullable;
 
 import java.io.File;
 import java.io.FileNotFoundException;
diff --git a/services/core/java/com/android/server/pm/dex/TEST_MAPPING b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
index ad52559..c93af2a 100644
--- a/services/core/java/com/android/server/pm/dex/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
@@ -1,19 +1,12 @@
 {
   "presubmit": [
     {
-      "name": "DexLoggerTests"
-    },
-    {
-      "name": "DexManagerTests"
-    },
-    {
-      "name": "DexoptOptionsTests"
-    },
-    {
-      "name": "DexoptUtilsTest"
-    },
-    {
-      "name": "PackageDexUsageTests"
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm.dex"
+        }
+      ]
     },
     {
       "name": "DexLoggerIntegrationTests"
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 1cba1c7..a55b49f 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -95,10 +95,22 @@
         mIsShowing = showing;
 
         mCallback.onShowingChanged();
-        try {
-            mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error informing keystore of screen lock", e);
+        int retry = 2;
+        while (retry > 0) {
+            try {
+                mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
+                break;
+            } catch (RemoteException e) {
+                if (retry == 2) {
+                    Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died"
+                            + " -> refreshing service token and retrying");
+                    mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
+                            .getService("android.security.keystore"));
+                } else {
+                    Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e);
+                }
+                --retry;
+            }
         }
     }
 
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 306f73a..902bafb 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -57,17 +57,6 @@
         "frameworks/native/services",
         "system/gatekeeper/include",
     ],
-
-    product_variables: {
-        arc: {
-            cflags: [
-                "-DUSE_ARC",
-            ],
-            srcs: [
-                "com_android_server_ArcVideoService.cpp",
-            ],
-        }
-    }
 }
 
 cc_defaults {
@@ -108,6 +97,7 @@
         "libutils",
         "libhwui",
         "libbpf",
+        "libnetdbpf",
         "libnetdutils",
         "android.hardware.audio.common@2.0",
         "android.hardware.broadcastradio@1.0",
@@ -142,7 +132,6 @@
             shared_libs: [
                 "libarcbridge",
                 "libarcbridgeservice",
-                "libarcvideobridge",
                 "libchrome",
                 "libmojo",
             ],
diff --git a/services/core/jni/com_android_server_ArcVideoService.cpp b/services/core/jni/com_android_server_ArcVideoService.cpp
deleted file mode 100644
index f93cd90..0000000
--- a/services/core/jni/com_android_server_ArcVideoService.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ArcVideoService"
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <media/arcvideobridge/IArcVideoBridge.h>
-#include <utils/Log.h>
-
-#include <base/bind.h>
-#include <base/bind_helpers.h>
-#include <mojo/edk/embedder/embedder.h>
-#include <mojo/public/cpp/bindings/binding.h>
-
-#include <arc/ArcBridgeSupport.h>
-#include <arc/ArcService.h>
-#include <arc/Future.h>
-#include <arc/IArcBridgeService.h>
-#include <arc/MojoProcessSupport.h>
-#include <components/arc/common/video.mojom.h>
-
-namespace {
-
-// [MinVersion] of OnVideoInstanceReady method in arc_bridge.mojom.
-constexpr int kMinimumArcBridgeHostVersion = 6;
-
-void onCaptureResult(arc::Future<arc::MojoBootstrapResult>* future, uint32_t version,
-                     mojo::ScopedHandle handle, const std::string& token) {
-    mojo::edk::ScopedPlatformHandle scoped_platform_handle;
-    MojoResult result =
-            mojo::edk::PassWrappedPlatformHandle(handle.release().value(), &scoped_platform_handle);
-    if (result != MOJO_RESULT_OK) {
-        ALOGE("Received invalid file descriptor.");
-        future->set(arc::MojoBootstrapResult());
-        return;
-    }
-
-    base::ScopedFD fd(scoped_platform_handle.release().handle);
-    future->set(arc::MojoBootstrapResult(std::move(fd), token, version));
-}
-
-}  // namespace
-
-namespace arc {
-
-class VideoService : public mojom::VideoInstance,
-                     public ArcService,
-                     public android::BnArcVideoBridge {
-public:
-    explicit VideoService(MojoProcessSupport* mojoProcessSupport)
-          : mMojoProcessSupport(mojoProcessSupport), mBinding(this) {
-        mMojoProcessSupport->arc_bridge_support().requestArcBridgeProxyAsync(
-                this, kMinimumArcBridgeHostVersion);
-    }
-
-    ~VideoService() override { mMojoProcessSupport->disconnect(&mBinding, &mHostPtr); }
-
-    // VideoInstance overrides:
-    void InitDeprecated(mojom::VideoHostPtr hostPtr) override {
-        Init(std::move(hostPtr), base::Bind(&base::DoNothing));
-    }
-
-    void Init(mojom::VideoHostPtr hostPtr, const InitCallback& callback) override {
-        ALOGV("Init");
-        mHostPtr = std::move(hostPtr);
-        // A method must be called while we are still in a Mojo thread so the
-        // proxy can perform lazy initialization and be able to be called from
-        // non-Mojo threads later.
-        // This also caches the version number so it can be obtained by calling
-        // .version().
-        mHostPtr.QueryVersion(base::Bind(
-            [](const InitCallback& callback, uint32_t version) {
-                ALOGI("VideoService ready (version=%d)", version);
-                callback.Run();
-            },
-            callback));
-        ALOGV("Init done");
-    }
-
-    // ArcService overrides:
-    void ready(mojom::ArcBridgeHostPtr* bridgeHost) override {
-        (*bridgeHost)->OnVideoInstanceReady(mBinding.CreateInterfacePtrAndBind());
-    }
-
-    void versionMismatch(uint32_t version) override {
-        ALOGE("ArcBridgeHost version %d, does not support video (version %d)\n", version,
-              kMinimumArcBridgeHostVersion);
-    }
-
-    // BnArcVideoBridge overrides:
-    MojoBootstrapResult bootstrapVideoAcceleratorFactory() override {
-        ALOGV("VideoService::bootstrapVideoAcceleratorFactory");
-
-        Future<MojoBootstrapResult> future;
-        mMojoProcessSupport->mojo_thread().getTaskRunner()->PostTask(
-                FROM_HERE, base::Bind(&VideoService::bootstrapVideoAcceleratorFactoryOnMojoThread,
-                                      base::Unretained(this), &future));
-        return future.get();
-    }
-
-    int32_t hostVersion() override {
-        ALOGV("VideoService::hostVersion");
-        return mHostPtr.version();
-    }
-
-private:
-    void bootstrapVideoAcceleratorFactoryOnMojoThread(Future<MojoBootstrapResult>* future) {
-        if (!mHostPtr) {
-            ALOGE("mHostPtr is not ready yet");
-            future->set(MojoBootstrapResult());
-            return;
-        }
-        mHostPtr->OnBootstrapVideoAcceleratorFactory(
-                base::Bind(&onCaptureResult, base::Unretained(future), mHostPtr.version()));
-    }
-
-    // Outlives VideoService.
-    MojoProcessSupport* const mMojoProcessSupport;
-    mojo::Binding<mojom::VideoInstance> mBinding;
-    mojom::VideoHostPtr mHostPtr;
-};
-
-}  // namespace arc
-
-namespace android {
-
-int register_android_server_ArcVideoService() {
-    defaultServiceManager()->addService(
-            String16("android.os.IArcVideoBridge"),
-            new arc::VideoService(arc::MojoProcessSupport::getLeakyInstance()));
-    return 0;
-}
-
-}  // namespace android
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
index 3302dea..649f1a5 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
@@ -30,8 +30,8 @@
 #include <utils/Log.h>
 
 #include "android-base/unique_fd.h"
-#include "bpf/BpfNetworkStats.h"
 #include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
 
 using android::bpf::Stats;
 using android::bpf::hasBpfSupport;
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 0ebef37..bb6e684 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -54,9 +54,6 @@
 int register_android_server_GraphicsStatsService(JNIEnv* env);
 int register_android_hardware_display_DisplayViewport(JNIEnv* env);
 int register_android_server_net_NetworkStatsService(JNIEnv* env);
-#ifdef USE_ARC
-int register_android_server_ArcVideoService();
-#endif
 };
 
 using namespace android;
@@ -104,8 +101,5 @@
     register_android_server_GraphicsStatsService(env);
     register_android_hardware_display_DisplayViewport(env);
     register_android_server_net_NetworkStatsService(env);
-#ifdef USE_ARC
-    register_android_server_ArcVideoService();
-#endif
     return JNI_VERSION_1_4;
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 82a2895..439f313 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -459,6 +459,12 @@
             }
         }
 
+        // Diagnostic to ensure that the system is in a base healthy state. Done here as a common
+        // non-zygote process.
+        if (!VMRuntime.hasBootImageSpaces()) {
+            Slog.wtf(TAG, "Runtime is not running with a boot image!");
+        }
+
         // Loop forever.
         Looper.loop();
         throw new RuntimeException("Main thread loop unexpectedly exited");
diff --git a/services/net/java/android/net/ip/IpNeighborMonitor.java b/services/net/java/android/net/ip/IpNeighborMonitor.java
index fc07aa1..9512f1b 100644
--- a/services/net/java/android/net/ip/IpNeighborMonitor.java
+++ b/services/net/java/android/net/ip/IpNeighborMonitor.java
@@ -40,7 +40,6 @@
 import com.android.internal.util.BitUtils;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.FileDescriptor;
 import java.net.InetAddress;
diff --git a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
index 9d686ef..d197d01 100644
--- a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
+++ b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
@@ -28,7 +28,6 @@
 import android.net.util.InterfaceParams;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.StructGroupReq;
 import android.system.StructTimeval;
 import android.util.Log;
 
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
index cfcba3a..40098c1 100644
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ b/services/net/java/android/net/netlink/NetlinkSocket.java
@@ -32,7 +32,6 @@
 import android.system.StructTimeval;
 import android.util.Log;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 3d7fdbdd..de54c4b 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -80,7 +80,7 @@
 
 LOCAL_JAVA_LIBRARIES := \
     junit \
-    platform-robolectric-3.6.1-prebuilt
+    platform-robolectric-3.6.2-prebuilt
 
 LOCAL_INSTRUMENTATION_FOR := FrameworksServicesLib
 LOCAL_MODULE := FrameworksServicesRoboTests
@@ -105,4 +105,4 @@
 
 LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java
 
-include prebuilts/misc/common/robolectric/3.6.1/run_robotests.mk
+include prebuilts/misc/common/robolectric/3.6.2/run_robotests.mk
diff --git a/services/tests/runtests.py b/services/tests/runtests.py
index 7980dc2..f19cc5d 100755
--- a/services/tests/runtests.py
+++ b/services/tests/runtests.py
@@ -22,8 +22,7 @@
                                'android.support.test.runner.AndroidJUnitRunner')
 
 PACKAGE_WHITELIST = (
-    'android.net',
-    'com.android.server.connectivity',
+    "com.android.server",
 )
 
 COLOR_RED = '\033[0;31m'
@@ -37,14 +36,27 @@
                 COLOR_NONE)
     return subprocess.check_call(shell_command, shell=True)
 
-
+# usage:
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py : run tests in com.android.server
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py -e package [package name, e.g. com.android.server]
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py -e class [class name, e.g. com.android.server.MountServiceTests]
+#
+#   The available INSTRUMENTED_PACKAGE_RUNNER may differ in different environments.
+#   In this case, use "adb shell pm list instrumentation" to query available runners
+#   and use the environment variable INSTRUMENTED_PACKAGE_RUNNER to overwrite
+#   the default one, e.g.,
+#   INSTRUMENTED_PACKAGE_RUNNER=com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner \
+#       ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py
+#
 def main():
     build_top = os.environ.get('ANDROID_BUILD_TOP', None)
     out_dir = os.environ.get('OUT', None)
+    runner = os.environ.get('INSTRUMENTED_PACKAGE_RUNNER', None)
     if build_top is None or out_dir is None:
         print 'You need to source and lunch before you can use this script'
         return 1
-
+    if runner is None:
+        runner = INSTRUMENTED_PACKAGE_RUNNER
     print 'Building tests...'
     run('make -j32 -C %s -f build/core/main.mk '
         'MODULES-IN-frameworks-base-services-tests-servicestests' % build_top,
@@ -57,19 +69,19 @@
     apk_path = (
             '%s/data/app/FrameworksServicesTests/FrameworksServicesTests.apk' %
             out_dir)
-    run('adb install -r -g "%s"' % apk_path)
+    run('adb install -t -r -g "%s"' % apk_path)
 
     print 'Running tests...'
     if len(sys.argv) != 1:
         run('adb shell am instrument -w %s "%s"' %
-            (' '.join(sys.argv[1:]), INSTRUMENTED_PACKAGE_RUNNER))
+            (' '.join(sys.argv[1:]), runner))
         return 0
 
     # It would be nice if the activity manager accepted a list of packages, but
     # in lieu of that...
     for package in PACKAGE_WHITELIST:
         run('adb shell am instrument -w -e package %s %s' %
-            (package, INSTRUMENTED_PACKAGE_RUNNER))
+            (package, runner))
 
     return 0
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 17babe9..39b6391 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -26,13 +26,21 @@
 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
 import static android.net.NetworkPolicyManager.POLICY_NONE;
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.os.Process.SYSTEM_UID;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -125,6 +133,7 @@
 import android.text.format.Time;
 import android.util.DataUnit;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Range;
 import android.util.RecurrenceRule;
 
@@ -169,6 +178,7 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Iterator;
@@ -1642,6 +1652,76 @@
                 true);
     }
 
+    /**
+     * Exhaustively test isUidNetworkingBlocked to output the expected results based on external
+     * conditions.
+     */
+    @Test
+    public void testIsUidNetworkingBlocked() {
+        final ArrayList<Pair<Boolean, Integer>> expectedBlockedStates = new ArrayList<>();
+
+        // Metered network. Data saver on.
+        expectedBlockedStates.add(new Pair<>(true, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                true /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+
+        // Metered network. Data saver off.
+        expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                true /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+
+        // Non-metered network. Data saver on.
+        expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                false /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+
+        // Non-metered network. Data saver off. The result is the same as previous case since
+        // the network is blocked only for RULE_REJECT_ALL regardless of data saver.
+        verifyNetworkBlockedState(
+                false /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+    }
+
+    private void verifyNetworkBlockedState(boolean metered, boolean backgroundRestricted,
+            ArrayList<Pair<Boolean, Integer>> expectedBlockedStateForRules) {
+        final NetworkPolicyManagerInternal npmi = LocalServices
+                .getService(NetworkPolicyManagerInternal.class);
+
+        for (Pair<Boolean, Integer> pair : expectedBlockedStateForRules) {
+            final boolean expectedResult = pair.first;
+            final int rule = pair.second;
+            assertEquals(formatBlockedStateError(UID_A, rule, metered, backgroundRestricted),
+                    expectedResult,
+                    npmi.isUidNetworkingBlocked(UID_A, rule, metered, backgroundRestricted));
+            assertFalse(formatBlockedStateError(SYSTEM_UID, rule, metered, backgroundRestricted),
+                    npmi.isUidNetworkingBlocked(SYSTEM_UID, rule, metered, backgroundRestricted));
+        }
+    }
+
+    private String formatBlockedStateError(int uid, int rule, boolean metered,
+            boolean backgroundRestricted) {
+        return String.format(
+                "Unexpected BlockedState: (uid=%d, rule=%s, metered=%b, backgroundRestricted=%b)",
+                uid, uidRulesToString(rule), metered, backgroundRestricted);
+    }
+
     private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
         return SubscriptionPlan.Builder
                 .createRecurringMonthly(start)
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
index 089dc61..f741c70 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
@@ -16,16 +16,6 @@
 
 package com.android.server.am;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
 import android.app.ActivityOptions;
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
@@ -34,16 +24,26 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.server.am.LaunchParamsController.LaunchParams;
-
+import org.junit.runner.RunWith;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.doAnswer;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
 
 /**
  * Tests for exercising resizing bounds due to activity options.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityLaunchParamsModifierTests
+ *  atest FrameworksServicesTests:ActivityLaunchParamsModifierTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
similarity index 93%
rename from services/tests/wmtests/src/com/android/server/am/ActivityManagerInternalTest.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index f393d14..bce87dc 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -33,8 +33,17 @@
 /**
  * Test class for {@link ActivityManagerInternal}.
  *
- * Build/Install/Run:
- *  atest WmTests:ActivityManagerInternalTest
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.ActivityManagerInternalTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerInternalTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
 @RunWith(AndroidJUnit4.class)
 public class ActivityManagerInternalTest {
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/ActivityManagerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index c41197d..c70d1e1 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -28,7 +28,6 @@
 import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
 import static android.util.DebugUtils.valueToString;
-
 import static com.android.server.am.ActivityManagerInternalTest.CustomThread;
 import static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG;
 import static com.android.server.am.ActivityManagerService.Injector;
@@ -89,8 +88,17 @@
 /**
  * Test class for {@link ActivityManagerService}.
  *
- * Build/Install/Run:
- *  atest WmTests:ActivityManagerServiceTest
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -822,4 +830,4 @@
             mRestricted = restricted;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
similarity index 94%
rename from services/tests/wmtests/src/com/android/server/am/ActivityManagerTest.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index a2f942e..ba25b16 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -18,18 +18,13 @@
 
 import android.app.ActivityManager;
 import android.app.IActivityManager;
-import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.RemoteException;
 import android.test.AndroidTestCase;
 
 import java.util.List;
 
-/**
- * Tests for {@link ActivityManager}.
- *
- * Build/Install/Run:
- *  atest WmTests:ActivityManagerTest
- */
 public class ActivityManagerTest extends AndroidTestCase {
 
     IActivityManager service;
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/am/ActivityRecordTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index 616cc0f..5ee1c40 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -22,7 +22,11 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
@@ -53,16 +57,17 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.MutableBoolean;
 
-import org.junit.Before;
-import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 
 /**
  * Tests for the {@link ActivityRecord} class.
  *
  * Build/Install/Run:
- *  atest WmTests:com.android.server.am.ActivityRecordTests
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityRecordTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/am/ActivityStackSupervisorTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 2209b66..1ce41a6 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -62,7 +62,7 @@
  * Tests for the {@link ActivityStackSupervisor} class.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityStackSupervisorTests
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/ActivityStackTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index cac264b..01425ed 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -33,9 +33,13 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import android.content.pm.ActivityInfo;
 import android.os.UserHandle;
@@ -43,15 +47,15 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import org.junit.runner.RunWith;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Tests for the {@link ActivityStack} class.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityStackTests
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/ActivityStartControllerTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index 37a5a17..7948e4c 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -19,13 +19,6 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
 import android.content.Intent;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
@@ -34,8 +27,15 @@
 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
 import com.android.server.am.ActivityStarter.Factory;
 
-import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
 
 import java.util.Random;
 
@@ -43,7 +43,7 @@
  * Tests for the {@link ActivityStartController} class.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityStartControllerTests
+ *  atest FrameworksServicesTests:ActivityStartControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/ActivityStartInterceptorTest.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index 8f2d284..b4b34c5 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -55,7 +55,7 @@
  * Unit tests for {@link ActivityStartInterceptorTest}.
  *
  * Build/Install/Run:
- *  bit WmTests:ActivityStartInterceptorTest
+ *  bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
  */
 @SmallTest
 public class ActivityStartInterceptorTest {
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/ActivityStarterTests.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 048df43..1520859 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -32,26 +32,10 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
-
-import static com.android.server.am.ActivityManagerService.ANIMATE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyObject;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
 
 import android.app.ActivityOptions;
 import android.app.IApplicationThread;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo.WindowLayout;
@@ -66,18 +50,39 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.view.Gravity;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
+import static com.android.server.am.ActivityManagerService.ANIMATE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.am.ActivityStarter.Factory;
 import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
 import com.android.server.am.TaskRecord.TaskRecordFactory;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import java.util.ArrayList;
 
 /**
  * Tests for the {@link ActivityStarter} class.
  *
  * Build/Install/Run:
- *  atest WmTests:ActivityStarterTests
+ *  atest FrameworksServicesTests:ActivityStarterTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/am/ActivityTestsBase.java
rename to services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index d9a346b..1cd111f 100644
--- a/services/tests/wmtests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -21,17 +21,21 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.view.Display.DEFAULT_DISPLAY;
-
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.app.ActivityOptions;
+import com.android.server.wm.DisplayWindowController;
+
+import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+
 import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Context;
@@ -48,21 +52,20 @@
 import android.support.test.InstrumentationRegistry;
 import android.testing.DexmakerShareClassLoaderRule;
 
+
 import com.android.internal.app.IVoiceInteractor;
+
 import com.android.server.AttributeCache;
 import com.android.server.wm.AppWindowContainerController;
-import com.android.server.wm.DisplayWindowController;
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.StackWindowController;
 import com.android.server.wm.TaskWindowContainerController;
 import com.android.server.wm.WindowManagerService;
 import com.android.server.wm.WindowTestUtils;
-
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
+
 
 /**
  * A base class to handle common operations in activity related unit tests.
diff --git a/services/tests/wmtests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/am/AppErrorDialogTest.java
rename to services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
index 2289dfc..3d11c4c 100644
--- a/services/tests/wmtests/src/com/android/server/am/AppErrorDialogTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -32,10 +32,7 @@
 import java.io.File;
 
 /**
- * Tests for {@link AppErrorDialog}.
- *
- * Build/Install/Run:
- *  atest WmTests:AppErrorDialogTest
+ * runtest -c com.android.server.am.AppErrorDialogTest frameworks-services
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
diff --git a/services/tests/wmtests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/AssistDataRequesterTest.java
rename to services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index 285a84f..ce88d84 100644
--- a/services/tests/wmtests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -62,8 +62,7 @@
  * Note: Currently, we only support fetching the screenshot for the current application, so the
  * screenshot checks are hardcoded accordingly.
  *
- * Build/Install/Run:
- *  atest WmTests:AssistDataRequesterTest
+ * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
  */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/am/ClientLifecycleManagerTests.java b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
similarity index 66%
rename from services/tests/wmtests/src/com/android/server/am/ClientLifecycleManagerTests.java
rename to services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
index 3098db2..ef6d5e8 100644
--- a/services/tests/wmtests/src/com/android/server/am/ClientLifecycleManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
@@ -1,19 +1,3 @@
-/*
- * 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.am;
 
 import static org.mockito.Mockito.mock;
@@ -31,12 +15,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Test class for {@link ClientLifecycleManager}.
- *
- * Build/Install/Run:
- *  atest WmTests:ClientLifecycleManagerTests
- */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
similarity index 91%
rename from services/tests/wmtests/src/com/android/server/am/CoreSettingsObserverTest.java
rename to services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index adf3f94..da30c11 100644
--- a/services/tests/wmtests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -37,6 +37,7 @@
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -47,8 +48,17 @@
 /**
  * Test class for {@link CoreSettingsObserver}.
  *
- * Build/Install/Run:
- *  atest WmTests:CoreSettingsObserverTest
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.CoreSettingsObserverTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java b/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
rename to services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
index b1e0b51..d9b3e1c 100644
--- a/services/tests/wmtests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
@@ -36,9 +36,6 @@
 
 /**
  * Tests for {@link GlobalSettingsToPropertiesMapper}
- *
- * Build/Install/Run:
- *  atest WmTests:GlobalSettingsToPropertiesMapperTest
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
diff --git a/services/tests/wmtests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/am/LaunchParamsControllerTests.java
rename to services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
index 5f2bc4d..161c287 100644
--- a/services/tests/wmtests/src/com/android/server/am/LaunchParamsControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -16,14 +16,20 @@
 
 package com.android.server.am;
 
+import android.app.ActivityOptions;
+import android.content.pm.ActivityInfo.WindowLayout;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.am.LaunchParamsController.LaunchParams;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
+
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doNothing;
@@ -34,24 +40,18 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo.WindowLayout;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
 
-import com.android.server.am.LaunchParamsController.LaunchParams;
-import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
 /**
  * Tests for exercising {@link LaunchParamsController}.
  *
  * Build/Install/Run:
- *  atest WmTests:LaunchParamsControllerTests
+ *  atest FrameworksServicesTests:LaunchParamsControllerTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/am/LockTaskControllerTest.java
rename to services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
index a2e9769..f46d712 100644
--- a/services/tests/wmtests/src/com/android/server/am/LockTaskControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
@@ -35,20 +35,9 @@
 import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED;
 import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_PINNED;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
 
 import android.app.StatusBarManager;
 import android.app.admin.DevicePolicyManager;
@@ -87,7 +76,7 @@
  * Unit tests for {@link LockTaskController}.
  *
  * Build/Install/Run:
- *  bit WmTests:LockTaskControllerTest
+ *  bit FrameworksServicesTests:com.android.server.am.LockTaskControllerTest
  */
 @Presubmit
 @SmallTest
diff --git a/services/tests/wmtests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/am/MemoryStatUtilTest.java
rename to services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
index 18b0988..5518ca5 100644
--- a/services/tests/wmtests/src/com/android/server/am/MemoryStatUtilTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -16,9 +16,9 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.MemoryStatUtil.MemoryStat;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
+import static com.android.server.am.MemoryStatUtil.MemoryStat;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -29,12 +29,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Tests for {@link MemoryStatUtil}.
- *
- * Build/Install/Run:
- *  atest WmTests:MemoryStatUtilTest
- */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class MemoryStatUtilTest {
diff --git a/services/tests/wmtests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
rename to services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
index f812ee6..2baf995 100644
--- a/services/tests/wmtests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
@@ -20,11 +20,14 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import android.annotation.Nullable;
 import android.app.ActivityOptions;
+import android.os.Handler;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
 import android.view.RemoteAnimationAdapter;
 
 import com.android.server.testutils.OffsettableClock;
@@ -37,10 +40,7 @@
 import org.mockito.MockitoAnnotations;
 
 /**
- * Tests for {@link PendingRemoteAnimationRegistry}.
- *
- * Build/Install/Run:
- *  atest WmTests:PendingRemoteAnimationRegistryTest
+ * atest PendingRemoteAnimationRegistryTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/PersistentConnectionTest.java
rename to services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
index 5c42081..54f93a8 100644
--- a/services/tests/wmtests/src/com/android/server/am/PersistentConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.server.am;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -42,12 +41,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 
-/**
- * Tests for {@link PersistentConnection}.
- *
- * Build/Install/Run:
- *  atest WmTests:PersistentConnectionTest
- */
 @SmallTest
 public class PersistentConnectionTest extends AndroidTestCase {
     private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
diff --git a/services/tests/wmtests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/am/RecentTasksTest.java
rename to services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 739467a..b73ac89 100644
--- a/services/tests/wmtests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -35,12 +35,16 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 
 import static java.lang.Integer.MAX_VALUE;
 
+import android.annotation.TestApi;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RecentTaskInfo;
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -49,6 +53,7 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -75,10 +80,7 @@
 import java.util.Set;
 
 /**
- * Tests for {@link RecentTasks}.
- *
- * Build/Install/Run:
- *  atest WmTests:RecentTasksTest
+ * atest FrameworksServicesTests:RecentTasksTest
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
similarity index 93%
rename from services/tests/wmtests/src/com/android/server/am/RecentsAnimationTest.java
rename to services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
index ee576e3..eefd973 100644
--- a/services/tests/wmtests/src/com/android/server/am/RecentsAnimationTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
@@ -16,13 +16,15 @@
 
 package com.android.server.am;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
-
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -37,18 +39,13 @@
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.IRecentsAnimationRunner;
-
 import com.android.server.AttributeCache;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 /**
- * Tests for {@link RecentsAnimation}.
- *
- * Build/Install/Run:
- *  atest WmTests:RecentsAnimationTest
+ * atest FrameworksServicesTests:RecentsAnimationTest
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/RunningTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/am/RunningTasksTest.java
rename to services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
index 4e5fbd8..c6ce7e1 100644
--- a/services/tests/wmtests/src/com/android/server/am/RunningTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
@@ -41,11 +41,8 @@
 
 import java.util.ArrayList;
 
- /**
- * Tests for {@link RunningTasks}.
- *
- * Build/Install/Run:
- *  atest WmTests:RunningTasksTest
+/**
+ * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
  */
 @MediumTest
 @Presubmit
@@ -126,4 +123,4 @@
                 .build();
         return task;
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/am/SafeActivityOptionsTest.java b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
similarity index 92%
rename from services/tests/wmtests/src/com/android/server/am/SafeActivityOptionsTest.java
rename to services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
index 3f05c8c..168bc17 100644
--- a/services/tests/wmtests/src/com/android/server/am/SafeActivityOptionsTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
@@ -27,12 +27,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Tests for {@link SafeActivityOptions}.
- *
- * Build/Install/Run:
- *  atest WmTests:SafeActivityOptionsTest
- */
 @MediumTest
 @Presubmit
 @FlakyTest
diff --git a/services/tests/wmtests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
rename to services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
index 7fb63d3..3d323f0 100644
--- a/services/tests/wmtests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
@@ -16,29 +16,37 @@
 
 package com.android.server.am;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
-
-import static org.junit.Assert.assertEquals;
-
 import android.content.pm.ActivityInfo.WindowLayout;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
+
 import android.view.Gravity;
 
+import org.junit.runner.RunWith;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import org.mockito.invocation.InvocationOnMock;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.junit.Assert.assertEquals;
+
 
 /**
  * Tests for exercising resizing task bounds.
  *
  * Build/Install/Run:
- *  atest WmTests:TaskLaunchParamsModifierTests
+ *  atest FrameworksServicesTests:TaskLaunchParamsModifierTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
similarity index 93%
rename from services/tests/wmtests/src/com/android/server/am/TaskPersisterTest.java
rename to services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
index cdafb52..9e6055d 100644
--- a/services/tests/wmtests/src/com/android/server/am/TaskPersisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -17,16 +17,20 @@
 package com.android.server.am;
 
 import android.content.pm.UserInfo;
+import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.test.AndroidTestCase;
+import android.util.Log;
 import android.util.SparseBooleanArray;
 
+import com.android.server.am.TaskPersister;
+
+import java.io.File;
+import java.util.Random;
+
 /**
- * Tests for {@link TaskPersister}.
- *
- * Build/Install/Run:
- *  atest WmTests:TaskPersisterTest
+ * atest FrameworksServicesTests:TaskPersisterTest
  */
 public class TaskPersisterTest extends AndroidTestCase {
     private static final String TEST_USER_NAME = "AM-Test-User";
diff --git a/services/tests/wmtests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/am/TaskRecordTests.java
rename to services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
index dbb3e7e..057fdc8 100644
--- a/services/tests/wmtests/src/com/android/server/am/TaskRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -29,16 +29,20 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.res.XmlResourceParser;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.service.voice.IVoiceInteractionSession;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Xml;
 
+import com.android.frameworks.servicestests.R;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.server.am.TaskRecord.TaskRecordFactory;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -53,13 +57,15 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Reader;
+import java.nio.file.Files;
 import java.util.ArrayList;
+import java.util.Comparator;
 
 /**
  * Tests for exercising {@link TaskRecord}.
  *
  * Build/Install/Run:
- *  atest WmTests:TaskRecordTests
+ *  atest FrameworksServicesTests:com.android.server.am.TaskRecordTests
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/am/TaskStackChangedListenerTest.java
rename to services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index 28689cb..0359096 100644
--- a/services/tests/wmtests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -33,30 +32,23 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.res.Resources.Theme;
 import android.os.RemoteException;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiDevice;
 import android.text.TextUtils;
-
+import android.util.Pair;
 import com.android.internal.annotations.GuardedBy;
-
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link TaskStackListener}.
- *
- * Build/Install/Run:
- *  atest WmTests:TaskStackChangedListenerTest
- */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class TaskStackChangedListenerTest {
diff --git a/services/tests/wmtests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/am/UserControllerTest.java
rename to services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index fb5ded5..cc4f519 100644
--- a/services/tests/wmtests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -16,30 +16,6 @@
 
 package com.android.server.am;
 
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
-
-import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
-import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
-import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
-import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-
 import android.app.IUserSwitchObserver;
 import android.content.Context;
 import android.content.IIntentReceiver;
@@ -72,11 +48,30 @@
 import java.util.List;
 import java.util.Set;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
+import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
+import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
 /**
- * Tests for {@link UserController}.
- *
- * Build/Install/Run:
- *  atest WmTests:UserControllerTest
+ * Usage: bit FrameworksServicesTests:com.android.server.am.UserControllerTest
  */
 @Presubmit
 public class UserControllerTest extends AndroidTestCase {
diff --git a/services/tests/wmtests/src/com/android/server/policy/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/policy/FakeWindowState.java
rename to services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java
rename to services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
rename to services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTest.java
rename to services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
rename to services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
similarity index 89%
rename from services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
rename to services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
index a396946..164c80b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
@@ -18,10 +18,13 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
-
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
@@ -30,9 +33,12 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
 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;
 
@@ -40,7 +46,7 @@
  * Tests for the {@link TaskStack} class.
  *
  * Build/Install/Run:
- *  atest WmTests:AnimatingAppWindowTokenRegistryTest
+ *  atest FrameworksServicesTests:com.android.server.wm.AnimatingAppWindowTokenRegistryTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
rename to services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
index 6b3266d..be7d781 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -20,7 +20,6 @@
 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-
 import static org.junit.Assert.assertEquals;
 
 import android.content.Context;
@@ -37,8 +36,7 @@
 /**
  * Test class for {@link AppTransition}.
  *
- * Build/Install/Run:
- *  atest WmTests:AppTransitionTests
+ * atest AppTransitionTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/AppWindowContainerControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index 09a0847..e0645b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -16,32 +16,30 @@
 
 package com.android.server.wm;
 
+import android.support.test.filters.FlakyTest;
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.EMPTY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
-import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
 import com.android.server.wm.WindowTestUtils.TestTaskWindowContainerController;
 
-import org.junit.Test;
-
 /**
  * Test class for {@link AppWindowContainerController}.
  *
- * Build/Install/Run:
- *  atest WmTests:AppWindowContainerControllerTests
+ * atest FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
rename to services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 8dedb584a..f6599dc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -16,6 +16,16 @@
 
 package com.android.server.wm;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Surface;
+import android.view.WindowManager;
+
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
@@ -28,27 +38,15 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_UNSET;
-
 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 android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /**
  * Tests for the {@link AppWindowToken} class.
  *
  * Build/Install/Run:
- *  atest WmTests:AppWindowTokenTests
+ *  atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
  */
 @SmallTest
 // TODO: b/68267650
diff --git a/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 7fbb4ee..ff631e7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -21,12 +21,6 @@
 import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
 import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Rect;
@@ -38,12 +32,23 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.server.wm.BoundsAnimationController.BoundsAnimator;
 import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+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.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.server.wm.BoundsAnimationController.BoundsAnimator;
+
 /**
  * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
  * depending on the various interactions.
@@ -55,7 +60,7 @@
  * appropriately.
  *
  * Build/Install/Run:
- *  bit WmTests:BoundsAnimationControllerTests
+ *  bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
index 6a6f954..192e156 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -27,7 +28,6 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
 import static android.content.res.Configuration.EMPTY;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -35,7 +35,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -46,7 +45,7 @@
  * Test class for {@link ConfigurationContainer}.
  *
  * Build/Install/Run:
- *  atest WmTests:ConfigurationContainerTests
+ *  bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
index a12a802f..6769e40 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
@@ -38,10 +38,8 @@
 import org.junit.runner.RunWith;
 
 /**
- * Tests for {@link Dimmer}.
- *
  * Build/Install/Run:
- *  atest WmTests:DimmerTests;
+ * atest FrameworksServicesTests:com.android.server.wm.DimmerTests;
  */
 @Presubmit
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
rename to services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index a9744ea..ac196f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -28,7 +28,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
-
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static org.hamcrest.Matchers.is;
@@ -39,6 +38,9 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import android.annotation.SuppressLint;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -55,9 +57,6 @@
 
 import com.android.server.wm.utils.WmDisplayCutout;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -68,7 +67,7 @@
  * Tests for the {@link DisplayContent} class.
  *
  * Build/Install/Run:
- *  atest WmTests:DisplayContentTests
+ *  atest com.android.server.wm.DisplayContentTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
index 68b0998..a09656c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
@@ -19,7 +19,6 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
@@ -40,23 +39,19 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.View;
-
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.LocalServices;
-
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 /**
  * Tests for the {@link DragDropController} class.
  *
- * Build/Install/Run:
- *  atest WmTests:DragDropControllerTests
+ * atest com.android.server.wm.DragDropControllerTests
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/PinnedStackControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
similarity index 94%
rename from services/tests/wmtests/src/com/android/server/wm/PinnedStackControllerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
index f0faf28..96745fa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PinnedStackControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
@@ -2,15 +2,6 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
@@ -23,12 +14,15 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-/**
- * Tests for {@link PinnedStackController}.
- *
- * Build/Install/Run:
- *  atest WmTests:PinnedStackControllerTest
- */
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index fdebaa6..a2af9b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -19,10 +19,8 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.Display.DEFAULT_DISPLAY;
-
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
-
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
@@ -37,9 +35,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.view.IRecentsAnimationRunner;
 import android.view.SurfaceControl;
-
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,10 +43,7 @@
 import org.mockito.MockitoAnnotations;
 
 /**
- * Tests for {@link RecentsAnimationController}.
- *
- * Build/Install/Run:
- *  atest WmTests:RecentsAnimationControllerTest
+ * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 383e53f..95361f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -31,6 +31,7 @@
 import android.os.Binder;
 import android.os.IInterface;
 import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.IRemoteAnimationFinishedCallback;
@@ -52,10 +53,7 @@
 import org.mockito.MockitoAnnotations;
 
 /**
- * Tests for {@link RemoteAnimationController}.
- *
- * Build/Install/Run:
- *  atest WmTests:RemoteAnimationControllerTest
+ * atest FrameworksServicesTests:com.android.server.wm.RemoteAnimationControllerTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
index 317f36c..204e26c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -1,21 +1,22 @@
 package com.android.server.wm;
 
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import android.content.res.Configuration;
 import android.graphics.Rect;
+
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests for the {@link RootWindowContainer} class.
  *
  * Build/Install/Run:
- *  atest WmTests:RootWindowContainerTests
+ *  atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
rename to services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
index 7e7cfed..a2ccee4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -32,7 +32,6 @@
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
 import static org.junit.Assert.assertEquals;
 
 import android.app.Activity;
@@ -71,7 +70,7 @@
  * Tests for the {@link android.view.WindowManager.LayoutParams#PRIVATE_FLAG_IS_SCREEN_DECOR} flag.
  *
  * Build/Install/Run:
- *  atest WmTests:ScreenDecorWindowTests
+ *  atest FrameworksServicesTests:com.android.server.wm.ScreenDecorWindowTests
  */
 // TODO: Add test for FLAG_FULLSCREEN which hides the status bar and also other flags.
 // TODO: Test non-Activity windows.
diff --git a/services/tests/wmtests/src/com/android/server/wm/StackWindowControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/StackWindowControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
index fb2986c..ab0a2bd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StackWindowControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
@@ -16,24 +16,25 @@
 
 package com.android.server.wm;
 
+import android.graphics.Rect;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
 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 android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /**
  * Test class for {@link StackWindowController}.
  *
  * Build/Install/Run:
- *  atest WmTests:StackWindowControllerTests
+ *  atest FrameworksServicesTests:StackWindowControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index 9ea3702..edac8a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -23,11 +24,11 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import static java.util.concurrent.TimeUnit.SECONDS;
-
+import android.animation.AnimationHandler;
 import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
 import android.animation.ValueAnimator;
 import android.graphics.Matrix;
@@ -36,6 +37,7 @@
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 import android.view.Choreographer;
 import android.view.Choreographer.FrameCallback;
 import android.view.SurfaceControl;
@@ -44,6 +46,7 @@
 import android.view.animation.TranslateAnimation;
 
 import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
+import com.android.server.wm.SurfaceAnimationRunner.AnimatorFactory;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -58,8 +61,7 @@
 /**
  * Test class for {@link SurfaceAnimationRunner}.
  *
- * Build/Install/Run:
- *  atest WmTests:SurfaceAnimationRunnerTest
+ * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimationRunnerTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
rename to services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 66f4b194..16b8458 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -46,11 +46,12 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+
 /**
  * Test class for {@link SurfaceAnimatorTest}.
  *
- * Build/Install/Run:
- *  atest WmTests:SurfaceAnimatorTest
+ * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimatorTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
index ae73089..7bf7dd7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -16,14 +16,10 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
-import static com.android.server.wm.WindowManagerService.dipToPixel;
-import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
-import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import android.graphics.Rect;
 import android.support.test.filters.SmallTest;
@@ -32,16 +28,18 @@
 import android.util.Log;
 import android.view.Display;
 
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
+import static com.android.server.wm.WindowManagerService.dipToPixel;
+import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
+import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests for the {@link TaskPositioner} class.
  *
- * Build/Install/Run:
- *  atest WmTests:TaskPositionerTests
+ * runtest frameworks-services -c com.android.server.wm.TaskPositionerTests
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 659ec41..6070516 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -31,7 +30,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.InputChannel;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,8 +37,7 @@
 /**
  * Tests for the {@link TaskPositioningController} class.
  *
- * Build/Install/Run:
- *  atest WmTests:TaskPositioningControllerTests
+ * atest com.android.server.wm.TaskPositioningControllerTests
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index 1aefa277..649de4a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 
@@ -32,8 +31,7 @@
 /**
  * Test class for {@link TaskSnapshotCache}.
  *
- * Build/Install/Run:
- *  atest WmTests:TaskSnapshotCacheTest
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotCacheTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 77521a6..5650050 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -19,11 +19,10 @@
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.TRANSIT_UNSET;
-
-import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME;
-import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL;
-
+import static com.android.server.wm.TaskSnapshotController.*;
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
@@ -31,15 +30,13 @@
 import android.util.ArraySet;
 
 import com.google.android.collect.Sets;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 /**
  * Test class for {@link TaskSnapshotController}.
  *
- * Build/Install/Run:
- *  atest WmTests:TaskSnapshotControllerTest
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotControllerTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index ed81daf..325d42a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -18,12 +18,12 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 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.app.ActivityManager.TaskSnapshot;
 import android.content.res.Configuration;
@@ -33,8 +33,8 @@
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArraySet;
-import android.view.View;
 
+import android.view.View;
 import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
 
 import org.junit.Test;
@@ -45,8 +45,7 @@
 /**
  * Test class for {@link TaskSnapshotPersister} and {@link TaskSnapshotLoader}
  *
- * Build/Install/Run:
- *  atest WmTests:TaskSnapshotPersisterLoaderTest
+ * atest FrameworksServicesTests:TaskSnapshotPersisterLoaderTest
  */
 @MediumTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 287fff5..b19373e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -19,7 +19,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -48,8 +47,7 @@
 /**
  * Test class for {@link TaskSnapshotSurface}.
  *
- * Build/Install/Run:
- *  atest WmTests:TaskSnapshotSurfaceTest
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotSurfaceTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
index e66b0d9..ca1994f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -18,25 +18,26 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.After;
+
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /**
  * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
  *
  * Build/Install/Run:
- *  atest WmTests:TaskStackContainersTests
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
index 0deb4af..eaf71f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -16,24 +16,27 @@
 
 package com.android.server.wm;
 
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests for the {@link TaskStack} class.
  *
  * Build/Install/Run:
- *  atest WmTests:TaskStackTests
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskStackTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
index e734bc0..1dd9365 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
@@ -16,23 +16,22 @@
 
 package com.android.server.wm;
 
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 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 android.platform.test.annotations.Presubmit;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /**
  * Test class for {@link TaskWindowContainerController}.
  *
  * Build/Install/Run:
- *  atest WmTests:TaskWindowContainerControllerTests
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
rename to services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
index 032f416..353aa7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import com.android.internal.os.IResultReceiver;
+
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -25,8 +27,6 @@
 import android.view.DragEvent;
 import android.view.IWindow;
 
-import com.android.internal.os.IResultReceiver;
-
 public class TestIWindow extends IWindow.Stub {
     @Override
     public void executeCommand(String command, String parameters,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
rename to services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 903352b..a5c47de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -29,8 +29,7 @@
 /**
  * Test class for {@link AppTransition}.
  *
- * Build/Install/Run:
- *  atest WmTests:UnknownAppVisibilityControllerTest
+ * runtest frameworks-services -c com.android.server.wm.UnknownAppVisibilityControllerTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/WindowAnimationSpecTest.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
index aac905e..ca520ed 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowAnimationSpecTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
@@ -40,8 +40,7 @@
 /**
  * Tests for the {@link WindowAnimationSpec} class.
  *
- * Build/Install/Run:
- *  atest WmTests:WindowAnimationSpecTest
+ *  atest FrameworksServicesTests:com.android.server.wm.WindowAnimationSpecTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
index 9c59a17..513c1ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -16,16 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
-import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
-import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import org.junit.Test;
 
 import android.app.WindowConfiguration;
 import android.content.res.Configuration;
@@ -36,13 +27,22 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.view.DisplayInfo;
 
-import org.junit.Test;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
+import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
+import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test class to for {@link android.app.WindowConfiguration}.
  *
  * Build/Install/Run:
- *  atest WmTests:WindowConfigurationTests
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
index 05f7c34..502cb6e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -16,26 +16,26 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.content.res.Configuration.EMPTY;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
+import android.app.WindowConfiguration;
 import android.content.res.Configuration;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.FlakyTest;
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Test;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.content.res.Configuration.EMPTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test class for {@link WindowContainerController}.
  *
  * Build/Install/Run:
- *  atest WmTests:WindowContainerControllerTests
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 5beeee1..6c7830e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -16,6 +16,20 @@
 
 package com.android.server.wm;
 
+import android.support.test.filters.FlakyTest;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Comparator;
+
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
@@ -30,6 +44,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyFloat;
 import static org.mockito.Mockito.eq;
@@ -38,25 +53,11 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Comparator;
-
 /**
  * Test class for {@link WindowContainer}.
  *
  * Build/Install/Run:
- *  atest WmTests:WindowContainerTests
+ *  atest FrameworksServicesTests:com.android.server.wm.WindowContainerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
index e1acd78..e076399 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -20,10 +20,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-
-import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.eq;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
@@ -32,13 +31,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.mockito.Mock;
+
 import java.util.function.Consumer;
 
 /**
  * Tests for {@link WindowContainer#forAllWindows} and various implementations.
- *
- * Build/Install/Run:
- *  atest WmTests:WindowContainerTraversalTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 6a00de4..5a56332 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -16,12 +16,9 @@
 
 package com.android.server.wm;
 
-import static android.view.DisplayCutout.fromBoundingRect;
-import static android.view.WindowManager.LayoutParams.FILL_PARENT;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
@@ -34,17 +31,18 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
-import com.android.server.wm.utils.WmDisplayCutout;
+import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.FILL_PARENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import com.android.server.wm.utils.WmDisplayCutout;
 
 /**
  * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
  *
- * Build/Install/Run:
- *  atest WmTests:WindowFrameTests
+ * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRuleTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 0f07e7e..85e846d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -16,6 +16,17 @@
 
 package com.android.server.wm;
 
+import android.view.WindowManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.LinkedList;
+
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -44,22 +55,10 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.WindowManager;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.LinkedList;
-
 /**
  * Tests for the {@link WindowState} class.
  *
- * Build/Install/Run:
- *  atest WmTests:WindowStateTests
+ * atest FrameworksServicesTests:com.android.server.wm.WindowStateTests
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowSurfacePlacerTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/WindowSurfacePlacerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
index 13f7916..e173b7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowSurfacePlacerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
@@ -20,7 +20,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
-
 import static junit.framework.Assert.assertEquals;
 
 import android.platform.test.annotations.Presubmit;
@@ -32,12 +31,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Tests for {@link WindowSurfacePlacer}.
- *
- * Build/Install/Run:
- *  atest WmTests:WindowSurfacePlacerTest
- */
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
similarity index 99%
rename from services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index 6ab9c30..2e4740b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -16,21 +16,8 @@
 
 package com.android.server.wm;
 
-import static android.app.AppOpsManager.OP_NONE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyFloat;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import android.app.ActivityManager;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -39,6 +26,19 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import org.mockito.invocation.InvocationOnMock;
 
 /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
similarity index 100%
rename from services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index 5ea87b1..e3b7174 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -16,29 +16,29 @@
 
 package com.android.server.wm;
 
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
 
 /**
  * Tests for the {@link WindowToken} class.
  *
  * Build/Install/Run:
- *  atest WmTests:WindowTokenTests
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
similarity index 97%
rename from services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
rename to services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
index f60ae75..5085254 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
@@ -30,12 +30,13 @@
 import android.content.Context;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
+import android.support.test.filters.FlakyTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.Preconditions;
+import com.android.server.wm.WindowManagerTraceProto;
 
 import org.junit.After;
 import org.junit.Before;
@@ -53,7 +54,7 @@
  * Test class for {@link WindowTracing}.
  *
  * Build/Install/Run:
- *  atest WmTests:WindowTracingTest
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowTracingTest
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
rename to services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
index a730b5c..547be55 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
@@ -27,14 +27,15 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
 
 import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
+import android.support.test.filters.FlakyTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -50,7 +51,7 @@
  * Tests for the {@link WindowLayersController} class.
  *
  * Build/Install/Run:
- *  atest WmTests:ZOrderingTests
+ *  bit FrameworksServicesTests:com.android.server.wm.ZOrderingTests
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/CoordinateTransformsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
similarity index 91%
rename from services/tests/wmtests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
rename to services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
index f0f3023..40a10e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
@@ -21,11 +21,10 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
-import static com.android.server.wm.utils.CoordinateTransforms
-        .transformPhysicalToLogicalCoordinates;
+import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
 
 import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import static org.junit.Assert.*;
 
 import android.graphics.Matrix;
 import android.graphics.Point;
@@ -36,12 +35,6 @@
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
 
-/**
- * Tests for {@link CoordinateTransforms}.
- *
- * Build/Install/Run:
- *  atest WmTests:CoordinateTransformsTest
- */
 public class CoordinateTransformsTest {
 
     private static final int W = 200;
@@ -102,4 +95,4 @@
     public interface DevicePointAssertable {
         void mapsToLogicalPoint(int x, int y);
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
similarity index 92%
rename from services/tests/wmtests/src/com/android/server/wm/utils/InsetUtilsTest.java
rename to services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
index ff3d883..d0f0fe3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/InsetUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
@@ -22,16 +22,11 @@
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Tests for {@link InsetUtils}.
- *
- * Build/Install/Run:
- *  atest WmTests:InsetUtilsTest
- */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
similarity index 96%
rename from services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
rename to services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
index c800fa2..6bbc7eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -29,16 +29,13 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Pair;
 
+import com.android.server.wm.utils.RotationCache.RotationDependentComputation;
+
+import org.hamcrest.Matchers;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-/**
- * Tests for {@link RotationCache}.
- *
- * Build/Install/Run:
- *  atest WmTests:RotationCacheTest
- */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @FlakyTest(bugId = 74078662)
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
similarity index 98%
rename from services/tests/wmtests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
rename to services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
index f4c208b..f7addf6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm.utils;
 
+
 import static android.view.DisplayCutout.NO_CUTOUT;
 import static android.view.DisplayCutout.fromBoundingRect;
 
@@ -37,8 +38,7 @@
 /**
  * Tests for {@link WmDisplayCutout}
  *
- * Build/Install/Run:
- *  atest WmTests:WmDisplayCutoutTest
+ * Run with: atest WmDisplayCutoutTest
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
index 942a07a..96ac935 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
@@ -121,7 +121,7 @@
         cal.set(Calendar.MINUTE, 15);
         cal.set(Calendar.SECOND, 0);
         cal.set(Calendar.MILLISECOND, 0);
-        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
+        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 1;
         mScheduleInfo.endHour = 3;
         mScheduleInfo.startMinute = 15;
@@ -149,7 +149,7 @@
         cal.set(Calendar.MINUTE, 15);
         cal.set(Calendar.SECOND, 0);
         cal.set(Calendar.MILLISECOND, 0);
-        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
+        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 22;
         mScheduleInfo.endHour = 3;
         mScheduleInfo.startMinute = 15;
@@ -250,7 +250,7 @@
         calAlarm.add(Calendar.DATE, 1); // add a day
 
         // ScheduleInfo: day 1, day 2: 9pm-7am
-        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
+        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 21;
         mScheduleInfo.endHour = 7;
         mScheduleInfo.startMinute = 0;
@@ -418,7 +418,7 @@
         now.set(Calendar.MILLISECOND, 0);
         now.add(Calendar.DATE, 1); // add a day
 
-        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
+        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 22;
         mScheduleInfo.startMinute = 15;
         mScheduleInfo.endHour = 3;
@@ -446,7 +446,7 @@
         now.set(Calendar.MILLISECOND, 0);
         now.add(Calendar.DATE, 1); // add a day
 
-        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
+        mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 22;
         mScheduleInfo.startMinute = 15;
         mScheduleInfo.endHour = 3;
@@ -464,4 +464,10 @@
     private int getTodayDay() {
         return new GregorianCalendar().get(Calendar.DAY_OF_WEEK);
     }
+
+    private int getTodayDay(int offset) {
+        Calendar cal = new GregorianCalendar();
+        cal.add(Calendar.DATE, offset);
+        return cal.get(Calendar.DAY_OF_WEEK);
+    }
 }
diff --git a/services/tests/wmtests/Android.mk b/services/tests/wmtests/Android.mk
index cd28974..0f8b18a 100644
--- a/services/tests/wmtests/Android.mk
+++ b/services/tests/wmtests/Android.mk
@@ -14,14 +14,9 @@
     $(call all-java-files-under, ../servicestests/utils)
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    frameworks-base-testutils \
-    services.core \
-    android-support-test \
+    androidx-test \
     mockito-target-minus-junit4 \
     platform-test-annotations \
-    truth-prebuilt \
-    testables \
-    ub-uiautomator \
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.mock \
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 7e4bd42..1fb9473 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -22,30 +22,10 @@
         android:minSdkVersion="1"
         android:targetSdkVersion="28" />
 
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-    <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
-    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
-    <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
-    <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
-    <uses-permission android:name="android.permission.REORDER_TASKS" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-
-    <application android:testOnly="true">
-        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityA" />
-        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityB" />
-        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" />
-        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" />
-        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" />
-        <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity" />
-    </application>
+    <application android:testOnly="true" />
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="androidx.test.runner.AndroidJUnitRunner"
         android:label="Window Manager Tests"
         android:targetPackage="com.android.frameworks.wmtests" />
 </manifest>
diff --git a/services/tests/wmtests/AndroidTest.xml b/services/tests/wmtests/AndroidTest.xml
index 38a62ae..2717ef90 100644
--- a/services/tests/wmtests/AndroidTest.xml
+++ b/services/tests/wmtests/AndroidTest.xml
@@ -24,9 +24,9 @@
     </target_preparer>
 
     <option name="test-tag" value="WmTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.frameworks.wmtests" />
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false" />
     </test>
 </configuration>
diff --git a/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java b/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java
new file mode 100644
index 0000000..023e4ab
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java
@@ -0,0 +1,46 @@
+/*
+ * 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.am;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import androidx.test.filters.FlakyTest;
+
+/**
+ * Dummy test for com.android.server.am.
+ * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests.
+ */
+public class DummyAmTests {
+
+    @Presubmit
+    @Test
+    public void preSubmitTest() {}
+
+    @FlakyTest
+    @Presubmit
+    @Test
+    public void flakyPreSubmitTest() {}
+
+    @Test
+    public void postSubmitTest() {}
+
+    @FlakyTest
+    @Test
+    public void flakyPostSubmitTest() {}
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java b/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java
new file mode 100644
index 0000000..aecb278
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wm;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import androidx.test.filters.FlakyTest;
+
+/**
+ * Dummy test for com.android.server.wm
+ * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests.
+ */
+public class DummyWmTests {
+
+    @Presubmit
+    @Test
+    public void preSubmitTest() {}
+
+    @FlakyTest
+    @Presubmit
+    @Test
+    public void flakyPreSubmitTest() {}
+
+    @Test
+    public void postSubmitTest() {}
+
+    @FlakyTest
+    @Test
+    public void flakyPostSubmitTest() {}
+}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 36f8063..4da7285 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -539,7 +539,8 @@
             // We do not show the USB notification if the primary volume supports mass storage.
             // The legacy mass storage UI will be used instead.
             final StorageManager storageManager = StorageManager.from(mContext);
-            final StorageVolume primary = storageManager.getPrimaryVolume();
+            final StorageVolume primary =
+                    storageManager != null ? storageManager.getPrimaryVolume() : null;
 
             boolean massStorageSupported = primary != null && primary.allowMassStorage();
             mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean(
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING
new file mode 100644
index 0000000..8c9d4df
--- /dev/null
+++ b/startop/iorap/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "libiorap-java-tests"
+    }
+  ],
+  "imports": [
+    {
+      "path": "system/iorap"
+    }
+  ]
+}
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
new file mode 100644
index 0000000..f83a16e
--- /dev/null
+++ b/startop/iorap/tests/AndroidTest.xml
@@ -0,0 +1,41 @@
+<?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 libiorap-java-tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="libiorap-java-tests.apk" />
+    </target_preparer>
+
+    <!--
+      Our IIorapIntegrationTest.kt requires setlinux to be disabled:
+      it connects to the iorapd binder service but this requires selinux permissions:
+
+      avc:  denied  { find } for service=iorapd pid=2738 uid=10050
+        scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0
+        tclass=service_manager permissive=0
+    -->
+    <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.google.android.startop.iorap.tests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
+
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
index 4ba44a9..16dcbe2 100644
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
@@ -77,17 +77,21 @@
             inOrder.verifyNoMoreInteractions()
 
         } finally {
-            iorapService.setTaskListener(null)
+            // iorapService.setTaskListener(null)
+            // FIXME: null is broken, C++ side sees a non-null object.
         }
     }
 
     @Test
     fun testOnPackageEvent() {
+        /*
         testAnyMethod { requestId : RequestId ->
             iorapService.onPackageEvent(requestId,
                     PackageEvent.createReplaced(
                             Uri.parse("https://www.google.com"), "com.fake.package"))
         }
+        */
+        // FIXME: Broken for some reason. C++ side never sees this call.
     }
 
     @Test
diff --git a/startop/tools/view_compiler/Android.bp b/startop/tools/view_compiler/Android.bp
index c3e9184..3681529 100644
--- a/startop/tools/view_compiler/Android.bp
+++ b/startop/tools/view_compiler/Android.bp
@@ -14,19 +14,30 @@
 // limitations under the License.
 //
 
+cc_defaults {
+    name: "viewcompiler_defaults",
+    shared_libs: [
+        "libdexfile",
+        "slicer",
+    ],
+}
+
 cc_library_host_static {
     name: "libviewcompiler",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
+        "dex_builder.cc",
         "java_lang_builder.cc",
         "util.cc",
     ],
     static_libs: [
-        "libbase"
-    ]
+        "libbase",
+    ],
 }
 
 cc_binary_host {
     name: "viewcompiler",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
         "main.cc",
     ],
@@ -40,10 +51,12 @@
 
 cc_test_host {
     name: "view-compiler-tests",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
+        "dex_builder_test.cc",
         "util_test.cc",
     ],
     static_libs: [
         "libviewcompiler",
-    ]
+    ],
 }
diff --git a/startop/tools/view_compiler/dex_builder.cc b/startop/tools/view_compiler/dex_builder.cc
new file mode 100644
index 0000000..7a9f41f
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder.cc
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+#include "dex_builder.h"
+
+#include "dex/descriptors_names.h"
+#include "dex/dex_instruction.h"
+
+#include <fstream>
+#include <memory>
+
+namespace startop {
+namespace dex {
+
+using std::shared_ptr;
+using std::string;
+
+using art::Instruction;
+using ::dex::kAccPublic;
+
+const TypeDescriptor TypeDescriptor::Int() { return TypeDescriptor{"I"}; };
+const TypeDescriptor TypeDescriptor::Void() { return TypeDescriptor{"V"}; };
+
+namespace {
+// From https://source.android.com/devices/tech/dalvik/dex-format#dex-file-magic
+constexpr uint8_t kDexFileMagic[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x38, 0x00};
+
+// Strings lengths can be 32 bits long, but encoded as LEB128 this can take up to five bytes.
+constexpr size_t kMaxEncodedStringLength{5};
+
+}  // namespace
+
+void* TrackingAllocator::Allocate(size_t size) {
+  std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
+  void* raw_buffer = buffer.get();
+  allocations_[raw_buffer] = std::move(buffer);
+  return raw_buffer;
+}
+
+void TrackingAllocator::Free(void* ptr) { allocations_.erase(allocations_.find(ptr)); }
+
+// Write out a DEX file that is basically:
+//
+// package dextest;
+// public class DexTest {
+//     public static int foo() { return 5; }
+// }
+void WriteTestDexFile(const string& filename) {
+  DexBuilder dex_file;
+
+  ClassBuilder cbuilder{dex_file.MakeClass("dextest.DexTest")};
+  cbuilder.set_source_file("dextest.java");
+
+  MethodBuilder method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Int()})};
+
+  MethodBuilder::Register r = method.MakeRegister();
+  method.BuildConst4(r, 5);
+  method.BuildReturn(r);
+
+  method.Encode();
+
+  slicer::MemView image{dex_file.CreateImage()};
+
+  std::ofstream out_file(filename);
+  out_file.write(image.ptr<const char>(), image.size());
+}
+
+DexBuilder::DexBuilder() : dex_file_{std::make_shared<ir::DexFile>()} {
+  dex_file_->magic = slicer::MemView{kDexFileMagic, sizeof(kDexFileMagic)};
+}
+
+slicer::MemView DexBuilder::CreateImage() {
+  ::dex::Writer writer(dex_file_);
+  size_t image_size{0};
+  ::dex::u1* image = writer.CreateImage(&allocator_, &image_size);
+  return slicer::MemView{image, image_size};
+}
+
+ir::String* DexBuilder::GetOrAddString(const std::string& string) {
+  ir::String*& entry = strings_[string];
+
+  if (entry == nullptr) {
+    // Need to encode the length and then write out the bytes, including 1 byte for null terminator
+    auto buffer = std::make_unique<uint8_t[]>(string.size() + kMaxEncodedStringLength + 1);
+    uint8_t* string_data_start = ::dex::WriteULeb128(buffer.get(), string.size());
+
+    size_t header_length =
+        reinterpret_cast<uintptr_t>(string_data_start) - reinterpret_cast<uintptr_t>(buffer.get());
+
+    auto end = std::copy(string.begin(), string.end(), string_data_start);
+    *end = '\0';
+
+    entry = Alloc<ir::String>();
+    // +1 for null terminator
+    entry->data = slicer::MemView{buffer.get(), header_length + string.size() + 1};
+    string_data_.push_back(std::move(buffer));
+  }
+  return entry;
+}
+
+ClassBuilder DexBuilder::MakeClass(const std::string& name) {
+  auto* class_def = Alloc<ir::Class>();
+  ir::Type* type_def = GetOrAddType(art::DotToDescriptor(name.c_str()));
+  type_def->class_def = class_def;
+
+  class_def->type = type_def;
+  class_def->super_class = GetOrAddType(art::DotToDescriptor("java.lang.Object"));
+  class_def->access_flags = kAccPublic;
+  return ClassBuilder{this, class_def};
+}
+
+// TODO(eholk): we probably want GetOrAddString() also
+ir::Type* DexBuilder::GetOrAddType(const std::string& descriptor) {
+  if (types_by_descriptor_.find(descriptor) != types_by_descriptor_.end()) {
+    return types_by_descriptor_[descriptor];
+  }
+
+  ir::Type* type = Alloc<ir::Type>();
+  type->descriptor = GetOrAddString(descriptor);
+  types_by_descriptor_[descriptor] = type;
+  return type;
+}
+
+ir::Proto* Prototype::Encode(DexBuilder* dex) const {
+  auto* proto = dex->Alloc<ir::Proto>();
+  proto->shorty = dex->GetOrAddString(Shorty());
+  proto->return_type = dex->GetOrAddType(return_type_.descriptor());
+  if (param_types_.size() > 0) {
+    proto->param_types = dex->Alloc<ir::TypeList>();
+    for (const auto& param_type : param_types_) {
+      proto->param_types->types.push_back(dex->GetOrAddType(param_type.descriptor()));
+    }
+  } else {
+    proto->param_types = nullptr;
+  }
+  return proto;
+}
+
+std::string Prototype::Shorty() const {
+  std::string shorty;
+  shorty.append(return_type_.short_descriptor());
+  for (const auto& type_descriptor : param_types_) {
+    shorty.append(type_descriptor.short_descriptor());
+  }
+  return shorty;
+}
+
+ClassBuilder::ClassBuilder(DexBuilder* parent, ir::Class* class_def)
+    : parent_(parent), class_(class_def) {}
+
+MethodBuilder ClassBuilder::CreateMethod(const std::string& name, Prototype prototype) {
+  ir::String* dex_name{parent_->GetOrAddString(name)};
+
+  auto* decl = parent_->Alloc<ir::MethodDecl>();
+  decl->name = dex_name;
+  decl->parent = class_->type;
+  decl->prototype = prototype.Encode(parent_);
+
+  return MethodBuilder{parent_, class_, decl};
+}
+
+void ClassBuilder::set_source_file(const string& source) {
+  class_->source_file = parent_->GetOrAddString(source);
+}
+
+MethodBuilder::MethodBuilder(DexBuilder* dex, ir::Class* class_def, ir::MethodDecl* decl)
+    : dex_{dex}, class_{class_def}, decl_{decl} {}
+
+ir::EncodedMethod* MethodBuilder::Encode() {
+  auto* method = dex_->Alloc<ir::EncodedMethod>();
+  method->decl = decl_;
+
+  // TODO: make access flags configurable
+  method->access_flags = kAccPublic | ::dex::kAccStatic;
+
+  auto* code = dex_->Alloc<ir::Code>();
+  code->registers = num_registers_;
+  // TODO: support ins and outs
+  code->instructions = slicer::ArrayView<const ::dex::u2>(buffer_.data(), buffer_.size());
+  method->code = code;
+
+  class_->direct_methods.push_back(method);
+
+  return method;
+}
+
+MethodBuilder::Register MethodBuilder::MakeRegister() { return num_registers_++; }
+
+void MethodBuilder::BuildReturn() { buffer_.push_back(Instruction::RETURN_VOID); }
+
+void MethodBuilder::BuildReturn(Register src) { buffer_.push_back(Instruction::RETURN | src << 8); }
+
+void MethodBuilder::BuildConst4(Register target, int value) {
+  DCHECK_LT(value, 16);
+  // TODO: support more registers
+  DCHECK_LT(target, 16);
+  buffer_.push_back(Instruction::CONST_4 | (value << 12) | (target << 8));
+}
+
+}  // namespace dex
+}  // namespace startop
diff --git a/startop/tools/view_compiler/dex_builder.h b/startop/tools/view_compiler/dex_builder.h
new file mode 100644
index 0000000..d280abc
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder.h
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+#ifndef DEX_BUILDER_H_
+#define DEX_BUILDER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "slicer/dex_ir.h"
+#include "slicer/writer.h"
+
+namespace startop {
+namespace dex {
+
+// TODO: remove this once the dex generation code is complete.
+void WriteTestDexFile(const std::string& filename);
+
+//////////////////////////
+// Forward declarations //
+//////////////////////////
+class DexBuilder;
+
+// Our custom allocator for dex::Writer
+//
+// This keeps track of all allocations and ensures they are freed when
+// TrackingAllocator is destroyed. Pointers to memory allocated by this
+// allocator must not outlive the allocator.
+class TrackingAllocator : public ::dex::Writer::Allocator {
+ public:
+  virtual void* Allocate(size_t size);
+  virtual void Free(void* ptr);
+
+ private:
+  std::map<void*, std::unique_ptr<uint8_t[]>> allocations_;
+};
+
+// Represents a DEX type descriptor.
+//
+// TODO: add a way to create a descriptor for a reference of a class type.
+class TypeDescriptor {
+ public:
+  // Named constructors for base type descriptors.
+  static const TypeDescriptor Int();
+  static const TypeDescriptor Void();
+
+  // Return the full descriptor, such as I or Ljava/lang/Object
+  const std::string& descriptor() const { return descriptor_; }
+  // Return the shorty descriptor, such as I or L
+  std::string short_descriptor() const { return descriptor().substr(0, 1); }
+
+ private:
+  TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
+
+  const std::string descriptor_;
+};
+
+// Defines a function signature. For example, Prototype{TypeDescriptor::VOID, TypeDescriptor::Int}
+// represents the function type (Int) -> Void.
+class Prototype {
+ public:
+  template <typename... TypeDescriptors>
+  Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
+      : return_type_{return_type}, param_types_{param_types...} {}
+
+  // Encode this prototype into the dex file.
+  ir::Proto* Encode(DexBuilder* dex) const;
+
+  // Get the shorty descriptor, such as VII for (Int, Int) -> Void
+  std::string Shorty() const;
+
+ private:
+  const TypeDescriptor return_type_;
+  const std::vector<TypeDescriptor> param_types_;
+};
+
+// Tools to help build methods and their bodies.
+class MethodBuilder {
+ public:
+  MethodBuilder(DexBuilder* dex, ir::Class* class_def, ir::MethodDecl* decl);
+
+  // Encode the method into DEX format.
+  ir::EncodedMethod* Encode();
+
+  // Registers are just represented by their number.
+  using Register = size_t;
+
+  // Create a new register to be used to storing values. Note that these are not SSA registers, like
+  // might be expected in similar code generators. This does no liveness tracking or anything, so
+  // it's up to the caller to reuse registers as appropriate.
+  Register MakeRegister();
+
+  /////////////////////////////////
+  // Instruction builder methods //
+  /////////////////////////////////
+
+  // return-void
+  void BuildReturn();
+  void BuildReturn(Register src);
+  // const/4
+  void BuildConst4(Register target, int value);
+
+  // TODO: add builders for more instructions
+
+ private:
+  DexBuilder* dex_;
+  ir::Class* class_;
+  ir::MethodDecl* decl_;
+
+  // A buffer to hold instructions we are generating.
+  std::vector<::dex::u2> buffer_;
+
+  // How many registers we've allocated
+  size_t num_registers_;
+};
+
+// A helper to build class definitions.
+class ClassBuilder {
+ public:
+  ClassBuilder(DexBuilder* parent, ir::Class* class_def);
+
+  void set_source_file(const std::string& source);
+
+  // Create a method with the given name and prototype. The returned MethodBuilder can be used to
+  // fill in the method body.
+  MethodBuilder CreateMethod(const std::string& name, Prototype prototype);
+
+ private:
+  DexBuilder* parent_;
+  ir::Class* class_;
+};
+
+// Builds Dex files from scratch.
+class DexBuilder {
+ public:
+  DexBuilder();
+
+  // Create an in-memory image of the DEX file that can either be loaded directly or written to a
+  // file.
+  slicer::MemView CreateImage();
+
+  template <typename T>
+  T* Alloc() {
+    return dex_file_->Alloc<T>();
+  }
+
+  // Find the ir::String that matches the given string, creating it if it does not exist.
+  ir::String* GetOrAddString(const std::string& string);
+  // Create a new class of the given name.
+  ClassBuilder MakeClass(const std::string& name);
+
+  // Add a type for the given descriptor, or return the existing one if it already exists.
+  // See the TypeDescriptor class for help generating these.
+  ir::Type* GetOrAddType(const std::string& descriptor);
+
+ private:
+  std::shared_ptr<ir::DexFile> dex_file_;
+
+  // allocator_ is needed to be able to encode the image.
+  TrackingAllocator allocator_;
+
+  // We'll need to allocate buffers for all of the encoded strings we create. This is where we store
+  // all of them.
+  std::vector<std::unique_ptr<uint8_t[]>> string_data_;
+
+  // Keep track of what types we've defined so we can look them up later.
+  std::map<std::string, ir::Type*> types_by_descriptor_;
+
+  // Keep track of what strings we've defined so we can look them up later.
+  std::map<std::string, ir::String*> strings_;
+};
+
+}  // namespace dex
+}  // namespace startop
+
+#endif  // DEX_BUILDER_H_
diff --git a/startop/tools/view_compiler/dex_builder_test.cc b/startop/tools/view_compiler/dex_builder_test.cc
new file mode 100644
index 0000000..0d8b854
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder_test.cc
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "dex_builder.h"
+
+#include "dex/art_dex_file_loader.h"
+#include "dex/dex_file.h"
+#include "gtest/gtest.h"
+
+using namespace startop::dex;
+
+// Takes a DexBuilder, encodes it into an in-memory DEX file, verifies the resulting DEX file and
+// returns whether the verification was successful.
+bool EncodeAndVerify(DexBuilder* dex_file) {
+  slicer::MemView image{dex_file->CreateImage()};
+
+  art::ArtDexFileLoader loader;
+  std::string error_msg;
+  std::unique_ptr<const art::DexFile> loaded_dex_file{loader.Open(image.ptr<const uint8_t>(),
+                                                                  image.size(),
+                                                                  /*location=*/"",
+                                                                  /*location_checksum=*/0,
+                                                                  /*oat_dex_file=*/nullptr,
+                                                                  /*verify=*/true,
+                                                                  /*verify_checksum=*/false,
+                                                                  &error_msg)};
+  return loaded_dex_file != nullptr;
+}
+
+TEST(DexBuilderTest, VerifyDexWithClassMethod) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  auto method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Void()})};
+  method.BuildReturn();
+  method.Encode();
+
+  EXPECT_TRUE(EncodeAndVerify(&dex_file));
+}
+
+// Makes sure a bad DEX class fails to verify.
+TEST(DexBuilderTest, VerifyBadDexWithClassMethod) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  // This method has the error, because methods cannot take Void() as a parameter.
+  auto method{
+      cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Void(), TypeDescriptor::Void()})};
+  method.BuildReturn();
+  method.Encode();
+
+  EXPECT_FALSE(EncodeAndVerify(&dex_file));
+}
+
+TEST(DexBuilderTest, VerifyDexReturn5) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  auto method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Int()})};
+  auto r = method.MakeRegister();
+  method.BuildConst4(r, 5);
+  method.BuildReturn(r);
+  method.Encode();
+
+  EXPECT_TRUE(EncodeAndVerify(&dex_file));
+}
diff --git a/startop/tools/view_compiler/main.cc b/startop/tools/view_compiler/main.cc
index 0ad7e24..7d791c2 100644
--- a/startop/tools/view_compiler/main.cc
+++ b/startop/tools/view_compiler/main.cc
@@ -16,6 +16,7 @@
 
 #include "gflags/gflags.h"
 
+#include "dex_builder.h"
 #include "java_lang_builder.h"
 #include "util.h"
 
@@ -27,15 +28,17 @@
 #include <string>
 #include <vector>
 
+namespace {
+
 using namespace tinyxml2;
 using std::string;
 
 constexpr char kStdoutFilename[]{"stdout"};
 
-DEFINE_string(package, "", "The package name for the generated class (required)");
+DEFINE_bool(dex, false, "Generate a DEX file instead of Java");
 DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
+DEFINE_string(package, "", "The package name for the generated class (required)");
 
-namespace {
 class ViewCompilerXmlVisitor : public XMLVisitor {
  public:
   ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
@@ -63,6 +66,7 @@
  private:
   JavaLangViewBuilder* builder_;
 };
+
 }  // end namespace
 
 int main(int argc, char** argv) {
@@ -82,6 +86,11 @@
     return 1;
   }
 
+  if (FLAGS_dex) {
+    startop::dex::WriteTestDexFile("test.dex");
+    return 0;
+  }
+
   const char* const filename = argv[kFileNameParam];
   const string layout_name = FindLayoutNameFromFilename(filename);
 
@@ -102,4 +111,4 @@
   xml.Accept(&visitor);
 
   return 0;
-}
\ No newline at end of file
+}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 08bc9bc..daa09f5 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -397,7 +397,19 @@
         public static final int PROPERTY_WIFI = 0x00000008;
 
         /**
-         * Call is using high definition audio.
+         * When set, the UI should indicate to the user that a call is using high definition
+         * audio.
+         * <p>
+         * The underlying {@link ConnectionService} is responsible for reporting this
+         * property.  It is important to note that this property is not intended to report the
+         * actual audio codec being used for a Call, but whether the call should be indicated
+         * to the user as high definition.
+         * <p>
+         * The Android Telephony stack reports this property for calls based on a number
+         * of factors, including which audio codec is used and whether a call is using an HD
+         * codec end-to-end.  Some mobile operators choose to suppress display of an HD indication,
+         * and in these cases this property will not be set for a call even if the underlying audio
+         * codec is in fact "high definition".
          */
         public static final int PROPERTY_HIGH_DEF_AUDIO = 0x00000010;
 
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 7e63230..954bb44 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.job.JobService;
@@ -2813,100 +2814,131 @@
         public static final String SUBSCRIPTION_ID = "sub_id";
 
         /**
-         * The profile_id to which the APN saved in modem
+         * The profile_id to which the APN saved in modem.
          * <p>Type: INTEGER</p>
          *@hide
          */
         public static final String PROFILE_ID = "profile_id";
 
         /**
-         * Is the apn setting to be set in modem
-         * <P>Type: INTEGER (boolean)</P>
+         * If set to {@code true}, then the APN setting will persist to the modem.
+         * <p>Type: INTEGER (boolean)</p>
          *@hide
          */
+        @SystemApi
         public static final String MODEM_COGNITIVE = "modem_cognitive";
 
         /**
-         * The max connections of this apn
+         * The max connections of this APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS = "max_conns";
 
         /**
-         * The wait time for retry of the apn
+         * The wait time for retry of the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String WAIT_TIME = "wait_time";
 
         /**
-         * The time to limit max connection for the apn
+         * The time to limit max connection for the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS_TIME = "max_conns_time";
 
         /**
-         * The MTU size of the mobile interface to  which the APN connected
+         * The MTU(Maxinum transmit unit) size of the mobile interface to which the APN connected.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String MTU = "mtu";
 
         /**
-         * Is this APN added/edited/deleted by a user or carrier?
+         * APN edit status. APN could be added/edited/deleted by a user or carrier.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String EDITED = "edited";
 
         /**
-         * Is this APN visible to the user?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if this APN visible to the user, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_VISIBLE = "user_visible";
 
         /**
-         * Is the user allowed to edit this APN?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if the user allowed to edit this APN, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_EDITABLE = "user_editable";
 
         /**
-         * Following are possible values for the EDITED field
+         * {@link #EDITED APN edit status} indicates that this APN has not been edited or fails to
+         * edit.
+         * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final int UNEDITED = 0;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_EDITED = 1;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_DELETED = 2;
+
         /**
-         * DELETED_BUT_PRESENT is an intermediate value used to indicate that an entry deleted
-         * by the user is still present in the new APN database and therefore must remain tagged
-         * as user deleted rather than completely removed from the database
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the user is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
          * @hide
          */
         public static final int USER_DELETED_BUT_PRESENT_IN_XML = 3;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by carriers.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int CARRIER_EDITED = 4;
+
         /**
-         * CARRIER_DELETED values are currently not used as there is no usecase. If they are used,
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by carriers.
+         * CARRIER_DELETED values are currently not used as there is no use case. If they are used,
          * delete() will have to change accordingly. Currently it is hardcoded to USER_DELETED.
+         * <p>Type: INTEGER </p>
          * @hide
          */
         public static final int CARRIER_DELETED = 5;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the carrier is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
+         * @hide
          */
         public static final int CARRIER_DELETED_BUT_PRESENT_IN_XML = 6;
 
@@ -2935,16 +2967,20 @@
          * The APN set id. When the user manually selects an APN or the framework sets an APN as
          * preferred, all APNs with the same set id as the selected APN should be prioritized over
          * APNs in other sets.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final String APN_SET_ID = "apn_set_id";
 
         /**
-         * Possible value for the APN_SET_ID field. By default APNs will not belong to a set. If the
-         * user manually selects an APN with no set set, there is no need to prioritize any specific
-         * APN set ids.
+         * Possible value for the{@link #APN_SET_ID} field. By default APNs will not belong to a
+         * set. If the user manually selects an APN with no set set, there is no need to prioritize
+         * any specific APN set ids.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final int NO_SET_SET = 0;
 
     }
@@ -3213,7 +3249,6 @@
             values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex());
             values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode());
             values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly());
-            values.put(IS_DATA_ROAMING_FROM_REGISTRATION, state.getDataRoamingFromRegistration());
             values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation());
             return values;
         }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6eaecc6..56ffe93 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1202,6 +1202,20 @@
             "always_show_data_rat_icon_bool";
 
     /**
+     * Boolean indicating if default data account should show LTE or 4G icon
+     * @hide
+     */
+    public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL =
+            "show_4g_for_lte_data_icon_bool";
+
+    /**
+     * Boolean indicating if lte+ icon should be shown if available
+     * @hide
+     */
+    public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL =
+            "hide_lte_plus_data_icon_bool";
+
+    /**
      * Boolean to decide whether to show precise call failed cause to user
      * @hide
      */
@@ -1965,6 +1979,31 @@
     public static final String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool";
 
     /**
+     * Indicates if the carrier supports auto-upgrading a call to RTT when receiving a call from a
+     * RTT-supported device.
+     * @hide
+     */
+    public static final String KEY_RTT_AUTO_UPGRADE_BOOL = "rtt_auto_upgrade_bool";
+
+    /**
+     * Indicates if the carrier supports RTT during a video call.
+     * @hide
+     */
+    public static final String KEY_RTT_SUPPORTED_FOR_VT_BOOL = "rtt_supported_for_vt_bool";
+
+    /**
+     * Indicates if the carrier supports upgrading a voice call to an RTT call during the call.
+     * @hide
+     */
+    public static final String KEY_RTT_UPGRADE_SUPPORTED_BOOL = "rtt_upgrade_supported_bool";
+
+    /**
+     * Indicates if the carrier supports downgrading a RTT call to a voice call during the call.
+     * @hide
+     */
+    public static final String KEY_RTT_DOWNGRADE_SUPPORTED_BOOL = "rtt_downgrade_supported_bool";
+
+    /**
      * The flag to disable the popup dialog which warns the user of data charges.
      * @hide
      */
@@ -2144,6 +2183,53 @@
     public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL =
             "show_call_blocking_disabled_notification_always_bool";
 
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call forwarding operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL =
+            "call_forwarding_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call barring operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_BARRING_OVER_UT_WARNING_BOOL =
+            "call_barring_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the caller id operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALLER_ID_OVER_UT_WARNING_BOOL =
+            "caller_id_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call waiting operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_WAITING_OVER_UT_WARNING_BOOL =
+            "call_waiting_over_ut_warning_bool";
+
+    /**
+     * Flag indicating whether to support "Network default" option in Caller ID settings for Calling
+     * Line Identification Restriction (CLIR).
+     */
+    public static final String KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL =
+            "support_clir_network_default_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -2466,6 +2552,8 @@
         sDefaults.putBoolean(KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL, false);
         sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
+        sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
+        sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
         sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
         sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
@@ -2485,6 +2573,11 @@
         sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "");
         sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_BARRING_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALLER_ID_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_WAITING_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL, true);
     }
 
     /**
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index ee5cdc2..d7169b2 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -319,6 +319,29 @@
      */
     public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71;
 
+    /**
+     * Indicates that a new outgoing call cannot be placed because there is already an outgoing
+     * call dialing out.
+     */
+    public static final int ALREADY_DIALING = 72;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed while there is a ringing call.
+     */
+    public static final int CANT_CALL_WHILE_RINGING = 73;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed because calling has been disabled using
+     * the ro.telephony.disable-call system property.
+     */
+    public static final int CALLING_DISABLED = 74;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed because there is currently an ongoing
+     * foreground and background call.
+     */
+    public static final int TOO_MANY_ONGOING_CALLS = 75;
+
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Update toString() with the newly added disconnect type.
@@ -474,6 +497,14 @@
             return "NORMAL_UNSPECIFIED";
         case IMS_SIP_ALTERNATE_EMERGENCY_CALL:
             return "IMS_SIP_ALTERNATE_EMERGENCY_CALL";
+        case ALREADY_DIALING:
+            return "ALREADY_DIALING";
+        case CANT_CALL_WHILE_RINGING:
+            return "CANT_CALL_WHILE_RINGING";
+        case CALLING_DISABLED:
+            return "CALLING_DISABLED";
+        case TOO_MANY_ONGOING_CALLS:
+            return "TOO_MANY_ONGOING_CALLS";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 79298fd..ac38efb 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -34,8 +34,8 @@
  * Received Signal Strength and Cell ID location.
  *
  * @deprecated This class should not be used by any app targeting
- *     {@link Build.VERSION_CODES.Q Android Q} or higher. Instead callers should use
- *     {@Link android.telephony.CellInfo CellInfo}.
+ *     {@link android.os.Build.VERSION_CODES#Q Android Q} or higher. Instead callers should use
+ *     {@link android.telephony.CellInfo CellInfo}.
  */
 @Deprecated
 public class NeighboringCellInfo implements Parcelable
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index c393155..b312f84 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -95,6 +95,13 @@
     @RegState
     private final int mRegState;
 
+    /**
+     * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type
+     * from resource overlay or carrier config.
+     */
+    @ServiceState.RoamingType
+    private int mRoamingType;
+
     private final int mAccessNetworkTechnology;
 
     private final int mRejectCause;
@@ -140,6 +147,8 @@
         mDomain = domain;
         mTransportType = transportType;
         mRegState = regState;
+        mRoamingType = (regState == REG_STATE_ROAMING)
+                ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
         mAccessNetworkTechnology = accessNetworkTechnology;
         mRejectCause = rejectCause;
         mAvailableServices = availableServices;
@@ -182,6 +191,7 @@
         mDomain = source.readInt();
         mTransportType = source.readInt();
         mRegState = source.readInt();
+        mRoamingType = source.readInt();
         mAccessNetworkTechnology = source.readInt();
         mRejectCause = source.readInt();
         mEmergencyOnly = source.readBoolean();
@@ -211,6 +221,31 @@
     }
 
     /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
+    public boolean isRoaming() {
+        return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
+    }
+
+    /**
+     * Set {@link ServiceState.RoamingType roaming type}. This could override
+     * roaming type based on resource overlay or carrier config.
+     * @hide
+     */
+    public void setRoamingType(@ServiceState.RoamingType int roamingType) {
+        mRoamingType = roamingType;
+    }
+
+    /**
+     * @return {@link ServiceState.RoamingType roaming type}. This could return
+     * overridden roaming type based on resource overlay or carrier config.
+     * @hide
+     */
+    public @ServiceState.RoamingType int getRoamingType() {
+        return mRoamingType;
+    }
+
+    /**
      * @return Whether emergency is enabled.
      */
     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
@@ -280,6 +315,7 @@
                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
                 .append("transportType=").append(mTransportType)
                 .append(" regState=").append(regStateToString(mRegState))
+                .append(" roamingType=").append(mRoamingType)
                 .append(" accessNetworkTechnology=")
                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
                 .append(" rejectCause=").append(mRejectCause)
@@ -293,9 +329,9 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDomain, mTransportType, mRegState, mAccessNetworkTechnology,
-                mRejectCause, mEmergencyOnly, mAvailableServices, mCellIdentity,
-                mVoiceSpecificStates, mDataSpecificStates);
+        return Objects.hash(mDomain, mTransportType, mRegState, mRoamingType,
+                mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
+                mCellIdentity, mVoiceSpecificStates, mDataSpecificStates);
     }
 
     @Override
@@ -310,6 +346,7 @@
         return mDomain == other.mDomain
                 && mTransportType == other.mTransportType
                 && mRegState == other.mRegState
+                && mRoamingType == other.mRoamingType
                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
                 && mRejectCause == other.mRejectCause
                 && mEmergencyOnly == other.mEmergencyOnly
@@ -325,6 +362,7 @@
         dest.writeInt(mDomain);
         dest.writeInt(mTransportType);
         dest.writeInt(mRegState);
+        dest.writeInt(mRoamingType);
         dest.writeInt(mAccessNetworkTechnology);
         dest.writeInt(mRejectCause);
         dest.writeBoolean(mEmergencyOnly);
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index bd6a59d..3476db4 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -17,12 +17,14 @@
 package android.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IPhoneStateListener;
 
 import java.lang.ref.WeakReference;
@@ -280,6 +282,15 @@
      */
     public static final int LISTEN_PHONE_CAPABILITY_CHANGE                 = 0x00200000;
 
+    /**
+     *  Listen for changes to the radio power state.
+     *
+     *  @see #onRadioPowerStateChanged
+     *  @hide
+     */
+    @SystemApi
+    public static final int LISTEN_RADIO_POWER_STATE_CHANGED               = 0x00800000;
+
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -406,6 +417,9 @@
                         PhoneStateListener.this.onPhoneCapabilityChanged(
                                 (PhoneCapability) msg.obj);
                         break;
+                    case LISTEN_RADIO_POWER_STATE_CHANGED:
+                        PhoneStateListener.this.onRadioPowerStateChanged((int) msg.obj);
+                        break;
                 }
             }
         };
@@ -646,6 +660,18 @@
     }
 
     /**
+     * Callback invoked when modem radio power state changes. Requires
+     * the READ_PRIVILEGED_PHONE_STATE permission.
+     * @param state the modem radio power state
+     * @hide
+     */
+    @SystemApi
+    public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+        // default implementation empty
+    }
+
+
+    /**
      * Callback invoked when telephony has received notice from a carrier
      * app that a network action that could result in connectivity loss
      * has been requested by an app using
@@ -776,10 +802,18 @@
         public void onPhoneCapabilityChanged(PhoneCapability capability) {
             send(LISTEN_PHONE_CAPABILITY_CHANGE, 0, 0, capability);
         }
+
+        public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+            send(LISTEN_RADIO_POWER_STATE_CHANGED, 0, 0, state);
+        }
     }
 
+    /**
+     * @hide
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     @UnsupportedAppUsage
-    IPhoneStateListener callback = new IPhoneStateListenerStub(this);
+    public final IPhoneStateListener callback = new IPhoneStateListenerStub(this);
 
     private void log(String s) {
         Rlog.d(LOG_TAG, s);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 7469186..e0ec2c5 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -20,6 +20,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -57,7 +58,7 @@
      * Normal operation condition, the phone is registered
      * with an operator either in home network or in roaming.
      */
-    public static final int STATE_IN_SERVICE = 0;
+    public static final int STATE_IN_SERVICE = TelephonyProtoEnums.SERVICE_STATE_IN_SERVICE; // 0
 
     /**
      * Phone is not registered with any operator, the phone
@@ -65,17 +66,19 @@
      * searching to registration at all, or registration is denied, or radio
      * signal is not available.
      */
-    public static final int STATE_OUT_OF_SERVICE = 1;
+    public static final int STATE_OUT_OF_SERVICE =
+            TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE;  // 1
 
     /**
      * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
      */
-    public static final int STATE_EMERGENCY_ONLY = 2;
+    public static final int STATE_EMERGENCY_ONLY =
+            TelephonyProtoEnums.SERVICE_STATE_EMERGENCY_ONLY;  // 2
 
     /**
      * Radio of telephony is explicitly powered off.
      */
-    public static final int STATE_POWER_OFF = 3;
+    public static final int STATE_POWER_OFF = TelephonyProtoEnums.SERVICE_STATE_POWER_OFF;  // 3
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -198,6 +201,15 @@
     private int mVoiceRegState = STATE_OUT_OF_SERVICE;
     private int mDataRegState = STATE_OUT_OF_SERVICE;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "ROAMING_TYPE_" }, value = {
+            ROAMING_TYPE_NOT_ROAMING,
+            ROAMING_TYPE_UNKNOWN,
+            ROAMING_TYPE_DOMESTIC,
+            ROAMING_TYPE_INTERNATIONAL
+    })
+    public @interface RoamingType {}
     /**
      * Roaming type
      * HOME : in home network
@@ -228,8 +240,6 @@
      */
     public static final int UNKNOWN_ID = -1;
 
-    private int mVoiceRoamingType;
-    private int mDataRoamingType;
     private String mVoiceOperatorAlphaLong;
     private String mVoiceOperatorAlphaShort;
     private String mVoiceOperatorNumeric;
@@ -259,8 +269,6 @@
     @UnsupportedAppUsage
     private int mCdmaEriIconMode;
 
-    private boolean mIsDataRoamingFromRegistration;
-
     @UnsupportedAppUsage
     private boolean mIsUsingCarrierAggregation;
 
@@ -332,8 +340,6 @@
     protected void copyFrom(ServiceState s) {
         mVoiceRegState = s.mVoiceRegState;
         mDataRegState = s.mDataRegState;
-        mVoiceRoamingType = s.mVoiceRoamingType;
-        mDataRoamingType = s.mDataRoamingType;
         mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong;
         mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort;
         mVoiceOperatorNumeric = s.mVoiceOperatorNumeric;
@@ -351,7 +357,6 @@
         mCdmaEriIconIndex = s.mCdmaEriIconIndex;
         mCdmaEriIconMode = s.mCdmaEriIconMode;
         mIsEmergencyOnly = s.mIsEmergencyOnly;
-        mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
         mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
         mChannelNumber = s.mChannelNumber;
         mCellBandwidths = s.mCellBandwidths == null ? null :
@@ -367,8 +372,6 @@
     public ServiceState(Parcel in) {
         mVoiceRegState = in.readInt();
         mDataRegState = in.readInt();
-        mVoiceRoamingType = in.readInt();
-        mDataRoamingType = in.readInt();
         mVoiceOperatorAlphaLong = in.readString();
         mVoiceOperatorAlphaShort = in.readString();
         mVoiceOperatorNumeric = in.readString();
@@ -386,7 +389,6 @@
         mCdmaEriIconIndex = in.readInt();
         mCdmaEriIconMode = in.readInt();
         mIsEmergencyOnly = in.readInt() != 0;
-        mIsDataRoamingFromRegistration = in.readInt() != 0;
         mIsUsingCarrierAggregation = in.readInt() != 0;
         mLteEarfcnRsrpBoost = in.readInt();
         mNetworkRegistrationStates = new ArrayList<>();
@@ -398,8 +400,6 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mVoiceRegState);
         out.writeInt(mDataRegState);
-        out.writeInt(mVoiceRoamingType);
-        out.writeInt(mDataRoamingType);
         out.writeString(mVoiceOperatorAlphaLong);
         out.writeString(mVoiceOperatorAlphaShort);
         out.writeString(mVoiceOperatorNumeric);
@@ -417,7 +417,6 @@
         out.writeInt(mCdmaEriIconIndex);
         out.writeInt(mCdmaEriIconMode);
         out.writeInt(mIsEmergencyOnly ? 1 : 0);
-        out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
         out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
         out.writeInt(mLteEarfcnRsrpBoost);
         out.writeList(mNetworkRegistrationStates);
@@ -535,17 +534,21 @@
      */
     @UnsupportedAppUsage
     public boolean getVoiceRoaming() {
-        return mVoiceRoamingType != ROAMING_TYPE_NOT_ROAMING;
+        return getVoiceRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
-
     /**
      * Get current voice network roaming type
      * @return roaming type
      * @hide
      */
     @UnsupportedAppUsage
-    public int getVoiceRoamingType() {
-        return mVoiceRoamingType;
+    public @RoamingType int getVoiceRoamingType() {
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return regState.getRoamingType();
+        }
+        return ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -555,19 +558,7 @@
      */
     @UnsupportedAppUsage
     public boolean getDataRoaming() {
-        return mDataRoamingType != ROAMING_TYPE_NOT_ROAMING;
-    }
-
-    /**
-     * Set whether data network registration state is roaming
-     *
-     * This should only be set to the roaming value received
-     * once the data registration phase has completed.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setDataRoamingFromRegistration(boolean dataRoaming) {
-        mIsDataRoamingFromRegistration = dataRoaming;
+        return getDataRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -576,7 +567,12 @@
      * @hide
      */
     public boolean getDataRoamingFromRegistration() {
-        return mIsDataRoamingFromRegistration;
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return (regState.getRegState() == NetworkRegistrationState.REG_STATE_ROAMING);
+        }
+        return false;
     }
 
     /**
@@ -585,8 +581,13 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public int getDataRoamingType() {
-        return mDataRoamingType;
+    public @RoamingType int getDataRoamingType() {
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return regState.getRoamingType();
+        }
+        return ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -759,8 +760,6 @@
         return Objects.hash(
                 mVoiceRegState,
                 mDataRegState,
-                mVoiceRoamingType,
-                mDataRoamingType,
                 mChannelNumber,
                 mCellBandwidths,
                 mVoiceOperatorAlphaLong,
@@ -780,7 +779,6 @@
                 mCdmaEriIconIndex,
                 mCdmaEriIconMode,
                 mIsEmergencyOnly,
-                mIsDataRoamingFromRegistration,
                 mIsUsingCarrierAggregation,
                 mLteEarfcnRsrpBoost,
                 mNetworkRegistrationStates);
@@ -794,8 +792,6 @@
         return (mVoiceRegState == s.mVoiceRegState
                 && mDataRegState == s.mDataRegState
                 && mIsManualNetworkSelection == s.mIsManualNetworkSelection
-                && mVoiceRoamingType == s.mVoiceRoamingType
-                && mDataRoamingType == s.mDataRoamingType
                 && mChannelNumber == s.mChannelNumber
                 && Arrays.equals(mCellBandwidths, s.mCellBandwidths)
                 && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
@@ -813,7 +809,6 @@
                 && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
                         s.mCdmaDefaultRoamingIndicator)
                 && mIsEmergencyOnly == s.mIsEmergencyOnly
-                && mIsDataRoamingFromRegistration == s.mIsDataRoamingFromRegistration
                 && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation)
                 && (mNetworkRegistrationStates == null ? s.mNetworkRegistrationStates == null :
                         s.mNetworkRegistrationStates != null &&
@@ -933,8 +928,6 @@
             .append(", mChannelNumber=").append(mChannelNumber)
             .append(", duplexMode()=").append(getDuplexMode())
             .append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths))
-            .append(", mVoiceRoamingType=").append(getRoamingLogString(mVoiceRoamingType))
-            .append(", mDataRoamingType=").append(getRoamingLogString(mDataRoamingType))
             .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong)
             .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort)
             .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong)
@@ -951,7 +944,6 @@
             .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator)
             .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator)
             .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
-            .append(", mIsDataRoamingFromRegistration=").append(mIsDataRoamingFromRegistration)
             .append(", mIsUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
             .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
             .append(", mNetworkRegistrationStates=").append(mNetworkRegistrationStates)
@@ -962,8 +954,6 @@
         if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
         mVoiceRegState = state;
         mDataRegState = state;
-        mVoiceRoamingType = ROAMING_TYPE_NOT_ROAMING;
-        mDataRoamingType = ROAMING_TYPE_NOT_ROAMING;
         mChannelNumber = -1;
         mCellBandwidths = new int[0];
         mVoiceOperatorAlphaLong = null;
@@ -983,7 +973,6 @@
         mCdmaEriIconIndex = -1;
         mCdmaEriIconMode = -1;
         mIsEmergencyOnly = false;
-        mIsDataRoamingFromRegistration = false;
         mIsUsingCarrierAggregation = false;
         mLteEarfcnRsrpBoost = 0;
         mNetworkRegistrationStates = new ArrayList<>();
@@ -1029,32 +1018,50 @@
     }
 
     public void setRoaming(boolean roaming) {
-        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
-        mDataRoamingType = mVoiceRoamingType;
+        setVoiceRoaming(roaming);
+        setDataRoaming(roaming);
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public void setVoiceRoaming(boolean roaming) {
-        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+        setVoiceRoamingType(roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
     }
 
     /** @hide */
     @UnsupportedAppUsage
-    public void setVoiceRoamingType(int type) {
-        mVoiceRoamingType = type;
+    public void setVoiceRoamingType(@RoamingType int type) {
+        NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState == null) {
+            regState = new NetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN,
+                    ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
+                    false, null, null);
+            addNetworkRegistrationState(regState);
+        }
+        regState.setRoamingType(type);
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public void setDataRoaming(boolean dataRoaming) {
-        mDataRoamingType = (dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+        setDataRoamingType(dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
     }
 
     /** @hide */
     @UnsupportedAppUsage
-    public void setDataRoamingType(int type) {
-        mDataRoamingType = type;
+    public void setDataRoamingType(@RoamingType int type) {
+        NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState == null) {
+            regState = new NetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
+                    ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
+                    false, null, null);
+            addNetworkRegistrationState(regState);
+        }
+        regState.setRoamingType(type);
     }
 
     /**
@@ -1166,30 +1173,10 @@
      */
     @UnsupportedAppUsage
     private void setFromNotifierBundle(Bundle m) {
-        mVoiceRegState = m.getInt("voiceRegState");
-        mDataRegState = m.getInt("dataRegState");
-        mVoiceRoamingType = m.getInt("voiceRoamingType");
-        mDataRoamingType = m.getInt("dataRoamingType");
-        mVoiceOperatorAlphaLong = m.getString("operator-alpha-long");
-        mVoiceOperatorAlphaShort = m.getString("operator-alpha-short");
-        mVoiceOperatorNumeric = m.getString("operator-numeric");
-        mDataOperatorAlphaLong = m.getString("data-operator-alpha-long");
-        mDataOperatorAlphaShort = m.getString("data-operator-alpha-short");
-        mDataOperatorNumeric = m.getString("data-operator-numeric");
-        mIsManualNetworkSelection = m.getBoolean("manual");
-        mRilVoiceRadioTechnology = m.getInt("radioTechnology");
-        mRilDataRadioTechnology = m.getInt("dataRadioTechnology");
-        mCssIndicator = m.getBoolean("cssIndicator");
-        mNetworkId = m.getInt("networkId");
-        mSystemId = m.getInt("systemId");
-        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
-        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
-        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
-        mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
-        mIsUsingCarrierAggregation = m.getBoolean("isUsingCarrierAggregation");
-        mLteEarfcnRsrpBoost = m.getInt("LteEarfcnRsrpBoost");
-        mChannelNumber = m.getInt("ChannelNumber");
-        mCellBandwidths = m.getIntArray("CellBandwidths");
+        ServiceState ssFromBundle = m.getParcelable(Intent.EXTRA_SERVICE_STATE);
+        if (ssFromBundle != null) {
+            copyFrom(ssFromBundle);
+        }
     }
 
     /**
@@ -1200,10 +1187,13 @@
      */
     @UnsupportedAppUsage
     public void fillInNotifierBundle(Bundle m) {
+        m.putParcelable(Intent.EXTRA_SERVICE_STATE, this);
+        // serviceState already consists of below entries.
+        // for backward compatibility, we continue fill in below entries.
         m.putInt("voiceRegState", mVoiceRegState);
         m.putInt("dataRegState", mDataRegState);
-        m.putInt("voiceRoamingType", mVoiceRoamingType);
-        m.putInt("dataRoamingType", mDataRoamingType);
+        m.putInt("dataRoamingType", getDataRoamingType());
+        m.putInt("voiceRoamingType", getVoiceRoamingType());
         m.putString("operator-alpha-long", mVoiceOperatorAlphaLong);
         m.putString("operator-alpha-short", mVoiceOperatorAlphaShort);
         m.putString("operator-numeric", mVoiceOperatorNumeric);
@@ -1219,7 +1209,7 @@
         m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
         m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
         m.putBoolean("emergencyOnly", mIsEmergencyOnly);
-        m.putBoolean("isDataRoamingFromRegistration", mIsDataRoamingFromRegistration);
+        m.putBoolean("isDataRoamingFromRegistration", getDataRoamingFromRegistration());
         m.putBoolean("isUsingCarrierAggregation", mIsUsingCarrierAggregation);
         m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost);
         m.putInt("ChannelNumber", mChannelNumber);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 3ef80c2..97b7414 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -32,12 +32,14 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
+import android.app.job.JobService;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkCapabilities;
 import android.net.Uri;
@@ -85,13 +87,10 @@
     /** @hide */
     public static final int INVALID_PHONE_INDEX = -1;
 
-    /** An invalid slot identifier */
-    /** @hide */
+    /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
     public static final int INVALID_SIM_SLOT_INDEX = -1;
 
-    /** Indicates the caller wants the default sub id. */
-    /** @hide */
-    @UnsupportedAppUsage
+    /** Indicates the default subscription ID in Telephony. */
     public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
 
     /**
@@ -117,6 +116,52 @@
     @UnsupportedAppUsage
     public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
 
+
+    /**
+     * Generates a content {@link Uri} used to receive updates on simInfo change
+     * on the given subscriptionId
+     * @param subscriptionId the subscriptionId to receive updates on
+     * @return the Uri used to observe carrier identity changes
+     * @hide
+     */
+    public static Uri getUriForSubscriptionId(int subscriptionId) {
+        return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
+    }
+
+    /**
+     * A content {@link Uri} used to receive updates on wfc enabled user setting.
+     * <p>
+     * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+     * subscription wfc enabled {@link SubscriptionManager#WFC_IMS_ENABLED}
+     * while your app is running. You can also use a {@link JobService} to ensure your app
+     * is notified of changes to the {@link Uri} even when it is not running.
+     * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+     * updates to the {@link Uri}.
+     * To be notified of changes to a specific subId, append subId to the URI
+     * {@link Uri#withAppendedPath(Uri, String)}.
+     * @hide
+     */
+    @SystemApi
+    public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
+
+    /**
+     * A content {@link Uri} used to receive updates on enhanced 4g user setting.
+     * <p>
+     * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+     * subscription enhanced 4G enabled {@link SubscriptionManager#ENHANCED_4G_MODE_ENABLED}
+     * while your app is running. You can also use a {@link JobService} to ensure your app
+     * is notified of changes to the {@link Uri} even when it is not running.
+     * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+     * updates to the {@link Uri}.
+     * To be notified of changes to a specific subId, append subId to the URI
+     * {@link Uri#withAppendedPath(Uri, String)}.
+     * @hide
+     */
+    @SystemApi
+    public static final Uri ENHANCED_4G_ENABLED_CONTENT_URI = Uri.withAppendedPath(
+            CONTENT_URI, "enhanced_4g");
+
+
     /**
      * TelephonyProvider unique key column name is the subscription id.
      * <P>Type: TEXT (String)</P>
@@ -1263,15 +1308,15 @@
 
     /**
      * Get slotIndex associated with the subscription.
-     * @return slotIndex as a positive integer or a negative value if an error either
-     * SIM_NOT_INSERTED or < 0 if an invalid slot index
-     * @hide
+     *
+     * @param subscriptionId the unique SubscriptionInfo index in database
+     * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
+     * subscriptionId doesn't have an associated slot index.
      */
-    @UnsupportedAppUsage
-    public static int getSlotIndex(int subId) {
-        if (!isValidSubscriptionId(subId)) {
+    public static int getSlotIndex(int subscriptionId) {
+        if (!isValidSubscriptionId(subscriptionId)) {
             if (DBG) {
-                logd("[getSlotIndex]- fail");
+                logd("[getSlotIndex]- supplied subscriptionId is invalid.");
             }
         }
 
@@ -1280,7 +1325,7 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getSlotIndex(subId);
+                result = iSub.getSlotIndex(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1601,6 +1646,19 @@
     }
 
     /**
+     * Check if the subscription ID is usable.
+     *
+     * A usable subscription ID has a valid value except some special values such as
+     * {@link #DEFAULT_SUBSCRIPTION_ID}. It can be used for subscription functions.
+     *
+     * @param subscriptionId the subscription ID
+     * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
+     */
+    public static boolean isUsableSubscriptionId(int subscriptionId) {
+        return isUsableSubIdValue(subscriptionId);
+    }
+
+    /**
      * @return true if subId is an usable subId value else false. A
      * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
      * @hide
@@ -2148,7 +2206,12 @@
 
     /**
      * Set preferred default data.
-     * Set on which slot default data will be on.
+     * Set on which slot most cellular data will be on.
+     * It's also usually what we set up internet connection on.
+     *
+     * PreferredData overwrites user setting of default data subscription. And it's used
+     * by ANAS or carrier apps to switch primary and CBRS subscription dynamically in multi-SIM
+     * devices.
      *
      * @param slotId which slot is preferred to for cellular data.
      * @hide
@@ -2162,20 +2225,21 @@
     }
 
     /**
-     * Get User downloaded Profiles.
+     * Get opportunistic data Profiles.
      *
-     *  Provide all available user downloaded profile on the phone.
-     *  @param slotId on which phone the switch will operate on
+     *  Provide all available user downloaded profiles on phone which are used only for
+     *  opportunistic data.
+     *  @param slotIndex slot on which the profiles are queried from.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    List<SubscriptionInfo> getOpportunisticSubscriptions(int slotId) {
+    public List<SubscriptionInfo> getOpportunisticSubscriptions(int slotIndex) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         List<SubscriptionInfo> subInfoList = null;
 
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                subInfoList = iSub.getOpportunisticSubscriptions(slotId, pkgForDebug);
+                subInfoList = iSub.getOpportunisticSubscriptions(slotIndex, pkgForDebug);
             }
         } catch (RemoteException ex) {
             // ignore it
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f83ea68..c276ed3 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -60,12 +60,14 @@
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.IAns;
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.ITelephonyRegistry;
@@ -166,7 +168,6 @@
     /** @hide */
     static public final int OTASP_SIM_UNPROVISIONED = 5;
 
-
     /** @hide */
     static public final int KEY_TYPE_EPDG = 1;
 
@@ -1590,8 +1591,7 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return null;
-            return telephony.getNeighboringCellInfo(mContext.getOpPackageName(),
-                    mContext.getApplicationInfo().targetSdkVersion);
+            return telephony.getNeighboringCellInfo(mContext.getOpPackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -2419,39 +2419,46 @@
      *
      * These are the ordinal value of IccCardConstants.State.
      */
-    public static final int SIM_STATE_UNKNOWN = 0;
+
+    public static final int SIM_STATE_UNKNOWN = TelephonyProtoEnums.SIM_STATE_UNKNOWN;  // 0
     /** SIM card state: no SIM card is available in the device */
-    public static final int SIM_STATE_ABSENT = 1;
+    public static final int SIM_STATE_ABSENT = TelephonyProtoEnums.SIM_STATE_ABSENT;  // 1
     /** SIM card state: Locked: requires the user's SIM PIN to unlock */
-    public static final int SIM_STATE_PIN_REQUIRED = 2;
+    public static final int SIM_STATE_PIN_REQUIRED =
+            TelephonyProtoEnums.SIM_STATE_PIN_REQUIRED;  // 2
     /** SIM card state: Locked: requires the user's SIM PUK to unlock */
-    public static final int SIM_STATE_PUK_REQUIRED = 3;
+    public static final int SIM_STATE_PUK_REQUIRED =
+            TelephonyProtoEnums.SIM_STATE_PUK_REQUIRED;  // 3
     /** SIM card state: Locked: requires a network PIN to unlock */
-    public static final int SIM_STATE_NETWORK_LOCKED = 4;
+    public static final int SIM_STATE_NETWORK_LOCKED =
+            TelephonyProtoEnums.SIM_STATE_NETWORK_LOCKED;  // 4
     /** SIM card state: Ready */
-    public static final int SIM_STATE_READY = 5;
+    public static final int SIM_STATE_READY = TelephonyProtoEnums.SIM_STATE_READY;  // 5
     /** SIM card state: SIM Card is NOT READY */
-    public static final int SIM_STATE_NOT_READY = 6;
+    public static final int SIM_STATE_NOT_READY = TelephonyProtoEnums.SIM_STATE_NOT_READY;  // 6
     /** SIM card state: SIM Card Error, permanently disabled */
-    public static final int SIM_STATE_PERM_DISABLED = 7;
+    public static final int SIM_STATE_PERM_DISABLED =
+            TelephonyProtoEnums.SIM_STATE_PERM_DISABLED;  // 7
     /** SIM card state: SIM Card Error, present but faulty */
-    public static final int SIM_STATE_CARD_IO_ERROR = 8;
+    public static final int SIM_STATE_CARD_IO_ERROR =
+            TelephonyProtoEnums.SIM_STATE_CARD_IO_ERROR;  // 8
     /** SIM card state: SIM Card restricted, present but not usable due to
      * carrier restrictions.
      */
-    public static final int SIM_STATE_CARD_RESTRICTED = 9;
+    public static final int SIM_STATE_CARD_RESTRICTED =
+            TelephonyProtoEnums.SIM_STATE_CARD_RESTRICTED;  // 9
     /**
      * SIM card state: Loaded: SIM card applications have been loaded
      * @hide
      */
     @SystemApi
-    public static final int SIM_STATE_LOADED = 10;
+    public static final int SIM_STATE_LOADED = TelephonyProtoEnums.SIM_STATE_LOADED;  // 10
     /**
      * SIM card state: SIM Card is present
      * @hide
      */
     @SystemApi
-    public static final int SIM_STATE_PRESENT = 11;
+    public static final int SIM_STATE_PRESENT = TelephonyProtoEnums.SIM_STATE_PRESENT;  // 11
 
     /**
      * Extra included in {@link #ACTION_SIM_CARD_STATE_CHANGED} and
@@ -2914,7 +2921,7 @@
      * of time the mode may be unknown.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
@@ -4413,6 +4420,10 @@
         return ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));
     }
 
+    private IAns getIAns() {
+        return IAns.Stub.asInterface(ServiceManager.getService("ians"));
+    }
+
     //
     //
     // PhoneStateListener
@@ -5375,7 +5386,7 @@
     @UnsupportedAppUsage
     public static String getTelephonyProperty(String property, String defaultVal) {
         String propVal = SystemProperties.get(property);
-        return propVal == null ? defaultVal : propVal;
+        return TextUtils.isEmpty(propVal) ? defaultVal : propVal;
     }
 
     /** @hide */
@@ -5949,7 +5960,7 @@
      * Sets the network selection mode to automatic.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5974,7 +5985,7 @@
      * Perform a radio scan and return the list of available networks.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p> Note that this scan can take a long time (sometimes minutes) to happen.
      *
@@ -6053,7 +6064,7 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -6078,7 +6089,7 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -6111,7 +6122,7 @@
      * Get the network selection mode.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
 
      * @return the network selection mode.
      *
@@ -6843,6 +6854,60 @@
     }
 
     /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"RADIO_POWER_"},
+            value = {RADIO_POWER_OFF,
+                    RADIO_POWER_ON,
+                    RADIO_POWER_UNAVAILABLE,
+            })
+    public @interface RadioPowerState {}
+
+    /**
+     * Radio explicitly powered off (e.g, airplane mode).
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_OFF = 0;
+
+    /**
+     * Radio power is on.
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_ON = 1;
+
+    /**
+     * Radio power unavailable (eg, modem resetting or not booted).
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_UNAVAILABLE = 2;
+
+    /**
+     * @return current modem radio state.
+     *
+     * <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling
+     * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PHONE_STATE})
+    public @RadioPowerState int getRadioPowerState() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return RADIO_POWER_UNAVAILABLE;
+    }
+
+    /** @hide */
     @SystemApi
     @SuppressLint("Doclava125")
     public void updateServiceLocation() {
@@ -7001,7 +7066,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                isDataRoamingEnabled = telephony.isDataRoamingEnabled(getSubId());
+                isDataRoamingEnabled = telephony.isDataRoamingEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isDataRoamingEnabled", e);
@@ -7013,7 +7079,7 @@
      * Gets the roaming mode for CDMA phone.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT}, {@link #CDMA_ROAMING_MODE_HOME},
      * {@link #CDMA_ROAMING_MODE_AFFILIATED}, {@link #CDMA_ROAMING_MODE_ANY}.
@@ -7038,7 +7104,7 @@
      * Sets the roaming mode for CDMA phone to the given mode {@code mode}.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @param mode should be one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT},
      * {@link #CDMA_ROAMING_MODE_HOME}, {@link #CDMA_ROAMING_MODE_AFFILIATED},
@@ -7107,7 +7173,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.setDataRoamingEnabled(getSubId(), isEnabled);
+                telephony.setDataRoamingEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), isEnabled);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#setDataRoamingEnabled", e);
@@ -7900,7 +7967,7 @@
      * Returns the current {@link ServiceState} information.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
@@ -8250,20 +8317,31 @@
     }
 
     /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns
-     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
-     * @param subId the subscription ID that this action applies to.
-     * @param enabled control enable or disable metered apns.
+     * Used to enable or disable carrier data by the system based on carrier signalling or
+     * carrier privileged apps. Different from {@link #setDataEnabled(boolean)} which is linked to
+     * user settings, carrier data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param enabled control enable or disable carrier data.
      * @hide
      */
-    public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setCarrierDataEnabled(boolean enabled) {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                service.carrierActionSetMeteredApnsEnabled(subId, enabled);
+                service.carrierActionSetMeteredApnsEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#carrierActionSetMeteredApnsEnabled", e);
+            Log.e(TAG, "Error calling ITelephony#setCarrierDataEnabled", e);
         }
     }
 
@@ -8369,7 +8447,7 @@
      * Checks if phone is in emergency callback mode.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return true if phone is in emergency callback mode.
      * @hide
@@ -8400,6 +8478,29 @@
     }
 
     /**
+     * Checks if manual network selection is allowed.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @return {@code true} if manual network selection is allowed, otherwise return {@code false}.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isManualNetworkSelectionAllowed() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isManualNetworkSelectionAllowed(getSubId());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#isManualNetworkSelectionAllowed", e);
+        }
+        return true;
+    }
+
+    /**
      * Get the most recently available signal strength information.
      *
      * Get the most recent SignalStrength information reported by the modem. Due
@@ -8579,7 +8680,6 @@
         return UNKNOWN_CARRIER_ID_LIST_VERSION;
     }
 
-
     /**
      * How many modems can have simultaneous data connections.
      * @hide
@@ -8597,4 +8697,62 @@
         }
         return 0;
     }
+
+    /**
+     * Enable or disable AlternativeNetworkService.
+     *
+     * This method should be called to enable or disable
+     * AlternativeNetwork service on the device.
+     *
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     *
+     * @param enable enable(True) or disable(False)
+     * @return returns true if successfully set.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setAlternativeNetworkState(boolean enable) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        boolean ret = false;
+        try {
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                ret = iAlternativeNetworkService.setEnable(enable, pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex);
+        }
+
+        return ret;
+    }
+
+    /**
+     * is AlternativeNetworkService enabled
+     *
+     * This method should be called to determine if the AlternativeNetworkService is
+     * enabled
+     *
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isAlternativeNetworkEnabled() {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        boolean isEnabled = false;
+
+        try {
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                isEnabled = iAlternativeNetworkService.isEnabled(pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex);
+        }
+
+        return isEnabled;
+    }
 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 951bed4..ed14f91 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -257,7 +257,7 @@
 
     private final int mProfileId;
 
-    private final boolean mModemCognitive;
+    private final boolean mPersistent;
     private final int mMaxConns;
     private final int mWaitTime;
     private final int mMaxConnsTime;
@@ -290,13 +290,13 @@
     }
 
     /**
-     * Returns if the APN setting is to be set in modem.
+     * Returns if the APN setting is persistent on the modem.
      *
      * @return is the APN setting to be set in modem
      * @hide
      */
-    public boolean getModemCognitive() {
-        return mModemCognitive;
+    public boolean isPersistent() {
+        return mPersistent;
     }
 
     /**
@@ -616,7 +616,7 @@
         this.mCarrierEnabled = builder.mCarrierEnabled;
         this.mNetworkTypeBitmask = builder.mNetworkTypeBitmask;
         this.mProfileId = builder.mProfileId;
-        this.mModemCognitive = builder.mModemCognitive;
+        this.mPersistent = builder.mModemCognitive;
         this.mMaxConns = builder.mMaxConns;
         this.mWaitTime = builder.mWaitTime;
         this.mMaxConnsTime = builder.mMaxConnsTime;
@@ -634,33 +634,33 @@
             int maxConns, int waitTime, int maxConnsTime, int mtu, int mvnoType,
             String mvnoMatchData, int apnSetId) {
         return new Builder()
-            .setId(id)
-            .setOperatorNumeric(operatorNumeric)
-            .setEntryName(entryName)
-            .setApnName(apnName)
-            .setProxyAddress(proxyAddress)
-            .setProxyPort(proxyPort)
-            .setMmsc(mmsc)
-            .setMmsProxyAddress(mmsProxyAddress)
-            .setMmsProxyPort(mmsProxyPort)
-            .setUser(user)
-            .setPassword(password)
-            .setAuthType(authType)
-            .setApnTypeBitmask(mApnTypeBitmask)
-            .setProtocol(protocol)
-            .setRoamingProtocol(roamingProtocol)
-            .setCarrierEnabled(carrierEnabled)
-            .setNetworkTypeBitmask(networkTypeBitmask)
-            .setProfileId(profileId)
-            .setModemCognitive(modemCognitive)
-            .setMaxConns(maxConns)
-            .setWaitTime(waitTime)
-            .setMaxConnsTime(maxConnsTime)
-            .setMtu(mtu)
-            .setMvnoType(mvnoType)
-            .setMvnoMatchData(mvnoMatchData)
-            .setApnSetId(apnSetId)
-            .buildWithoutCheck();
+                .setId(id)
+                .setOperatorNumeric(operatorNumeric)
+                .setEntryName(entryName)
+                .setApnName(apnName)
+                .setProxyAddress(proxyAddress)
+                .setProxyPort(proxyPort)
+                .setMmsc(mmsc)
+                .setMmsProxyAddress(mmsProxyAddress)
+                .setMmsProxyPort(mmsProxyPort)
+                .setUser(user)
+                .setPassword(password)
+                .setAuthType(authType)
+                .setApnTypeBitmask(mApnTypeBitmask)
+                .setProtocol(protocol)
+                .setRoamingProtocol(roamingProtocol)
+                .setCarrierEnabled(carrierEnabled)
+                .setNetworkTypeBitmask(networkTypeBitmask)
+                .setProfileId(profileId)
+                .setModemCognitive(modemCognitive)
+                .setMaxConns(maxConns)
+                .setWaitTime(waitTime)
+                .setMaxConnsTime(maxConnsTime)
+                .setMtu(mtu)
+                .setMvnoType(mvnoType)
+                .setMvnoMatchData(mvnoMatchData)
+                .setApnSetId(apnSetId)
+                .buildWithoutCheck();
     }
 
     /** @hide */
@@ -692,56 +692,56 @@
         }
 
         return makeApnSetting(
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
-            cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
-            cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
-            cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
-            cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY)),
-            portFromString(cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT))),
-            UriFromString(cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
-            cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY)),
-            portFromString(cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT))),
-            cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
-            cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
-            apnTypesBitmask,
-            getProtocolIntFromString(
-                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL))),
-            getProtocolIntFromString(
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
+                cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY)),
+                portFromString(cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT))),
+                UriFromString(cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
+                cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY)),
+                portFromString(cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT))),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
+                apnTypesBitmask,
+                getProtocolIntFromString(
+                    cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL))),
+                getProtocolIntFromString(
+                    cursor.getString(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.ROAMING_PROTOCOL))),
+                cursor.getInt(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
+                networkTypeBitmask,
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.MODEM_COGNITIVE)) == 1,
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.WAIT_TIME)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.MAX_CONNS_TIME)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
+                getMvnoTypeIntFromString(
+                    cursor.getString(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.MVNO_TYPE))),
                 cursor.getString(cursor.getColumnIndexOrThrow(
-                    Telephony.Carriers.ROAMING_PROTOCOL))),
-            cursor.getInt(cursor.getColumnIndexOrThrow(
-                Telephony.Carriers.CARRIER_ENABLED)) == 1,
-            networkTypeBitmask,
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(
-                Telephony.Carriers.MODEM_COGNITIVE)) == 1,
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.WAIT_TIME)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(
-                Telephony.Carriers.MAX_CONNS_TIME)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
-            getMvnoTypeIntFromString(
-                cursor.getString(cursor.getColumnIndexOrThrow(
-                    Telephony.Carriers.MVNO_TYPE))),
-            cursor.getString(cursor.getColumnIndexOrThrow(
-                Telephony.Carriers.MVNO_MATCH_DATA)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)));
+                        Telephony.Carriers.MVNO_MATCH_DATA)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)));
     }
 
     /** @hide */
     public static ApnSetting makeApnSetting(ApnSetting apn) {
         return makeApnSetting(apn.mId, apn.mOperatorNumeric, apn.mEntryName, apn.mApnName,
-            apn.mProxyAddress, apn.mProxyPort, apn.mMmsc, apn.mMmsProxyAddress,
-            apn.mMmsProxyPort, apn.mUser, apn.mPassword, apn.mAuthType, apn.mApnTypeBitmask,
-            apn.mProtocol, apn.mRoamingProtocol, apn.mCarrierEnabled, apn.mNetworkTypeBitmask,
-            apn.mProfileId, apn.mModemCognitive, apn.mMaxConns, apn.mWaitTime,
-            apn.mMaxConnsTime, apn.mMtu, apn.mMvnoType, apn.mMvnoMatchData, apn.mApnSetId);
+                apn.mProxyAddress, apn.mProxyPort, apn.mMmsc, apn.mMmsProxyAddress,
+                apn.mMmsProxyPort, apn.mUser, apn.mPassword, apn.mAuthType, apn.mApnTypeBitmask,
+                apn.mProtocol, apn.mRoamingProtocol, apn.mCarrierEnabled, apn.mNetworkTypeBitmask,
+                apn.mProfileId, apn.mPersistent, apn.mMaxConns, apn.mWaitTime,
+                apn.mMaxConnsTime, apn.mMtu, apn.mMvnoType, apn.mMvnoMatchData, apn.mApnSetId);
     }
 
     /**
@@ -931,23 +931,23 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("[ApnSettingV5] ")
-            .append(mEntryName)
-            .append(", ").append(mId)
-            .append(", ").append(mOperatorNumeric)
-            .append(", ").append(mApnName)
-            .append(", ").append(mProxyAddress)
-            .append(", ").append(UriToString(mMmsc))
-            .append(", ").append(mMmsProxyAddress)
-            .append(", ").append(portToString(mMmsProxyPort))
-            .append(", ").append(portToString(mProxyPort))
-            .append(", ").append(mAuthType).append(", ");
+                .append(mEntryName)
+                .append(", ").append(mId)
+                .append(", ").append(mOperatorNumeric)
+                .append(", ").append(mApnName)
+                .append(", ").append(mProxyAddress)
+                .append(", ").append(UriToString(mMmsc))
+                .append(", ").append(mMmsProxyAddress)
+                .append(", ").append(portToString(mMmsProxyPort))
+                .append(", ").append(portToString(mProxyPort))
+                .append(", ").append(mAuthType).append(", ");
         final String[] types = getApnTypesStringFromBitmask(mApnTypeBitmask).split(",");
         sb.append(TextUtils.join(" | ", types));
         sb.append(", ").append(PROTOCOL_INT_MAP.get(mProtocol));
         sb.append(", ").append(PROTOCOL_INT_MAP.get(mRoamingProtocol));
         sb.append(", ").append(mCarrierEnabled);
         sb.append(", ").append(mProfileId);
-        sb.append(", ").append(mModemCognitive);
+        sb.append(", ").append(mPersistent);
         sb.append(", ").append(mMaxConns);
         sb.append(", ").append(mWaitTime);
         sb.append(", ").append(mMaxConnsTime);
@@ -1022,31 +1022,31 @@
         ApnSetting other = (ApnSetting) o;
 
         return mEntryName.equals(other.mEntryName)
-            && Objects.equals(mId, other.mId)
-            && Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
-            && Objects.equals(mApnName, other.mApnName)
-            && Objects.equals(mProxyAddress, other.mProxyAddress)
-            && Objects.equals(mMmsc, other.mMmsc)
-            && Objects.equals(mMmsProxyAddress, other.mMmsProxyAddress)
-            && Objects.equals(mMmsProxyPort, other.mMmsProxyPort)
-            && Objects.equals(mProxyPort, other.mProxyPort)
-            && Objects.equals(mUser, other.mUser)
-            && Objects.equals(mPassword, other.mPassword)
-            && Objects.equals(mAuthType, other.mAuthType)
-            && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask)
-            && Objects.equals(mProtocol, other.mProtocol)
-            && Objects.equals(mRoamingProtocol, other.mRoamingProtocol)
-            && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
-            && Objects.equals(mProfileId, other.mProfileId)
-            && Objects.equals(mModemCognitive, other.mModemCognitive)
-            && Objects.equals(mMaxConns, other.mMaxConns)
-            && Objects.equals(mWaitTime, other.mWaitTime)
-            && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
-            && Objects.equals(mMtu, other.mMtu)
-            && Objects.equals(mMvnoType, other.mMvnoType)
-            && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
-            && Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask)
-            && Objects.equals(mApnSetId, other.mApnSetId);
+                && Objects.equals(mId, other.mId)
+                && Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
+                && Objects.equals(mApnName, other.mApnName)
+                && Objects.equals(mProxyAddress, other.mProxyAddress)
+                && Objects.equals(mMmsc, other.mMmsc)
+                && Objects.equals(mMmsProxyAddress, other.mMmsProxyAddress)
+                && Objects.equals(mMmsProxyPort, other.mMmsProxyPort)
+                && Objects.equals(mProxyPort, other.mProxyPort)
+                && Objects.equals(mUser, other.mUser)
+                && Objects.equals(mPassword, other.mPassword)
+                && Objects.equals(mAuthType, other.mAuthType)
+                && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask)
+                && Objects.equals(mProtocol, other.mProtocol)
+                && Objects.equals(mRoamingProtocol, other.mRoamingProtocol)
+                && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
+                && Objects.equals(mProfileId, other.mProfileId)
+                && Objects.equals(mPersistent, other.mPersistent)
+                && Objects.equals(mMaxConns, other.mMaxConns)
+                && Objects.equals(mWaitTime, other.mWaitTime)
+                && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
+                && Objects.equals(mMtu, other.mMtu)
+                && Objects.equals(mMvnoType, other.mMvnoType)
+                && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
+                && Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask)
+                && Objects.equals(mApnSetId, other.mApnSetId);
     }
 
     /**
@@ -1069,29 +1069,29 @@
         ApnSetting other = (ApnSetting) o;
 
         return mEntryName.equals(other.mEntryName)
-            && Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
-            && Objects.equals(mApnName, other.mApnName)
-            && Objects.equals(mProxyAddress, other.mProxyAddress)
-            && Objects.equals(mMmsc, other.mMmsc)
-            && Objects.equals(mMmsProxyAddress, other.mMmsProxyAddress)
-            && Objects.equals(mMmsProxyPort, other.mMmsProxyPort)
-            && Objects.equals(mProxyPort, other.mProxyPort)
-            && Objects.equals(mUser, other.mUser)
-            && Objects.equals(mPassword, other.mPassword)
-            && Objects.equals(mAuthType, other.mAuthType)
-            && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask)
-            && (isDataRoaming || Objects.equals(mProtocol, other.mProtocol))
-            && (!isDataRoaming || Objects.equals(mRoamingProtocol, other.mRoamingProtocol))
-            && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
-            && Objects.equals(mProfileId, other.mProfileId)
-            && Objects.equals(mModemCognitive, other.mModemCognitive)
-            && Objects.equals(mMaxConns, other.mMaxConns)
-            && Objects.equals(mWaitTime, other.mWaitTime)
-            && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
-            && Objects.equals(mMtu, other.mMtu)
-            && Objects.equals(mMvnoType, other.mMvnoType)
-            && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
-            && Objects.equals(mApnSetId, other.mApnSetId);
+                && Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
+                && Objects.equals(mApnName, other.mApnName)
+                && Objects.equals(mProxyAddress, other.mProxyAddress)
+                && Objects.equals(mMmsc, other.mMmsc)
+                && Objects.equals(mMmsProxyAddress, other.mMmsProxyAddress)
+                && Objects.equals(mMmsProxyPort, other.mMmsProxyPort)
+                && Objects.equals(mProxyPort, other.mProxyPort)
+                && Objects.equals(mUser, other.mUser)
+                && Objects.equals(mPassword, other.mPassword)
+                && Objects.equals(mAuthType, other.mAuthType)
+                && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask)
+                && (isDataRoaming || Objects.equals(mProtocol, other.mProtocol))
+                && (!isDataRoaming || Objects.equals(mRoamingProtocol, other.mRoamingProtocol))
+                && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
+                && Objects.equals(mProfileId, other.mProfileId)
+                && Objects.equals(mPersistent, other.mPersistent)
+                && Objects.equals(mMaxConns, other.mMaxConns)
+                && Objects.equals(mWaitTime, other.mWaitTime)
+                && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
+                && Objects.equals(mMtu, other.mMtu)
+                && Objects.equals(mMvnoType, other.mMvnoType)
+                && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
+                && Objects.equals(mApnSetId, other.mApnSetId);
     }
 
     /**
@@ -1103,22 +1103,22 @@
      */
     public boolean similar(ApnSetting other) {
         return (!this.canHandleType(TYPE_DUN)
-            && !other.canHandleType(TYPE_DUN)
-            && Objects.equals(this.mApnName, other.mApnName)
-            && !typeSameAny(this, other)
-            && xorEquals(this.mProxyAddress, other.mProxyAddress)
-            && xorEqualsInt(this.mProxyPort, other.mProxyPort)
-            && xorEquals(this.mProtocol, other.mProtocol)
-            && xorEquals(this.mRoamingProtocol, other.mRoamingProtocol)
-            && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled)
-            && Objects.equals(this.mProfileId, other.mProfileId)
-            && Objects.equals(this.mMvnoType, other.mMvnoType)
-            && Objects.equals(this.mMvnoMatchData, other.mMvnoMatchData)
-            && xorEquals(this.mMmsc, other.mMmsc)
-            && xorEquals(this.mMmsProxyAddress, other.mMmsProxyAddress)
-            && xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
-            && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
-            && Objects.equals(mApnSetId, other.mApnSetId);
+                && !other.canHandleType(TYPE_DUN)
+                && Objects.equals(this.mApnName, other.mApnName)
+                && !typeSameAny(this, other)
+                && xorEquals(this.mProxyAddress, other.mProxyAddress)
+                && xorEqualsInt(this.mProxyPort, other.mProxyPort)
+                && xorEquals(this.mProtocol, other.mProtocol)
+                && xorEquals(this.mRoamingProtocol, other.mRoamingProtocol)
+                && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled)
+                && Objects.equals(this.mProfileId, other.mProfileId)
+                && Objects.equals(this.mMvnoType, other.mMvnoType)
+                && Objects.equals(this.mMvnoMatchData, other.mMvnoMatchData)
+                && xorEquals(this.mMmsc, other.mMmsc)
+                && xorEquals(this.mMmsProxyAddress, other.mMmsProxyAddress)
+                && xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
+                && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
+                && Objects.equals(mApnSetId, other.mApnSetId);
     }
 
     // Equal or one is null.
@@ -1343,13 +1343,13 @@
             new Parcelable.Creator<ApnSetting>() {
                 @Override
                 public ApnSetting createFromParcel(Parcel in) {
-                return readFromParcel(in);
-            }
+                    return readFromParcel(in);
+                }
 
                 @Override
                 public ApnSetting[] newArray(int size) {
-                return new ApnSetting[size];
-            }
+                    return new ApnSetting[size];
+                }
             };
 
     /**
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index e8597b2..da4822c 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -68,17 +68,15 @@
 
     private final int mMtu;
 
-    private final String mMvnoType;
+    private final boolean mPersistent;
 
-    private final String mMvnoMatchData;
+    private final boolean mPreferred;
 
-    private final boolean mModemCognitive;
-
-    public DataProfile(int profileId, String apn, String protocol, int authType,
-                String userName, String password, int type, int maxConnsTime, int maxConns,
-                int waitTime, boolean enabled, int supportedApnTypesBitmap, String roamingProtocol,
-                int bearerBitmap, int mtu, String mvnoType, String mvnoMatchData,
-                boolean modemCognitive) {
+    /** @hide */
+    public DataProfile(int profileId, String apn, String protocol, int authType, String userName,
+                       String password, int type, int maxConnsTime, int maxConns, int waitTime,
+                       boolean enabled, int supportedApnTypesBitmap, String roamingProtocol,
+                       int bearerBitmap, int mtu, boolean persistent, boolean preferred) {
 
         this.mProfileId = profileId;
         this.mApn = apn;
@@ -100,11 +98,11 @@
         this.mRoamingProtocol = roamingProtocol;
         this.mBearerBitmap = bearerBitmap;
         this.mMtu = mtu;
-        this.mMvnoType = mvnoType;
-        this.mMvnoMatchData = mvnoMatchData;
-        this.mModemCognitive = modemCognitive;
+        this.mPersistent = persistent;
+        this.mPreferred = preferred;
     }
 
+    /** @hide */
     public DataProfile(Parcel source) {
         mProfileId = source.readInt();
         mApn = source.readString();
@@ -121,9 +119,8 @@
         mRoamingProtocol = source.readString();
         mBearerBitmap = source.readInt();
         mMtu = source.readInt();
-        mMvnoType = source.readString();
-        mMvnoMatchData = source.readString();
-        mModemCognitive = source.readBoolean();
+        mPersistent = source.readBoolean();
+        mPreferred = source.readBoolean();
     }
 
     /**
@@ -207,23 +204,17 @@
     public int getMtu() { return mMtu; }
 
     /**
-     * @return The MVNO type: possible values are "imsi", "gid", "spn".
+     * @return {@code true} if modem must persist this data profile.
      */
-    public String getMvnoType() { return mMvnoType; }
+    public boolean isPersistent() { return mPersistent; }
 
     /**
-     * @return The MVNO match data. For example,
-     * SPN: A MOBILE, BEN NL, ...
-     * IMSI: 302720x94, 2060188, ...
-     * GID: 4E, 33, ...
+     * @return {@code true} if this data profile was used to bring up the last default
+     * (i.e internet) data connection successfully.
      */
-    public String getMvnoMatchData() { return mMvnoMatchData; }
+    public boolean isPreferred() { return  mPreferred; }
 
-    /**
-     * @return True if the data profile was sent to the modem through setDataProfile earlier.
-     */
-    public boolean isModemCognitive() { return mModemCognitive; }
-
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
@@ -233,11 +224,11 @@
     public String toString() {
         return "DataProfile=" + mProfileId + "/" + mProtocol + "/" + mAuthType
                 + "/" + (Build.IS_USER ? "***/***/***" :
-                         (mApn + "/" + mUserName + "/" + mPassword))
-                + "/" + mType + "/" + mMaxConnsTime
-                + "/" + mMaxConns + "/" + mWaitTime + "/" + mEnabled + "/"
-                + mSupportedApnTypesBitmap + "/" + mRoamingProtocol + "/" + mBearerBitmap + "/"
-                + mMtu + "/" + mMvnoType + "/" + mMvnoMatchData + "/" + mModemCognitive;
+                         (mApn + "/" + mUserName + "/" + mPassword)) + "/" + mType + "/"
+                + mMaxConnsTime + "/" + mMaxConns + "/"
+                + mWaitTime + "/" + mEnabled + "/" + mSupportedApnTypesBitmap + "/"
+                + mRoamingProtocol + "/" + mBearerBitmap + "/" + mMtu + "/" + mPersistent + "/"
+                + mPreferred;
     }
 
     @Override
@@ -246,6 +237,7 @@
         return (o == this || toString().equals(o.toString()));
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mProfileId);
@@ -263,11 +255,11 @@
         dest.writeString(mRoamingProtocol);
         dest.writeInt(mBearerBitmap);
         dest.writeInt(mMtu);
-        dest.writeString(mMvnoType);
-        dest.writeString(mMvnoMatchData);
-        dest.writeBoolean(mModemCognitive);
+        dest.writeBoolean(mPersistent);
+        dest.writeBoolean(mPreferred);
     }
 
+    /** @hide */
     public static final Parcelable.Creator<DataProfile> CREATOR =
             new Parcelable.Creator<DataProfile>() {
         @Override
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.aidl b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
new file mode 100644
index 0000000..bfb0a59
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.emergency;
+
+parcelable EmergencyNumber;
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
new file mode 100644
index 0000000..bdba8c8
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -0,0 +1,434 @@
+/*
+ * 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.telephony.emergency;
+
+import android.annotation.IntDef;
+import android.hardware.radio.V1_3.EmergencyNumberSource;
+import android.hardware.radio.V1_3.EmergencyServiceCategory;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A parcelable class that wraps and retrieves the information of number, service category(s) and
+ * country code for a specific emergency number.
+ */
+public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNumber> {
+
+    private static final String LOG_TAG = "EmergencyNumber";
+
+    /**
+     * Defining Emergency Service Category as follows:
+     *  - General emergency call, all categories;
+     *  - Police;
+     *  - Ambulance;
+     *  - Fire Brigade;
+     *  - Marine Guard;
+     *  - Mountain Rescue;
+     *  - Manually Initiated eCall (MIeC);
+     *  - Automatically Initiated eCall (AIeC);
+     *
+     * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific
+     * services are associated with this emergency number; if the emergency number is specified,
+     * it has one or more defined emergency service categories.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     *
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "EMERGENCY_SERVICE_CATEGORY_" }, value = {
+            EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+            EMERGENCY_SERVICE_CATEGORY_POLICE,
+            EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+            EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+            EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD,
+            EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE,
+            EMERGENCY_SERVICE_CATEGORY_MIEC,
+            EMERGENCY_SERVICE_CATEGORY_AIEC
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EmergencyServiceCategories {}
+
+    /**
+     * Emergency Service Category UNSPECIFIED (General emergency call, all categories) bit-field
+     * indicates that no specific services are associated with this emergency number; if the
+     * emergency number is specified, it has one or more defined emergency service categories.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED =
+            EmergencyServiceCategory.UNSPECIFIED;
+    /**
+     * Bit-field that indicates Emergency Service Category for Police.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_POLICE = EmergencyServiceCategory.POLICE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Ambulance.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_AMBULANCE =
+            EmergencyServiceCategory.AMBULANCE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Fire Brigade.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE =
+            EmergencyServiceCategory.FIRE_BRIGADE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Marine Guard.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD =
+            EmergencyServiceCategory.MARINE_GUARD;
+    /**
+     * Bit-field that indicates Emergency Service Category for Mountain Rescue.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE =
+            EmergencyServiceCategory.MOUNTAIN_RESCUE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Manually Initiated eCall (MIeC)
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MIEC = EmergencyServiceCategory.MIEC;
+    /**
+     * Bit-field that indicates Emergency Service Category for Automatically Initiated eCall (AIeC)
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_AIEC = EmergencyServiceCategory.AIEC;
+
+    private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET;
+    static {
+        EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>();
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_POLICE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MIEC);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AIEC);
+    }
+
+    /**
+     * The source to tell where the corresponding @1.3::EmergencyNumber comes from.
+     *
+     * The emergency number has one or more defined emergency number sources.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     *
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "EMERGENCY_NUMBER_SOURCE_" }, value = {
+            EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+            EMERGENCY_NUMBER_SOURCE_SIM,
+            EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+            EMERGENCY_NUMBER_SOURCE_DEFAULT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EmergencyNumberSources {}
+
+    /**
+     * Bit-field which indicates the number is from the network signaling.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING =
+            EmergencyNumberSource.NETWORK_SIGNALING;
+    /**
+     * Bit-field which indicates the number is from the sim.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_SIM = EmergencyNumberSource.SIM;
+    /** Bit-field which indicates the number is from the modem config. */
+    public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG =
+            EmergencyNumberSource.MODEM_CONFIG;
+    /**
+     * Bit-field which indicates the number is available as default.
+     *
+     * 112, 911 must always be available; additionally, 000, 08, 110, 999, 118 and 119 must be
+     * available when sim is not present.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = EmergencyNumberSource.DEFAULT;
+
+    private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET;
+    static {
+        EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_SIM);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DEFAULT);
+    }
+
+    private final String mNumber;
+    private final String mCountryIso;
+    private final int mEmergencyServiceCategoryBitmask;
+    private final int mEmergencyNumberSourceBitmask;
+
+    /** @hide */
+    public EmergencyNumber(String number, String countryIso,
+                           int emergencyServiceCategories,
+                           int emergencyNumberSources) {
+        this.mNumber = number;
+        this.mCountryIso = countryIso;
+        this.mEmergencyServiceCategoryBitmask = emergencyServiceCategories;
+        this.mEmergencyNumberSourceBitmask = emergencyNumberSources;
+    }
+
+    /** @hide */
+    public EmergencyNumber(Parcel source) {
+        mNumber = source.readString();
+        mCountryIso = source.readString();
+        mEmergencyServiceCategoryBitmask = source.readInt();
+        mEmergencyNumberSourceBitmask = source.readInt();
+    }
+
+    /**
+     * Get the dialing number of the emergency number.
+     *
+     * The character in the number string is only the dial pad
+     * character('0'-'9', '*', or '#'). For example: 911.
+     *
+     * @return the dialing number.
+     */
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Get the country code string (lowercase character) in ISO 3166 format of the emergency number.
+     *
+     * @return the country code string (lowercase character) in ISO 3166 format.
+     */
+    public String getCountryIso() {
+        return mCountryIso;
+    }
+
+    /**
+     * Returns the bitmask of emergency service categories of the emergency number.
+     *
+     * @return bitmask of the emergency service categories
+     */
+    public @EmergencyServiceCategories int getEmergencyServiceCategoryBitmask() {
+        return mEmergencyServiceCategoryBitmask;
+    }
+
+    /**
+     * Returns the emergency service categories of the emergency number.
+     *
+     * Note: if the emergency number is in {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}, only
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} is returned and it means the number is in
+     * all categories.
+     *
+     * @return a list of the emergency service categories
+     */
+    public List<Integer> getEmergencyServiceCategories() {
+        List<Integer> categories = new ArrayList<>();
+        if (serviceUnspecified()) {
+            categories.add(EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);
+            return categories;
+        }
+        for (Integer category : EMERGENCY_SERVICE_CATEGORY_SET) {
+            if (isInEmergencyServiceCategories(category)) {
+                categories.add(category);
+            }
+        }
+        return categories;
+    }
+
+    /**
+     * Checks if the emergency service category is unspecified for the emergency number
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}.
+     *
+     * @return {@code true} if the emergency service category is unspecified for the emergency
+     * number {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
+     */
+    private boolean serviceUnspecified() {
+        return mEmergencyServiceCategoryBitmask == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+    }
+
+    /**
+     * Checks if the emergency number is in the supplied emergency service category(s).
+     *
+     * @param categories - the supplied emergency service categories
+     *
+     * @return {@code true} if the emergency number is in the specified emergency service
+     * category(s) or if its emergency service category is
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
+     */
+    public boolean isInEmergencyServiceCategories(@EmergencyServiceCategories int categories) {
+        if (categories == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
+            return serviceUnspecified();
+        }
+        if (serviceUnspecified()) {
+            return true;
+        }
+        return (mEmergencyServiceCategoryBitmask & categories) == categories;
+    }
+
+    /**
+     * Returns the bitmask of the sources of the emergency number.
+     *
+     * @return bitmask of the emergency number sources
+     */
+    public @EmergencyNumberSources int getEmergencyNumberSourceBitmask() {
+        return mEmergencyNumberSourceBitmask;
+    }
+
+    /**
+     * Returns a list of sources of the emergency number.
+     *
+     * @return a list of emergency number sources
+     */
+    public List<Integer> getEmergencyNumberSources() {
+        List<Integer> sources = new ArrayList<>();
+        for (Integer source : EMERGENCY_NUMBER_SOURCE_SET) {
+            if ((mEmergencyNumberSourceBitmask & source) == source) {
+                sources.add(source);
+            }
+        }
+        return sources;
+    }
+
+    /**
+     * Checks if the emergency number is from the specified emergency number source(s).
+     *
+     * @return {@code true} if the emergency number is from the specified emergency number
+     * source(s); {@code false} otherwise.
+     *
+     * @param sources - the supplied emergency number sources
+     */
+    public boolean isFromSources(@EmergencyNumberSources int sources) {
+        return (mEmergencyNumberSourceBitmask & sources) == sources;
+    }
+
+    @Override
+    /** @hide */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mNumber);
+        dest.writeString(mCountryIso);
+        dest.writeInt(mEmergencyServiceCategoryBitmask);
+        dest.writeInt(mEmergencyNumberSourceBitmask);
+    }
+
+    @Override
+    /** @hide */
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "EmergencyNumber = " + "[Number]" + mNumber + " / [CountryIso]" + mCountryIso
+                + " / [ServiceCategories]"
+                + Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
+                + " / [Sources]" + Integer.toBinaryString(mEmergencyNumberSourceBitmask);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!EmergencyNumber.class.isInstance(o)) {
+            return false;
+        }
+        return (o == this || toString().equals(o.toString()));
+    }
+
+    /**
+     * Calculate the score for display priority.
+     *
+     * A higher display priority score means the emergency number has a higher display priority.
+     * The score is higher if the source is defined for a higher display priority.
+     *
+     * The priority of sources are defined as follows:
+     *     EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING >
+     *     EMERGENCY_NUMBER_SOURCE_SIM >
+     *     EMERGENCY_NUMBER_SOURCE_DEFAULT >
+     *     EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
+     *
+     */
+    private int getDisplayPriorityScore() {
+        int score = 0;
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING)) {
+            score += 1 << 4;
+        }
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_SIM)) {
+            score += 1 << 3;
+        }
+        // TODO add a score if the number comes from Google's emergency number database
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DEFAULT)) {
+            score += 1 << 1;
+        }
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG)) {
+            score += 1 << 0;
+        }
+        return score;
+    }
+
+    /**
+     * Compare the display priority for this emergency number and the supplied emergency number.
+     *
+     * @param emergencyNumber the supplied emergency number
+     * @return a negative value if the supplied emergency number has a lower display priority;
+     *         a positive value if the supplied emergency number has a higher display priority;
+     *         0 if both have equal display priority.
+     */
+    @Override
+    public int compareTo(EmergencyNumber emergencyNumber) {
+        if (this.getDisplayPriorityScore()
+                > emergencyNumber.getDisplayPriorityScore()) {
+            return -1;
+        } else if (this.getDisplayPriorityScore()
+                < emergencyNumber.getDisplayPriorityScore()) {
+            return 1;
+        } else {
+            /**
+             * TODO if both numbers have the same display priority score, the number matches the
+             * Google's emergency number database has a higher display priority.
+             */
+            return 0;
+        }
+    }
+
+    public static final Parcelable.Creator<EmergencyNumber> CREATOR =
+            new Parcelable.Creator<EmergencyNumber>() {
+        @Override
+        public EmergencyNumber createFromParcel(Parcel in) {
+            return new EmergencyNumber(in);
+        }
+
+        @Override
+        public EmergencyNumber[] newArray(int size) {
+            return new EmergencyNumber[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index a20d4f5..df903cc2 100644
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -16,22 +16,16 @@
 
 package android.telephony.ims;
 
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.ims.aidl.IImsCallSessionListener;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-import android.telephony.ims.stub.ImsCallSessionImplBase;
 import android.util.Log;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.Objects;
+
 /**
  * Provides the call initiation/termination, and media exchange between two IMS endpoints.
  * It directly communicates with IMS service which implements the IMS protocol behavior.
@@ -42,7 +36,8 @@
     private static final String TAG = "ImsCallSession";
 
     /**
-     * Defines IMS call session state. Please use {@link ImsCallSessionImplBase.State} definition.
+     * Defines IMS call session state. Please use
+     * {@link android.telephony.ims.stub.ImsCallSessionImplBase.State} definition.
      * This is kept around for capability reasons.
      */
     public static class State {
@@ -1027,9 +1022,9 @@
     }
 
     /**
-     * Sends RTT Upgrade request
+     * Sends RTT Upgrade or downgrade request
      *
-     * @param to   : expected profile
+     * @param to Profile with the RTT flag set to the desired value
      */
     public void sendRttModifyRequest(ImsCallProfile to) {
         if (mClosed) {
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 8d18ae8..f2d0cbf 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -16,22 +16,19 @@
 
 package android.telephony.ims;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
-import android.annotation.UnsupportedAppUsage;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telecom.Log;
 import android.telephony.Rlog;
 
-/*
- * This file contains all the api's through which
- * information received in Dialog Event Package can be
- * queried
- */
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
- * Parcelable object to handle MultiEndpoint Dialog Information
+ * Parcelable object to handle MultiEndpoint Dialog Event Package Information.
  * @hide
  */
 @SystemApi
@@ -40,8 +37,39 @@
     private static final String TAG = "ImsExternalCallState";
 
     // Dialog States
+    /**
+     * The external call is in the confirmed dialog state.
+     */
     public static final int CALL_STATE_CONFIRMED = 1;
+    /**
+     * The external call is in the terminated dialog state.
+     */
     public static final int CALL_STATE_TERMINATED = 2;
+
+    /**@hide*/
+    @IntDef(flag = true,
+            value = {
+                    CALL_STATE_CONFIRMED,
+                    CALL_STATE_TERMINATED
+            },
+            prefix = "CALL_STATE_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ExternalCallState {}
+
+    /**@hide*/
+    @IntDef(flag = true,
+            value = {
+                    ImsCallProfile.CALL_TYPE_VOICE,
+                    ImsCallProfile.CALL_TYPE_VT_TX,
+                    ImsCallProfile.CALL_TYPE_VT_RX,
+                    ImsCallProfile.CALL_TYPE_VT
+            },
+            prefix = "CALL_TYPE_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ExternalCallType {}
+
+
+
     // Dialog Id
     private int mCallId;
     // Number
@@ -58,10 +86,9 @@
     public ImsExternalCallState() {
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public ImsExternalCallState(int callId, Uri address, boolean isPullable, int callState,
-            int callType, boolean isCallheld) {
+    /**@hide*/
+    public ImsExternalCallState(int callId, Uri address, boolean isPullable,
+            @ExternalCallState int callState, int callType, boolean isCallheld) {
         mCallId = callId;
         mAddress = address;
         mIsPullable = isPullable;
@@ -71,9 +98,10 @@
         Rlog.d(TAG, "ImsExternalCallState = " + this);
     }
 
-    /** @hide */
+    /**@hide*/
     public ImsExternalCallState(int callId, Uri address, Uri localAddress,
-            boolean isPullable, int callState, int callType, boolean isCallheld) {
+            boolean isPullable, @ExternalCallState int callState, int callType,
+            boolean isCallheld) {
         mCallId = callId;
         mAddress = address;
         mLocalAddress = localAddress;
@@ -84,6 +112,31 @@
         Rlog.d(TAG, "ImsExternalCallState = " + this);
     }
 
+    /**
+     * Create a new ImsExternalCallState instance to contain Multiendpoint Dialog information.
+     * @param callId The unique ID of the call, which will be used to identify this external
+     *               connection.
+     * @param address A {@link Uri} containing the remote address of this external connection.
+     * @param localAddress A {@link Uri} containing the local address information.
+     * @param isPullable A flag determining if this external connection can be pulled to the current
+     *         device.
+     * @param callState The state of the external call.
+     * @param callType The type of external call.
+     * @param isCallheld A flag determining if the external connection is currently held.
+     */
+    public ImsExternalCallState(String callId, Uri address, Uri localAddress,
+            boolean isPullable, @ExternalCallState int callState, @ExternalCallType int callType,
+            boolean isCallheld) {
+        mCallId = getIdForString(callId);
+        mAddress = address;
+        mLocalAddress = localAddress;
+        mIsPullable = isPullable;
+        mCallState = callState;
+        mCallType = callType;
+        mIsHeld = isCallheld;
+        Rlog.d(TAG, "ImsExternalCallState = " + this);
+    }
+
     /** @hide */
     public ImsExternalCallState(Parcel in) {
         mCallId = in.readInt();
@@ -135,7 +188,9 @@
         return mAddress;
     }
 
-    /** @hide */
+    /**
+     * @return A {@link Uri} containing the local address from the Multiendpoint Dialog Information.
+     */
     public Uri getLocalAddress() {
         return mLocalAddress;
     }
@@ -144,11 +199,11 @@
         return mIsPullable;
     }
 
-    public int getCallState() {
+    public @ExternalCallState int getCallState() {
         return mCallState;
     }
 
-    public int getCallType() {
+    public @ExternalCallType int getCallType() {
         return mCallType;
     }
 
@@ -166,4 +221,15 @@
                 ", mCallType = " + mCallType +
                 ", mIsHeld = " + mIsHeld + "}";
     }
+
+    private int getIdForString(String idString) {
+        try {
+            return Integer.parseInt(idString);
+        } catch (NumberFormatException e) {
+            // In the case that there are alphanumeric characters, we will create a hash of the
+            // String value as a backup.
+            // TODO: Modify call IDs to use Strings as keys instead of integers in telephony/telecom
+            return idString.hashCode();
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 86cb1b7..b0c875e 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -100,6 +100,7 @@
     public static final int EVENT_DATA_RECONNECT = BASE + 47;
     public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
     public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
+    public static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = BASE + 50;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
new file mode 100755
index 0000000..6eb8d66
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.internal.telephony;
+
+
+interface IAns {
+
+    /**
+    * Enable or disable Alternative Network service.
+    *
+    * This method should be called to enable or disable
+    * AlternativeNetwork service on the device.
+    *
+    * <p>
+    * Requires Permission:
+    *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+    *
+    * @param enable enable(True) or disable(False)
+    * @param callingPackage caller's package name
+    * @return returns true if successfully set.
+    */
+    boolean setEnable(boolean enable, String callingPackage);
+
+    /**
+     * is Alternative Network service enabled
+     *
+     * This method should be called to determine if the Alternative Network service is enabled
+    *
+    * <p>
+    * Requires Permission:
+    *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+    * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+    *
+    * @param callingPackage caller's package name
+    */
+    boolean isEnabled(String callingPackage);
+}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 1ebb697..8681859 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -52,5 +52,6 @@
     void onCarrierNetworkChange(in boolean active);
     void onUserMobileDataStateChanged(in boolean enabled);
     void onPhoneCapabilityChanged(in PhoneCapability capability);
+    void onRadioPowerStateChanged(in int state);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 627dfaa..3417da1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -280,7 +280,7 @@
     /**
      * Returns the neighboring cell information of the device.
      */
-    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg, int targetSdk);
+    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
 
      int getCallState();
 
@@ -808,6 +808,13 @@
      */
     boolean isDataEnabled(int subId);
 
+     /**
+     * Checks if manual network selection is allowed.
+     *
+     * @return {@code true} if manual network selection is allowed, otherwise return {@code false}.
+     */
+     boolean isManualNetworkSelectionAllowed(int subId);
+
     /**
      * Get P-CSCF address from PCO after data connection is established or modified.
      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
@@ -1477,4 +1484,10 @@
      * Return the network selection mode on the subscription with id {@code subId}.
      */
      int getNetworkSelectionMode(int subId);
+
+     /**
+      * Return the modem radio power state for slot index.
+      *
+      */
+     int getRadioPowerState(int slotIdex, String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 43d56b3..2f40fcc 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -79,4 +79,5 @@
     void notifyCarrierNetworkChange(in boolean active);
     void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state);
     void notifyPhoneCapabilityChanged(in PhoneCapability capability);
+    void notifyRadioPowerStateChanged(in int state);
 }
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 0b8a02a..4d765d3 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -37,7 +37,8 @@
         "junit.framework",
     ],
 
-    droiddoc_options: ["stubsourceonly"],
+    droiddoc_options: ["-stubsourceonly"],
+    metalava_enabled: false,
     compile_dex: true,
 }
 
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 5eba017..37158e5 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -26,5 +26,6 @@
     ],
 
     srcs_lib_whitelist_pkgs: ["android"],
+    metalava_enabled: false,
     compile_dex: true,
 }
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index ea615b9..0a0d50c 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -40,7 +40,8 @@
         "junit.textui",
     ],
 
-    droiddoc_options: ["stubsourceonly"],
+    droiddoc_options: ["-stubsourceonly"],
+    metalava_enabled: false,
     compile_dex: true
 }
 
diff --git a/tests/ActivityTests/Android.mk b/tests/ActivityTests/Android.mk
index 4c68c8b..94294f6 100644
--- a/tests/ActivityTests/Android.mk
+++ b/tests/ActivityTests/Android.mk
@@ -10,9 +10,5 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/tests/ActivityTests/AndroidManifest.xml:42: error: unexpected element <preferred> found in <manifest><application><activity>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 639ed7d..bd8c7dd 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -92,7 +92,9 @@
             "com.google.android.wearable.action.GOOGLE";
     private static final int INITIAL_LAUNCH_IDLE_TIMEOUT = 5000; // 5s to allow app to idle
     private static final int POST_LAUNCH_IDLE_TIMEOUT = 750; // 750ms idle for non initial launches
-    private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 5000; // 5s between launching apps
+    private static final int BEFORE_FORCE_STOP_SLEEP_TIMEOUT = 1000; // 1s before force stopping
+    private static final int BEFORE_KILL_APP_SLEEP_TIMEOUT = 1000; // 1s before killing
+    private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 3000; // 3s between launching apps
     private static final int PROFILE_SAVE_SLEEP_TIMEOUT = 1000; // Allow 1s for the profile to save
     private static final String LAUNCH_SUB_DIRECTORY = "launch_logs";
     private static final String LAUNCH_FILE = "applaunch.txt";
@@ -326,7 +328,14 @@
                     }
                 }
                 if(mForceStopApp) {
-                    closeApp(launch.getApp());
+                    sleep(BEFORE_FORCE_STOP_SLEEP_TIMEOUT);
+                    forceStopApp(launch.getApp());
+                    sleep(BEFORE_KILL_APP_SLEEP_TIMEOUT);
+                    // Close again for good measure (just in case).
+                    forceStopApp(launch.getApp());
+                    // Kill the backgrounded process in the case forceStopApp only sent it to
+                    // background.
+                    killBackgroundApp(launch.getApp());
                 } else {
                     startHomeIntent();
                 }
@@ -637,7 +646,7 @@
         // Kill all the apps
         for (String appName : mNameToIntent.keySet()) {
             Log.w(TAG, String.format("killing %s", appName));
-            closeApp(appName);
+            forceStopApp(appName);
         }
         // Drop all the cache.
         assertNotNull("Issue in dropping the cache",
@@ -645,7 +654,7 @@
                         .executeShellCommand(DROP_CACHE_SCRIPT));
     }
 
-    private void closeApp(String appName) {
+    private void forceStopApp(String appName) {
         Intent startIntent = mNameToIntent.get(appName);
         if (startIntent != null) {
             String packageName = startIntent.getComponent().getPackageName();
@@ -657,6 +666,18 @@
         }
     }
 
+    private void killBackgroundApp(String appName) {
+        Intent startIntent = mNameToIntent.get(appName);
+        if (startIntent != null) {
+            String packageName = startIntent.getComponent().getPackageName();
+            try {
+                mAm.killBackgroundProcesses(packageName, UserHandle.USER_CURRENT);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Error closing app", e);
+            }
+        }
+    }
+
     private void sleep(int time) {
         try {
             Thread.sleep(time);
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
index c225e17..a6c21db 100644
--- a/tests/NetworkSecurityConfigTest/Android.mk
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -7,7 +7,6 @@
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.runner \
-    conscrypt \
     android.test.base \
 
 LOCAL_STATIC_JAVA_LIBRARIES := junit
diff --git a/tests/RemoteDisplayProvider/Android.mk b/tests/RemoteDisplayProvider/Android.mk
index e827ec2..43bf024 100644
--- a/tests/RemoteDisplayProvider/Android.mk
+++ b/tests/RemoteDisplayProvider/Android.mk
@@ -18,9 +18,9 @@
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := RemoteDisplayProviderTest
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := system_current
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
-LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay.stubs
+LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index 750e2fb..132135d 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -63,7 +63,8 @@
     libunwindstack \
     libutilscallstack \
     libziparchive \
-    libz
+    libz \
+    netd_aidl_interface-cpp
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
@@ -92,7 +93,8 @@
   liblog \
   libcutils \
   libnativehelper \
-  libnetdaidl
+  libnetdaidl \
+  netd_aidl_interface-cpp
 
 LOCAL_STATIC_LIBRARIES := \
   libpcap \
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 03a617c..6174c6c 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -219,7 +219,7 @@
         // callback triggers
         captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE));
         verify(callback, timeout(500).times(1)).onAvailable(any(Network.class),
-                any(NetworkCapabilities.class), any(LinkProperties.class));
+                any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
 
         // unregister callback
         manager.unregisterNetworkCallback(callback);
@@ -247,7 +247,7 @@
         // callback triggers
         captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE));
         verify(callback, timeout(100).times(1)).onAvailable(any(Network.class),
-                any(NetworkCapabilities.class), any(LinkProperties.class));
+                any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
 
         // unregister callback
         manager.unregisterNetworkCallback(callback);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1c77fcc..17bcea0 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -51,6 +51,10 @@
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
 import static com.android.internal.util.TestUtils.waitForIdleLooper;
@@ -92,6 +96,7 @@
 import android.net.ConnectivityManager.PacketKeepaliveCallback;
 import android.net.ConnectivityManager.TooManyRequestsException;
 import android.net.ConnectivityThread;
+import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
@@ -148,6 +153,7 @@
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
+import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -215,11 +221,13 @@
     private MockNetworkAgent mEthernetNetworkAgent;
     private MockVpn mMockVpn;
     private Context mContext;
+    private INetworkPolicyListener mPolicyListener;
 
     @Mock IpConnectivityMetrics.Logger mMetricsService;
     @Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
     @Mock INetworkManagementService mNetworkManagementService;
     @Mock INetworkStatsService mStatsService;
+    @Mock INetworkPolicyManager mNpm;
 
     private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class);
 
@@ -934,6 +942,11 @@
         }
 
         @Override
+        protected Tethering makeTethering() {
+            return mock(Tethering.class);
+        }
+
+        @Override
         protected int reserveNetId() {
             while (true) {
                 final int netId = super.reserveNetId();
@@ -1023,6 +1036,20 @@
         public void waitForIdle() {
             waitForIdle(TIMEOUT_MS);
         }
+
+        public void setUidRulesChanged(int uidRules) {
+            try {
+                mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
+            } catch (RemoteException ignored) {
+            }
+        }
+
+        public void setRestrictBackgroundChanged(boolean restrictBackground) {
+            try {
+                mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
+            } catch (RemoteException ignored) {
+            }
+        }
     }
 
     /**
@@ -1055,12 +1082,18 @@
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
         LocalServices.addService(
                 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
+
         mService = new WrappedConnectivityService(mServiceContext,
                 mNetworkManagementService,
                 mStatsService,
-                mock(INetworkPolicyManager.class),
+                mNpm,
                 mock(IpConnectivityLog.class));
 
+        final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
+                ArgumentCaptor.forClass(INetworkPolicyListener.class);
+        verify(mNpm).registerListener(policyListenerCaptor.capture());
+        mPolicyListener = policyListenerCaptor.getValue();
+
         // Create local CM before sending system ready so that we can answer
         // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
@@ -1441,7 +1474,8 @@
         RESUMED,
         LOSING,
         LOST,
-        UNAVAILABLE
+        UNAVAILABLE,
+        BLOCKED_STATUS
     }
 
     private static class CallbackInfo {
@@ -1522,6 +1556,11 @@
             setLastCallback(CallbackState.LOST, network, null);
         }
 
+        @Override
+        public void onBlockedStatusChanged(Network network, boolean blocked) {
+            setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked);
+        }
+
         public Network getLastAvailableNetwork() {
             return mLastAvailableNetwork;
         }
@@ -1582,6 +1621,7 @@
         // - onSuspended, iff the network was suspended when the callbacks fire.
         // - onCapabilitiesChanged.
         // - onLinkPropertiesChanged.
+        // - onBlockedStatusChanged.
         //
         // @param agent the network to expect the callbacks on.
         // @param expectSuspended whether to expect a SUSPENDED callback.
@@ -1589,7 +1629,7 @@
         //        onCapabilitiesChanged callback.
         // @param timeoutMs how long to wait for the callbacks.
         void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended,
-                boolean expectValidated, int timeoutMs) {
+                boolean expectValidated, boolean expectBlocked, int timeoutMs) {
             expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
             if (expectSuspended) {
                 expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
@@ -1600,19 +1640,28 @@
                 expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, agent, timeoutMs);
             }
             expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
+            expectBlockedStatusCallback(expectBlocked, agent);
         }
 
         // Expects the available callbacks (validated), plus onSuspended.
         void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated) {
-            expectAvailableCallbacks(agent, true, expectValidated, TEST_CALLBACK_TIMEOUT_MS);
+            expectAvailableCallbacks(agent, true, expectValidated, false, TEST_CALLBACK_TIMEOUT_MS);
         }
 
         void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, true, TEST_CALLBACK_TIMEOUT_MS);
+            expectAvailableCallbacks(agent, false, true, false, TEST_CALLBACK_TIMEOUT_MS);
+        }
+
+        void expectAvailableCallbacksValidatedAndBlocked(MockNetworkAgent agent) {
+            expectAvailableCallbacks(agent, false, true, true, TEST_CALLBACK_TIMEOUT_MS);
         }
 
         void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, false, TEST_CALLBACK_TIMEOUT_MS);
+            expectAvailableCallbacks(agent, false, false, false, TEST_CALLBACK_TIMEOUT_MS);
+        }
+
+        void expectAvailableCallbacksUnvalidatedAndBlocked(MockNetworkAgent agent) {
+            expectAvailableCallbacks(agent, false, false, true, TEST_CALLBACK_TIMEOUT_MS);
         }
 
         // Expects the available callbacks (where the onCapabilitiesChanged must contain the
@@ -1623,6 +1672,9 @@
             expectCallback(CallbackState.AVAILABLE, agent, TEST_CALLBACK_TIMEOUT_MS);
             NetworkCapabilities nc1 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
             expectCallback(CallbackState.LINK_PROPERTIES, agent, TEST_CALLBACK_TIMEOUT_MS);
+            // Implicitly check the network is allowed to use.
+            // TODO: should we need to consider if network is in blocked status in this case?
+            expectBlockedStatusCallback(false, agent);
             NetworkCapabilities nc2 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
             assertEquals(nc1, nc2);
         }
@@ -1665,6 +1717,12 @@
                     fn.test((NetworkCapabilities) cbi.arg));
         }
 
+        void expectBlockedStatusCallback(boolean expectBlocked, MockNetworkAgent agent) {
+            CallbackInfo cbi = expectCallback(CallbackState.BLOCKED_STATUS, agent);
+            boolean actualBlocked = (boolean) cbi.arg;
+            assertEquals(expectBlocked, actualBlocked);
+        }
+
         void assertNoCallback() {
             waitForIdle();
             CallbackInfo c = mCallbacks.peek();
@@ -3223,7 +3281,7 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
                 TEST_CALLBACK_TIMEOUT_MS);
 
         // pass timeout and validate that UNAVAILABLE is not called
@@ -3243,7 +3301,7 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
                 TEST_CALLBACK_TIMEOUT_MS);
         mWiFiNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
@@ -3802,6 +3860,7 @@
         networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
         CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
                 networkAgent);
+        networkCallback.expectCallback(CallbackState.BLOCKED_STATUS, networkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
         networkCallback.assertNoCallback();
         checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
@@ -4010,6 +4069,7 @@
                 mCellNetworkAgent);
         CallbackInfo cbi = cellNetworkCallback.expectCallback(
                 CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
         assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4068,6 +4128,7 @@
                 mCellNetworkAgent);
         CallbackInfo cbi = cellNetworkCallback.expectCallback(
                 CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
         assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4444,6 +4505,101 @@
         mMockVpn.disconnect();
     }
 
+    @Test
+    public void testNetworkBlockedStatus() {
+        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+        final NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .build();
+        mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_REJECT_ALL);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+        // ConnectivityService should cache it not to invoke the callback again.
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        cellNetworkCallback.assertNoCallback();
+
+        mService.setUidRulesChanged(RULE_NONE);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+        // Restrict the network based on UID rule and NOT_METERED capability change.
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
+                mCellNetworkAgent);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        mService.setUidRulesChanged(RULE_ALLOW_METERED);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_NONE);
+        cellNetworkCallback.assertNoCallback();
+
+        // Restrict the network based on BackgroundRestricted.
+        mService.setRestrictBackgroundChanged(true);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        mService.setRestrictBackgroundChanged(true);
+        cellNetworkCallback.assertNoCallback();
+        mService.setRestrictBackgroundChanged(false);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(cellNetworkCallback);
+    }
+
+    @Test
+    public void testNetworkBlockedStatusBeforeAndAfterConnect() {
+        final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(defaultCallback);
+
+        // No Networkcallbacks invoked before any network is active.
+        mService.setUidRulesChanged(RULE_REJECT_ALL);
+        mService.setUidRulesChanged(RULE_NONE);
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        defaultCallback.assertNoCallback();
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
+        defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent);
+
+        // Allow to use the network after switching to NOT_METERED network.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+
+        // Switch to METERED network. Restrict the use of the network.
+        mWiFiNetworkAgent.disconnect();
+        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
+
+        // Network becomes NOT_METERED.
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+        defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        // Verify there's no Networkcallbacks invoked after data saver on/off.
+        mService.setRestrictBackgroundChanged(true);
+        mService.setRestrictBackgroundChanged(false);
+        defaultCallback.assertNoCallback();
+
+        mCellNetworkAgent.disconnect();
+        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        defaultCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(defaultCallback);
+    }
+
     /**
      * Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info.
      */
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 99a5a69..9b919abf 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -34,8 +36,10 @@
 import android.net.IpSecConfig;
 import android.net.IpSecManager;
 import android.net.IpSecSpiResponse;
+import android.net.IpSecTransform;
 import android.net.IpSecTransformResponse;
 import android.net.IpSecTunnelInterfaceResponse;
+import android.net.IpSecUdpEncapResponse;
 import android.net.LinkAddress;
 import android.net.Network;
 import android.net.NetworkUtils;
@@ -62,16 +66,17 @@
 
     private static final int TEST_SPI = 0xD1201D;
 
-    private final String mDestinationAddr;
     private final String mSourceAddr;
+    private final String mDestinationAddr;
     private final LinkAddress mLocalInnerAddress;
+    private final int mFamily;
 
     @Parameterized.Parameters
     public static Collection ipSecConfigs() {
         return Arrays.asList(
                 new Object[][] {
-                {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"},
-                {"2601::2", "2601::10", "2001:db8::1/64"}
+                {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET},
+                {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6}
         });
     }
 
@@ -129,12 +134,14 @@
             new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
     private static final IpSecAlgorithm AEAD_ALGO =
             new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+    private static final int REMOTE_ENCAP_PORT = 4500;
 
     public IpSecServiceParameterizedTest(
-            String sourceAddr, String destAddr, String localInnerAddr) {
+            String sourceAddr, String destAddr, String localInnerAddr, int family) {
         mSourceAddr = sourceAddr;
         mDestinationAddr = destAddr;
         mLocalInnerAddress = new LinkAddress(localInnerAddr);
+        mFamily = family;
     }
 
     @Before
@@ -157,6 +164,8 @@
             .thenReturn(AppOpsManager.MODE_IGNORED);
     }
 
+    //TODO: Add a test to verify SPI.
+
     @Test
     public void testIpSecServiceReserveSpi() throws Exception {
         when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
@@ -257,6 +266,47 @@
         config.setAuthentication(AUTH_ALGO);
     }
 
+    private void addEncapSocketToIpSecConfig(int resourceId, IpSecConfig config) throws Exception {
+        config.setEncapType(IpSecTransform.ENCAP_ESPINUDP);
+        config.setEncapSocketResourceId(resourceId);
+        config.setEncapRemotePort(REMOTE_ENCAP_PORT);
+    }
+
+    private void verifyTransformNetdCalledForCreatingSA(
+            IpSecConfig config, IpSecTransformResponse resp) throws Exception {
+        verifyTransformNetdCalledForCreatingSA(config, resp, 0);
+    }
+
+    private void verifyTransformNetdCalledForCreatingSA(
+            IpSecConfig config, IpSecTransformResponse resp, int encapSocketPort) throws Exception {
+        IpSecAlgorithm auth = config.getAuthentication();
+        IpSecAlgorithm crypt = config.getEncryption();
+        IpSecAlgorithm authCrypt = config.getAuthenticatedEncryption();
+
+        verify(mMockNetd, times(1))
+                .ipSecAddSecurityAssociation(
+                        eq(mUid),
+                        eq(config.getMode()),
+                        eq(config.getSourceAddress()),
+                        eq(config.getDestinationAddress()),
+                        eq((config.getNetwork() != null) ? config.getNetwork().netId : 0),
+                        eq(TEST_SPI),
+                        eq(0),
+                        eq(0),
+                        eq((auth != null) ? auth.getName() : ""),
+                        eq((auth != null) ? auth.getKey() : new byte[] {}),
+                        eq((auth != null) ? auth.getTruncationLengthBits() : 0),
+                        eq((crypt != null) ? crypt.getName() : ""),
+                        eq((crypt != null) ? crypt.getKey() : new byte[] {}),
+                        eq((crypt != null) ? crypt.getTruncationLengthBits() : 0),
+                        eq((authCrypt != null) ? authCrypt.getName() : ""),
+                        eq((authCrypt != null) ? authCrypt.getKey() : new byte[] {}),
+                        eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0),
+                        eq(config.getEncapType()),
+                        eq(encapSocketPort),
+                        eq(config.getEncapRemotePort()));
+    }
+
     @Test
     public void testCreateTransform() throws Exception {
         IpSecConfig ipSecConfig = new IpSecConfig();
@@ -267,28 +317,7 @@
                 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
         assertEquals(IpSecManager.Status.OK, createTransformResp.status);
 
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(mUid),
-                        anyInt(),
-                        anyString(),
-                        anyString(),
-                        anyInt(),
-                        eq(TEST_SPI),
-                        anyInt(),
-                        anyInt(),
-                        eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
-                        eq(AUTH_KEY),
-                        anyInt(),
-                        eq(IpSecAlgorithm.CRYPT_AES_CBC),
-                        eq(CRYPT_KEY),
-                        anyInt(),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
+        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
     }
 
     @Test
@@ -302,28 +331,59 @@
                 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
         assertEquals(IpSecManager.Status.OK, createTransformResp.status);
 
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(mUid),
-                        anyInt(),
-                        anyString(),
-                        anyString(),
-                        anyInt(),
-                        eq(TEST_SPI),
-                        anyInt(),
-                        anyInt(),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
-                        eq(AEAD_KEY),
-                        anyInt(),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
+        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
+    }
+
+    @Test
+    public void testCreateTransportModeTransformWithEncap() throws Exception {
+        IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        ipSecConfig.setMode(IpSecTransform.MODE_TRANSPORT);
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+        addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
+
+        if (mFamily == AF_INET) {
+            IpSecTransformResponse createTransformResp =
+                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+            assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
+        } else {
+            try {
+                IpSecTransformResponse createTransformResp =
+                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+                fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
+            } catch (IllegalArgumentException expected) {
+            }
+        }
+    }
+
+    @Test
+    public void testCreateTunnelModeTransformWithEncap() throws Exception {
+        IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+        addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
+
+        if (mFamily == AF_INET) {
+            IpSecTransformResponse createTransformResp =
+                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+            assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
+        } else {
+            try {
+                IpSecTransformResponse createTransformResp =
+                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+                fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
+            } catch (IllegalArgumentException expected) {
+            }
+        }
     }
 
     @Test
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 48cfc44..750fb56 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -120,7 +120,6 @@
         "util/BigBuffer.cpp",
         "util/Files.cpp",
         "util/Util.cpp",
-        "ConfigDescription.cpp",
         "Debug.cpp",
         "DominatorTree.cpp",
         "Flags.cpp",
@@ -130,7 +129,6 @@
         "java/ManifestClassGenerator.cpp",
         "java/ProguardRules.cpp",
         "LoadedApk.cpp",
-        "Locale.cpp",
         "Resource.cpp",
         "ResourceParser.cpp",
         "ResourceTable.cpp",
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index c9987b8..b165c6b 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -2,10 +2,19 @@
 
 include $(CLEAR_VARS)
 
+aapt2_results := $(call intermediates-dir-for,PACKAGING,aapt2_run_host_unit_tests)/result.xml
+
 # Target for running host unit tests on post/pre-submit.
 .PHONY: aapt2_run_host_unit_tests
-aapt2_run_host_unit_tests: PRIVATE_GTEST_OPTIONS := --gtest_output=xml:$(DIST_DIR)/gtest/aapt2_host_unit_tests_result.xml
-aapt2_run_host_unit_tests: $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
-	-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests $(PRIVATE_GTEST_OPTIONS) > /dev/null 2>&1
+aapt2_run_host_unit_tests: $(aapt2_results)
+
+$(call dist-for-goals,aapt2_run_host_unit_tests,$(aapt2_results):gtest/aapt2_host_unit_tests_result.xml)
+
+# Always run the tests again, even if they haven't changed
+$(aapt2_results): .KATI_IMPLICIT_OUTPUTS := $(aapt2_results)-nocache
+$(aapt2_results): $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
+	-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests --gtest_output=xml:$@ > /dev/null 2>&1
+
+aapt2_results :=
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/DominatorTree.cpp b/tools/aapt2/DominatorTree.cpp
index 118a385..ff18033 100644
--- a/tools/aapt2/DominatorTree.cpp
+++ b/tools/aapt2/DominatorTree.cpp
@@ -19,8 +19,9 @@
 #include <algorithm>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
+using ::android::ConfigDescription;
 
 namespace aapt {
 
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index efc523f..fe4f951 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -23,6 +23,8 @@
 #include "test/Test.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/OWNERS b/tools/aapt2/OWNERS
index 23ec5ab..f1903a5 100644
--- a/tools/aapt2/OWNERS
+++ b/tools/aapt2/OWNERS
@@ -1,2 +1,3 @@
 set noparent
 toddke@google.com
+rtmitchell@google.com
\ No newline at end of file
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 6fcf0f6..1c1aedd 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -24,10 +24,10 @@
 #include <tuple>
 #include <vector>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "utils/JenkinsHash.h"
 
-#include "ConfigDescription.h"
 #include "Source.h"
 
 namespace aapt {
@@ -171,7 +171,7 @@
   ResourceName name;
 
   // Configuration
-  ConfigDescription config;
+  android::ConfigDescription config;
 
   // Type
   Type type;
@@ -189,7 +189,7 @@
  */
 struct ResourceKey {
   ResourceName name;
-  ConfigDescription config;
+  android::ConfigDescription config;
 };
 
 bool operator<(const ResourceKey& a, const ResourceKey& b);
@@ -201,16 +201,16 @@
  */
 struct ResourceKeyRef {
   ResourceNameRef name;
-  ConfigDescription config;
+  android::ConfigDescription config;
 
   ResourceKeyRef() = default;
-  ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c)
+  ResourceKeyRef(const ResourceNameRef& n, const android::ConfigDescription& c)
       : name(n), config(c) {}
 
   /**
    * Prevent taking a reference to a temporary. This is bad.
    */
-  ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
+  ResourceKeyRef(ResourceName&& n, const android::ConfigDescription& c) = delete;
 };
 
 bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 7f48544..39ca80b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -34,6 +34,7 @@
 
 using ::aapt::ResourceUtils::StringBuilder;
 using ::aapt::text::Utf8Iterator;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 namespace aapt {
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index fb9dbd0..6cc7b76 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -20,9 +20,9 @@
 #include <memory>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -53,7 +53,7 @@
 class ResourceParser {
  public:
   ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
-                 const ConfigDescription& config,
+                 const android::ConfigDescription& config,
                  const ResourceParserOptions& options = {});
   bool Parse(xml::XmlPullParser* parser);
 
@@ -110,7 +110,7 @@
   IDiagnostics* diag_;
   ResourceTable* table_;
   Source source_;
-  ConfigDescription config_;
+  android::ConfigDescription config_;
   ResourceParserOptions options_;
 };
 
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 41b4041..9de43c0 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -29,6 +29,7 @@
 using ::aapt::io::StringInputStream;
 using ::aapt::test::StrValueEq;
 using ::aapt::test::ValueEq;
+using ::android::ConfigDescription;
 using ::android::Res_value;
 using ::android::ResTable_map;
 using ::android::StringPiece;
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index d0faac3..c2274d0 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -23,9 +23,9 @@
 
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "NameMangler.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
@@ -33,6 +33,7 @@
 #include "util/Util.h"
 
 using ::aapt::text::IsValidResourceEntryName;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::StringPrintf;
 
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 8534eaa..7b19a31 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -17,7 +17,6 @@
 #ifndef AAPT_RESOURCE_TABLE_H
 #define AAPT_RESOURCE_TABLE_H
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "Resource.h"
 #include "ResourceValues.h"
@@ -26,6 +25,7 @@
 #include "io/File.h"
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include <functional>
@@ -66,7 +66,7 @@
 class ResourceConfigValue {
  public:
   // The configuration for which this value is defined.
-  const ConfigDescription config;
+  const android::ConfigDescription config;
 
   // The product for which this value is defined.
   const std::string product;
@@ -74,7 +74,7 @@
   // The actual Value.
   std::unique_ptr<Value> value;
 
-  ResourceConfigValue(const ConfigDescription& config, const android::StringPiece& product)
+  ResourceConfigValue(const android::ConfigDescription& config, const android::StringPiece& product)
       : config(config), product(product.to_string()) {}
 
  private:
@@ -103,14 +103,14 @@
 
   explicit ResourceEntry(const android::StringPiece& name) : name(name.to_string()) {}
 
-  ResourceConfigValue* FindValue(const ConfigDescription& config);
+  ResourceConfigValue* FindValue(const android::ConfigDescription& config);
 
-  ResourceConfigValue* FindValue(const ConfigDescription& config,
+  ResourceConfigValue* FindValue(const android::ConfigDescription& config,
                                  const android::StringPiece& product);
 
-  ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config,
+  ResourceConfigValue* FindOrCreateValue(const android::ConfigDescription& config,
                                          const android::StringPiece& product);
-  std::vector<ResourceConfigValue*> FindAllValues(const ConfigDescription& config);
+  std::vector<ResourceConfigValue*> FindAllValues(const android::ConfigDescription& config);
 
   template <typename Func>
   std::vector<ResourceConfigValue*> FindValuesIf(Func f) {
@@ -182,29 +182,30 @@
   // When a collision of resources occurs, this method decides which value to keep.
   static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);
 
-  bool AddResource(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddResource(const ResourceNameRef& name, const android::ConfigDescription& config,
                    const android::StringPiece& product, std::unique_ptr<Value> value,
                    IDiagnostics* diag);
 
   bool AddResourceWithId(const ResourceNameRef& name, const ResourceId& res_id,
-                         const ConfigDescription& config, const android::StringPiece& product,
-                         std::unique_ptr<Value> value, IDiagnostics* diag);
+                         const android::ConfigDescription& config,
+                         const android::StringPiece& product, std::unique_ptr<Value> value,
+                         IDiagnostics* diag);
 
-  bool AddFileReference(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReference(const ResourceNameRef& name, const android::ConfigDescription& config,
                         const Source& source, const android::StringPiece& path, IDiagnostics* diag);
 
-  bool AddFileReferenceMangled(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReferenceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
                                const Source& source, const android::StringPiece& path,
                                io::IFile* file, IDiagnostics* diag);
 
   // Same as AddResource, but doesn't verify the validity of the name. This is used
   // when loading resources from an existing binary resource table that may have mangled names.
-  bool AddResourceMangled(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddResourceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
                           const android::StringPiece& product, std::unique_ptr<Value> value,
                           IDiagnostics* diag);
 
   bool AddResourceWithIdMangled(const ResourceNameRef& name, const ResourceId& id,
-                                const ConfigDescription& config,
+                                const android::ConfigDescription& config,
                                 const android::StringPiece& product, std::unique_ptr<Value> value,
                                 IDiagnostics* diag);
 
@@ -277,11 +278,12 @@
                     IDiagnostics* diag);
 
   bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
-                       const ConfigDescription& config, const android::StringPiece& product,
-                       std::unique_ptr<Value> value, NameValidator name_validator,
-                       const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag);
+                       const android::ConfigDescription& config,
+                       const android::StringPiece& product, std::unique_ptr<Value> value,
+                       NameValidator name_validator, const CollisionResolverFunc& conflict_resolver,
+                       IDiagnostics* diag);
 
-  bool AddFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReferenceImpl(const ResourceNameRef& name, const android::ConfigDescription& config,
                             const Source& source, const android::StringPiece& path, io::IFile* file,
                             NameValidator name_validator, IDiagnostics* diag);
 
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 7fa8ea2..1a1f73f 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -24,6 +24,7 @@
 #include <ostream>
 #include <string>
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::testing::Eq;
 using ::testing::NotNull;
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 560077c..82d9e04 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -31,6 +31,7 @@
 #include "util/Util.h"
 
 using ::aapt::text::Utf8Iterator;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 using ::android::base::StringPrintf;
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 7af2fe0..e2f1c89 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -20,6 +20,7 @@
 #include <functional>
 #include <memory>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
@@ -219,7 +220,8 @@
 
 // Parses the binary form of a resource value. `type` is used as a hint to know when a value is
 // an ID versus a False boolean value, etc. `config` is for sorting strings in the string pool.
-std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const ConfigDescription& config,
+std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type,
+                                          const android::ConfigDescription& config,
                                           const android::ResStringPool& src_pool,
                                           const android::Res_value& res_value,
                                           StringPool* dst_pool);
diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h
index f5b464d..1006ca9 100644
--- a/tools/aapt2/StringPool.h
+++ b/tools/aapt2/StringPool.h
@@ -24,9 +24,9 @@
 #include <vector>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "util/BigBuffer.h"
 
@@ -60,12 +60,12 @@
       kLowPriority = 0xffffffffu,
     };
     uint32_t priority = kNormalPriority;
-    ConfigDescription config;
+    android::ConfigDescription config;
 
     Context() = default;
-    Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
+    Context(uint32_t p, const android::ConfigDescription& c) : priority(p), config(c) {}
     explicit Context(uint32_t p) : priority(p) {}
-    explicit Context(const ConfigDescription& c) : priority(kNormalPriority), config(c) {
+    explicit Context(const android::ConfigDescription& c) : priority(kNormalPriority), config(c) {
     }
   };
 
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index ab8a4b7..411ad74 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -21,11 +21,11 @@
 #include "android-base/errors.h"
 #include "android-base/file.h"
 #include "android-base/utf8.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "google/protobuf/io/coded_stream.h"
 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "Flags.h"
 #include "ResourceParser.h"
@@ -50,6 +50,7 @@
 
 using ::aapt::io::FileInputStream;
 using ::aapt::text::Printer;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::SystemErrorCodeToString;
 using ::google::protobuf::io::CopyingOutputStreamAdaptor;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index db42e7c..60cab5d 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -24,13 +24,13 @@
 #include "android-base/errors.h"
 #include "android-base/file.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/Locale.h"
 #include "androidfw/StringPiece.h"
 
 #include "AppInfo.h"
 #include "Debug.h"
 #include "Flags.h"
 #include "LoadedApk.h"
-#include "Locale.h"
 #include "NameMangler.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
@@ -68,6 +68,7 @@
 #include "xml/XmlDom.h"
 
 using ::aapt::io::FileInputStream;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::StringPrintf;
 
@@ -105,6 +106,7 @@
   bool no_version_vectors = false;
   bool no_version_transitions = false;
   bool no_resource_deduping = false;
+  bool no_resource_removal = false;
   bool no_xml_namespaces = false;
   bool do_not_compress_anything = false;
   std::unordered_set<std::string> extensions_to_not_compress;
@@ -1806,10 +1808,12 @@
 
     // Before we process anything, remove the resources whose default values don't exist.
     // We want to force any references to these to fail the build.
-    if (!NoDefaultResourceRemover{}.Consume(context_, &final_table_)) {
-      context_->GetDiagnostics()->Error(DiagMessage()
-                                        << "failed removing resources with no defaults");
-      return 1;
+    if (!options_.no_resource_removal) {
+      if (!NoDefaultResourceRemover{}.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
+                                          << "failed removing resources with no defaults");
+        return 1;
+      }
     }
 
     ReferenceLinker linker;
@@ -2084,6 +2088,10 @@
                           "Disables automatic deduping of resources with\n"
                           "identical values across compatible configurations.",
                           &options.no_resource_deduping)
+          .OptionalSwitch("--no-resource-removal",
+                          "Disables automatic removal of resources without defaults. Use this only\n"
+                          "when building runtime resource overlay packages.",
+                          &options.no_resource_removal)
           .OptionalSwitch("--enable-sparse-encoding",
                           "Enables encoding sparse entries using a binary search tree.\n"
                           "This decreases APK size at the cost of resource retrieval performance.",
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 9c76119..45297a7 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -20,6 +20,7 @@
 #include "android-base/file.h"
 #include "android-base/stringprintf.h"
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
@@ -45,6 +46,7 @@
 
 using ::aapt::configuration::Abi;
 using ::aapt::configuration::OutputArtifact;
+using ::android::ConfigDescription;
 using ::android::ResTable_config;
 using ::android::StringPiece;
 using ::android::base::ReadFileToString;
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 8b3a670..25010c5 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -19,15 +19,17 @@
 #include <vector>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/Locale.h"
 
-#include "ConfigDescription.h"
-#include "Locale.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "split/TableSplitter.h"
 #include "util/Maybe.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+using ::android::LocaleValue;
 using ::android::StringPiece;
 
 namespace aapt {
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index 36c24bc..c5de9e0 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -24,6 +24,7 @@
 #include "compile/Pseudolocalizer.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 711558a..3135802 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -19,6 +19,8 @@
 #include "test/Test.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 902334b..dd06b38 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -25,8 +25,8 @@
 
 #include "android-base/file.h"
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceUtils.h"
 #include "configuration/ConfigurationParser.internal.h"
@@ -40,6 +40,8 @@
 #include "xml/XmlDom.h"
 #include "xml/XmlUtil.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index 7f1d445..b9e3be9 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -22,7 +22,8 @@
 #include <unordered_map>
 #include <vector>
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+
 #include "Diagnostics.h"
 #include "util/Maybe.h"
 
@@ -109,8 +110,8 @@
   std::string name;
   int version;
   std::vector<Abi> abis;
-  std::vector<ConfigDescription> screen_densities;
-  std::vector<ConfigDescription> locales;
+  std::vector<android::ConfigDescription> screen_densities;
+  std::vector<android::ConfigDescription> locales;
   Maybe<AndroidSdk> android_sdk;
   std::vector<DeviceFeature> features;
   std::vector<GlTexture> textures;
diff --git a/tools/aapt2/configuration/ConfigurationParser.internal.h b/tools/aapt2/configuration/ConfigurationParser.internal.h
index f071a69..c541688 100644
--- a/tools/aapt2/configuration/ConfigurationParser.internal.h
+++ b/tools/aapt2/configuration/ConfigurationParser.internal.h
@@ -17,6 +17,8 @@
 #ifndef AAPT2_CONFIGURATIONPARSER_INTERNAL_H
 #define AAPT2_CONFIGURATIONPARSER_INTERNAL_H
 
+#include "androidfw/ConfigDescription.h"
+
 #include "configuration/ConfigurationParser.h"
 
 #include <algorithm>
@@ -148,8 +150,8 @@
   Maybe<std::string> artifact_format;
 
   Group<Abi> abi_groups;
-  Group<ConfigDescription> screen_density_groups;
-  Group<ConfigDescription> locale_groups;
+  Group<android::ConfigDescription> screen_density_groups;
+  Group<android::ConfigDescription> locale_groups;
   Group<DeviceFeature> device_feature_groups;
   Group<GlTexture> gl_texture_groups;
   Entry<AndroidSdk> android_sdks;
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index febbb2e..960880a 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -26,6 +26,8 @@
 #include "test/Test.h"
 #include "xml/XmlDom.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace configuration {
diff --git a/tools/aapt2/filter/ConfigFilter.cpp b/tools/aapt2/filter/ConfigFilter.cpp
index 5fbe77e..9d10d59 100644
--- a/tools/aapt2/filter/ConfigFilter.cpp
+++ b/tools/aapt2/filter/ConfigFilter.cpp
@@ -16,9 +16,10 @@
 
 #include "filter/ConfigFilter.h"
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
+using ::android::ConfigDescription;
 
 namespace aapt {
 
diff --git a/tools/aapt2/filter/ConfigFilter.h b/tools/aapt2/filter/ConfigFilter.h
index ebb8151..c4b7e43 100644
--- a/tools/aapt2/filter/ConfigFilter.h
+++ b/tools/aapt2/filter/ConfigFilter.h
@@ -20,7 +20,7 @@
 #include <set>
 #include <utility>
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
 
 namespace aapt {
 
@@ -34,7 +34,7 @@
   /**
    * Returns true if the filter matches the configuration, false otherwise.
    */
-  virtual bool Match(const ConfigDescription& config) const = 0;
+  virtual bool Match(const android::ConfigDescription& config) const = 0;
 };
 
 /**
@@ -46,12 +46,12 @@
  */
 class AxisConfigFilter : public IConfigFilter {
  public:
-  void AddConfig(ConfigDescription config);
+  void AddConfig(android::ConfigDescription config);
 
-  bool Match(const ConfigDescription& config) const override;
+  bool Match(const android::ConfigDescription& config) const override;
 
  private:
-  std::set<std::pair<ConfigDescription, uint32_t>> configs_;
+  std::set<std::pair<android::ConfigDescription, uint32_t>> configs_;
   uint32_t config_mask_ = 0;
 };
 
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.h b/tools/aapt2/format/binary/BinaryResourceParser.h
index a1f9f83..2bdc051 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.h
+++ b/tools/aapt2/format/binary/BinaryResourceParser.h
@@ -20,6 +20,7 @@
 #include <string>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
 #include "ResourceTable.h"
@@ -54,22 +55,28 @@
   bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseLibrary(const android::ResChunk_header* chunk);
 
-  std::unique_ptr<Item> ParseValue(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Item> ParseValue(const ResourceNameRef& name,
+                                   const android::ConfigDescription& config,
                                    const android::Res_value& value);
 
-  std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name,
+                                       const android::ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name,
+                                    const android::ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name,
+                                       const android::ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Array> ParseArray(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Array> ParseArray(const ResourceNameRef& name,
+                                    const android::ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name,
+                                      const android::ConfigDescription& config,
                                       const android::ResTable_map_entry* map);
 
   /**
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 3b101b7..d1b2fdb 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -19,13 +19,15 @@
 #include "android-base/logging.h"
 #include "android-base/macros.h"
 #include "androidfw/ResourceTypes.h"
+#include "androidfw/Locale.h"
 
-#include "Locale.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 
+using ::android::ConfigDescription;
+using ::android::LocaleValue;
 using ::android::ResStringPool;
 
 namespace aapt {
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.h b/tools/aapt2/format/proto/ProtoDeserialize.h
index 0c581a1..723a1c0 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.h
+++ b/tools/aapt2/format/proto/ProtoDeserialize.h
@@ -18,9 +18,9 @@
 #define AAPT_FORMAT_PROTO_PROTODESERIALIZE_H
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "Configuration.pb.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -34,14 +34,15 @@
 
 std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
                                               const android::ResStringPool& src_pool,
-                                              const ConfigDescription& config,
+                                              const android::ConfigDescription& config,
                                               StringPool* value_pool, io::IFileCollection* files,
                                               std::string* out_error);
 
 std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
                                             const android::ResStringPool& src_pool,
-                                            const ConfigDescription& config, StringPool* value_pool,
-                                            io::IFileCollection* files, std::string* out_error);
+                                            const android::ConfigDescription& config,
+                                            StringPool* value_pool, io::IFileCollection* files,
+                                            std::string* out_error);
 
 std::unique_ptr<xml::XmlResource> DeserializeXmlResourceFromPb(const pb::XmlNode& pb_node,
                                                                std::string* out_error);
@@ -49,8 +50,8 @@
 bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el, StringPool* value_pool,
                           std::string* out_error);
 
-bool DeserializeConfigFromPb(const pb::Configuration& pb_config, ConfigDescription* out_config,
-                             std::string* out_error);
+bool DeserializeConfigFromPb(const pb::Configuration& pb_config,
+                             android::ConfigDescription* out_config, std::string* out_error);
 
 // Optional io::IFileCollection used to lookup references to files in the ResourceTable.
 bool DeserializeTableFromPb(const pb::ResourceTable& pb_table, io::IFileCollection* files,
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 411cc29..7e35ea7 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -19,6 +19,8 @@
 #include "ValueVisitor.h"
 #include "util/BigBuffer.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.h b/tools/aapt2/format/proto/ProtoSerialize.h
index 951494c..c40e5dd 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.h
+++ b/tools/aapt2/format/proto/ProtoSerialize.h
@@ -18,8 +18,8 @@
 #define AAPT_FORMAT_PROTO_PROTOSERIALIZE_H
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "Configuration.pb.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -49,7 +49,7 @@
 void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag);
 
 // Serializes a ConfigDescription into its protobuf representation.
-void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_config);
+void SerializeConfig(const android::ConfigDescription& config, pb::Configuration* out_pb_config);
 
 // Serializes a ResourceTable into its protobuf representation.
 void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table, IDiagnostics* diag);
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index 21fdbd8..a0d92f7 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -20,6 +20,7 @@
 #include "format/proto/ProtoDeserialize.h"
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::testing::Eq;
 using ::testing::IsEmpty;
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index 37d1a5f..f774e3a 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -21,6 +21,7 @@
 #include "test/Test.h"
 
 using ::aapt::io::StringOutputStream;
+using ::android::ConfigDescription;
 using ::testing::HasSubstr;
 using ::testing::Not;
 
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index f80c6e9..960c7d4 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -20,14 +20,16 @@
 
 #include "android-base/logging.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
-bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
+                                     const ConfigDescription& config,
                                      const ApiVersion sdk_version_to_generate) {
   // We assume the caller is trying to generate a version greater than the current configuration.
   CHECK(sdk_version_to_generate > config.sdkVersion);
diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp
index 49639f8..1117472 100644
--- a/tools/aapt2/link/AutoVersioner_test.cpp
+++ b/tools/aapt2/link/AutoVersioner_test.cpp
@@ -16,9 +16,11 @@
 
 #include "link/Linkers.h"
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
 using ::testing::NotNull;
 
 namespace aapt {
diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h
index 3c9c476..c9b8d39 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -21,6 +21,7 @@
 #include <unordered_set>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include "Resource.h"
@@ -32,7 +33,6 @@
 
 class ResourceTable;
 class ResourceEntry;
-struct ConfigDescription;
 
 // Defines the context in which a resource value is defined. Most resources are defined with the
 // implicit package name of their compilation context. Understanding the package name of a resource
@@ -43,12 +43,14 @@
 
 // Determines whether a versioned resource should be created. If a versioned resource already
 // exists, it takes precedence.
-bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
+                                     const android::ConfigDescription& config,
                                      const ApiVersion sdk_version_to_generate);
 
 // Finds the next largest ApiVersion of the config which is identical to the given config except
 // for sdkVersion.
-ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry, const ConfigDescription& config);
+ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry,
+                                       const android::ConfigDescription& config);
 
 class AutoVersioner : public IResourceTableConsumer {
  public:
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index ee4e702..7180a99 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -252,6 +252,7 @@
   xml::XmlNodeAction component_action;
   component_action.Action(RequiredNameIsJavaClassName);
   component_action["intent-filter"] = intent_filter_action;
+  component_action["preferred"] = intent_filter_action;
   component_action["meta-data"] = meta_data_action;
 
   // Manifest actions.
@@ -346,6 +347,7 @@
   manifest_action["uses-permission"];
   manifest_action["uses-permission-sdk-23"];
   manifest_action["permission"];
+  manifest_action["permission"]["meta-data"] = meta_data_action;
   manifest_action["permission-tree"];
   manifest_action["permission-group"];
   manifest_action["uses-configuration"];
@@ -355,6 +357,8 @@
   manifest_action["compatible-screens"];
   manifest_action["compatible-screens"]["screen"];
   manifest_action["supports-gl-texture"];
+  manifest_action["restrict-update"];
+  manifest_action["package-verifier"];
   manifest_action["meta-data"] = meta_data_action;
   manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
 
@@ -376,6 +380,7 @@
   uses_static_library_action.Action(RequiredNameIsJavaPackage);
   uses_static_library_action.Action(RequiredAndroidAttribute("version"));
   uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
+  uses_static_library_action["additional-certificate"];
 
   if (options_.debug_mode) {
     application_action.Action([&](xml::Element* el) -> bool {
@@ -399,6 +404,8 @@
   application_action["provider"]["grant-uri-permission"];
   application_action["provider"]["path-permission"];
 
+  manifest_action["package"] = manifest_action;
+
   return true;
 }
 
diff --git a/tools/aapt2/link/NoDefaultResourceRemover.cpp b/tools/aapt2/link/NoDefaultResourceRemover.cpp
index cfb4b26..13054bf 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover.cpp
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
+#include "androidfw/Locale.h"
+
 #include "link/NoDefaultResourceRemover.h"
 
 #include <algorithm>
 
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 static bool IsDefaultConfigRequired(const ConfigDescription& config) {
diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp
index 86dd56a..dd47674 100644
--- a/tools/aapt2/link/ProductFilter_test.cpp
+++ b/tools/aapt2/link/ProductFilter_test.cpp
@@ -18,6 +18,8 @@
 
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(ProductFilterTest, SelectTwoProducts) {
diff --git a/tools/aapt2/optimize/MultiApkGenerator.cpp b/tools/aapt2/optimize/MultiApkGenerator.cpp
index 588b331..aa9f9ab 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator.cpp
@@ -20,6 +20,7 @@
 #include <regex>
 #include <string>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include "LoadedApk.h"
@@ -43,6 +44,7 @@
 using ::aapt::configuration::OutputArtifact;
 using ::aapt::xml::kSchemaAndroid;
 using ::aapt::xml::XmlResource;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 /**
diff --git a/tools/aapt2/optimize/MultiApkGenerator.h b/tools/aapt2/optimize/MultiApkGenerator.h
index c858879..4a5a6c3d 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.h
+++ b/tools/aapt2/optimize/MultiApkGenerator.h
@@ -22,6 +22,8 @@
 #include <unordered_set>
 #include <vector>
 
+#include "androidfw/ConfigDescription.h"
+
 #include "Diagnostics.h"
 #include "LoadedApk.h"
 #include "configuration/ConfigurationParser.h"
@@ -66,7 +68,7 @@
   /**
    * Adds the <screen> elements to the parent node for the provided density configuration.
    */
-  void AddScreens(const ConfigDescription& config, xml::Element* parent);
+  void AddScreens(const android::ConfigDescription& config, xml::Element* parent);
 
   LoadedApk* apk_;
   IAaptContext* context_;
diff --git a/tools/aapt2/optimize/MultiApkGenerator_test.cpp b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
index 80eb737..7d87eb8 100644
--- a/tools/aapt2/optimize/MultiApkGenerator_test.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
@@ -31,6 +31,8 @@
 #include "test/Context.h"
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 namespace {
 
diff --git a/tools/aapt2/optimize/ResourceDeduper.cpp b/tools/aapt2/optimize/ResourceDeduper.cpp
index 9d16268..ee2dfbc 100644
--- a/tools/aapt2/optimize/ResourceDeduper.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper.cpp
@@ -21,6 +21,8 @@
 #include "DominatorTree.h"
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/optimize/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp
index d9f384c0..2e098ae 100644
--- a/tools/aapt2/optimize/ResourceDeduper_test.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp
@@ -20,6 +20,7 @@
 #include "test/Test.h"
 
 using ::aapt::test::HasValue;
+using ::android::ConfigDescription;
 using ::testing::Not;
 
 namespace aapt {
diff --git a/tools/aapt2/optimize/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp
index cc1fc1e..f985604 100644
--- a/tools/aapt2/optimize/VersionCollapser.cpp
+++ b/tools/aapt2/optimize/VersionCollapser.cpp
@@ -21,6 +21,8 @@
 
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 template <typename Iterator, typename Pred>
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 70efbf5..a844a43 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -21,15 +21,16 @@
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
 #include "androidfw/AssetManager.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "NameMangler.h"
 #include "Resource.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index e991743..1dd5502 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -24,11 +24,13 @@
 #include <vector>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 using ConfigClaimedMap = std::unordered_map<ResourceConfigValue*, bool>;
diff --git a/tools/aapt2/split/TableSplitter.h b/tools/aapt2/split/TableSplitter.h
index 6aec257..91afaa3 100644
--- a/tools/aapt2/split/TableSplitter.h
+++ b/tools/aapt2/split/TableSplitter.h
@@ -20,8 +20,8 @@
 #include <set>
 #include <vector>
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "filter/ConfigFilter.h"
 #include "process/IResourceTableConsumer.h"
@@ -29,7 +29,7 @@
 namespace aapt {
 
 struct SplitConstraints {
-  std::set<ConfigDescription> configs;
+  std::set<android::ConfigDescription> configs;
 };
 
 struct TableSplitterOptions {
diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp
index d52f4b44..cdf0738 100644
--- a/tools/aapt2/split/TableSplitter_test.cpp
+++ b/tools/aapt2/split/TableSplitter_test.cpp
@@ -18,6 +18,8 @@
 
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(TableSplitterTest, NoSplitPreferredDensity) {
diff --git a/tools/aapt2/test/Builders.cpp b/tools/aapt2/test/Builders.cpp
index c4eab12..f33ae31 100644
--- a/tools/aapt2/test/Builders.cpp
+++ b/tools/aapt2/test/Builders.cpp
@@ -28,6 +28,7 @@
 using ::aapt::configuration::ConfiguredArtifact;
 using ::aapt::configuration::GetOrCreateGroup;
 using ::aapt::io::StringInputStream;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 namespace aapt {
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index fd5262a..a88b11e 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -20,6 +20,7 @@
 #include <memory>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
 #include "Resource.h"
 #include "ResourceTable.h"
@@ -40,7 +41,8 @@
 
   ResourceTableBuilder& SetPackageId(const android::StringPiece& package_name, uint8_t id);
   ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ResourceId& id = {});
-  ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ConfigDescription& config,
+  ResourceTableBuilder& AddSimple(const android::StringPiece& name,
+                                  const android::ConfigDescription& config,
                                   const ResourceId& id = {});
   ResourceTableBuilder& AddReference(const android::StringPiece& name,
                                      const android::StringPiece& ref);
@@ -51,7 +53,8 @@
   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
                                   const android::StringPiece& str);
   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
-                                  const ConfigDescription& config, const android::StringPiece& str);
+                                  const android::ConfigDescription& config,
+                                  const android::StringPiece& str);
   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
                                          const android::StringPiece& path,
                                          io::IFile* file = nullptr);
@@ -60,12 +63,13 @@
                                          io::IFile* file = nullptr);
   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
                                          const android::StringPiece& path,
-                                         const ConfigDescription& config,
+                                         const android::ConfigDescription& config,
                                          io::IFile* file = nullptr);
   ResourceTableBuilder& AddValue(const android::StringPiece& name, std::unique_ptr<Value> value);
   ResourceTableBuilder& AddValue(const android::StringPiece& name, const ResourceId& id,
                                  std::unique_ptr<Value> value);
-  ResourceTableBuilder& AddValue(const android::StringPiece& name, const ConfigDescription& config,
+  ResourceTableBuilder& AddValue(const android::StringPiece& name,
+                                 const android::ConfigDescription& config,
                                  const ResourceId& id, std::unique_ptr<Value> value);
   ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
                                        Visibility::Level level, bool allow_new = false);
@@ -163,8 +167,8 @@
   ArtifactBuilder& SetName(const std::string& name);
   ArtifactBuilder& SetVersion(int version);
   ArtifactBuilder& AddAbi(configuration::Abi abi);
-  ArtifactBuilder& AddDensity(const ConfigDescription& density);
-  ArtifactBuilder& AddLocale(const ConfigDescription& locale);
+  ArtifactBuilder& AddDensity(const android::ConfigDescription& density);
+  ArtifactBuilder& AddLocale(const android::ConfigDescription& locale);
   ArtifactBuilder& SetAndroidSdk(int min_sdk);
   configuration::OutputArtifact Build();
 
diff --git a/tools/aapt2/test/Common.cpp b/tools/aapt2/test/Common.cpp
index 0fabbc4..b54c155 100644
--- a/tools/aapt2/test/Common.cpp
+++ b/tools/aapt2/test/Common.cpp
@@ -16,6 +16,8 @@
 
 #include "test/Common.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 namespace test {
 
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index aca161a..50b41f1 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -21,11 +21,11 @@
 
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-#include "ConfigDescription.h"
 #include "Debug.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
@@ -45,15 +45,15 @@
   return ref.ToResourceName();
 }
 
-inline ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
-  ConfigDescription config;
-  CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
+inline android::ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
+    android::ConfigDescription config;
+  CHECK(android::ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
   return config;
 }
 
 template <typename T = Value>
 T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name,
-                               const ConfigDescription& config,
+                               const android::ConfigDescription& config,
                                const android::StringPiece& product) {
   Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name));
   if (result) {
@@ -68,12 +68,12 @@
 template <>
 Value* GetValueForConfigAndProduct<Value>(ResourceTable* table,
                                           const android::StringPiece& res_name,
-                                          const ConfigDescription& config,
+                                          const android::ConfigDescription& config,
                                           const android::StringPiece& product);
 
 template <typename T = Value>
 T* GetValueForConfig(ResourceTable* table, const android::StringPiece& res_name,
-                     const ConfigDescription& config) {
+                     const android::ConfigDescription& config) {
   return GetValueForConfigAndProduct<T>(table, res_name, config, {});
 }
 
diff --git a/tools/hiddenapi/merge_csv.py b/tools/hiddenapi/merge_csv.py
new file mode 100755
index 0000000..48c0755
--- /dev/null
+++ b/tools/hiddenapi/merge_csv.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# 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.
+"""
+Merge mutliple CSV files, possibly with different columns, writing to stdout.
+"""
+
+import csv
+import sys
+
+csv_readers = [
+    csv.DictReader(open(csv_file, 'rb'), delimiter=',', quotechar='|')
+    for csv_file in sys.argv[1:]
+]
+
+# Build union of all columns from source files:
+headers = set()
+for reader in csv_readers:
+  headers = headers.union(reader.fieldnames)
+
+# Concatenate all files to output:
+out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', fieldnames = sorted(headers))
+out.writeheader()
+for reader in csv_readers:
+  for row in reader:
+    out.writerow(row)
+
+
diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh
index 76a2f2d..710da40 100755
--- a/tools/hiddenapi/sort_api.sh
+++ b/tools/hiddenapi/sort_api.sh
@@ -21,4 +21,6 @@
 A=( ${C[*]} ${A[*]} )
 unset IFS
 # Dump array back into the file
-printf '%s\n' "${A[@]}" > "$dest_list"
+if [ ${#A[@]} -ne 0 ]; then
+  printf '%s\n' "${A[@]}" > "$dest_list"
+fi
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
index 5c9df6a..c7993e3 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
@@ -189,8 +189,7 @@
         Map<String, Long> homeNetworkIds = new HashMap<>();
         byte[] rawSsidBytes = new byte[33];
         Arrays.fill(rawSsidBytes, (byte) 'a');
-        homeNetworkIds.put(
-                StringFactory.newStringFromBytes(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
+        homeNetworkIds.put(new String(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
         homeSp.setHomeNetworkIds(homeNetworkIds);
         assertFalse(homeSp.validate());
     }