Merge "create getModemEnabled function in PhoneConfigurationManager"
diff --git a/api/current.txt b/api/current.txt
index 5084fda..513d3a4 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -39440,7 +39440,7 @@
 
   public class CarrierIdentifier implements android.os.Parcelable {
     ctor public CarrierIdentifier(String, String, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
-    ctor public CarrierIdentifier(String, String, @Nullable String, @Nullable String, @Nullable String, @Nullable String, int, int);
+    ctor public CarrierIdentifier(@NonNull String, @NonNull String, @Nullable String, @Nullable String, @Nullable String, @Nullable String, int, int);
     ctor public CarrierIdentifier(byte[], @Nullable String, @Nullable String);
     method public int describeContents();
     method public int getCarrierId();
@@ -41263,14 +41263,14 @@
     field public static final android.os.Parcelable.Creator<android.telecom.CallIdentification> CREATOR;
   }
 
-  public static class CallIdentification.Builder {
+  public static final class CallIdentification.Builder {
     ctor public CallIdentification.Builder();
-    method public android.telecom.CallIdentification build();
-    method public android.telecom.CallIdentification.Builder setDescription(@Nullable CharSequence);
-    method public android.telecom.CallIdentification.Builder setDetails(@Nullable CharSequence);
-    method public android.telecom.CallIdentification.Builder setName(@Nullable CharSequence);
-    method public android.telecom.CallIdentification.Builder setNuisanceConfidence(int);
-    method public android.telecom.CallIdentification.Builder setPhoto(@Nullable android.graphics.drawable.Icon);
+    method @NonNull public android.telecom.CallIdentification build();
+    method @NonNull public android.telecom.CallIdentification.Builder setDescription(@Nullable CharSequence);
+    method @NonNull public android.telecom.CallIdentification.Builder setDetails(@Nullable CharSequence);
+    method @NonNull public android.telecom.CallIdentification.Builder setName(@Nullable CharSequence);
+    method @NonNull public android.telecom.CallIdentification.Builder setNuisanceConfidence(int);
+    method @NonNull public android.telecom.CallIdentification.Builder setPhoto(@Nullable android.graphics.drawable.Icon);
   }
 
   public abstract class CallRedirectionService extends android.app.Service {
@@ -41736,6 +41736,7 @@
   }
 
   public final class PhoneAccountSuggestion implements android.os.Parcelable {
+    ctor public PhoneAccountSuggestion(@NonNull android.telecom.PhoneAccountHandle, int, boolean);
     method public int describeContents();
     method @NonNull public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
     method public int getReason();
@@ -41891,8 +41892,8 @@
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts();
     method public android.telecom.PhoneAccountHandle getSimCallManager();
-    method public String getSystemDialerPackage();
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telecom.PhoneAccountHandle getUserSelectedOutgoingPhoneAccount();
+    method @Nullable public String getSystemDialerPackage();
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public android.telecom.PhoneAccountHandle getUserSelectedOutgoingPhoneAccount();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
@@ -42727,7 +42728,7 @@
   public class ServiceState implements android.os.Parcelable {
     ctor public ServiceState();
     ctor public ServiceState(android.telephony.ServiceState);
-    ctor public ServiceState(android.os.Parcel);
+    ctor @Deprecated public ServiceState(android.os.Parcel);
     method protected void copyFrom(android.telephony.ServiceState);
     method public int describeContents();
     method public int getCdmaNetworkId();
@@ -43043,8 +43044,8 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getImei();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getImei(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}) public String getLine1Number();
-    method public String getManufacturerCode();
-    method public String getManufacturerCode(int);
+    method @Nullable public String getManufacturerCode();
+    method @Nullable public String getManufacturerCode(int);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getMeid();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getMeid(int);
     method public String getMmsUAProfUrl();
@@ -43071,8 +43072,8 @@
     method public int getSimState();
     method public int getSimState(int);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getSubscriberId();
-    method public String getTypeAllocationCode();
-    method public String getTypeAllocationCode(int);
+    method @Nullable public String getTypeAllocationCode();
+    method @Nullable public String getTypeAllocationCode(int);
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @NonNull public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVisualVoicemailPackageName();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailAlphaTag();
@@ -43454,7 +43455,7 @@
   }
 
   public class EuiccManager {
-    method public android.telephony.euicc.EuiccManager createForCardId(int);
+    method @NonNull public android.telephony.euicc.EuiccManager createForCardId(int);
     method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void deleteSubscription(int, android.app.PendingIntent);
     method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void downloadSubscription(android.telephony.euicc.DownloadableSubscription, boolean, android.app.PendingIntent);
     method @Nullable public String getEid();
diff --git a/api/system-current.txt b/api/system-current.txt
index 9eee606..1f58de8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4863,8 +4863,8 @@
 
   public abstract class ApnService extends android.app.Service {
     ctor public ApnService();
-    method public android.os.IBinder onBind(android.content.Intent);
-    method @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
+    method @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
+    method @WorkerThread @NonNull public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
   }
 
 }
@@ -5412,10 +5412,6 @@
     field public static final int CAPABILITY_MULTI_USER = 32; // 0x20
   }
 
-  public final class PhoneAccountSuggestion implements android.os.Parcelable {
-    ctor public PhoneAccountSuggestion(@NonNull android.telecom.PhoneAccountHandle, int, boolean);
-  }
-
   public class PhoneAccountSuggestionService extends android.app.Service {
     ctor public PhoneAccountSuggestionService();
     method public void onAccountSuggestionRequest(@NonNull String);
@@ -5491,8 +5487,8 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall();
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(String);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(android.telecom.PhoneAccountHandle);
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(@Nullable String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle);
     field public static final String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
     field public static final String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
     field public static final String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
@@ -5512,12 +5508,12 @@
     field public static final int WWAN = 1; // 0x1
   }
 
-  public class CallAttributes implements android.os.Parcelable {
-    ctor public CallAttributes(android.telephony.PreciseCallState, int, android.telephony.CallQuality);
+  public final class CallAttributes implements android.os.Parcelable {
+    ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
     method public int describeContents();
-    method public android.telephony.CallQuality getCallQuality();
+    method @NonNull public android.telephony.CallQuality getCallQuality();
     method public int getNetworkType();
-    method public android.telephony.PreciseCallState getPreciseCallState();
+    method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
   }
@@ -6030,12 +6026,11 @@
   }
 
   public class NetworkRegistrationState implements android.os.Parcelable {
-    ctor public NetworkRegistrationState(int, int, int, int, int, boolean, int[], @Nullable android.telephony.CellIdentity);
-    ctor protected NetworkRegistrationState(android.os.Parcel);
+    ctor public NetworkRegistrationState(int, int, int, int, int, boolean, @NonNull int[], @Nullable android.telephony.CellIdentity);
     method public int describeContents();
     method public int getAccessNetworkTechnology();
-    method public int[] getAvailableServices();
-    method public android.telephony.CellIdentity getCellIdentity();
+    method @NonNull public int[] getAvailableServices();
+    method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates();
     method public int getDomain();
     method public int getRegState();
@@ -6061,9 +6056,25 @@
     field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
+  public static class NetworkRegistrationState.Builder {
+    ctor public NetworkRegistrationState.Builder();
+    method @NonNull public android.telephony.NetworkRegistrationState build();
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setAccessNetworkTechnology(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setAvailableServices(@NonNull int[]);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setDomain(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setNrStatus(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRegState(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRejectCause(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRoamingType(int);
+    method @NonNull public android.telephony.NetworkRegistrationState.Builder setTransportType(int);
+  }
+
   public abstract class NetworkService extends android.app.Service {
     ctor public NetworkService();
-    method protected abstract android.telephony.NetworkService.NetworkServiceProvider createNetworkServiceProvider(int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int);
     field public static final String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
   }
 
@@ -6071,12 +6082,12 @@
     ctor public NetworkService.NetworkServiceProvider(int);
     method public abstract void close();
     method public void getNetworkRegistrationState(int, @NonNull android.telephony.NetworkServiceCallback);
-    method public final int getSlotId();
+    method public final int getSlotIndex();
     method public final void notifyNetworkRegistrationStateChanged();
   }
 
   public class NetworkServiceCallback {
-    method public void onGetNetworkRegistrationStateComplete(int, android.telephony.NetworkRegistrationState);
+    method public void onGetNetworkRegistrationStateComplete(int, @Nullable android.telephony.NetworkRegistrationState);
     field public static final int RESULT_ERROR_BUSY = 3; // 0x3
     field public static final int RESULT_ERROR_FAILED = 5; // 0x5
     field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
@@ -6364,7 +6375,7 @@
     method @Deprecated public boolean getDataEnabled(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.util.Pair<java.lang.Integer,java.lang.Integer>> getLogicalToPhysicalSlotMapping();
     method public static long getMaxNumberVerificationTimeoutMillis();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmap();
@@ -6507,7 +6518,6 @@
 
   public final class DataCallResponse implements android.os.Parcelable {
     ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List<android.net.LinkAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.lang.String>, int);
-    ctor public DataCallResponse(android.os.Parcel);
     method public int describeContents();
     method public int getActive();
     method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -6549,7 +6559,8 @@
 
   public abstract class DataService extends android.app.Service {
     ctor public DataService();
-    method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int);
     field public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
     field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
     field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
@@ -6561,7 +6572,7 @@
     method public abstract void close();
     method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
     method public void getDataCallList(@NonNull android.telephony.data.DataServiceCallback);
-    method public final int getSlotId();
+    method public final int getSlotIndex();
     method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
     method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @Nullable android.telephony.data.DataServiceCallback);
     method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @Nullable android.telephony.data.DataServiceCallback);
@@ -6569,12 +6580,12 @@
   }
 
   public class DataServiceCallback {
-    method public void onDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
     method public void onDeactivateDataCallComplete(int);
-    method public void onGetDataCallListComplete(int, java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onGetDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>);
     method public void onSetDataProfileComplete(int);
     method public void onSetInitialAttachApnComplete(int);
-    method public void onSetupDataCallComplete(int, android.telephony.data.DataCallResponse);
+    method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse);
     field public static final int RESULT_ERROR_BUSY = 3; // 0x3
     field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
     field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
@@ -6834,7 +6845,7 @@
   }
 
   public class ImsCallSessionListener {
-    method public void callQualityChanged(android.telephony.CallQuality);
+    method public void callQualityChanged(@NonNull android.telephony.CallQuality);
     method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
@@ -6859,7 +6870,7 @@
     method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
-    method public void callSessionRttAudioIndicatorChanged(android.telephony.ims.ImsStreamMediaProfile);
+    method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
     method public void callSessionRttMessageReceived(String);
     method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionRttModifyResponseReceived(int);
@@ -7163,12 +7174,12 @@
   public final class ImsSsData implements android.os.Parcelable {
     ctor public ImsSsData(int, int, int, int, int);
     method public int describeContents();
-    method public android.telephony.ims.ImsCallForwardInfo[] getCallForwardInfo();
+    method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
     method public int getRequestType();
     method public int getResult();
     method public int getServiceClass();
     method public int getServiceType();
-    method @NonNull public android.telephony.ims.ImsSsInfo[] getSuppServiceInfo();
+    method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
     method public int getTeleserviceType();
     method public boolean isTypeBarring();
     method public boolean isTypeCf();
@@ -7228,11 +7239,11 @@
     field public static final int SS_WAIT = 12; // 0xc
   }
 
-  public static class ImsSsData.Builder {
+  public static final class ImsSsData.Builder {
     ctor public ImsSsData.Builder(int, int, int, int, int);
     method @NonNull public android.telephony.ims.ImsSsData build();
-    method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull android.telephony.ims.ImsCallForwardInfo[]);
-    method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull android.telephony.ims.ImsSsInfo[]);
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
   }
 
   public final class ImsSsInfo implements android.os.Parcelable {
@@ -7241,7 +7252,7 @@
     method public int getClirInterrogationStatus();
     method public int getClirOutgoingState();
     method @Deprecated public String getIcbNum();
-    method public String getIncomingCommunicationBarringNumber();
+    method @Nullable public String getIncomingCommunicationBarringNumber();
     method public int getProvisionStatus();
     method public int getStatus();
     method public void writeToParcel(android.os.Parcel, int);
@@ -7262,7 +7273,7 @@
     field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
   }
 
-  public static class ImsSsInfo.Builder {
+  public static final class ImsSsInfo.Builder {
     ctor public ImsSsInfo.Builder(int);
     method @NonNull public android.telephony.ims.ImsSsInfo build();
     method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 271f7cb..2300906 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1443,10 +1443,6 @@
     method public android.telecom.Connection getPrimaryConnection();
   }
 
-  public final class PhoneAccountSuggestion implements android.os.Parcelable {
-    ctor public PhoneAccountSuggestion(@NonNull android.telecom.PhoneAccountHandle, int, boolean);
-  }
-
   public class PhoneAccountSuggestionService extends android.app.Service {
     ctor public PhoneAccountSuggestionService();
     method public void onAccountSuggestionRequest(@NonNull String);
@@ -1458,7 +1454,7 @@
   public class TelecomManager {
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCurrentTtyMode();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall();
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(android.telecom.PhoneAccountHandle);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle);
     field public static final int TTY_MODE_FULL = 1; // 0x1
     field public static final int TTY_MODE_HCO = 2; // 0x2
     field public static final int TTY_MODE_OFF = 0; // 0x0
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2fe6caf..47eccdb 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -2410,6 +2410,9 @@
 
     // The elapsed real time of start of the process.
     optional int64 process_start_time_nanos = 9;
+
+    // Min oom adj score considered by lmkd.
+    optional int32 min_oom_score = 10;
 }
 
 /*
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index e9bd735..709f115 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -3444,7 +3444,6 @@
 Lcom/android/internal/telephony/ServiceStateTracker;->isInvalidOperatorNumeric(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/ServiceStateTracker;->log(Ljava/lang/String;)V
 Lcom/android/internal/telephony/ServiceStateTracker;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->mAttachedRegistrants:Landroid/os/RegistrantList;
 Lcom/android/internal/telephony/ServiceStateTracker;->mCi:Lcom/android/internal/telephony/CommandsInterface;
 Lcom/android/internal/telephony/ServiceStateTracker;->mCr:Landroid/content/ContentResolver;
 Lcom/android/internal/telephony/ServiceStateTracker;->mCurDataSpn:Ljava/lang/String;
@@ -3456,7 +3455,6 @@
 Lcom/android/internal/telephony/ServiceStateTracker;->mDataRoamingOnRegistrants:Landroid/os/RegistrantList;
 Lcom/android/internal/telephony/ServiceStateTracker;->mDefaultRoamingIndicator:I
 Lcom/android/internal/telephony/ServiceStateTracker;->mDesiredPowerState:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mDetachedRegistrants:Landroid/os/RegistrantList;
 Lcom/android/internal/telephony/ServiceStateTracker;->mDeviceShuttingDown:Z
 Lcom/android/internal/telephony/ServiceStateTracker;->mEmergencyOnly:Z
 Lcom/android/internal/telephony/ServiceStateTracker;->mIccRecords:Lcom/android/internal/telephony/uicc/IccRecords;
@@ -3484,7 +3482,6 @@
 Lcom/android/internal/telephony/ServiceStateTracker;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
 Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOffRegistrants:Landroid/os/RegistrantList;
 Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOnRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->notifyDataRegStateRilRadioTechnologyChanged()V
 Lcom/android/internal/telephony/ServiceStateTracker;->notifySignalStrength()Z
 Lcom/android/internal/telephony/ServiceStateTracker;->pollState()V
 Lcom/android/internal/telephony/ServiceStateTracker;->reRegisterNetwork(Landroid/os/Message;)V
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index af451c2..9bc719e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -300,7 +300,6 @@
     String[] mInstrumentedSplitAppDirs = null;
     String mInstrumentedLibDir = null;
     boolean mSystemThread = false;
-    boolean mJitEnabled = false;
     boolean mSomeActivitiesChanged = false;
     boolean mUpdatingSystemConfig = false;
     /* package */ boolean mHiddenApiWarningShown = false;
@@ -1633,7 +1632,6 @@
         public static final int SUICIDE                 = 130;
         @UnsupportedAppUsage
         public static final int REMOVE_PROVIDER         = 131;
-        public static final int ENABLE_JIT              = 132;
         public static final int DISPATCH_PACKAGE_BROADCAST = 133;
         @UnsupportedAppUsage
         public static final int SCHEDULE_CRASH          = 134;
@@ -1683,7 +1681,6 @@
                     case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
                     case SUICIDE: return "SUICIDE";
                     case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
-                    case ENABLE_JIT: return "ENABLE_JIT";
                     case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
                     case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
                     case DUMP_HEAP: return "DUMP_HEAP";
@@ -1795,9 +1792,6 @@
                     completeRemoveProvider((ProviderRefCount)msg.obj);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
-                case ENABLE_JIT:
-                    ensureJitEnabled();
-                    break;
                 case DISPATCH_PACKAGE_BROADCAST:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
                     handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
@@ -1933,7 +1927,6 @@
             if (stopProfiling) {
                 mProfiler.stopProfiling();
             }
-            ensureJitEnabled();
             return false;
         }
     }
@@ -2258,13 +2251,6 @@
         }
     }
 
-    void ensureJitEnabled() {
-        if (!mJitEnabled) {
-            mJitEnabled = true;
-            dalvik.system.VMRuntime.getRuntime().startJitCompilation();
-        }
-    }
-
     @UnsupportedAppUsage
     void scheduleGcIdler() {
         if (!mGcIdlerScheduled) {
@@ -3690,7 +3676,6 @@
                         ActivityManager.getService().serviceDoneExecuting(
                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                     }
-                    ensureJitEnabled();
                 } catch (RemoteException ex) {
                     throw ex.rethrowFromSystemServer();
                 }
@@ -3804,7 +3789,6 @@
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
-                ensureJitEnabled();
             } catch (Exception e) {
                 if (!mInstrumentation.onException(s, e)) {
                     throw new RuntimeException(
@@ -5979,9 +5963,6 @@
             if (!data.restrictedBackupMode) {
                 if (!ArrayUtils.isEmpty(data.providers)) {
                     installContentProviders(app, data.providers);
-                    // For process that contains content providers, we want to
-                    // ensure that the JIT is enabled "at some point".
-                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                 }
             }
 
@@ -6614,12 +6595,6 @@
         sCurrentActivityThread = this;
         mSystemThread = system;
         if (!system) {
-            ViewRootImpl.addFirstDrawHandler(new Runnable() {
-                @Override
-                public void run() {
-                    ensureJitEnabled();
-                }
-            });
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                     UserHandle.myUserId());
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
diff --git a/core/java/android/service/carrier/ApnService.java b/core/java/android/service/carrier/ApnService.java
index d53eb37..57e4b1b 100644
--- a/core/java/android/service/carrier/ApnService.java
+++ b/core/java/android/service/carrier/ApnService.java
@@ -16,6 +16,8 @@
 
 package android.service.carrier;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.app.Service;
@@ -60,7 +62,8 @@
     };
 
     @Override
-    public IBinder onBind(Intent intent) {
+    @NonNull
+    public IBinder onBind(@Nullable Intent intent) {
         return mBinder;
     }
 
@@ -73,5 +76,6 @@
      * subId.
      */
     @WorkerThread
+    @NonNull
     public abstract List<ContentValues> onRestoreApns(int subId);
 }
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
index 568ca0f..8c73a87 100644
--- a/core/java/android/service/carrier/CarrierIdentifier.java
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -16,6 +16,7 @@
 
 package android.service.carrier;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -74,7 +75,7 @@
      * @param preciseCarrierId precise carrier identifier
      * {@link TelephonyManager#getSimPreciseCarrierId()}
      */
-    public CarrierIdentifier(String mcc, String mnc, @Nullable String spn,
+    public CarrierIdentifier(@NonNull String mcc, @NonNull String mnc, @Nullable String spn,
                              @Nullable String imsi, @Nullable String gid1, @Nullable String gid2,
                              int carrierid, int preciseCarrierId) {
         mMcc = mcc;
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index de9f55b..544cc1c 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -397,15 +397,18 @@
     /**
      * @return the verity root hash in the Signing Block.
      */
-    public static byte[] getVerityRootHash(String apkPath)
-            throws IOException, SignatureNotFoundException, SecurityException {
+    public static byte[] getVerityRootHash(String apkPath) throws IOException, SecurityException {
         // first try v3
         try {
             return ApkSignatureSchemeV3Verifier.getVerityRootHash(apkPath);
         } catch (SignatureNotFoundException e) {
             // try older version
         }
-        return ApkSignatureSchemeV2Verifier.getVerityRootHash(apkPath);
+        try {
+            return ApkSignatureSchemeV2Verifier.getVerityRootHash(apkPath);
+        } catch (SignatureNotFoundException e) {
+            return null;
+        }
     }
 
     /**
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f70cf07..6302aa7 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -127,113 +127,17 @@
 }
 
 int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f) {
-
-    switch(f) {
-        case PublicFormat::JPEG:
-        case PublicFormat::DEPTH_POINT_CLOUD:
-            return HAL_PIXEL_FORMAT_BLOB;
-        case PublicFormat::DEPTH16:
-            return HAL_PIXEL_FORMAT_Y16;
-        case PublicFormat::RAW_SENSOR:
-        case PublicFormat::RAW_DEPTH:
-            return HAL_PIXEL_FORMAT_RAW16;
-        default:
-            // Most formats map 1:1
-            return static_cast<int>(f);
-    }
+    return mapPublicFormatToHalFormat(f);
 }
 
 android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
         PublicFormat f) {
-    switch(f) {
-        case PublicFormat::JPEG:
-            return HAL_DATASPACE_V0_JFIF;
-        case PublicFormat::DEPTH_POINT_CLOUD:
-        case PublicFormat::DEPTH16:
-        case PublicFormat::RAW_DEPTH:
-            return HAL_DATASPACE_DEPTH;
-        case PublicFormat::RAW_SENSOR:
-        case PublicFormat::RAW_PRIVATE:
-        case PublicFormat::RAW10:
-        case PublicFormat::RAW12:
-            return HAL_DATASPACE_ARBITRARY;
-        case PublicFormat::YUV_420_888:
-        case PublicFormat::NV21:
-        case PublicFormat::YV12:
-            return HAL_DATASPACE_V0_JFIF;
-        default:
-            // Most formats map to UNKNOWN
-            return HAL_DATASPACE_UNKNOWN;
-    }
+    return mapPublicFormatToHalDataspace(f);
 }
 
 PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
         int format, android_dataspace dataSpace) {
-    switch(format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_RGBA_FP16:
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-        case HAL_PIXEL_FORMAT_RGB_888:
-        case HAL_PIXEL_FORMAT_RGB_565:
-        case HAL_PIXEL_FORMAT_Y8:
-        case HAL_PIXEL_FORMAT_RAW10:
-        case HAL_PIXEL_FORMAT_RAW12:
-        case HAL_PIXEL_FORMAT_YCbCr_420_888:
-        case HAL_PIXEL_FORMAT_YV12:
-            // Enums overlap in both name and value
-            return static_cast<PublicFormat>(format);
-        case HAL_PIXEL_FORMAT_RAW16:
-            switch (dataSpace) {
-                case HAL_DATASPACE_DEPTH:
-                  return PublicFormat::RAW_DEPTH;
-                default:
-                  return PublicFormat::RAW_SENSOR;
-            }
-        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
-            // Name differs, though value is the same
-            return PublicFormat::RAW_PRIVATE;
-        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-            // Name differs, though the value is the same
-            return PublicFormat::NV16;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            // Name differs, though the value is the same
-            return PublicFormat::NV21;
-        case HAL_PIXEL_FORMAT_YCbCr_422_I:
-            // Name differs, though the value is the same
-            return PublicFormat::YUY2;
-        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-            // Name differs, though the value is the same
-            return PublicFormat::PRIVATE;
-        case HAL_PIXEL_FORMAT_Y16:
-            // Dataspace-dependent
-            switch (dataSpace) {
-                case HAL_DATASPACE_DEPTH:
-                    return PublicFormat::DEPTH16;
-                default:
-                    // Assume non-depth Y16 is just Y16.
-                    return PublicFormat::Y16;
-            }
-            break;
-        case HAL_PIXEL_FORMAT_BLOB:
-            // Dataspace-dependent
-            switch (dataSpace) {
-                case HAL_DATASPACE_DEPTH:
-                    return PublicFormat::DEPTH_POINT_CLOUD;
-                case HAL_DATASPACE_V0_JFIF:
-                    return PublicFormat::JPEG;
-                default:
-                    // Assume otherwise-marked blobs are also JPEG
-                    return PublicFormat::JPEG;
-            }
-            break;
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            // Not defined in public API
-            return PublicFormat::UNKNOWN;
-
-        default:
-            return PublicFormat::UNKNOWN;
-    }
+    return mapHalFormatDataspaceToPublicFormat(format, dataSpace);
 }
 // ----------------------------------------------------------------------------
 
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 36487b3..04718cd 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -19,6 +19,7 @@
 
 #include <android/native_window.h>
 #include <system/graphics.h>
+#include <ui/PublicFormat.h>
 
 #include "jni.h"
 
@@ -27,39 +28,6 @@
 class Surface;
 class IGraphicBufferProducer;
 
-/**
- * Enum mirroring the public API definitions for image and pixel formats.
- * Some of these are hidden in the public API
- *
- * Keep up to date with android.graphics.ImageFormat and
- * android.graphics.PixelFormat
- */
-enum class PublicFormat {
-    UNKNOWN           = 0x0,
-    RGBA_8888         = 0x1,
-    RGBX_8888         = 0x2,
-    RGB_888           = 0x3,
-    RGB_565           = 0x4,
-    NV16              = 0x10,
-    NV21              = 0x11,
-    YUY2              = 0x14,
-    RGBA_FP16         = 0x16,
-    RAW_SENSOR        = 0x20,
-    PRIVATE           = 0x22,
-    YUV_420_888       = 0x23,
-    RAW_PRIVATE       = 0x24,
-    RAW10             = 0x25,
-    RAW12             = 0x26,
-    RGBA_1010102      = 0x2b,
-    JPEG              = 0x100,
-    DEPTH_POINT_CLOUD = 0x101,
-    RAW_DEPTH         = 0x1002, // @hide
-    YV12              = 0x32315659,
-    Y8                = 0x20203859, // @hide
-    Y16               = 0x20363159, // @hide
-    DEPTH16           = 0x44363159
-};
-
 /* Gets the underlying ANativeWindow for a Surface. */
 extern sp<ANativeWindow> android_view_Surface_getNativeWindow(
         JNIEnv* env, jobject surfaceObj);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e40d97b..35bc46a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1839,12 +1839,12 @@
 
     <!-- Must be required by a {@link android.telecom.PhoneAccountSuggestionService},
          to ensure that only the system can bind to it.
-         <p>Protection level: signature|privileged
+         <p>Protection level: signature
          @SystemApi
          @hide
     -->
     <permission android:name="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.telecom.CallRedirectionService},
          to ensure that only the system can bind to it.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5444c69..6e380c8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -653,7 +653,7 @@
     <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
 
     <!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
-    <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">false</bool>
+    <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">true</bool>
 
     <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
     <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 25c7b5c..5966192 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -20,8 +20,8 @@
         "android_media_MediaScanner.cpp",
         "android_media_MediaSync.cpp",
         "android_media_ResampleInputStream.cpp",
+        "android_media_Streams.cpp",
         "android_media_SyncParams.cpp",
-        "android_media_Utils.cpp",
         "android_mtp_MtpDatabase.cpp",
         "android_mtp_MtpDevice.cpp",
         "android_mtp_MtpServer.cpp",
@@ -36,6 +36,7 @@
         "libbinder",
         "libmedia",
         "libmediaextractor",
+        "libmedia_jni_utils",
         "libmedia_omx",
         "libmediametrics",
         "libmediadrm",
@@ -91,6 +92,36 @@
 }
 
 cc_library_shared {
+    name: "libmedia_jni_utils",
+    srcs: [
+        "android_media_Utils.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libmedia_omx",
+        "libnativewindow",
+        "libui",
+        "libutils",
+        "android.hidl.token@1.0-utils",
+    ],
+
+    include_dirs: [
+        "system/media/camera/include",
+    ],
+
+    export_include_dirs: ["."],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
+
+cc_library_shared {
     name: "libmedia2_jni",
 
     srcs: [
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 3490ff8..cf73b21 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -23,7 +23,7 @@
 #include "android_media_MediaCrypto.h"
 #include "android_media_MediaDescrambler.h"
 #include "android_media_MediaMetricsJNI.h"
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_runtime/android_view_Surface.h"
 #include "android_util_Binder.h"
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index 8de11ca..878910a 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -27,7 +27,7 @@
 #include "android_runtime/AndroidRuntime.h"
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 
 using namespace android;
 
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index dad0e53..3edac44 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -21,7 +21,7 @@
 #include "android_media_MediaDataSource.h"
 #include "android_media_MediaExtractor.h"
 #include "android_media_MediaMetricsJNI.h"
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 #include "android_os_HwRemoteBinder.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_runtime/Log.h"
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index c1226fa..a480784 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaMetadataRetrieverJNI"
 
+#include <cmath>
 #include <assert.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
@@ -32,7 +33,7 @@
 #include <nativehelper/JNIHelp.h>
 #include "android_runtime/AndroidRuntime.h"
 #include "android_media_MediaDataSource.h"
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 #include "android_util_Binder.h"
 
 #include "android/graphics/GraphicsJNI.h"
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index f11452a..f0aa4c3 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "MediaMuxer-JNI"
 #include <utils/Log.h>
 
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 5dd01b0..2acb0e5 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -45,7 +45,7 @@
 #include "android_media_PlaybackParams.h"
 #include "android_media_SyncParams.h"
 #include "android_media_VolumeShaper.h"
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
diff --git a/media/jni/android_media_Streams.cpp b/media/jni/android_media_Streams.cpp
new file mode 100644
index 0000000..b7cbd97
--- /dev/null
+++ b/media/jni/android_media_Streams.cpp
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "AndroidMediaStreams"
+
+#include <utils/Log.h>
+#include "android_media_Streams.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace android {
+
+AssetStream::AssetStream(SkStream* stream)
+    : mStream(stream), mPosition(0) {
+}
+
+AssetStream::~AssetStream() {
+}
+
+piex::Error AssetStream::GetData(
+        const size_t offset, const size_t length, std::uint8_t* data) {
+    // Seek first.
+    if (mPosition != offset) {
+        if (!mStream->seek(offset)) {
+            return piex::Error::kFail;
+        }
+    }
+
+    // Read bytes.
+    size_t size = mStream->read((void*)data, length);
+    mPosition = offset + size;
+
+    return size == length ? piex::Error::kOk : piex::Error::kFail;
+}
+
+BufferedStream::BufferedStream(SkStream* stream)
+    : mStream(stream) {
+}
+
+BufferedStream::~BufferedStream() {
+}
+
+piex::Error BufferedStream::GetData(
+        const size_t offset, const size_t length, std::uint8_t* data) {
+    // Seek first.
+    if (offset + length > mStreamBuffer.bytesWritten()) {
+        size_t sizeToRead = offset + length - mStreamBuffer.bytesWritten();
+        if (sizeToRead <= kMinSizeToRead) {
+            sizeToRead = kMinSizeToRead;
+        }
+
+        void* tempBuffer = malloc(sizeToRead);
+        if (tempBuffer == NULL) {
+          return piex::Error::kFail;
+        }
+
+        size_t bytesRead = mStream->read(tempBuffer, sizeToRead);
+        if (bytesRead != sizeToRead) {
+            free(tempBuffer);
+            return piex::Error::kFail;
+        }
+        mStreamBuffer.write(tempBuffer, bytesRead);
+        free(tempBuffer);
+    }
+
+    // Read bytes.
+    if (mStreamBuffer.read((void*)data, offset, length)) {
+        return piex::Error::kOk;
+    } else {
+        return piex::Error::kFail;
+    }
+}
+
+FileStream::FileStream(const int fd)
+    : mPosition(0) {
+    mFile = fdopen(fd, "r");
+    if (mFile == NULL) {
+        return;
+    }
+}
+
+FileStream::FileStream(const String8 filename)
+    : mPosition(0) {
+    mFile = fopen(filename.string(), "r");
+    if (mFile == NULL) {
+        return;
+    }
+}
+
+FileStream::~FileStream() {
+    if (mFile != NULL) {
+        fclose(mFile);
+        mFile = NULL;
+    }
+}
+
+piex::Error FileStream::GetData(
+        const size_t offset, const size_t length, std::uint8_t* data) {
+    if (mFile == NULL) {
+        return piex::Error::kFail;
+    }
+
+    // Seek first.
+    if (mPosition != offset) {
+        fseek(mFile, offset, SEEK_SET);
+    }
+
+    // Read bytes.
+    size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
+    mPosition += size;
+
+    // Handle errors and verify the size.
+    if (ferror(mFile) || size != length) {
+        ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length);
+        return piex::Error::kFail;
+    }
+    return piex::Error::kOk;
+}
+
+bool FileStream::exists() const {
+    return mFile != NULL;
+}
+
+bool GetExifFromRawImage(
+        piex::StreamInterface* stream, const String8& filename,
+        piex::PreviewImageData& image_data) {
+    // Reset the PreviewImageData to its default.
+    image_data = piex::PreviewImageData();
+
+    if (!piex::IsRaw(stream)) {
+        // Format not supported.
+        ALOGV("Format not supported: %s", filename.string());
+        return false;
+    }
+
+    piex::Error err = piex::GetPreviewImageData(stream, &image_data);
+
+    if (err != piex::Error::kOk) {
+        // The input data seems to be broken.
+        ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err);
+        return false;
+    }
+
+    return true;
+}
+
+bool ConvertKeyValueArraysToKeyedVector(
+        JNIEnv *env, jobjectArray keys, jobjectArray values,
+        KeyedVector<String8, String8>* keyedVector) {
+
+    int nKeyValuePairs = 0;
+    bool failed = false;
+    if (keys != NULL && values != NULL) {
+        nKeyValuePairs = env->GetArrayLength(keys);
+        failed = (nKeyValuePairs != env->GetArrayLength(values));
+    }
+
+    if (!failed) {
+        failed = ((keys != NULL && values == NULL) ||
+                  (keys == NULL && values != NULL));
+    }
+
+    if (failed) {
+        ALOGE("keys and values arrays have different length");
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return false;
+    }
+
+    for (int i = 0; i < nKeyValuePairs; ++i) {
+        // No need to check on the ArrayIndexOutOfBoundsException, since
+        // it won't happen here.
+        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
+        jstring value = (jstring) env->GetObjectArrayElement(values, i);
+
+        const char* keyStr = env->GetStringUTFChars(key, NULL);
+        if (!keyStr) {  // OutOfMemoryError
+            return false;
+        }
+
+        const char* valueStr = env->GetStringUTFChars(value, NULL);
+        if (!valueStr) {  // OutOfMemoryError
+            env->ReleaseStringUTFChars(key, keyStr);
+            return false;
+        }
+
+        keyedVector->add(String8(keyStr), String8(valueStr));
+
+        env->ReleaseStringUTFChars(key, keyStr);
+        env->ReleaseStringUTFChars(value, valueStr);
+        env->DeleteLocalRef(key);
+        env->DeleteLocalRef(value);
+    }
+    return true;
+}
+
+static jobject makeIntegerObject(JNIEnv *env, int32_t value) {
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer"));
+    CHECK(clazz.get() != NULL);
+
+    jmethodID integerConstructID =
+        env->GetMethodID(clazz.get(), "<init>", "(I)V");
+    CHECK(integerConstructID != NULL);
+
+    return env->NewObject(clazz.get(), integerConstructID, value);
+}
+
+static jobject makeLongObject(JNIEnv *env, int64_t value) {
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long"));
+    CHECK(clazz.get() != NULL);
+
+    jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V");
+    CHECK(longConstructID != NULL);
+
+    return env->NewObject(clazz.get(), longConstructID, value);
+}
+
+static jobject makeFloatObject(JNIEnv *env, float value) {
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float"));
+    CHECK(clazz.get() != NULL);
+
+    jmethodID floatConstructID =
+        env->GetMethodID(clazz.get(), "<init>", "(F)V");
+    CHECK(floatConstructID != NULL);
+
+    return env->NewObject(clazz.get(), floatConstructID, value);
+}
+
+static jobject makeByteBufferObject(
+        JNIEnv *env, const void *data, size_t size) {
+    jbyteArray byteArrayObj = env->NewByteArray(size);
+    env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data);
+
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer"));
+    CHECK(clazz.get() != NULL);
+
+    jmethodID byteBufWrapID =
+        env->GetStaticMethodID(
+                clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;");
+    CHECK(byteBufWrapID != NULL);
+
+    jobject byteBufObj = env->CallStaticObjectMethod(
+            clazz.get(), byteBufWrapID, byteArrayObj);
+
+    env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL;
+
+    return byteBufObj;
+}
+
+static void SetMapInt32(
+        JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID,
+        const char *key, int32_t value) {
+    jstring keyObj = env->NewStringUTF(key);
+    jobject valueObj = makeIntegerObject(env, value);
+
+    env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj);
+
+    env->DeleteLocalRef(valueObj); valueObj = NULL;
+    env->DeleteLocalRef(keyObj); keyObj = NULL;
+}
+
+status_t ConvertMessageToMap(
+        JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
+    ScopedLocalRef<jclass> hashMapClazz(
+            env, env->FindClass("java/util/HashMap"));
+
+    if (hashMapClazz.get() == NULL) {
+        return -EINVAL;
+    }
+
+    jmethodID hashMapConstructID =
+        env->GetMethodID(hashMapClazz.get(), "<init>", "()V");
+
+    if (hashMapConstructID == NULL) {
+        return -EINVAL;
+    }
+
+    jmethodID hashMapPutID =
+        env->GetMethodID(
+                hashMapClazz.get(),
+                "put",
+                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
+    if (hashMapPutID == NULL) {
+        return -EINVAL;
+    }
+
+    jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID);
+
+    for (size_t i = 0; i < msg->countEntries(); ++i) {
+        AMessage::Type valueType;
+        const char *key = msg->getEntryNameAt(i, &valueType);
+
+        if (!strncmp(key, "android._", 9)) {
+            // don't expose private keys (starting with android._)
+            continue;
+        }
+
+        jobject valueObj = NULL;
+
+        switch (valueType) {
+            case AMessage::kTypeInt32:
+            {
+                int32_t val;
+                CHECK(msg->findInt32(key, &val));
+
+                valueObj = makeIntegerObject(env, val);
+                break;
+            }
+
+            case AMessage::kTypeInt64:
+            {
+                int64_t val;
+                CHECK(msg->findInt64(key, &val));
+
+                valueObj = makeLongObject(env, val);
+                break;
+            }
+
+            case AMessage::kTypeFloat:
+            {
+                float val;
+                CHECK(msg->findFloat(key, &val));
+
+                valueObj = makeFloatObject(env, val);
+                break;
+            }
+
+            case AMessage::kTypeString:
+            {
+                AString val;
+                CHECK(msg->findString(key, &val));
+
+                valueObj = env->NewStringUTF(val.c_str());
+                break;
+            }
+
+            case AMessage::kTypeBuffer:
+            {
+                sp<ABuffer> buffer;
+                CHECK(msg->findBuffer(key, &buffer));
+
+                valueObj = makeByteBufferObject(
+                        env, buffer->data(), buffer->size());
+                break;
+            }
+
+            case AMessage::kTypeRect:
+            {
+                int32_t left, top, right, bottom;
+                CHECK(msg->findRect(key, &left, &top, &right, &bottom));
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        AStringPrintf("%s-left", key).c_str(),
+                        left);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        AStringPrintf("%s-top", key).c_str(),
+                        top);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        AStringPrintf("%s-right", key).c_str(),
+                        right);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        AStringPrintf("%s-bottom", key).c_str(),
+                        bottom);
+                break;
+            }
+
+            default:
+                break;
+        }
+
+        if (valueObj != NULL) {
+            jstring keyObj = env->NewStringUTF(key);
+
+            env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj);
+
+            env->DeleteLocalRef(keyObj); keyObj = NULL;
+            env->DeleteLocalRef(valueObj); valueObj = NULL;
+        }
+    }
+
+    *map = hashMap;
+
+    return OK;
+}
+
+status_t ConvertKeyValueArraysToMessage(
+        JNIEnv *env, jobjectArray keys, jobjectArray values,
+        sp<AMessage> *out) {
+    ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String"));
+    CHECK(stringClass.get() != NULL);
+    ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer"));
+    CHECK(integerClass.get() != NULL);
+    ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long"));
+    CHECK(longClass.get() != NULL);
+    ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float"));
+    CHECK(floatClass.get() != NULL);
+    ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
+    CHECK(byteBufClass.get() != NULL);
+
+    sp<AMessage> msg = new AMessage;
+
+    jsize numEntries = 0;
+
+    if (keys != NULL) {
+        if (values == NULL) {
+            return -EINVAL;
+        }
+
+        numEntries = env->GetArrayLength(keys);
+
+        if (numEntries != env->GetArrayLength(values)) {
+            return -EINVAL;
+        }
+    } else if (values != NULL) {
+        return -EINVAL;
+    }
+
+    for (jsize i = 0; i < numEntries; ++i) {
+        jobject keyObj = env->GetObjectArrayElement(keys, i);
+
+        if (!env->IsInstanceOf(keyObj, stringClass.get())) {
+            return -EINVAL;
+        }
+
+        const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL);
+
+        if (tmp == NULL) {
+            return -ENOMEM;
+        }
+
+        AString key = tmp;
+
+        env->ReleaseStringUTFChars((jstring)keyObj, tmp);
+        tmp = NULL;
+
+        if (key.startsWith("android._")) {
+            // don't propagate private keys (starting with android._)
+            continue;
+        }
+
+        jobject valueObj = env->GetObjectArrayElement(values, i);
+
+        if (env->IsInstanceOf(valueObj, stringClass.get())) {
+            const char *value = env->GetStringUTFChars((jstring)valueObj, NULL);
+
+            if (value == NULL) {
+                return -ENOMEM;
+            }
+
+            msg->setString(key.c_str(), value);
+
+            env->ReleaseStringUTFChars((jstring)valueObj, value);
+            value = NULL;
+        } else if (env->IsInstanceOf(valueObj, integerClass.get())) {
+            jmethodID intValueID =
+                env->GetMethodID(integerClass.get(), "intValue", "()I");
+            CHECK(intValueID != NULL);
+
+            jint value = env->CallIntMethod(valueObj, intValueID);
+
+            msg->setInt32(key.c_str(), value);
+        } else if (env->IsInstanceOf(valueObj, longClass.get())) {
+            jmethodID longValueID =
+                env->GetMethodID(longClass.get(), "longValue", "()J");
+            CHECK(longValueID != NULL);
+
+            jlong value = env->CallLongMethod(valueObj, longValueID);
+
+            msg->setInt64(key.c_str(), value);
+        } else if (env->IsInstanceOf(valueObj, floatClass.get())) {
+            jmethodID floatValueID =
+                env->GetMethodID(floatClass.get(), "floatValue", "()F");
+            CHECK(floatValueID != NULL);
+
+            jfloat value = env->CallFloatMethod(valueObj, floatValueID);
+
+            msg->setFloat(key.c_str(), value);
+        } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) {
+            jmethodID positionID =
+                env->GetMethodID(byteBufClass.get(), "position", "()I");
+            CHECK(positionID != NULL);
+
+            jmethodID limitID =
+                env->GetMethodID(byteBufClass.get(), "limit", "()I");
+            CHECK(limitID != NULL);
+
+            jint position = env->CallIntMethod(valueObj, positionID);
+            jint limit = env->CallIntMethod(valueObj, limitID);
+
+            sp<ABuffer> buffer = new ABuffer(limit - position);
+
+            void *data = env->GetDirectBufferAddress(valueObj);
+
+            if (data != NULL) {
+                memcpy(buffer->data(),
+                       (const uint8_t *)data + position,
+                       buffer->size());
+            } else {
+                jmethodID arrayID =
+                    env->GetMethodID(byteBufClass.get(), "array", "()[B");
+                CHECK(arrayID != NULL);
+
+                jbyteArray byteArray =
+                    (jbyteArray)env->CallObjectMethod(valueObj, arrayID);
+                CHECK(byteArray != NULL);
+
+                env->GetByteArrayRegion(
+                        byteArray,
+                        position,
+                        buffer->size(),
+                        (jbyte *)buffer->data());
+
+                env->DeleteLocalRef(byteArray); byteArray = NULL;
+            }
+
+            msg->setBuffer(key.c_str(), buffer);
+        }
+    }
+
+    *out = msg;
+
+    return OK;
+}
+
+}  // namespace android
+
diff --git a/media/jni/android_media_Streams.h b/media/jni/android_media_Streams.h
new file mode 100644
index 0000000..d174f9a
--- /dev/null
+++ b/media/jni/android_media_Streams.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_MEDIA_STREAMS_H_
+#define _ANDROID_MEDIA_STREAMS_H_
+
+#include "src/piex_types.h"
+#include "src/piex.h"
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/StrongPointer.h>
+#include <SkStream.h>
+
+
+namespace android {
+
+class AssetStream : public piex::StreamInterface {
+private:
+    SkStream *mStream;
+    size_t mPosition;
+
+public:
+    explicit AssetStream(SkStream* stream);
+    ~AssetStream();
+
+    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
+    // provided by the caller, guaranteed to be at least "length" bytes long.
+    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
+    // 'offset' bytes from the start of the stream.
+    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
+    // change the contents of 'data'.
+    piex::Error GetData(
+            const size_t offset, const size_t length, std::uint8_t* data) override;
+};
+
+class BufferedStream : public piex::StreamInterface {
+private:
+    SkStream *mStream;
+    // Growable memory stream
+    SkDynamicMemoryWStream mStreamBuffer;
+
+    // Minimum size to read on filling the buffer.
+    const size_t kMinSizeToRead = 8192;
+
+public:
+    explicit BufferedStream(SkStream* stream);
+    ~BufferedStream();
+
+    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
+    // provided by the caller, guaranteed to be at least "length" bytes long.
+    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
+    // 'offset' bytes from the start of the stream.
+    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
+    // change the contents of 'data'.
+    piex::Error GetData(
+            const size_t offset, const size_t length, std::uint8_t* data) override;
+};
+
+class FileStream : public piex::StreamInterface {
+private:
+    FILE *mFile;
+    size_t mPosition;
+
+public:
+    explicit FileStream(const int fd);
+    explicit FileStream(const String8 filename);
+    ~FileStream();
+
+    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
+    // provided by the caller, guaranteed to be at least "length" bytes long.
+    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
+    // 'offset' bytes from the start of the stream.
+    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
+    // change the contents of 'data'.
+    piex::Error GetData(
+            const size_t offset, const size_t length, std::uint8_t* data) override;
+    bool exists() const;
+};
+
+// Reads EXIF metadata from a given raw image via piex.
+// And returns true if the operation is successful; otherwise, false.
+bool GetExifFromRawImage(
+        piex::StreamInterface* stream, const String8& filename, piex::PreviewImageData& image_data);
+
+// Returns true if the conversion is successful; otherwise, false.
+bool ConvertKeyValueArraysToKeyedVector(
+        JNIEnv *env, jobjectArray keys, jobjectArray values,
+        KeyedVector<String8, String8>* vector);
+
+struct AMessage;
+status_t ConvertMessageToMap(
+        JNIEnv *env, const sp<AMessage> &msg, jobject *map);
+
+status_t ConvertKeyValueArraysToMessage(
+        JNIEnv *env, jobjectArray keys, jobjectArray values,
+        sp<AMessage> *msg);
+
+};  // namespace android
+
+#endif //  _ANDROID_MEDIA_STREAMS_H_
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index 458d847..8bdf534 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -21,543 +21,10 @@
 #include <utils/Log.h>
 #include "android_media_Utils.h"
 
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <nativehelper/ScopedLocalRef.h>
-
 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
 
 namespace android {
 
-AssetStream::AssetStream(SkStream* stream)
-    : mStream(stream), mPosition(0) {
-}
-
-AssetStream::~AssetStream() {
-}
-
-piex::Error AssetStream::GetData(
-        const size_t offset, const size_t length, std::uint8_t* data) {
-    // Seek first.
-    if (mPosition != offset) {
-        if (!mStream->seek(offset)) {
-            return piex::Error::kFail;
-        }
-    }
-
-    // Read bytes.
-    size_t size = mStream->read((void*)data, length);
-    mPosition = offset + size;
-
-    return size == length ? piex::Error::kOk : piex::Error::kFail;
-}
-
-BufferedStream::BufferedStream(SkStream* stream)
-    : mStream(stream) {
-}
-
-BufferedStream::~BufferedStream() {
-}
-
-piex::Error BufferedStream::GetData(
-        const size_t offset, const size_t length, std::uint8_t* data) {
-    // Seek first.
-    if (offset + length > mStreamBuffer.bytesWritten()) {
-        size_t sizeToRead = offset + length - mStreamBuffer.bytesWritten();
-        if (sizeToRead <= kMinSizeToRead) {
-            sizeToRead = kMinSizeToRead;
-        }
-
-        void* tempBuffer = malloc(sizeToRead);
-        if (tempBuffer == NULL) {
-          return piex::Error::kFail;
-        }
-
-        size_t bytesRead = mStream->read(tempBuffer, sizeToRead);
-        if (bytesRead != sizeToRead) {
-            free(tempBuffer);
-            return piex::Error::kFail;
-        }
-        mStreamBuffer.write(tempBuffer, bytesRead);
-        free(tempBuffer);
-    }
-
-    // Read bytes.
-    if (mStreamBuffer.read((void*)data, offset, length)) {
-        return piex::Error::kOk;
-    } else {
-        return piex::Error::kFail;
-    }
-}
-
-FileStream::FileStream(const int fd)
-    : mPosition(0) {
-    mFile = fdopen(fd, "r");
-    if (mFile == NULL) {
-        return;
-    }
-}
-
-FileStream::FileStream(const String8 filename)
-    : mPosition(0) {
-    mFile = fopen(filename.string(), "r");
-    if (mFile == NULL) {
-        return;
-    }
-}
-
-FileStream::~FileStream() {
-    if (mFile != NULL) {
-        fclose(mFile);
-        mFile = NULL;
-    }
-}
-
-piex::Error FileStream::GetData(
-        const size_t offset, const size_t length, std::uint8_t* data) {
-    if (mFile == NULL) {
-        return piex::Error::kFail;
-    }
-
-    // Seek first.
-    if (mPosition != offset) {
-        fseek(mFile, offset, SEEK_SET);
-    }
-
-    // Read bytes.
-    size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
-    mPosition += size;
-
-    // Handle errors and verify the size.
-    if (ferror(mFile) || size != length) {
-        ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length);
-        return piex::Error::kFail;
-    }
-    return piex::Error::kOk;
-}
-
-bool FileStream::exists() const {
-    return mFile != NULL;
-}
-
-bool GetExifFromRawImage(
-        piex::StreamInterface* stream, const String8& filename,
-        piex::PreviewImageData& image_data) {
-    // Reset the PreviewImageData to its default.
-    image_data = piex::PreviewImageData();
-
-    if (!piex::IsRaw(stream)) {
-        // Format not supported.
-        ALOGV("Format not supported: %s", filename.string());
-        return false;
-    }
-
-    piex::Error err = piex::GetPreviewImageData(stream, &image_data);
-
-    if (err != piex::Error::kOk) {
-        // The input data seems to be broken.
-        ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err);
-        return false;
-    }
-
-    return true;
-}
-
-bool ConvertKeyValueArraysToKeyedVector(
-        JNIEnv *env, jobjectArray keys, jobjectArray values,
-        KeyedVector<String8, String8>* keyedVector) {
-
-    int nKeyValuePairs = 0;
-    bool failed = false;
-    if (keys != NULL && values != NULL) {
-        nKeyValuePairs = env->GetArrayLength(keys);
-        failed = (nKeyValuePairs != env->GetArrayLength(values));
-    }
-
-    if (!failed) {
-        failed = ((keys != NULL && values == NULL) ||
-                  (keys == NULL && values != NULL));
-    }
-
-    if (failed) {
-        ALOGE("keys and values arrays have different length");
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return false;
-    }
-
-    for (int i = 0; i < nKeyValuePairs; ++i) {
-        // No need to check on the ArrayIndexOutOfBoundsException, since
-        // it won't happen here.
-        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
-        jstring value = (jstring) env->GetObjectArrayElement(values, i);
-
-        const char* keyStr = env->GetStringUTFChars(key, NULL);
-        if (!keyStr) {  // OutOfMemoryError
-            return false;
-        }
-
-        const char* valueStr = env->GetStringUTFChars(value, NULL);
-        if (!valueStr) {  // OutOfMemoryError
-            env->ReleaseStringUTFChars(key, keyStr);
-            return false;
-        }
-
-        keyedVector->add(String8(keyStr), String8(valueStr));
-
-        env->ReleaseStringUTFChars(key, keyStr);
-        env->ReleaseStringUTFChars(value, valueStr);
-        env->DeleteLocalRef(key);
-        env->DeleteLocalRef(value);
-    }
-    return true;
-}
-
-static jobject makeIntegerObject(JNIEnv *env, int32_t value) {
-    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer"));
-    CHECK(clazz.get() != NULL);
-
-    jmethodID integerConstructID =
-        env->GetMethodID(clazz.get(), "<init>", "(I)V");
-    CHECK(integerConstructID != NULL);
-
-    return env->NewObject(clazz.get(), integerConstructID, value);
-}
-
-static jobject makeLongObject(JNIEnv *env, int64_t value) {
-    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long"));
-    CHECK(clazz.get() != NULL);
-
-    jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V");
-    CHECK(longConstructID != NULL);
-
-    return env->NewObject(clazz.get(), longConstructID, value);
-}
-
-static jobject makeFloatObject(JNIEnv *env, float value) {
-    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float"));
-    CHECK(clazz.get() != NULL);
-
-    jmethodID floatConstructID =
-        env->GetMethodID(clazz.get(), "<init>", "(F)V");
-    CHECK(floatConstructID != NULL);
-
-    return env->NewObject(clazz.get(), floatConstructID, value);
-}
-
-static jobject makeByteBufferObject(
-        JNIEnv *env, const void *data, size_t size) {
-    jbyteArray byteArrayObj = env->NewByteArray(size);
-    env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data);
-
-    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer"));
-    CHECK(clazz.get() != NULL);
-
-    jmethodID byteBufWrapID =
-        env->GetStaticMethodID(
-                clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;");
-    CHECK(byteBufWrapID != NULL);
-
-    jobject byteBufObj = env->CallStaticObjectMethod(
-            clazz.get(), byteBufWrapID, byteArrayObj);
-
-    env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL;
-
-    return byteBufObj;
-}
-
-static void SetMapInt32(
-        JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID,
-        const char *key, int32_t value) {
-    jstring keyObj = env->NewStringUTF(key);
-    jobject valueObj = makeIntegerObject(env, value);
-
-    env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj);
-
-    env->DeleteLocalRef(valueObj); valueObj = NULL;
-    env->DeleteLocalRef(keyObj); keyObj = NULL;
-}
-
-status_t ConvertMessageToMap(
-        JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
-    ScopedLocalRef<jclass> hashMapClazz(
-            env, env->FindClass("java/util/HashMap"));
-
-    if (hashMapClazz.get() == NULL) {
-        return -EINVAL;
-    }
-
-    jmethodID hashMapConstructID =
-        env->GetMethodID(hashMapClazz.get(), "<init>", "()V");
-
-    if (hashMapConstructID == NULL) {
-        return -EINVAL;
-    }
-
-    jmethodID hashMapPutID =
-        env->GetMethodID(
-                hashMapClazz.get(),
-                "put",
-                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-
-    if (hashMapPutID == NULL) {
-        return -EINVAL;
-    }
-
-    jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID);
-
-    for (size_t i = 0; i < msg->countEntries(); ++i) {
-        AMessage::Type valueType;
-        const char *key = msg->getEntryNameAt(i, &valueType);
-
-        if (!strncmp(key, "android._", 9)) {
-            // don't expose private keys (starting with android._)
-            continue;
-        }
-
-        jobject valueObj = NULL;
-
-        switch (valueType) {
-            case AMessage::kTypeInt32:
-            {
-                int32_t val;
-                CHECK(msg->findInt32(key, &val));
-
-                valueObj = makeIntegerObject(env, val);
-                break;
-            }
-
-            case AMessage::kTypeInt64:
-            {
-                int64_t val;
-                CHECK(msg->findInt64(key, &val));
-
-                valueObj = makeLongObject(env, val);
-                break;
-            }
-
-            case AMessage::kTypeFloat:
-            {
-                float val;
-                CHECK(msg->findFloat(key, &val));
-
-                valueObj = makeFloatObject(env, val);
-                break;
-            }
-
-            case AMessage::kTypeString:
-            {
-                AString val;
-                CHECK(msg->findString(key, &val));
-
-                valueObj = env->NewStringUTF(val.c_str());
-                break;
-            }
-
-            case AMessage::kTypeBuffer:
-            {
-                sp<ABuffer> buffer;
-                CHECK(msg->findBuffer(key, &buffer));
-
-                valueObj = makeByteBufferObject(
-                        env, buffer->data(), buffer->size());
-                break;
-            }
-
-            case AMessage::kTypeRect:
-            {
-                int32_t left, top, right, bottom;
-                CHECK(msg->findRect(key, &left, &top, &right, &bottom));
-
-                SetMapInt32(
-                        env,
-                        hashMap,
-                        hashMapPutID,
-                        AStringPrintf("%s-left", key).c_str(),
-                        left);
-
-                SetMapInt32(
-                        env,
-                        hashMap,
-                        hashMapPutID,
-                        AStringPrintf("%s-top", key).c_str(),
-                        top);
-
-                SetMapInt32(
-                        env,
-                        hashMap,
-                        hashMapPutID,
-                        AStringPrintf("%s-right", key).c_str(),
-                        right);
-
-                SetMapInt32(
-                        env,
-                        hashMap,
-                        hashMapPutID,
-                        AStringPrintf("%s-bottom", key).c_str(),
-                        bottom);
-                break;
-            }
-
-            default:
-                break;
-        }
-
-        if (valueObj != NULL) {
-            jstring keyObj = env->NewStringUTF(key);
-
-            env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj);
-
-            env->DeleteLocalRef(keyObj); keyObj = NULL;
-            env->DeleteLocalRef(valueObj); valueObj = NULL;
-        }
-    }
-
-    *map = hashMap;
-
-    return OK;
-}
-
-status_t ConvertKeyValueArraysToMessage(
-        JNIEnv *env, jobjectArray keys, jobjectArray values,
-        sp<AMessage> *out) {
-    ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String"));
-    CHECK(stringClass.get() != NULL);
-    ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer"));
-    CHECK(integerClass.get() != NULL);
-    ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long"));
-    CHECK(longClass.get() != NULL);
-    ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float"));
-    CHECK(floatClass.get() != NULL);
-    ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
-    CHECK(byteBufClass.get() != NULL);
-
-    sp<AMessage> msg = new AMessage;
-
-    jsize numEntries = 0;
-
-    if (keys != NULL) {
-        if (values == NULL) {
-            return -EINVAL;
-        }
-
-        numEntries = env->GetArrayLength(keys);
-
-        if (numEntries != env->GetArrayLength(values)) {
-            return -EINVAL;
-        }
-    } else if (values != NULL) {
-        return -EINVAL;
-    }
-
-    for (jsize i = 0; i < numEntries; ++i) {
-        jobject keyObj = env->GetObjectArrayElement(keys, i);
-
-        if (!env->IsInstanceOf(keyObj, stringClass.get())) {
-            return -EINVAL;
-        }
-
-        const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL);
-
-        if (tmp == NULL) {
-            return -ENOMEM;
-        }
-
-        AString key = tmp;
-
-        env->ReleaseStringUTFChars((jstring)keyObj, tmp);
-        tmp = NULL;
-
-        if (key.startsWith("android._")) {
-            // don't propagate private keys (starting with android._)
-            continue;
-        }
-
-        jobject valueObj = env->GetObjectArrayElement(values, i);
-
-        if (env->IsInstanceOf(valueObj, stringClass.get())) {
-            const char *value = env->GetStringUTFChars((jstring)valueObj, NULL);
-
-            if (value == NULL) {
-                return -ENOMEM;
-            }
-
-            msg->setString(key.c_str(), value);
-
-            env->ReleaseStringUTFChars((jstring)valueObj, value);
-            value = NULL;
-        } else if (env->IsInstanceOf(valueObj, integerClass.get())) {
-            jmethodID intValueID =
-                env->GetMethodID(integerClass.get(), "intValue", "()I");
-            CHECK(intValueID != NULL);
-
-            jint value = env->CallIntMethod(valueObj, intValueID);
-
-            msg->setInt32(key.c_str(), value);
-        } else if (env->IsInstanceOf(valueObj, longClass.get())) {
-            jmethodID longValueID =
-                env->GetMethodID(longClass.get(), "longValue", "()J");
-            CHECK(longValueID != NULL);
-
-            jlong value = env->CallLongMethod(valueObj, longValueID);
-
-            msg->setInt64(key.c_str(), value);
-        } else if (env->IsInstanceOf(valueObj, floatClass.get())) {
-            jmethodID floatValueID =
-                env->GetMethodID(floatClass.get(), "floatValue", "()F");
-            CHECK(floatValueID != NULL);
-
-            jfloat value = env->CallFloatMethod(valueObj, floatValueID);
-
-            msg->setFloat(key.c_str(), value);
-        } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) {
-            jmethodID positionID =
-                env->GetMethodID(byteBufClass.get(), "position", "()I");
-            CHECK(positionID != NULL);
-
-            jmethodID limitID =
-                env->GetMethodID(byteBufClass.get(), "limit", "()I");
-            CHECK(limitID != NULL);
-
-            jint position = env->CallIntMethod(valueObj, positionID);
-            jint limit = env->CallIntMethod(valueObj, limitID);
-
-            sp<ABuffer> buffer = new ABuffer(limit - position);
-
-            void *data = env->GetDirectBufferAddress(valueObj);
-
-            if (data != NULL) {
-                memcpy(buffer->data(),
-                       (const uint8_t *)data + position,
-                       buffer->size());
-            } else {
-                jmethodID arrayID =
-                    env->GetMethodID(byteBufClass.get(), "array", "()[B");
-                CHECK(arrayID != NULL);
-
-                jbyteArray byteArray =
-                    (jbyteArray)env->CallObjectMethod(valueObj, arrayID);
-                CHECK(byteArray != NULL);
-
-                env->GetByteArrayRegion(
-                        byteArray,
-                        position,
-                        buffer->size(),
-                        (jbyte *)buffer->data());
-
-                env->DeleteLocalRef(byteArray); byteArray = NULL;
-            }
-
-            msg->setBuffer(key.c_str(), buffer);
-        }
-    }
-
-    *out = msg;
-
-    return OK;
-}
-
 // -----------Utility functions used by ImageReader/Writer JNI-----------------
 
 enum {
diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h
index 821c6b2..24f1610 100644
--- a/media/jni/android_media_Utils.h
+++ b/media/jni/android_media_Utils.h
@@ -17,100 +17,10 @@
 #ifndef _ANDROID_MEDIA_UTILS_H_
 #define _ANDROID_MEDIA_UTILS_H_
 
-#include "src/piex_types.h"
-#include "src/piex.h"
-
-#include <android_runtime/AndroidRuntime.h>
 #include <gui/CpuConsumer.h>
-#include <jni.h>
-#include <nativehelper/JNIHelp.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include <SkStream.h>
 
 namespace android {
 
-class AssetStream : public piex::StreamInterface {
-private:
-    SkStream *mStream;
-    size_t mPosition;
-
-public:
-    explicit AssetStream(SkStream* stream);
-    ~AssetStream();
-
-    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
-    // provided by the caller, guaranteed to be at least "length" bytes long.
-    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
-    // 'offset' bytes from the start of the stream.
-    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
-    // change the contents of 'data'.
-    piex::Error GetData(
-            const size_t offset, const size_t length, std::uint8_t* data) override;
-};
-
-class BufferedStream : public piex::StreamInterface {
-private:
-    SkStream *mStream;
-    // Growable memory stream
-    SkDynamicMemoryWStream mStreamBuffer;
-
-    // Minimum size to read on filling the buffer.
-    const size_t kMinSizeToRead = 8192;
-
-public:
-    explicit BufferedStream(SkStream* stream);
-    ~BufferedStream();
-
-    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
-    // provided by the caller, guaranteed to be at least "length" bytes long.
-    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
-    // 'offset' bytes from the start of the stream.
-    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
-    // change the contents of 'data'.
-    piex::Error GetData(
-            const size_t offset, const size_t length, std::uint8_t* data) override;
-};
-
-class FileStream : public piex::StreamInterface {
-private:
-    FILE *mFile;
-    size_t mPosition;
-
-public:
-    explicit FileStream(const int fd);
-    explicit FileStream(const String8 filename);
-    ~FileStream();
-
-    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
-    // provided by the caller, guaranteed to be at least "length" bytes long.
-    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
-    // 'offset' bytes from the start of the stream.
-    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
-    // change the contents of 'data'.
-    piex::Error GetData(
-            const size_t offset, const size_t length, std::uint8_t* data) override;
-    bool exists() const;
-};
-
-// Reads EXIF metadata from a given raw image via piex.
-// And returns true if the operation is successful; otherwise, false.
-bool GetExifFromRawImage(
-        piex::StreamInterface* stream, const String8& filename, piex::PreviewImageData& image_data);
-
-// Returns true if the conversion is successful; otherwise, false.
-bool ConvertKeyValueArraysToKeyedVector(
-        JNIEnv *env, jobjectArray keys, jobjectArray values,
-        KeyedVector<String8, String8>* vector);
-
-struct AMessage;
-status_t ConvertMessageToMap(
-        JNIEnv *env, const sp<AMessage> &msg, jobject *map);
-
-status_t ConvertKeyValueArraysToMessage(
-        JNIEnv *env, jobjectArray keys, jobjectArray values,
-        sp<AMessage> *msg);
-
 // -----------Utility functions used by ImageReader/Writer JNI-----------------
 
 typedef CpuConsumer::LockedBuffer LockedImage;
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 213c3d9..a6c5fc8 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -18,7 +18,7 @@
 #include "utils/Log.h"
 #include "utils/String8.h"
 
-#include "android_media_Utils.h"
+#include "android_media_Streams.h"
 #include "mtp.h"
 #include "IMtpDatabase.h"
 #include "MtpDataPacket.h"
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
index 9c31b4d..f545a61 100644
--- a/packages/CaptivePortalLogin/Android.bp
+++ b/packages/CaptivePortalLogin/Android.bp
@@ -18,6 +18,7 @@
     name: "CaptivePortalLogin",
     srcs: ["src/**/*.java"],
     sdk_version: "system_current",
+    min_sdk_version: "28",
     certificate: "networkstack",
     static_libs: [
         "android-support-v4",
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index a5f3b88fe..44e0a65 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -18,7 +18,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.captiveportallogin"
-    android:versionCode="10"
+    android:versionCode="11"
     android:versionName="Q-initial">
 
     <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 5f1f26d..f210840 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -36,6 +36,7 @@
 android_app {
     name: "NetworkStack",
     sdk_version: "system_current",
+    min_sdk_version: "28",
     certificate: "networkstack",
     privileged: true,
     static_libs: [
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 740c573..003f1e5 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -19,7 +19,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.networkstack"
           android:sharedUserId="android.uid.networkstack"
-          android:versionCode="10"
+          android:versionCode="11"
           android:versionName="Q-initial">
     <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
     <uses-permission android:name="android.permission.INTERNET" />
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkStackPermissionStub/Android.bp
index dd70cf5..8cee92e 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/packages/NetworkStackPermissionStub/Android.bp
@@ -21,6 +21,7 @@
     // a classes.dex.
     srcs: ["src/**/*.java"],
     platform_apis: true,
+    min_sdk_version: "28",
     certificate: "networkstack",
     privileged: true,
     manifest: "AndroidManifest.xml",
diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkStackPermissionStub/AndroidManifest.xml
index 62bf3de..e83f050 100644
--- a/packages/NetworkStackPermissionStub/AndroidManifest.xml
+++ b/packages/NetworkStackPermissionStub/AndroidManifest.xml
@@ -19,7 +19,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.networkstack.permissionstub"
     android:sharedUserId="android.uid.networkstack"
-    android:versionCode="10"
+    android:versionCode="11"
     android:versionName="Q-initial">
     <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
     <!--
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index cc3e6fb..ac71ae5 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1573,8 +1573,7 @@
     public boolean isActiveNetworkMetered() {
         enforceAccessPermission();
 
-        final int uid = Binder.getCallingUid();
-        final NetworkCapabilities caps = getUnfilteredActiveNetworkState(uid).networkCapabilities;
+        final NetworkCapabilities caps = getNetworkCapabilities(getActiveNetwork());
         if (caps != null) {
             return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
         } else {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6cbb35b..d288910 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1682,19 +1682,6 @@
         mSystemServiceManager.startService(StatsCompanionService.Lifecycle.class);
         traceEnd();
 
-        if (safeMode) {
-            traceBeginAndSlog("EnterSafeModeAndDisableJitCompilation");
-            mActivityManagerService.enterSafeMode();
-            // Disable the JIT for the system_server process
-            VMRuntime.getRuntime().disableJitCompilation();
-            traceEnd();
-        } else {
-            // Enable the JIT for the system_server process
-            traceBeginAndSlog("StartJitCompilation");
-            VMRuntime.getRuntime().startJitCompilation();
-            traceEnd();
-        }
-
         // MMS service broker
         traceBeginAndSlog("StartMmsService");
         mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
diff --git a/telecomm/java/android/telecom/CallIdentification.java b/telecomm/java/android/telecom/CallIdentification.java
index cde7f60..fffc123 100644
--- a/telecomm/java/android/telecom/CallIdentification.java
+++ b/telecomm/java/android/telecom/CallIdentification.java
@@ -44,7 +44,7 @@
      * A {@link CallScreeningService} uses this class to create new instances of
      * {@link CallIdentification} for a screened call.
      */
-    public static class Builder {
+    public final static class Builder {
         private CharSequence mName;
         private CharSequence mDescription;
         private CharSequence mDetails;
@@ -67,7 +67,7 @@
          * @param callIdAppName The app name.
          * @hide
          */
-        public Builder(String callIdPackageName, CharSequence callIdAppName) {
+        public Builder(@NonNull String callIdPackageName, @NonNull CharSequence callIdAppName) {
             mPackageName = callIdPackageName;
             mAppName = callIdAppName;
         }
@@ -80,7 +80,7 @@
          * @param name The name associated with the call, or {@code null} if none is provided.
          * @return Builder instance.
          */
-        public Builder setName(@Nullable CharSequence name) {
+        public @NonNull Builder setName(@Nullable CharSequence name) {
             mName = name;
             return this;
         }
@@ -97,7 +97,7 @@
          * @param description The call description, or {@code null} if none is provided.
          * @return Builder instance.
          */
-        public Builder setDescription(@Nullable CharSequence description) {
+        public @NonNull Builder setDescription(@Nullable CharSequence description) {
             mDescription = description;
             return this;
         }
@@ -114,7 +114,8 @@
          * @param details The call details, or {@code null} if none is provided.
          * @return Builder instance.
          */
-        public Builder setDetails(@Nullable CharSequence details) {
+
+        public @NonNull Builder setDetails(@Nullable CharSequence details) {
             mDetails = details;
             return this;
         }
@@ -127,7 +128,7 @@
          * @param photo The photo associated with the call, or {@code null} if none was provided.
          * @return Builder instance.
          */
-        public Builder setPhoto(@Nullable Icon photo) {
+        public @NonNull Builder setPhoto(@Nullable Icon photo) {
             mPhoto = photo;
             return this;
         }
@@ -141,7 +142,7 @@
          * @param nuisanceConfidence The nuisance confidence.
          * @return The builder.
          */
-        public Builder setNuisanceConfidence(@NuisanceConfidence int nuisanceConfidence) {
+        public @NonNull Builder setNuisanceConfidence(@NuisanceConfidence int nuisanceConfidence) {
             mNuisanceConfidence = nuisanceConfidence;
             return this;
         }
@@ -152,7 +153,7 @@
          *
          * @return {@link CallIdentification} instance.
          */
-        public CallIdentification build() {
+        public @NonNull CallIdentification build() {
             return new CallIdentification(mName, mDescription, mDetails, mPhoto,
                     mNuisanceConfidence, mPackageName, mAppName);
         }
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
index f23f4c9..563c2dc 100644
--- a/telecomm/java/android/telecom/PhoneAccountSuggestion.java
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
@@ -18,8 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -69,10 +67,15 @@
     private boolean mShouldAutoSelect;
 
     /**
-     * @hide
+     * Creates a new instance of {@link PhoneAccountSuggestion}. This constructor is intended for
+     * use by apps implementing a {@link PhoneAccountSuggestionService}, and generally should not be
+     * used by dialer apps other than for testing purposes.
+     *
+     * @param handle The {@link PhoneAccountHandle} for this suggestion.
+     * @param reason The reason for this suggestion
+     * @param shouldAutoSelect Whether the dialer should automatically place the call using this
+     *                         account. See {@link #shouldAutoSelect()}.
      */
-    @SystemApi
-    @TestApi
     public PhoneAccountSuggestion(@NonNull PhoneAccountHandle handle, @SuggestionReason int reason,
             boolean shouldAutoSelect) {
         this.mHandle = handle;
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index e655e4f..84b2238 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -17,6 +17,7 @@
 import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SuppressLint;
@@ -809,10 +810,11 @@
      * <p>
      * The default dialer has access to use this method.
      *
-     * @return The user outgoing phone account selected by the user.
+     * @return The user outgoing phone account selected by the user, or {@code null} if there is no
+     * user selected outgoing {@link PhoneAccountHandle}.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
+    public @Nullable PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
         try {
             if (isServiceConnected()) {
                 return getTelecomService().getUserSelectedOutgoingPhoneAccount(
@@ -828,13 +830,14 @@
      * Sets the user-chosen default {@link PhoneAccountHandle} for making outgoing phone calls.
      *
      * @param accountHandle The {@link PhoneAccountHandle} which will be used by default for making
-     *                      outgoing voice calls.
+     *                      outgoing voice calls, or {@code null} if no default is specified (the
+     *                      user will be asked each time a call is placed in this case).
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @TestApi
     @SystemApi
-    public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
+    public void setUserSelectedOutgoingPhoneAccount(@Nullable PhoneAccountHandle accountHandle) {
         try {
             if (isServiceConnected()) {
                 getTelecomService().setUserSelectedOutgoingPhoneAccount(accountHandle);
@@ -1201,7 +1204,8 @@
     /**
      * Used to set the default dialer package.
      *
-     * @param packageName to set the default dialer to.
+     * @param packageName to set the default dialer to, or {@code null} if the system provided
+     *                    dialer should be used instead.
      *
      * @result {@code true} if the default dialer was successfully changed, {@code false} if
      *         the specified package does not correspond to an installed dialer, or is already
@@ -1218,7 +1222,7 @@
     @RequiresPermission(allOf = {
             android.Manifest.permission.MODIFY_PHONE_STATE,
             android.Manifest.permission.WRITE_SECURE_SETTINGS})
-    public boolean setDefaultDialer(String packageName) {
+    public boolean setDefaultDialer(@Nullable String packageName) {
         try {
             if (isServiceConnected()) {
                 return getTelecomService().setDefaultDialer(packageName);
@@ -1232,9 +1236,10 @@
     /**
      * Determines the package name of the system-provided default phone app.
      *
-     * @return package name for the system dialer package or null if no system dialer is preloaded.
+     * @return package name for the system dialer package or {@code null} if no system dialer is
+     *         preloaded.
      */
-    public String getSystemDialerPackage() {
+    public @Nullable String getSystemDialerPackage() {
         try {
             if (isServiceConnected()) {
                 return getTelecomService().getSystemDialerPackage();
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index a09aed7..4939157 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3765,6 +3765,42 @@
          */
         public static final String CARRIER_ID = "carrier_id";
 
+        /**
+         * The skip 464xlat flag. Flag works as follows.
+         * {@link #SKIP_464XLAT_DEFAULT}: the APN will skip only APN is IMS and no internet.
+         * {@link #SKIP_464XLAT_DISABLE}: the APN will NOT skip 464xlat
+         * {@link #SKIP_464XLAT_ENABLE}: the APN will skip 464xlat
+         * <p>Type: INTEGER</p>
+         *
+         * @hide
+         */
+        public static final String SKIP_464XLAT = "skip_464xlat";
+
+        /**
+         * Possible value for the {@link #SKIP_464XLAT} field.
+         * <p>Type: INTEGER</p>
+         *
+         * @hide
+         */
+        public static final int SKIP_464XLAT_DEFAULT = -1;
+
+        /**
+         * Possible value for the {@link #SKIP_464XLAT} field.
+         * <p>Type: INTEGER</p>
+         *
+         * @hide
+         */
+        public static final int SKIP_464XLAT_DISABLE = 0;
+
+        /**
+         * Possible value for the {@link #SKIP_464XLAT} field.
+         * <p>Type: INTEGER</p>
+         *
+         * @hide
+         */
+        public static final int SKIP_464XLAT_ENABLE = 1;
+
+
         /** @hide */
         @IntDef({
                 UNEDITED,
@@ -3775,6 +3811,16 @@
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface EditStatus {}
+
+        /** @hide */
+        @IntDef({
+                SKIP_464XLAT_DEFAULT,
+                SKIP_464XLAT_DISABLE,
+                SKIP_464XLAT_ENABLE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Skip464XlatStatus {}
+
     }
 
     /**
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index 0d4f09f..2ff2d91 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -29,15 +30,15 @@
  * @hide
  */
 @SystemApi
-public class CallAttributes implements Parcelable {
+public final class CallAttributes implements Parcelable {
     private PreciseCallState mPreciseCallState;
     @NetworkType
     private int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints
     private CallQuality mCallQuality;
 
 
-    public CallAttributes(PreciseCallState state, @NetworkType int networkType,
-            CallQuality callQuality) {
+    public CallAttributes(@NonNull PreciseCallState state, @NetworkType int networkType,
+            @NonNull CallQuality callQuality) {
         this.mPreciseCallState = state;
         this.mNetworkType = networkType;
         this.mCallQuality = callQuality;
@@ -59,6 +60,7 @@
     /**
      * Returns the {@link PreciseCallState} of the call.
      */
+    @NonNull
     public PreciseCallState getPreciseCallState() {
         return mPreciseCallState;
     }
@@ -96,6 +98,7 @@
     /**
      * Returns the {#link CallQuality} of the call.
      */
+    @NonNull
     public CallQuality getCallQuality() {
         return mCallQuality;
     }
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index 84d6628..4d97f81 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -17,11 +17,13 @@
 package android.telephony;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.TelephonyManager.NetworkType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -140,6 +142,7 @@
     @ServiceState.RoamingType
     private int mRoamingType;
 
+    @NetworkType
     private int mAccessNetworkTechnology;
 
     @NRStatus
@@ -149,6 +152,7 @@
 
     private final boolean mEmergencyOnly;
 
+    @ServiceType
     private final int[] mAvailableServices;
 
     @Nullable
@@ -167,9 +171,8 @@
      * @param regState Network registration state. Must be one of the {@link RegState}. For
      * {@link TransportType#WLAN} transport, only {@link #REG_STATE_HOME} and
      * {@link #REG_STATE_NOT_REG_NOT_SEARCHING} are valid states.
-     * @param accessNetworkTechnology Access network technology. Must be one of TelephonyManager
-     * NETWORK_TYPE_XXXX. For {@link TransportType#WLAN} transport, set to
-     * {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
+     * @param accessNetworkTechnology Access network technology.For {@link TransportType#WLAN}
+     * transport, set to {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
      * @param rejectCause Reason for denial if the registration state is {@link #REG_STATE_DENIED}.
      * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
      * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA. If
@@ -182,8 +185,9 @@
      * information is not available.
      */
     public NetworkRegistrationState(@Domain int domain, int transportType, @RegState int regState,
-                                    int accessNetworkTechnology, int rejectCause,
-                                    boolean emergencyOnly, int[] availableServices,
+                                    @NetworkType int accessNetworkTechnology, int rejectCause,
+                                    boolean emergencyOnly,
+                                    @NonNull @ServiceType int[] availableServices,
                                     @Nullable CellIdentity cellIdentity) {
         mDomain = domain;
         mTransportType = transportType;
@@ -230,7 +234,7 @@
         updateNrStatus(mDataSpecificStates);
     }
 
-    protected NetworkRegistrationState(Parcel source) {
+    private NetworkRegistrationState(Parcel source) {
         mDomain = source.readInt();
         mTransportType = source.readInt();
         mRegState = source.readInt();
@@ -285,6 +289,14 @@
     }
 
     /**
+     * @hide
+     * @return {@code true} if in service.
+     */
+    public boolean isInService() {
+        return mRegState == REG_STATE_HOME || mRegState == REG_STATE_ROAMING;
+    }
+
+    /**
      * Set {@link ServiceState.RoamingType roaming type}. This could override
      * roaming type based on resource overlay or carrier config.
      * @hide
@@ -309,25 +321,29 @@
     /**
      * @return List of available service types.
      */
+    @NonNull
+    @ServiceType
     public int[] getAvailableServices() { return mAvailableServices; }
 
     /**
-     * @return The access network technology {@link TelephonyManager.NetworkType}.
+     * @return The access network technology {@link NetworkType}.
      */
-    public @TelephonyManager.NetworkType int getAccessNetworkTechnology() {
+    public @NetworkType int getAccessNetworkTechnology() {
         return mAccessNetworkTechnology;
     }
 
     /**
-     * override the access network technology {@link TelephonyManager.NetworkType} e.g, rat ratchet.
+     * override the access network technology {@link NetworkType} e.g, rat ratchet.
      * @hide
      */
-    public void setAccessNetworkTechnology(@TelephonyManager.NetworkType int tech) {
+    public void setAccessNetworkTechnology(@NetworkType int tech) {
         mAccessNetworkTechnology = tech;
     }
 
     /**
-     * @return Network reject cause
+     * @return Reason for denial if the registration state is {@link #REG_STATE_DENIED}.
+     * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
+     * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
      */
     public int getRejectCause() {
         return mRejectCause;
@@ -336,6 +352,7 @@
     /**
      * @return The cell information.
      */
+    @Nullable
     public CellIdentity getCellIdentity() {
         return mCellIdentity;
     }
@@ -539,4 +556,192 @@
         p.recycle();
         return result;
     }
+
+    /**
+     * Provides a convenient way to set the fields of a {@link NetworkRegistrationState} when
+     * creating a new instance.
+     *
+     * <p>The example below shows how you might create a new {@code NetworkRegistrationState}:
+     *
+     * <pre><code>
+     *
+     * NetworkRegistrationState nrs = new NetworkRegistrationState.Builder()
+     *     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+     *     .setApnName("apn.example.com")
+     *     .setEntryName("Example Carrier APN")
+     *     .setMmsc(Uri.parse("http://mms.example.com:8002"))
+     *     .setMmsProxyAddress(mmsProxy)
+     *     .setMmsProxyPort(8799)
+     *     .build();
+     * </code></pre>
+     */
+    public static class Builder{
+        @Domain
+        private int mDomain;
+
+        private int mTransportType;
+
+        @RegState
+        private int mRegState;
+
+        @ServiceState.RoamingType
+        private int mRoamingType;
+
+        @NetworkType
+        private int mAccessNetworkTechnology;
+
+        @NRStatus
+        private int mNrStatus;
+
+        private int mRejectCause;
+
+        private boolean mEmergencyOnly;
+
+        @ServiceType
+        private int[] mAvailableServices;
+
+        @Nullable
+        private CellIdentity mCellIdentity;
+
+        /**
+         * Default constructor for Builder.
+         */
+        public Builder() {}
+
+        /**
+         * Set the network domain.
+         *
+         * @param domain Network domain.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setDomain(@Domain int domain) {
+            mDomain = domain;
+            return this;
+        }
+
+        /**
+         * Set the transport type.
+         *
+         * @param transportType Transport type.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setTransportType(int transportType) {
+            mTransportType = transportType;
+            return this;
+        }
+
+        /**
+         * Set the registration state.
+         *
+         * @param regState The registration state.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setRegState(@RegState int regState) {
+            mRegState = regState;
+            return this;
+        }
+
+        /**
+         * Set the roaming type.
+         *
+         * @param roamingType Roaming type.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setRoamingType(@ServiceState.RoamingType int roamingType) {
+            mRoamingType = roamingType;
+            return this;
+        }
+
+        /**
+         * Set tne access network technology.
+         *
+         * @return The same instance of the builder.
+         *
+         * @param accessNetworkTechnology The access network technology
+         */
+        public @NonNull Builder setAccessNetworkTechnology(
+                @NetworkType int accessNetworkTechnology) {
+            mAccessNetworkTechnology = accessNetworkTechnology;
+            return this;
+        }
+
+        /**
+         * Set the 5G NR connection status.
+         *
+         * @param nrStatus 5G NR connection status.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setNrStatus(@NRStatus int nrStatus) {
+            mNrStatus = nrStatus;
+            return this;
+        }
+
+        /**
+         * Set the network reject cause.
+         *
+         * @param rejectCause Reason for denial if the registration state is
+         * {@link #REG_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the values are
+         * defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2
+         * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setRejectCause(int rejectCause) {
+            mRejectCause = rejectCause;
+            return this;
+        }
+
+        /**
+         * Set emergency only.
+         *
+         * @param emergencyOnly True if this network registration is for emergency use only.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
+            mEmergencyOnly = emergencyOnly;
+            return this;
+        }
+
+        /**
+         * Set the available services.
+         *
+         * @param availableServices Available services.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setAvailableServices(
+                @NonNull @ServiceType int[] availableServices) {
+            mAvailableServices = availableServices;
+            return this;
+        }
+
+        /**
+         * Set the cell identity.
+         *
+         * @param cellIdentity The cell identity.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
+            mCellIdentity = cellIdentity;
+            return this;
+        }
+
+        /**
+         * Build the NetworkRegistrationState.
+         *
+         * @return the NetworkRegistrationState object.
+         */
+        public @NonNull NetworkRegistrationState build() {
+            return new NetworkRegistrationState(mDomain, mTransportType, mRegState,
+                    mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
+                    mCellIdentity);
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index bec9494..f1240e9 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
@@ -82,27 +83,30 @@
      * service is associated with one physical SIM slot.
      */
     public abstract class NetworkServiceProvider implements AutoCloseable {
-        private final int mSlotId;
+        private final int mSlotIndex;
 
         private final List<INetworkServiceCallback>
                 mNetworkRegistrationStateChangedCallbacks = new ArrayList<>();
 
-        public NetworkServiceProvider(int slotId) {
-            mSlotId = slotId;
+        /**
+         * Constructor
+         * @param slotIndex SIM slot id the data service provider associated with.
+         */
+        public NetworkServiceProvider(int slotIndex) {
+            mSlotIndex = slotIndex;
         }
 
         /**
-         * @return SIM slot id the network service associated with.
+         * @return SIM slot index the network service associated with.
          */
-        public final int getSlotId() {
-            return mSlotId;
+        public final int getSlotIndex() {
+            return mSlotIndex;
         }
 
         /**
          * API to get network registration state. The result will be passed to the callback.
          * @param domain Network domain
          * @param callback The callback for reporting network registration state
-         * @return SIM slot id the network service associated with.
          */
         public void getNetworkRegistrationState(@Domain int domain,
                                                 @NonNull NetworkServiceCallback callback) {
@@ -110,9 +114,12 @@
                     NetworkServiceCallback.RESULT_ERROR_UNSUPPORTED, null);
         }
 
+        /**
+         * Notify the system that network registration state is changed.
+         */
         public final void notifyNetworkRegistrationStateChanged() {
             mHandler.obtainMessage(NETWORK_SERVICE_INDICATION_NETWORK_STATE_CHANGED,
-                    mSlotId, 0, null).sendToTarget();
+                    mSlotIndex, 0, null).sendToTarget();
         }
 
         private void registerForStateChanged(@NonNull INetworkServiceCallback callback) {
@@ -154,23 +161,23 @@
 
         @Override
         public void handleMessage(Message message) {
-            final int slotId = message.arg1;
+            final int slotIndex = message.arg1;
             final INetworkServiceCallback callback = (INetworkServiceCallback) message.obj;
 
-            NetworkServiceProvider serviceProvider = mServiceMap.get(slotId);
+            NetworkServiceProvider serviceProvider = mServiceMap.get(slotIndex);
 
             switch (message.what) {
                 case NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER:
                     // If the service provider doesn't exist yet, we try to create it.
                     if (serviceProvider == null) {
-                        mServiceMap.put(slotId, createNetworkServiceProvider(slotId));
+                        mServiceMap.put(slotIndex, onCreateNetworkServiceProvider(slotIndex));
                     }
                     break;
                 case NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER:
                     // If the service provider doesn't exist yet, we try to create it.
                     if (serviceProvider != null) {
                         serviceProvider.close();
-                        mServiceMap.remove(slotId);
+                        mServiceMap.remove(slotIndex);
                     }
                     break;
                 case NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS:
@@ -223,12 +230,12 @@
      * this method to facilitate the creation of {@link NetworkServiceProvider} instances. The system
      * will call this method after binding the network service for each active SIM slot id.
      *
-     * @param slotId SIM slot id the network service associated with.
+     * @param slotIndex SIM slot id the network service associated with.
      * @return Network service object
      */
-    protected abstract NetworkServiceProvider createNetworkServiceProvider(int slotId);
+    @Nullable
+    public abstract NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex);
 
-    /** @hide */
     @Override
     public IBinder onBind(Intent intent) {
         if (intent == null || !NETWORK_SERVICE_INTERFACE.equals(intent.getAction())) {
@@ -239,7 +246,6 @@
         return mBinder;
     }
 
-    /** @hide */
     @Override
     public boolean onUnbind(Intent intent) {
         mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS, 0,
@@ -252,6 +258,7 @@
     @Override
     public void onDestroy() {
         mHandlerThread.quit();
+        super.onDestroy();
     }
 
     /**
@@ -261,35 +268,35 @@
     private class INetworkServiceWrapper extends INetworkService.Stub {
 
         @Override
-        public void createNetworkServiceProvider(int slotId) {
-            mHandler.obtainMessage(NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER, slotId,
+        public void createNetworkServiceProvider(int slotIndex) {
+            mHandler.obtainMessage(NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER, slotIndex,
                     0, null).sendToTarget();
         }
 
         @Override
-        public void removeNetworkServiceProvider(int slotId) {
-            mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER, slotId,
+        public void removeNetworkServiceProvider(int slotIndex) {
+            mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER, slotIndex,
                     0, null).sendToTarget();
         }
 
         @Override
         public void getNetworkRegistrationState(
-                int slotId, int domain, INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_STATE, slotId,
+                int slotIndex, int domain, INetworkServiceCallback callback) {
+            mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_STATE, slotIndex,
                     domain, callback).sendToTarget();
         }
 
         @Override
         public void registerForNetworkRegistrationStateChanged(
-                int slotId, INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE, slotId,
+                int slotIndex, INetworkServiceCallback callback) {
+            mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE, slotIndex,
                     0, callback).sendToTarget();
         }
 
         @Override
         public void unregisterForNetworkRegistrationStateChanged(
-                int slotId,INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE, slotId,
+                int slotIndex, INetworkServiceCallback callback) {
+            mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE, slotIndex,
                     0, callback).sendToTarget();
         }
     }
diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java
index dbad02f..c2fcfb7 100644
--- a/telephony/java/android/telephony/NetworkServiceCallback.java
+++ b/telephony/java/android/telephony/NetworkServiceCallback.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.RemoteException;
 import android.telephony.NetworkService.NetworkServiceProvider;
@@ -75,7 +76,8 @@
      *                {@link NetworkServiceCallback#RESULT_ERROR_UNSUPPORTED}
      * @param state The state information to be returned to callback.
      */
-    public void onGetNetworkRegistrationStateComplete(int result, NetworkRegistrationState state) {
+    public void onGetNetworkRegistrationStateComplete(int result,
+                                                      @Nullable NetworkRegistrationState state) {
         INetworkServiceCallback callback = mCallback.get();
         if (callback != null) {
             try {
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index c1786be..eb889c6 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -22,6 +22,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.TelephonyManager.PrefNetworkMode;
 
 import com.android.internal.telephony.RILConstants;
 
@@ -170,7 +171,8 @@
     };
 
     @UnsupportedAppUsage
-    public static int getRafFromNetworkType(int type) {
+    @TelephonyManager.NetworkTypeBitMask
+    public static int getRafFromNetworkType(@PrefNetworkMode int type) {
         switch (type) {
             case RILConstants.NETWORK_MODE_WCDMA_PREF:
                 return GSM | WCDMA;
@@ -279,6 +281,7 @@
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @PrefNetworkMode
     public static int getNetworkTypeFromRaf(int raf) {
         raf = getAdjustedRaf(raf);
 
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f2daace..6118129 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -438,7 +438,11 @@
 
     /**
      * Construct a ServiceState object from the given parcel.
+     *
+     * @deprecated The constructor takes parcel should not be public at the beginning. Use
+     * {@link #ServiceState()} instead.
      */
+    @Deprecated
     public ServiceState(Parcel in) {
         mVoiceRegState = in.readInt();
         mDataRegState = in.readInt();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0235201..769d1a4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1539,6 +1539,7 @@
      * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
      * available.
      */
+    @Nullable
     public String getTypeAllocationCode() {
         return getTypeAllocationCode(getSlotIndex());
     }
@@ -1549,6 +1550,7 @@
      *
      * @param slotIndex of which Type Allocation Code is returned
      */
+    @Nullable
     public String getTypeAllocationCode(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -1601,6 +1603,7 @@
      * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
      * available.
      */
+    @Nullable
     public String getManufacturerCode() {
         return getManufacturerCode(getSlotIndex());
     }
@@ -1611,6 +1614,7 @@
      *
      * @param slotIndex of which Type Allocation Code is returned
      */
+    @Nullable
     public String getManufacturerCode(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -5981,6 +5985,7 @@
      * @return IMS Service Table or null if not present or not loaded
      * @hide
      */
+    @Nullable
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getIsimIst() {
@@ -6832,12 +6837,12 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
      * @param subId the id of the subscription to set the preferred network type for.
-     * @param networkType the preferred network type, defined in RILConstants.java.
+     * @param networkType the preferred network type
      * @return true on success; false on any failure.
      * @hide
      */
     @UnsupportedAppUsage
-    public boolean setPreferredNetworkType(int subId, int networkType) {
+    public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -10301,12 +10306,6 @@
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void switchMultiSimConfig(int numOfSims) {
-        //only proceed if multi-sim is not restricted
-        if (!isMultisimSupported()) {
-            Rlog.e(TAG, "switchMultiSimConfig not possible. It is restricted or not supported.");
-            return;
-        }
-
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 97a2f13..c802e63 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -61,6 +61,7 @@
     private static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*";
     private static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*";
     private static final String V6_FORMAT_REGEX = "^\\[ApnSettingV6\\]\\s*";
+    private static final String V7_FORMAT_REGEX = "^\\[ApnSettingV7\\]\\s*";
 
     /**
      * Default value for mtu if it's not set. Moved from PhoneConstants.
@@ -286,6 +287,8 @@
     private boolean mPermanentFailed = false;
     private final int mCarrierId;
 
+    private final int mSkip464Xlat;
+
     /**
      * Returns the MTU size of the mobile interface to which the APN connected.
      *
@@ -623,6 +626,17 @@
         return mCarrierId;
     }
 
+    /**
+     * Returns the skip464xlat flag for this APN.
+     *
+     * @return SKIP_464XLAT_DEFAULT, SKIP_464XLAT_DISABLE or SKIP_464XLAT_ENABLE
+     * @hide
+     */
+    @Carriers.Skip464XlatStatus
+    public int getSkip464Xlat() {
+        return mSkip464Xlat;
+    }
+
     private ApnSetting(Builder builder) {
         this.mEntryName = builder.mEntryName;
         this.mApnName = builder.mApnName;
@@ -651,6 +665,7 @@
         this.mMvnoMatchData = builder.mMvnoMatchData;
         this.mApnSetId = builder.mApnSetId;
         this.mCarrierId = builder.mCarrierId;
+        this.mSkip464Xlat = builder.mSkip464Xlat;
     }
 
     /**
@@ -662,7 +677,7 @@
             int authType, int mApnTypeBitmask, int protocol, int roamingProtocol,
             boolean carrierEnabled, int networkTypeBitmask, int profileId,
             boolean modemCognitive, int maxConns, int waitTime, int maxConnsTime, int mtu,
-            int mvnoType, String mvnoMatchData, int apnSetId, int carrierId) {
+            int mvnoType, String mvnoMatchData, int apnSetId, int carrierId, int skip464xlat) {
         return new Builder()
             .setId(id)
             .setOperatorNumeric(operatorNumeric)
@@ -691,6 +706,7 @@
             .setMvnoMatchData(mvnoMatchData)
             .setApnSetId(apnSetId)
             .setCarrierId(carrierId)
+            .setSkip464Xlat(skip464xlat)
             .buildWithoutCheck();
     }
 
@@ -708,7 +724,8 @@
             mmsc, mmsProxyAddress, mmsProxyPort, user, password, authType, mApnTypeBitmask,
             protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, profileId,
             modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType, mvnoMatchData,
-            Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+            Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID,
+            Carriers.SKIP_464XLAT_DEFAULT);
     }
 
     /**
@@ -767,7 +784,8 @@
             cursor.getString(cursor.getColumnIndexOrThrow(
                 Telephony.Carriers.MVNO_MATCH_DATA)),
             cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)),
-            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)));
+            cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)),
+            cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.SKIP_464XLAT)));
     }
 
     /**
@@ -780,7 +798,7 @@
             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,
-            apn.mCarrierId);
+            apn.mCarrierId, apn.mSkip464Xlat);
     }
 
     /**
@@ -829,6 +847,13 @@
      *   <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
      *   <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>
      *
+     * v7 format:
+     *   [ApnSettingV7] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
+     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
+     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
+     *   <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
+     *   <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>, <skip464xlat>
+     *
      * Note that the strings generated by {@link #toString()} do not contain the username
      * and password and thus cannot be read by this method.
      *
@@ -841,7 +866,10 @@
 
         int version;
         // matches() operates on the whole string, so append .* to the regex.
-        if (data.matches(V6_FORMAT_REGEX + ".*")) {
+        if (data.matches(V7_FORMAT_REGEX + ".*")) {
+            version = 7;
+            data = data.replaceFirst(V7_FORMAT_REGEX, "");
+        } else if (data.matches(V6_FORMAT_REGEX + ".*")) {
             version = 6;
             data = data.replaceFirst(V6_FORMAT_REGEX, "");
         } else if (data.matches(V5_FORMAT_REGEX + ".*")) {
@@ -887,6 +915,7 @@
         String mvnoMatchData = "";
         int apnSetId = Carriers.NO_APN_SET_ID;
         int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+        int skip464xlat = Carriers.SKIP_464XLAT_DEFAULT;
         if (version == 1) {
             typeArray = new String[a.length - 13];
             System.arraycopy(a, 13, typeArray, 0, a.length - 13);
@@ -933,6 +962,12 @@
             if (a.length > 28) {
                 carrierId = Integer.parseInt(a[28]);
             }
+            if (a.length > 29) {
+                try {
+                    skip464xlat = Integer.parseInt(a[29]);
+                } catch (NumberFormatException e) {
+                }
+            }
         }
 
         // If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be
@@ -948,7 +983,7 @@
             getProtocolIntFromString(protocol), getProtocolIntFromString(roamingProtocol),
             carrierEnabled, networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime,
             maxConnsTime, mtu, getMvnoTypeIntFromString(mvnoType), mvnoMatchData, apnSetId,
-            carrierId);
+            carrierId, skip464xlat);
     }
 
     /**
@@ -984,7 +1019,7 @@
      */
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("[ApnSettingV6] ")
+        sb.append("[ApnSettingV7] ")
                 .append(mEntryName)
                 .append(", ").append(mId)
                 .append(", ").append(mOperatorNumeric)
@@ -1012,6 +1047,7 @@
         sb.append(", ").append(mNetworkTypeBitmask);
         sb.append(", ").append(mApnSetId);
         sb.append(", ").append(mCarrierId);
+        sb.append(", ").append(mSkip464Xlat);
         return sb.toString();
     }
 
@@ -1105,7 +1141,8 @@
             && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
             && Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask)
             && Objects.equals(mApnSetId, other.mApnSetId)
-            && Objects.equals(mCarrierId, other.mCarrierId);
+            && Objects.equals(mCarrierId, other.mCarrierId)
+            && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
     }
 
     /**
@@ -1151,7 +1188,8 @@
             && Objects.equals(mMvnoType, other.mMvnoType)
             && Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
             && Objects.equals(mApnSetId, other.mApnSetId)
-            && Objects.equals(mCarrierId, other.mCarrierId);
+            && Objects.equals(mCarrierId, other.mCarrierId)
+            && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
     }
 
     /**
@@ -1179,7 +1217,8 @@
             && xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
             && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
             && Objects.equals(mApnSetId, other.mApnSetId)
-            && Objects.equals(mCarrierId, other.mCarrierId);
+            && Objects.equals(mCarrierId, other.mCarrierId)
+            && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
     }
 
     // Equal or one is null.
@@ -1226,6 +1265,7 @@
         apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
         apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
         apnValue.put(Telephony.Carriers.CARRIER_ID, mCarrierId);
+        apnValue.put(Telephony.Carriers.SKIP_464XLAT, mSkip464Xlat);
 
         return apnValue;
     }
@@ -1385,6 +1425,7 @@
         dest.writeInt(mNetworkTypeBitmask);
         dest.writeInt(mApnSetId);
         dest.writeInt(mCarrierId);
+        dest.writeInt(mSkip464Xlat);
     }
 
     private static ApnSetting readFromParcel(Parcel in) {
@@ -1408,11 +1449,12 @@
         final int networkTypeBitmask = in.readInt();
         final int apnSetId = in.readInt();
         final int carrierId = in.readInt();
+        final int skip464xlat = in.readInt();
 
         return makeApnSetting(id, operatorNumeric, entryName, apnName,
-            proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
-            protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
-            0, 0, 0, 0, mvnoType, null, apnSetId, carrierId);
+                proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
+                protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
+                0, 0, 0, 0, mvnoType, null, apnSetId, carrierId, skip464xlat);
     }
 
     public static final Parcelable.Creator<ApnSetting> CREATOR =
@@ -1489,6 +1531,7 @@
         private String mMvnoMatchData;
         private int mApnSetId;
         private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+        private int mSkip464Xlat = Carriers.SKIP_464XLAT_DEFAULT;
 
         /**
          * Default constructor for Builder.
@@ -1831,6 +1874,17 @@
         }
 
         /**
+         * Sets skip464xlat flag for this APN.
+         *
+         * @param skip464xlat skip464xlat for this APN
+         * @hide
+         */
+        public Builder setSkip464Xlat(@Carriers.Skip464XlatStatus int skip464xlat) {
+            this.mSkip464Xlat = skip464xlat;
+            return this;
+        }
+
+        /**
          * Builds {@link ApnSetting} from this builder.
          *
          * @return {@code null} if {@link #setApnName(String)} or {@link #setEntryName(String)}
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 3d2fe5f..6d74ded 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -25,6 +25,8 @@
 import android.os.Parcelable;
 import android.telephony.data.ApnSetting.ProtocolType;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
@@ -90,6 +92,8 @@
         mMtu = mtu;
     }
 
+    /** @hide */
+    @VisibleForTesting
     public DataCallResponse(Parcel source) {
         mStatus = source.readInt();
         mSuggestedRetryTime = source.readInt();
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index a3fa77b..59d1e1e 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -116,23 +116,23 @@
      */
     public abstract class DataServiceProvider implements AutoCloseable {
 
-        private final int mSlotId;
+        private final int mSlotIndex;
 
         private final List<IDataServiceCallback> mDataCallListChangedCallbacks = new ArrayList<>();
 
         /**
          * Constructor
-         * @param slotId SIM slot id the data service provider associated with.
+         * @param slotIndex SIM slot index the data service provider associated with.
          */
-        public DataServiceProvider(int slotId) {
-            mSlotId = slotId;
+        public DataServiceProvider(int slotIndex) {
+            mSlotIndex = slotIndex;
         }
 
         /**
-         * @return SIM slot id the data service provider associated with.
+         * @return SIM slot index the data service provider associated with.
          */
-        public final int getSlotId() {
-            return mSlotId;
+        public final int getSlotIndex() {
+            return mSlotIndex;
         }
 
         /**
@@ -251,9 +251,9 @@
         public final void notifyDataCallListChanged(List<DataCallResponse> dataCallList) {
             synchronized (mDataCallListChangedCallbacks) {
                 for (IDataServiceCallback callback : mDataCallListChangedCallbacks) {
-                    mHandler.obtainMessage(DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED, mSlotId,
-                            0, new DataCallListChangedIndication(dataCallList, callback))
-                            .sendToTarget();
+                    mHandler.obtainMessage(DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED,
+                            mSlotIndex, 0, new DataCallListChangedIndication(dataCallList,
+                                    callback)).sendToTarget();
                 }
             }
         }
@@ -342,20 +342,20 @@
         @Override
         public void handleMessage(Message message) {
             IDataServiceCallback callback;
-            final int slotId = message.arg1;
-            DataServiceProvider serviceProvider = mServiceMap.get(slotId);
+            final int slotIndex = message.arg1;
+            DataServiceProvider serviceProvider = mServiceMap.get(slotIndex);
 
             switch (message.what) {
                 case DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER:
-                    serviceProvider = createDataServiceProvider(message.arg1);
+                    serviceProvider = onCreateDataServiceProvider(message.arg1);
                     if (serviceProvider != null) {
-                        mServiceMap.put(slotId, serviceProvider);
+                        mServiceMap.put(slotIndex, serviceProvider);
                     }
                     break;
                 case DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER:
                     if (serviceProvider != null) {
                         serviceProvider.close();
-                        mServiceMap.remove(slotId);
+                        mServiceMap.remove(slotIndex);
                     }
                     break;
                 case DATA_SERVICE_REMOVE_ALL_DATA_SERVICE_PROVIDERS:
@@ -454,12 +454,12 @@
      * this method to facilitate the creation of {@link DataServiceProvider} instances. The system
      * will call this method after binding the data service for each active SIM slot id.
      *
-     * @param slotId SIM slot id the data service associated with.
+     * @param slotIndex SIM slot id the data service associated with.
      * @return Data service object
      */
-    public abstract DataServiceProvider createDataServiceProvider(int slotId);
+    @Nullable
+    public abstract DataServiceProvider onCreateDataServiceProvider(int slotIndex);
 
-    /** @hide */
     @Override
     public IBinder onBind(Intent intent) {
         if (intent == null || !DATA_SERVICE_INTERFACE.equals(intent.getAction())) {
@@ -469,17 +469,16 @@
         return mBinder;
     }
 
-    /** @hide */
     @Override
     public boolean onUnbind(Intent intent) {
         mHandler.obtainMessage(DATA_SERVICE_REMOVE_ALL_DATA_SERVICE_PROVIDERS).sendToTarget();
         return false;
     }
 
-    /** @hide */
     @Override
     public void onDestroy() {
         mHandlerThread.quit();
+        super.onDestroy();
     }
 
     /**
@@ -487,78 +486,78 @@
      */
     private class IDataServiceWrapper extends IDataService.Stub {
         @Override
-        public void createDataServiceProvider(int slotId) {
-            mHandler.obtainMessage(DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER, slotId, 0)
+        public void createDataServiceProvider(int slotIndex) {
+            mHandler.obtainMessage(DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER, slotIndex, 0)
                     .sendToTarget();
         }
 
         @Override
-        public void removeDataServiceProvider(int slotId) {
-            mHandler.obtainMessage(DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER, slotId, 0)
+        public void removeDataServiceProvider(int slotIndex) {
+            mHandler.obtainMessage(DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER, slotIndex, 0)
                     .sendToTarget();
         }
 
         @Override
-        public void setupDataCall(int slotId, int accessNetworkType, DataProfile dataProfile,
+        public void setupDataCall(int slotIndex, int accessNetworkType, DataProfile dataProfile,
                                   boolean isRoaming, boolean allowRoaming, int reason,
                                   LinkProperties linkProperties, IDataServiceCallback callback) {
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotId, 0,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotIndex, 0,
                     new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming,
                             allowRoaming, reason, linkProperties, callback))
                     .sendToTarget();
         }
 
         @Override
-        public void deactivateDataCall(int slotId, int cid, int reason,
+        public void deactivateDataCall(int slotIndex, int cid, int reason,
                                        IDataServiceCallback callback) {
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL, slotId, 0,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL, slotIndex, 0,
                     new DeactivateDataCallRequest(cid, reason, callback))
                     .sendToTarget();
         }
 
         @Override
-        public void setInitialAttachApn(int slotId, DataProfile dataProfile, boolean isRoaming,
+        public void setInitialAttachApn(int slotIndex, DataProfile dataProfile, boolean isRoaming,
                                         IDataServiceCallback callback) {
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN, slotId, 0,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN, slotIndex, 0,
                     new SetInitialAttachApnRequest(dataProfile, isRoaming, callback))
                     .sendToTarget();
         }
 
         @Override
-        public void setDataProfile(int slotId, List<DataProfile> dps, boolean isRoaming,
+        public void setDataProfile(int slotIndex, List<DataProfile> dps, boolean isRoaming,
                                    IDataServiceCallback callback) {
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_DATA_PROFILE, slotId, 0,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_DATA_PROFILE, slotIndex, 0,
                     new SetDataProfileRequest(dps, isRoaming, callback)).sendToTarget();
         }
 
         @Override
-        public void getDataCallList(int slotId, IDataServiceCallback callback) {
+        public void getDataCallList(int slotIndex, IDataServiceCallback callback) {
             if (callback == null) {
                 loge("getDataCallList: callback is null");
                 return;
             }
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST, slotId, 0,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST, slotIndex, 0,
                     callback).sendToTarget();
         }
 
         @Override
-        public void registerForDataCallListChanged(int slotId, IDataServiceCallback callback) {
+        public void registerForDataCallListChanged(int slotIndex, IDataServiceCallback callback) {
             if (callback == null) {
                 loge("registerForDataCallListChanged: callback is null");
                 return;
             }
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED, slotId,
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED, slotIndex,
                     0, callback).sendToTarget();
         }
 
         @Override
-        public void unregisterForDataCallListChanged(int slotId, IDataServiceCallback callback) {
+        public void unregisterForDataCallListChanged(int slotIndex, IDataServiceCallback callback) {
             if (callback == null) {
                 loge("unregisterForDataCallListChanged: callback is null");
                 return;
             }
-            mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED, slotId,
-                    0, callback).sendToTarget();
+            mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED,
+                    slotIndex, 0, callback).sendToTarget();
         }
     }
 
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index bef1142..2d0cfe8 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -17,6 +17,8 @@
 package android.telephony.data;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.LinkProperties;
 import android.os.RemoteException;
@@ -74,7 +76,8 @@
      * @param result The result code. Must be one of the {@link ResultCode}.
      * @param response Setup data call response.
      */
-    public void onSetupDataCallComplete(@ResultCode int result, DataCallResponse response) {
+    public void onSetupDataCallComplete(@ResultCode int result,
+                                        @Nullable DataCallResponse response) {
         IDataServiceCallback callback = mCallback.get();
         if (callback != null) {
             try {
@@ -141,10 +144,11 @@
      * DataServiceCallback)}.
      *
      * @param result The result code. Must be one of the {@link ResultCode}.
-     * @param dataCallList List of the current active data connection.
+     * @param dataCallList List of the current active data connection. If no data call is presented,
+     * set it to an empty list.
      */
     public void onGetDataCallListComplete(@ResultCode int result,
-                                          List<DataCallResponse> dataCallList) {
+                                          @NonNull List<DataCallResponse> dataCallList) {
         IDataServiceCallback callback = mCallback.get();
         if (callback != null) {
             try {
@@ -156,11 +160,12 @@
     }
 
     /**
-     * Called to indicate that data connection list changed.
+     * Called to indicate that data connection list changed. If no data call is presented, set it to
+     * an empty list.
      *
      * @param dataCallList List of the current active data connection.
      */
-    public void onDataCallListChanged(List<DataCallResponse> dataCallList) {
+    public void onDataCallListChanged(@NonNull List<DataCallResponse> dataCallList) {
         IDataServiceCallback callback = mCallback.get();
         if (callback != null) {
             try {
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index d049547..b8a07e4 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -17,6 +17,7 @@
 
 import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
@@ -365,6 +366,7 @@
      *
      * @return an EuiccManager that uses the given card ID for all calls.
      */
+    @NonNull
     public EuiccManager createForCardId(int cardId) {
         return new EuiccManager(mContext, cardId);
     }
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 337375a..a09844d 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -16,6 +16,7 @@
 
 package android.telephony.ims;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.RemoteException;
 import android.telephony.CallQuality;
@@ -606,7 +607,7 @@
      *
      * @param profile updated ImsStreamMediaProfile
      */
-    public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
+    public void callSessionRttAudioIndicatorChanged(@NonNull ImsStreamMediaProfile profile) {
         try {
             mListener.callSessionRttAudioIndicatorChanged(profile);
         } catch (RemoteException e) {
@@ -619,7 +620,7 @@
      *
      * @param callQuality The new call quality
      */
-    public void callQualityChanged(CallQuality callQuality) {
+    public void callQualityChanged(@NonNull CallQuality callQuality) {
         try {
             mListener.callQualityChanged(callQuality);
         } catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index 3a82517..86832bb 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -17,6 +17,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -24,6 +25,9 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Provides STK Call Control Supplementary Service information.
@@ -260,13 +264,13 @@
     public final int result;
 
     private int[] mSsInfo;
-    private ImsCallForwardInfo[] mCfInfo;
-    private ImsSsInfo[] mImsSsInfo;
+    private List<ImsCallForwardInfo> mCfInfo;
+    private List<ImsSsInfo> mImsSsInfo;
 
     /**
      * Builder for optional ImsSsData parameters.
      */
-    public static class Builder {
+    public static final class Builder {
         private ImsSsData mImsSsData;
 
         /**
@@ -301,7 +305,7 @@
          * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service
          * data.
          */
-        public @NonNull Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) {
+        public @NonNull Builder setSuppServiceInfo(@NonNull List<ImsSsInfo> imsSsInfos) {
             mImsSsData.mImsSsInfo = imsSsInfos;
             return this;
         }
@@ -311,7 +315,7 @@
          * service data.
          */
         public @NonNull Builder setCallForwardingInfo(
-                @NonNull ImsCallForwardInfo[] imsCallForwardInfos) {
+                @NonNull List<ImsCallForwardInfo> imsCallForwardInfos) {
             mImsSsData.mCfInfo = imsCallForwardInfos;
             return this;
         }
@@ -360,8 +364,8 @@
         serviceClass = in.readInt();
         result = in.readInt();
         mSsInfo = in.createIntArray();
-        mCfInfo = (ImsCallForwardInfo[])in.readParcelableArray(this.getClass().getClassLoader());
-        mImsSsInfo = (ImsSsInfo[])in.readParcelableArray(this.getClass().getClassLoader());
+        mCfInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader());
+        mImsSsInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader());
     }
 
     public static final Creator<ImsSsData> CREATOR = new Creator<ImsSsData>() {
@@ -384,8 +388,8 @@
         out.writeInt(getServiceClass());
         out.writeInt(getResult());
         out.writeIntArray(mSsInfo);
-        out.writeParcelableArray(mCfInfo, 0);
-        out.writeParcelableArray(mImsSsInfo, 0);
+        out.writeParcelableList(mCfInfo, 0);
+        out.writeParcelableList(mImsSsInfo, 0);
     }
 
     @Override
@@ -500,12 +504,12 @@
 
     /** @hide */
     public void setImsSpecificSuppServiceInfo(ImsSsInfo[] imsSsInfo) {
-        mImsSsInfo = imsSsInfo;
+        mImsSsInfo = Arrays.asList(imsSsInfo);
     }
 
     /** @hide */
     public void setCallForwardingInfo(ImsCallForwardInfo[] cfInfo) {
-        mCfInfo = cfInfo;
+        mCfInfo = Arrays.asList(cfInfo);
     }
 
     /**
@@ -524,7 +528,7 @@
 
 
         int[] result = new int[2];
-        if (mImsSsInfo == null || mImsSsInfo.length == 0) {
+        if (mImsSsInfo == null || mImsSsInfo.size() == 0) {
             Rlog.e(TAG, "getSuppServiceInfoCompat: Could not parse mImsSsInfo, returning empty "
                     + "int[]");
             return result;
@@ -535,26 +539,26 @@
         if (isTypeClir()) {
             // Assume there will only be one ImsSsInfo.
             // contains {"n","m"} parameters
-            result[0] = mImsSsInfo[0].getClirOutgoingState();
-            result[1] = mImsSsInfo[0].getClirInterrogationStatus();
+            result[0] = mImsSsInfo.get(0).getClirOutgoingState();
+            result[1] = mImsSsInfo.get(0).getClirInterrogationStatus();
             return result;
         }
         // COLR 7.31
         if (isTypeColr()) {
-            result[0] = mImsSsInfo[0].getProvisionStatus();
+            result[0] = mImsSsInfo.get(0).getProvisionStatus();
         }
         // Facility Lock CLCK 7.4 (for call barring), CLIP 7.6, COLP 7.8, as well as any
         // other result, just return the status for the "n" parameter and provisioning status for
         // "m" as the default.
-        result[0] = mImsSsInfo[0].getStatus();
-        result[1] = mImsSsInfo[0].getProvisionStatus();
+        result[0] = mImsSsInfo.get(0).getStatus();
+        result[1] = mImsSsInfo.get(0).getProvisionStatus();
         return result;
     }
 
     /**
      * @return an array of {@link ImsSsInfo}s associated with this supplementary service data.
      */
-    public @NonNull ImsSsInfo[] getSuppServiceInfo() {
+    public @NonNull List<ImsSsInfo> getSuppServiceInfo() {
         return mImsSsInfo;
     }
 
@@ -562,7 +566,7 @@
      * @return an array of {@link ImsCallForwardInfo}s associated with this supplementary service
      * data.
      **/
-    public ImsCallForwardInfo[] getCallForwardInfo() {
+    public @Nullable List<ImsCallForwardInfo> getCallForwardInfo() {
         return mCfInfo;
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 031f9e1..fba390c 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -173,7 +173,7 @@
     /**
      * Builds {@link ImsSsInfo} instances, which may include optional parameters.
      */
-    public static class Builder {
+    public static final class Builder {
 
         private final ImsSsInfo mImsSsInfo;
 
@@ -304,7 +304,7 @@
     /**
      * @return The Incoming Communication Barring (ICB) number.
      */
-    public String getIncomingCommunicationBarringNumber() {
+    public @Nullable String getIncomingCommunicationBarringNumber() {
         return mIcbNum;
     }
 
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b460c90..c25ad5f 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -909,11 +909,19 @@
             return mConnected;  // Similar trickery
         }
 
-        public void connect() {
+        private void connect(boolean isAlwaysMetered) {
             mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
             mConnected = true;
             mConfig = new VpnConfig();
-            mConfig.isMetered = false;
+            mConfig.isMetered = isAlwaysMetered;
+        }
+
+        public void connectAsAlwaysMetered() {
+            connect(true /* isAlwaysMetered */);
+        }
+
+        public void connect() {
+            connect(false /* isAlwaysMetered */);
         }
 
         @Override
@@ -5015,6 +5023,202 @@
     }
 
     @Test
+    public void testIsActiveNetworkMeteredOverWifi() {
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        waitForIdle();
+
+        assertFalse(mCm.isActiveNetworkMetered());
+    }
+
+    @Test
+    public void testIsActiveNetworkMeteredOverCell() {
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        mCellNetworkAgent.connect(true);
+        waitForIdle();
+
+        assertTrue(mCm.isActiveNetworkMetered());
+    }
+
+    @Test
+    public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() {
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        mCellNetworkAgent.connect(true);
+        waitForIdle();
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // Connect VPN network. By default it is using current default network (Cell).
+        MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        final ArraySet<UidRange> ranges = new ArraySet<>();
+        final int uid = Process.myUid();
+        ranges.add(new UidRange(uid, uid));
+        mMockVpn.setNetworkAgent(vpnNetworkAgent);
+        mMockVpn.setUids(ranges);
+        vpnNetworkAgent.connect(true);
+        mMockVpn.connect();
+        waitForIdle();
+        // Ensure VPN is now the active network.
+        assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // Expect VPN to be metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // Connect WiFi.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        waitForIdle();
+        // VPN should still be the active network.
+        assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // Expect VPN to be unmetered as it should now be using WiFi (new default).
+        assertFalse(mCm.isActiveNetworkMetered());
+
+        // Disconnecting Cell should not affect VPN's meteredness.
+        mCellNetworkAgent.disconnect();
+        waitForIdle();
+
+        assertFalse(mCm.isActiveNetworkMetered());
+
+        // Disconnect WiFi; Now there is no platform default network.
+        mWiFiNetworkAgent.disconnect();
+        waitForIdle();
+
+        // VPN without any underlying networks is treated as metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        vpnNetworkAgent.disconnect();
+        mMockVpn.disconnect();
+    }
+
+   @Test
+   public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() {
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        mCellNetworkAgent.connect(true);
+        waitForIdle();
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        waitForIdle();
+        assertFalse(mCm.isActiveNetworkMetered());
+
+        // Connect VPN network.
+        MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        final ArraySet<UidRange> ranges = new ArraySet<>();
+        final int uid = Process.myUid();
+        ranges.add(new UidRange(uid, uid));
+        mMockVpn.setNetworkAgent(vpnNetworkAgent);
+        mMockVpn.setUids(ranges);
+        vpnNetworkAgent.connect(true);
+        mMockVpn.connect();
+        waitForIdle();
+        // Ensure VPN is now the active network.
+        assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        // VPN is using Cell
+        mService.setUnderlyingNetworksForVpn(
+                new Network[] { mCellNetworkAgent.getNetwork() });
+        waitForIdle();
+
+        // Expect VPN to be metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // VPN is now using WiFi
+        mService.setUnderlyingNetworksForVpn(
+                new Network[] { mWiFiNetworkAgent.getNetwork() });
+        waitForIdle();
+
+        // Expect VPN to be unmetered
+        assertFalse(mCm.isActiveNetworkMetered());
+
+        // VPN is using Cell | WiFi.
+        mService.setUnderlyingNetworksForVpn(
+                new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
+        waitForIdle();
+
+        // Expect VPN to be metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // VPN is using WiFi | Cell.
+        mService.setUnderlyingNetworksForVpn(
+                new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() });
+        waitForIdle();
+
+        // Order should not matter and VPN should still be metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // VPN is not using any underlying networks.
+        mService.setUnderlyingNetworksForVpn(new Network[0]);
+        waitForIdle();
+
+        // VPN without underlying networks is treated as metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        vpnNetworkAgent.disconnect();
+        mMockVpn.disconnect();
+    }
+
+    @Test
+    public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() {
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        waitForIdle();
+        assertFalse(mCm.isActiveNetworkMetered());
+
+        // Connect VPN network.
+        MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        final ArraySet<UidRange> ranges = new ArraySet<>();
+        final int uid = Process.myUid();
+        ranges.add(new UidRange(uid, uid));
+        mMockVpn.setNetworkAgent(vpnNetworkAgent);
+        mMockVpn.setUids(ranges);
+        vpnNetworkAgent.connect(true);
+        mMockVpn.connectAsAlwaysMetered();
+        waitForIdle();
+        assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // VPN is tracking current platform default (WiFi).
+        mService.setUnderlyingNetworksForVpn(null);
+        waitForIdle();
+
+        // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // VPN explicitly declares WiFi as its underlying network.
+        mService.setUnderlyingNetworksForVpn(
+                new Network[] { mWiFiNetworkAgent.getNetwork() });
+        waitForIdle();
+
+        // Doesn't really matter whether VPN declares its underlying networks explicitly.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // With WiFi lost, VPN is basically without any underlying networks. And in that case it is
+        // anyways suppose to be metered.
+        mWiFiNetworkAgent.disconnect();
+        waitForIdle();
+
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        vpnNetworkAgent.disconnect();
+    }
+
+    @Test
     public void testNetworkBlockedStatus() {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
         final NetworkRequest cellRequest = new NetworkRequest.Builder()
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 295e3de..a91fbe7 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -196,8 +196,10 @@
 
             if "implements" in raw:
                 self.implements = raw[raw.index("implements")+1]
+                self.implements_all = [self.implements]
             else:
                 self.implements = None
+                self.implements_all = []
         else:
             raise ValueError("Unknown signature format: " + sig_format)
 
@@ -224,7 +226,7 @@
 
 
 class Package():
-    NAME = re.compile("package(?: .*)? ([A-Za-z.]+)")
+    NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")
 
     def __init__(self, line, raw, blame):
         self.line = line
@@ -364,12 +366,12 @@
         self.parse_matching_paren("<", ">")
         extends = self.parse_extends()
         clazz.extends = extends[0] if extends else None
-        implements = self.parse_implements()
-        clazz.implements = implements[0] if implements else None
+        clazz.implements_all = self.parse_implements()
         # The checks assume that interfaces are always found in implements, which isn't true for
         # subinterfaces.
-        if not implements and "interface" in clazz.split:
-            clazz.implements = clazz.extends
+        if not clazz.implements_all and "interface" in clazz.split:
+            clazz.implements_all = [clazz.extends]
+        clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
         self.parse_token("{")
         self.parse_eof()
 
@@ -761,6 +763,14 @@
     noticed[clazz.fullname] = hash(clazz)
 
 
+verifiers = {}
+
+def verifier(f):
+    verifiers[f.__name__] = f
+    return f
+
+
+@verifier
 def verify_constants(clazz):
     """All static final constants must be FOO_NAME style."""
     if re.match("android\.R\.[a-z]+", clazz.fullname): return
@@ -778,13 +788,13 @@
             if f.typ in req and f.value is None:
                 error(clazz, f, None, "All constants must be defined at compile time")
 
-
+@verifier
 def verify_enums(clazz):
     """Enums are bad, mmkay?"""
     if clazz.extends == "java.lang.Enum" or "enum" in clazz.split:
         error(clazz, None, "F5", "Enums are not allowed")
 
-
+@verifier
 def verify_class_names(clazz):
     """Try catching malformed class names like myMtp or MTPUser."""
     if clazz.fullname.startswith("android.opengl"): return
@@ -799,6 +809,7 @@
         error(clazz, None, None, "Don't expose your implementation details")
 
 
+@verifier
 def verify_method_names(clazz):
     """Try catching malformed method names, like Foo() or getMTU()."""
     if clazz.fullname.startswith("android.opengl"): return
@@ -812,9 +823,9 @@
             error(clazz, m, "S1", "Method name must start with lowercase char")
 
 
+@verifier
 def verify_callbacks(clazz):
     """Verify Callback classes.
-    All callback classes must be abstract.
     All methods must follow onFoo() naming style."""
     if clazz.fullname == "android.speech.tts.SynthesisCallback": return
 
@@ -824,14 +835,12 @@
         warn(clazz, None, "L1", "Class should be named FooCallback")
 
     if clazz.name.endswith("Callback"):
-        if "interface" in clazz.split:
-            error(clazz, None, "CL3", "Callbacks must be abstract class to enable extension in future API levels")
-
         for m in clazz.methods:
             if not re.match("on[A-Z][a-z]*", m.name):
                 error(clazz, m, "L1", "Callback method names must be onFoo() style")
 
 
+@verifier
 def verify_listeners(clazz):
     """Verify Listener classes.
     All Listener classes must be interface.
@@ -853,6 +862,7 @@
                 error(clazz, m, "L1", "Single listener method name must match class name")
 
 
+@verifier
 def verify_actions(clazz):
     """Verify intent actions.
     All action names must be named ACTION_FOO.
@@ -884,6 +894,7 @@
                         error(clazz, f, "C4", "Inconsistent action value; expected '%s'" % (expected))
 
 
+@verifier
 def verify_extras(clazz):
     """Verify intent extras.
     All extra names must be named EXTRA_FOO.
@@ -914,6 +925,7 @@
                         error(clazz, f, "C4", "Inconsistent extra value; expected '%s'" % (expected))
 
 
+@verifier
 def verify_equals(clazz):
     """Verify that equals() and hashCode() must be overridden together."""
     eq = False
@@ -926,6 +938,7 @@
         error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
 
 
+@verifier
 def verify_parcelable(clazz):
     """Verify that Parcelable objects aren't hiding required bits."""
     if clazz.implements == "android.os.Parcelable":
@@ -944,6 +957,7 @@
                 error(clazz, c, "FW3", "Parcelable inflation is exposed through CREATOR, not raw constructors")
 
 
+@verifier
 def verify_protected(clazz):
     """Verify that no protected methods or fields are allowed."""
     for m in clazz.methods:
@@ -955,6 +969,7 @@
             error(clazz, f, "M7", "Protected fields not allowed; must be public")
 
 
+@verifier
 def verify_fields(clazz):
     """Verify that all exposed fields are final.
     Exposed fields must follow myName style.
@@ -1000,6 +1015,7 @@
                 error(clazz, f, "C2", "Constants must be marked static final")
 
 
+@verifier
 def verify_register(clazz):
     """Verify parity of registration methods.
     Callback objects use register/unregister methods.
@@ -1033,6 +1049,7 @@
                 error(clazz, m, "L3", "Listener methods should be named add/remove")
 
 
+@verifier
 def verify_sync(clazz):
     """Verify synchronized methods aren't exposed."""
     for m in clazz.methods:
@@ -1040,6 +1057,7 @@
             error(clazz, m, "M5", "Internal locks must not be exposed")
 
 
+@verifier
 def verify_intent_builder(clazz):
     """Verify that Intent builders are createFooIntent() style."""
     if clazz.name == "Intent": return
@@ -1052,6 +1070,7 @@
                 warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
 
 
+@verifier
 def verify_helper_classes(clazz):
     """Verify that helper classes are named consistently with what they extend.
     All developer extendable methods should be named onFoo()."""
@@ -1100,6 +1119,7 @@
                     warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
 
 
+@verifier
 def verify_builder(clazz):
     """Verify builder classes.
     Methods should return the builder to enable chaining."""
@@ -1132,12 +1152,14 @@
         error(clazz, None, None, "Builder should be final")
 
 
+@verifier
 def verify_aidl(clazz):
     """Catch people exposing raw AIDL."""
     if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface":
         error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
 
 
+@verifier
 def verify_internal(clazz):
     """Catch people exposing internal classes."""
     if clazz.pkg.name.startswith("com.android"):
@@ -1172,6 +1194,7 @@
     "android.util"
 ])
 
+@verifier
 def verify_layering(clazz):
     """Catch package layering violations.
     For example, something in android.os depending on android.app."""
@@ -1206,6 +1229,7 @@
                 warn(clazz, m, "FW6", "Method argument type violates package layering")
 
 
+@verifier
 def verify_boolean(clazz):
     """Verifies that boolean accessors are named correctly.
     For example, hasFoo() and setHasFoo()."""
@@ -1246,9 +1270,11 @@
                 error_if_exists(sets, m.name, expected, "has" + target)
 
 
+@verifier
 def verify_collections(clazz):
     """Verifies that collection types are interfaces."""
     if clazz.fullname == "android.os.Bundle": return
+    if clazz.fullname == "android.os.Parcel": return
 
     bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
            "java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
@@ -1260,6 +1286,23 @@
                 error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
 
 
+@verifier
+def verify_uris(clazz):
+    bad = ["java.net.URL", "java.net.URI", "android.net.URL"]
+
+    for f in clazz.fields:
+        if f.typ in bad:
+            error(clazz, f, None, "Field must be android.net.Uri instead of " + f.typ)
+
+    for m in clazz.methods + clazz.ctors:
+        if m.typ in bad:
+            error(clazz, m, None, "Must return android.net.Uri instead of " + m.typ)
+        for arg in m.args:
+            if arg in bad:
+                error(clazz, m, None, "Argument must take android.net.Uri instead of " + arg)
+
+
+@verifier
 def verify_flags(clazz):
     """Verifies that flags are non-overlapping."""
     known = collections.defaultdict(int)
@@ -1276,6 +1319,7 @@
             known[scope] |= val
 
 
+@verifier
 def verify_exception(clazz):
     """Verifies that methods don't throw generic exceptions."""
     for m in clazz.methods:
@@ -1284,17 +1328,19 @@
                 error(clazz, m, "S1", "Methods must not throw generic exceptions")
 
             if t in ["android.os.RemoteException"]:
-                if clazz.name == "android.content.ContentProviderClient": continue
-                if clazz.name == "android.os.Binder": continue
-                if clazz.name == "android.os.IBinder": continue
+                if clazz.fullname == "android.content.ContentProviderClient": continue
+                if clazz.fullname == "android.os.Binder": continue
+                if clazz.fullname == "android.os.IBinder": continue
 
                 error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
 
             if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]:
                 warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException")
 
+
 GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE)
 
+# Not marked as @verifier, because it is only conditionally applied.
 def verify_google(clazz):
     """Verifies that APIs never reference Google."""
 
@@ -1307,6 +1353,7 @@
                 error(clazz, t, None, "Must never reference Google")
 
 
+@verifier
 def verify_bitset(clazz):
     """Verifies that we avoid using heavy BitSet."""
 
@@ -1322,6 +1369,7 @@
                 error(clazz, m, None, "Argument type must not be heavy BitSet")
 
 
+@verifier
 def verify_manager(clazz):
     """Verifies that FooManager is only obtained from Context."""
 
@@ -1335,6 +1383,7 @@
             error(clazz, m, None, "Managers must always be obtained from Context")
 
 
+@verifier
 def verify_boxed(clazz):
     """Verifies that methods avoid boxed primitives."""
 
@@ -1357,6 +1406,7 @@
                 error(clazz, m, "M11", "Must avoid boxed primitives")
 
 
+@verifier
 def verify_static_utils(clazz):
     """Verifies that helper classes can't be constructed."""
     if clazz.fullname.startswith("android.opengl"): return
@@ -1376,6 +1426,7 @@
         error(clazz, None, None, "Fully-static utility classes must not have constructor")
 
 
+# @verifier  # Disabled for now
 def verify_overload_args(clazz):
     """Verifies that method overloads add new arguments at the end."""
     if clazz.fullname.startswith("android.opengl"): return
@@ -1416,6 +1467,7 @@
                 error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
 
 
+@verifier
 def verify_callback_handlers(clazz):
     """Verifies that methods adding listener/callback have overload
     for specifying delivery thread."""
@@ -1467,6 +1519,7 @@
             warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Executor")
 
 
+@verifier
 def verify_context_first(clazz):
     """Verifies that methods accepting a Context keep it the first argument."""
     examine = clazz.ctors + clazz.methods
@@ -1479,6 +1532,7 @@
                 error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
 
 
+@verifier
 def verify_listener_last(clazz):
     """Verifies that methods accepting a Listener or Callback keep them as last arguments."""
     examine = clazz.ctors + clazz.methods
@@ -1492,6 +1546,7 @@
                 warn(clazz, m, "M3", "Listeners should always be at end of argument list")
 
 
+@verifier
 def verify_resource_names(clazz):
     """Verifies that resource names have consistent case."""
     if not re.match("android\.R\.[a-z]+", clazz.fullname): return
@@ -1523,6 +1578,7 @@
             error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
 
 
+@verifier
 def verify_files(clazz):
     """Verifies that methods accepting File also accept streams."""
 
@@ -1544,6 +1600,7 @@
             warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
 
 
+@verifier
 def verify_manager_list(clazz):
     """Verifies that managers return List<? extends Parcelable> instead of arrays."""
 
@@ -1554,6 +1611,7 @@
             warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
 
 
+@verifier
 def verify_abstract_inner(clazz):
     """Verifies that abstract inner classes are static."""
 
@@ -1562,6 +1620,7 @@
             warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
 
 
+@verifier
 def verify_runtime_exceptions(clazz):
     """Verifies that runtime exceptions aren't listed in throws."""
 
@@ -1606,6 +1665,7 @@
                 error(clazz, m, None, "Methods must not mention RuntimeException subclasses in throws clauses")
 
 
+@verifier
 def verify_error(clazz):
     """Verifies that we always use Exception instead of Error."""
     if not clazz.extends: return
@@ -1615,6 +1675,7 @@
         error(clazz, None, None, "Exceptions must be named FooException")
 
 
+@verifier
 def verify_units(clazz):
     """Verifies that we use consistent naming for units."""
 
@@ -1651,10 +1712,11 @@
             error(clazz, m, None, "Percentage must use ints")
 
 
+@verifier
 def verify_closable(clazz):
     """Verifies that classes are AutoClosable."""
-    if clazz.implements == "java.lang.AutoCloseable": return
-    if clazz.implements == "java.io.Closeable": return
+    if "java.lang.AutoCloseable" in clazz.implements_all: return
+    if "java.io.Closeable" in clazz.implements_all: return
 
     for m in clazz.methods:
         if len(m.args) > 0: continue
@@ -1663,6 +1725,7 @@
             return
 
 
+@verifier
 def verify_member_name_not_kotlin_keyword(clazz):
     """Prevent method names which are keywords in Kotlin."""
 
@@ -1688,6 +1751,7 @@
             error(clazz, f, None, "Field name must not be a Kotlin keyword")
 
 
+@verifier
 def verify_method_name_not_kotlin_operator(clazz):
     """Warn about method names which become operators in Kotlin."""
 
@@ -1737,6 +1801,7 @@
             unique_binary_op(m, m.name[:-6])  # Remove 'Assign' suffix
 
 
+@verifier
 def verify_collections_over_arrays(clazz):
     """Warn that [] should be Collections."""
 
@@ -1752,6 +1817,7 @@
                 warn(clazz, m, None, "Method argument should be Collection<> (or subclass) instead of raw array")
 
 
+@verifier
 def verify_user_handle(clazz):
     """Methods taking UserHandle should be ForUser or AsUser."""
     if clazz.name.endswith("Listener") or clazz.name.endswith("Callback") or clazz.name.endswith("Callbacks"): return
@@ -1776,6 +1842,7 @@
                  "or 'queryFooForUser'")
 
 
+@verifier
 def verify_params(clazz):
     """Parameter classes should be 'Params'."""
     if clazz.name.endswith("Params"): return
@@ -1791,6 +1858,7 @@
             error(clazz, None, None, "Classes holding a set of parameters should be called 'FooParams'")
 
 
+@verifier
 def verify_services(clazz):
     """Service name should be FOO_BAR_SERVICE = 'foo_bar'."""
     if clazz.fullname != "android.content.Context": return
@@ -1804,6 +1872,7 @@
                 error(clazz, f, "C4", "Inconsistent service value; expected '%s'" % (expected))
 
 
+@verifier
 def verify_tense(clazz):
     """Verify tenses of method names."""
     if clazz.fullname.startswith("android.opengl"): return
@@ -1813,6 +1882,7 @@
             warn(clazz, m, None, "Unexpected tense; probably meant 'enabled'")
 
 
+@verifier
 def verify_icu(clazz):
     """Verifies that richer ICU replacements are used."""
     better = {
@@ -1844,6 +1914,7 @@
                 warn(clazz, m, None, "Type %s should be replaced with richer ICU type %s" % (arg, better[arg]))
 
 
+@verifier
 def verify_clone(clazz):
     """Verify that clone() isn't implemented; see EJ page 61."""
     for m in clazz.methods:
@@ -1851,8 +1922,12 @@
             error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")
 
 
+@verifier
 def verify_pfd(clazz):
     """Verify that android APIs use PFD over FD."""
+    if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
+        return
+
     examine = clazz.ctors + clazz.methods
     for m in examine:
         if m.typ == "java.io.FileDescriptor":
@@ -1869,6 +1944,7 @@
             error(clazz, f, "FW11", "Must use ParcelFileDescriptor")
 
 
+@verifier
 def verify_numbers(clazz):
     """Discourage small numbers types like short and byte."""
 
@@ -1890,8 +1966,10 @@
             if arg in discouraged:
                 warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
 
+
 PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}
 
+@verifier
 def verify_nullability(clazz):
     """Catches missing nullability annotations"""
 
@@ -1920,6 +1998,8 @@
 def has_nullability(annotations):
     return "@NonNull" in annotations or "@Nullable" in annotations
 
+
+@verifier
 def verify_singleton(clazz):
     """Catch singleton objects with constructors."""
 
@@ -1954,60 +2034,10 @@
 
     if not is_interesting(clazz): return
 
-    verify_constants(clazz)
-    verify_enums(clazz)
-    verify_class_names(clazz)
-    verify_method_names(clazz)
-    verify_callbacks(clazz)
-    verify_listeners(clazz)
-    verify_actions(clazz)
-    verify_extras(clazz)
-    verify_equals(clazz)
-    verify_parcelable(clazz)
-    verify_protected(clazz)
-    verify_fields(clazz)
-    verify_register(clazz)
-    verify_sync(clazz)
-    verify_intent_builder(clazz)
-    verify_helper_classes(clazz)
-    verify_builder(clazz)
-    verify_aidl(clazz)
-    verify_internal(clazz)
-    verify_layering(clazz)
-    verify_boolean(clazz)
-    verify_collections(clazz)
-    verify_flags(clazz)
-    verify_exception(clazz)
+    for v in verifiers.itervalues():
+        v(clazz)
+
     if not ALLOW_GOOGLE: verify_google(clazz)
-    verify_bitset(clazz)
-    verify_manager(clazz)
-    verify_boxed(clazz)
-    verify_static_utils(clazz)
-    # verify_overload_args(clazz)
-    verify_callback_handlers(clazz)
-    verify_context_first(clazz)
-    verify_listener_last(clazz)
-    verify_resource_names(clazz)
-    verify_files(clazz)
-    verify_manager_list(clazz)
-    verify_abstract_inner(clazz)
-    verify_runtime_exceptions(clazz)
-    verify_error(clazz)
-    verify_units(clazz)
-    verify_closable(clazz)
-    verify_member_name_not_kotlin_keyword(clazz)
-    verify_method_name_not_kotlin_operator(clazz)
-    verify_collections_over_arrays(clazz)
-    verify_user_handle(clazz)
-    verify_params(clazz)
-    verify_services(clazz)
-    verify_tense(clazz)
-    verify_icu(clazz)
-    verify_clone(clazz)
-    verify_pfd(clazz)
-    verify_numbers(clazz)
-    verify_singleton(clazz)
-    verify_nullability(clazz)
 
 
 def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
index f34492d..5cb43db 100644
--- a/tools/apilint/apilint_test.py
+++ b/tools/apilint/apilint_test.py
@@ -242,6 +242,10 @@
         cls = self._cls("class Class {")
         return apilint.Field(cls, 1, raw, '', sig_format=2)
 
+    def test_parse_package(self):
+        pkg = apilint.Package(999, "package wifi.p2p {", None)
+        self.assertEquals("wifi.p2p", pkg.name)
+
     def test_class(self):
         cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {")
         self.assertTrue('deprecated' in cls.split)