diff options
68 files changed, 1744 insertions, 1148 deletions
diff --git a/Android.bp b/Android.bp index 79734df6a9b9..b27455202ab8 100644 --- a/Android.bp +++ b/Android.bp @@ -1189,10 +1189,7 @@ stubs_defaults { "test-base/src/**/*.java", ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":openjdk_javadoc_files", - ":non_openjdk_javadoc_files", - ":android_icu4j_src_files_for_docs", - ":conscrypt_public_api_files", + ":core_public_api_files", "test-mock/src/**/*.java", "test-runner/src/**/*.java", ], @@ -1250,10 +1247,7 @@ stubs_defaults { srcs: [ ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":openjdk_javadoc_files", - ":non_openjdk_javadoc_files", - ":android_icu4j_src_files_for_docs", - ":conscrypt_public_api_files", + ":core_public_api_files", ], srcs_lib: "framework", srcs_lib_whitelist_dirs: frameworks_base_subdirs, diff --git a/api/current.txt b/api/current.txt index 28fcac412c20..513d3a4143ef 100755 --- a/api/current.txt +++ b/api/current.txt @@ -27469,6 +27469,7 @@ package android.net { field public static final int NET_CAPABILITY_IA = 7; // 0x7 field public static final int NET_CAPABILITY_IMS = 4; // 0x4 field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc + field public static final int NET_CAPABILITY_MCX = 23; // 0x17 field public static final int NET_CAPABILITY_MMS = 0; // 0x0 field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14 field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb @@ -27890,7 +27891,7 @@ package android.net.http { method public java.util.Date getValidNotAfterDate(); method @Deprecated public String getValidNotBefore(); method public java.util.Date getValidNotBeforeDate(); - method public java.security.cert.X509Certificate getX509Certificate(); + method @Nullable public java.security.cert.X509Certificate getX509Certificate(); method public static android.net.http.SslCertificate restoreState(android.os.Bundle); method public static android.os.Bundle saveState(android.net.http.SslCertificate); } @@ -39439,7 +39440,7 @@ package android.service.carrier { 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(); @@ -41262,14 +41263,14 @@ package android.telecom { 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 { @@ -41735,6 +41736,7 @@ package android.telecom { } 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(); @@ -41890,8 +41892,8 @@ package android.telecom { 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); @@ -42726,7 +42728,7 @@ package android.telephony { 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(); @@ -43042,8 +43044,8 @@ package android.telephony { 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(); @@ -43070,8 +43072,8 @@ package android.telephony { 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(); @@ -43363,6 +43365,7 @@ package android.telephony.data { field public static final int TYPE_HIPRI = 16; // 0x10 field public static final int TYPE_IA = 256; // 0x100 field public static final int TYPE_IMS = 64; // 0x40 + field public static final int TYPE_MCX = 1024; // 0x400 field public static final int TYPE_MMS = 2; // 0x2 field public static final int TYPE_SUPL = 4; // 0x4 } @@ -43452,7 +43455,7 @@ package android.telephony.euicc { } 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 41d8eea73013..96cd11179d40 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4655,6 +4655,7 @@ package android.provider { field public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist"; field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold"; field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type"; + field public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; // 0x1 field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval"; field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold"; field public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus"; @@ -4863,8 +4864,8 @@ package android.service.carrier { 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 +5413,6 @@ package android.telecom { 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 +5488,8 @@ package android.telecom { 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 +5509,12 @@ package android.telephony { 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; } @@ -5554,13 +5551,13 @@ package android.telephony { } public final class CarrierRestrictionRules implements android.os.Parcelable { + method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); method public int describeContents(); method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(); method public int getDefaultCarrierRestriction(); method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers(); method public int getMultiSimPolicy(); method public boolean isAllCarriersAllowed(); - method public java.util.List<java.lang.Boolean> isCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); method public void writeToParcel(android.os.Parcel, int); field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1 field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0 @@ -5569,13 +5566,13 @@ package android.telephony { field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1 } - public static class CarrierRestrictionRules.Builder { - method public android.telephony.CarrierRestrictionRules build(); - method public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed(); - method public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(java.util.List<android.service.carrier.CarrierIdentifier>); - method public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int); - method public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(java.util.List<android.service.carrier.CarrierIdentifier>); - method public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int); + public static final class CarrierRestrictionRules.Builder { + method @NonNull public android.telephony.CarrierRestrictionRules build(); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed(); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int); } public final class DataFailCause { @@ -6030,12 +6027,11 @@ package android.telephony { } 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 +6057,25 @@ package android.telephony { 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 +6083,12 @@ package android.telephony { 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 +6376,7 @@ package android.telephony { 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 +6519,6 @@ package android.telephony.data { 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 +6560,8 @@ package android.telephony.data { 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 +6573,7 @@ package android.telephony.data { 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 +6581,12 @@ package android.telephony.data { } 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 +6846,7 @@ package android.telephony.ims { } 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 +6871,7 @@ package android.telephony.ims { 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 +7175,12 @@ package android.telephony.ims { 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 +7240,11 @@ package android.telephony.ims { 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 +7253,7 @@ package android.telephony.ims { 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 +7274,7 @@ package android.telephony.ims { 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 91dea4e51621..dcd23b7c77ae 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1227,6 +1227,7 @@ package android.provider { field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https"; field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold"; field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type"; + field public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; // 0x1 field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval"; field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold"; field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions"; @@ -1439,8 +1440,8 @@ package android.telecom { ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>); } - public final class PhoneAccountSuggestion implements android.os.Parcelable { - ctor public PhoneAccountSuggestion(@NonNull android.telecom.PhoneAccountHandle, int, boolean); + public abstract class Conference extends android.telecom.Conferenceable { + method public android.telecom.Connection getPrimaryConnection(); } public class PhoneAccountSuggestionService extends android.app.Service { @@ -1451,6 +1452,16 @@ package android.telecom { field public static final String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService"; } + 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(@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 + field public static final int TTY_MODE_VCO = 3; // 0x3 + } + } package android.telephony { diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 2fe6caf8844c..47eccdbc8c1f 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -2410,6 +2410,9 @@ message LmkKillOccurred { // 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 e9bd735fd919..709f1159caec 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -3444,7 +3444,6 @@ Lcom/android/internal/telephony/ServiceStateTracker;->isInHomeSidNid(II)Z 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;->mDataRoamingOffRegistrants 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;->mUiccApplcation:Lcom/andro 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 af451c253f6c..9bc719eae223 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -300,7 +300,6 @@ public final class ActivityThread extends ClientTransactionHandler { 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 final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { if (stopProfiling) { mProfiler.stopProfiling(); } - ensureJitEnabled(); return false; } } @@ -2258,13 +2251,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } - void ensureJitEnabled() { - if (!mJitEnabled) { - mJitEnabled = true; - dalvik.system.VMRuntime.getRuntime().startJitCompilation(); - } - } - @UnsupportedAppUsage void scheduleGcIdler() { if (!mGcIdlerScheduled) { @@ -3690,7 +3676,6 @@ public final class ActivityThread extends ClientTransactionHandler { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } - ensureJitEnabled(); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } @@ -3804,7 +3789,6 @@ public final class ActivityThread extends ClientTransactionHandler { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - ensureJitEnabled(); } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( @@ -5979,9 +5963,6 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { 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/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 1d2d81dc4fbe..0a63e75d1a31 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -143,6 +143,7 @@ public final class NetworkCapabilities implements Parcelable { NET_CAPABILITY_NOT_CONGESTED, NET_CAPABILITY_NOT_SUSPENDED, NET_CAPABILITY_OEM_PAID, + NET_CAPABILITY_MCX }) public @interface NetCapability { } @@ -297,8 +298,14 @@ public final class NetworkCapabilities implements Parcelable { @SystemApi public static final int NET_CAPABILITY_OEM_PAID = 22; + /** + * Indicates this is a network that has the ability to reach a carrier's Mission Critical + * servers. + */ + public static final int NET_CAPABILITY_MCX = 23; + private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; - private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_OEM_PAID; + private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_MCX; /** * Network capabilities that are expected to be mutable, i.e., can change while a particular @@ -346,7 +353,8 @@ public final class NetworkCapabilities implements Parcelable { (1 << NET_CAPABILITY_IA) | (1 << NET_CAPABILITY_IMS) | (1 << NET_CAPABILITY_RCS) | - (1 << NET_CAPABILITY_XCAP); + (1 << NET_CAPABILITY_XCAP) | + (1 << NET_CAPABILITY_MCX); /** * Capabilities that force network to be restricted. @@ -1614,6 +1622,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED"; case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED"; case NET_CAPABILITY_OEM_PAID: return "OEM_PAID"; + case NET_CAPABILITY_MCX: return "MCX"; default: return Integer.toString(capability); } } diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java index 6fcd6ebe148a..01dd08f4ad9c 100644 --- a/core/java/android/net/http/SslCertificate.java +++ b/core/java/android/net/http/SslCertificate.java @@ -16,6 +16,7 @@ package android.net.http; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Bundle; @@ -252,7 +253,7 @@ public class SslCertificate { * @return The {@code X509Certificate} used to create this {@code SslCertificate} or * {@code null} if no certificate was provided. */ - public X509Certificate getX509Certificate() { + public @Nullable X509Certificate getX509Certificate() { return mX509Certificate; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e945c5fb12fb..946d38667fea 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10475,8 +10475,9 @@ public final class Settings { /** * The threshold value for the number of consecutive dns timeout events received to be a - * signal of data stall. Set the value to 0 or less than 0 to disable. Note that the value - * should be larger than 0 if the DNS data stall detection is enabled. + * signal of data stall. The number of consecutive timeouts needs to be {@code >=} this + * threshold to be considered a data stall. Set the value to {@code <= 0} to disable. Note + * that the value should be {@code > 0} if the DNS data stall detection is enabled. * * @hide */ @@ -10507,9 +10508,12 @@ public final class Settings { "data_stall_valid_dns_time_threshold"; /** - * Which data stall detection signal to use. Possible values are a union of the powers of 2 - * of DATA_STALL_EVALUATION_TYPE_*. + * Which data stall detection signal to use. This is a bitmask constructed by bitwise-or-ing + * (i.e. {@code |}) the DATA_STALL_EVALUATION_TYPE_* values. * + * Type: int + * Valid values: + * {@link #DATA_STALL_EVALUATION_TYPE_DNS} : Use dns as a signal. * @hide */ @SystemApi @@ -10517,6 +10521,15 @@ public final class Settings { public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type"; /** + * Use dns timeout counts to detect data stall. + * + * @hide + */ + @SystemApi + @TestApi + public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; + + /** * Whether to try cellular data recovery when a bad network is reported. * * @hide diff --git a/core/java/android/service/carrier/ApnService.java b/core/java/android/service/carrier/ApnService.java index d53eb37ca786..57e4b1b40748 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 @@ public abstract class ApnService extends Service { }; @Override - public IBinder onBind(Intent intent) { + @NonNull + public IBinder onBind(@Nullable Intent intent) { return mBinder; } @@ -73,5 +76,6 @@ public abstract class ApnService extends Service { * 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 568ca0f6b56e..8c73a87e2132 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 @@ public class CarrierIdentifier implements Parcelable { * @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/LocalLog.java b/core/java/android/util/LocalLog.java index adfa4fc55567..8b5659b3fa31 100644 --- a/core/java/android/util/LocalLog.java +++ b/core/java/android/util/LocalLog.java @@ -17,6 +17,7 @@ package android.util; import android.annotation.UnsupportedAppUsage; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.time.LocalDateTime; @@ -55,6 +56,10 @@ public final class LocalLog { @UnsupportedAppUsage public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + dump(pw); + } + + public synchronized void dump(PrintWriter pw) { Iterator<String> itr = mLog.iterator(); while (itr.hasNext()) { pw.println(itr.next()); @@ -62,6 +67,10 @@ public final class LocalLog { } public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { + reverseDump(pw); + } + + public synchronized void reverseDump(PrintWriter pw) { Iterator<String> itr = mLog.descendingIterator(); while (itr.hasNext()) { pw.println(itr.next()); @@ -75,10 +84,16 @@ public final class LocalLog { } @UnsupportedAppUsage public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - mLog.dump(fd, pw, args); + mLog.dump(pw); + } + public void dump(PrintWriter pw) { + mLog.dump(pw); } public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { - mLog.reverseDump(fd, pw, args); + mLog.reverseDump(pw); + } + public void reverseDump(PrintWriter pw) { + mLog.reverseDump(pw); } } diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java index de9f55b09200..544cc1c76d4e 100644 --- a/core/java/android/util/apk/ApkSignatureVerifier.java +++ b/core/java/android/util/apk/ApkSignatureVerifier.java @@ -397,15 +397,18 @@ public class ApkSignatureVerifier { /** * @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 f70cf07b9535..6302aa725fc4 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -127,113 +127,17 @@ jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env, } 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 36487b3b40b3..04718cd981ff 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 @@ namespace android { 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 e40d97bb1396..35bc46ae33ab 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 5444c690f821..6e380c8a6639 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/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index d34d461e8a87..2a286afd7b63 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -579,9 +579,9 @@ public class GradientDrawable extends Drawable { * The default value for this property is {@code false}. * <p> * <strong>Note</strong>: This property corresponds to the - * {@code android:useLevel} attribute on the inner {@code <gradient>} + * {@code android:useLevel} attribute on the inner {@code <gradient>} * tag, NOT the {@code android:useLevel} attribute on the outer - * {@code <shape>} tag. For example, + * {@code <shape>} tag. For example, * <pre>{@code * <shape ...> * <gradient diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 25c7b5cc5cd6..5966192707f7 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -20,8 +20,8 @@ cc_library_shared { "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 @@ cc_library_shared { "libbinder", "libmedia", "libmediaextractor", + "libmedia_jni_utils", "libmedia_omx", "libmediametrics", "libmediadrm", @@ -91,6 +92,36 @@ cc_library_shared { } 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 3490ff8fcf43..cf73b21c3300 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 8de11caf7d7a..878910ab1c87 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 dad0e53963b0..3edac443ab8c 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 c1226fa89fe4..a4807843d7d8 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 f11452a9d80d..f0aa4c3f1ab6 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 5dd01b03274a..2acb0e5818fa 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 000000000000..b7cbd97409a2 --- /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 000000000000..d174f9a6650c --- /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 458d8471dafd..8bdf53440edc 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 821c6b25c333..24f16101d4d9 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 213c3d9b120c..a6c5fc86249d 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 9c31b4d4374f..f545a61aff4f 100644 --- a/packages/CaptivePortalLogin/Android.bp +++ b/packages/CaptivePortalLogin/Android.bp @@ -18,6 +18,7 @@ android_app { 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 a5f3b88fef0a..44e0a659212a 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 5f1f26d88171..f210840b976f 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -36,6 +36,7 @@ java_library { 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 740c573eb914..003f1e59d743 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/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index e82a5d7b4881..c3447fdb3d78 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -32,6 +32,7 @@ import static android.net.metrics.ValidationProbeEvent.DNS_SUCCESS; import static android.net.metrics.ValidationProbeEvent.PROBE_FALLBACK; import static android.net.metrics.ValidationProbeEvent.PROBE_PRIVDNS; import static android.net.util.NetworkStackUtils.isEmpty; +import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS; import android.annotation.NonNull; import android.annotation.Nullable; @@ -128,9 +129,8 @@ public class NetworkMonitor extends StateMachine { private static final int DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS = 60 * 1000; private static final int DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS = 30 * 60 * 1000; - private static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; private static final int DEFAULT_DATA_STALL_EVALUATION_TYPES = - (1 << DATA_STALL_EVALUATION_TYPE_DNS); + DATA_STALL_EVALUATION_TYPE_DNS; // Reevaluate it as intending to increase the number. Larger log size may cause statsd // log buffer bust and have stats log lost. private static final int DEFAULT_DNS_LOG_SIZE = 20; @@ -1772,7 +1772,7 @@ public class NetworkMonitor extends StateMachine { } private boolean dataStallEvaluateTypeEnabled(int type) { - return (mDataStallEvaluationType & (1 << type)) != 0; + return (mDataStallEvaluationType & type) != 0; } @VisibleForTesting @@ -1792,7 +1792,7 @@ public class NetworkMonitor extends StateMachine { } // Check dns signal. Suspect it may be a data stall if both : - // 1. The number of consecutive DNS query timeouts > mConsecutiveDnsTimeoutThreshold. + // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold. // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms. if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) { if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold, diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java index 04b906b4b9b1..ee2baf20bb8e 100644 --- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java @@ -20,6 +20,7 @@ import static android.net.CaptivePortal.APP_RETURN_DISMISSED; import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID; import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -114,7 +115,6 @@ public class NetworkMonitorTest { private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204"; private static final String TEST_MCCMNC = "123456"; - private static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; private static final int RETURN_CODE_DNS_SUCCESS = 0; private static final int RETURN_CODE_DNS_TIMEOUT = 255; private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5; @@ -186,7 +186,7 @@ public class NetworkMonitorTest { when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES); setMinDataStallEvaluateInterval(500); - setDataStallEvaluationType(1 << DATA_STALL_EVALUATION_TYPE_DNS); + setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS); setValidDataStallDnsTimeThreshold(500); setConsecutiveDnsTimeoutThreshold(5); } diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkStackPermissionStub/Android.bp index dd70cf56b51b..8cee92e5fe6d 100644 --- a/packages/NetworkStackPermissionStub/Android.bp +++ b/packages/NetworkStackPermissionStub/Android.bp @@ -21,6 +21,7 @@ android_app { // 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 62bf3de3fb95..e83f0503d280 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 cc3e6fb3d2cb..ac71ae5c2114 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1573,8 +1573,7 @@ public class ConnectivityService extends IConnectivityManager.Stub 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/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index 8a9ac23cf06a..65de83b2045c 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -16,10 +16,12 @@ package com.android.server.connectivity; import static android.net.SocketKeepalive.DATA_RECEIVED; +import static android.net.SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED; import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET; import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; +import static android.system.OsConstants.ENOPROTOOPT; import static android.system.OsConstants.FIONREAD; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.TIOCOUTQ; @@ -179,12 +181,13 @@ public class TcpKeepaliveController { trw = NetworkUtils.getTcpRepairWindow(fd); } catch (ErrnoException e) { Log.e(TAG, "Exception reading TCP state from socket", e); - try { - Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_OFF); - } catch (ErrnoException ex) { - Log.e(TAG, "Exception while turning off repair mode due to exception", ex); + if (e.errno == ENOPROTOOPT) { + // ENOPROTOOPT may happen in kernel version lower than 4.8. + // Treat it as ERROR_HARDWARE_UNSUPPORTED. + throw new InvalidSocketException(ERROR_HARDWARE_UNSUPPORTED, e); + } else { + throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); } - throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); } finally { dropAllIncomingPackets(fd, false); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6cbb35b152c5..d288910871bc 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1682,19 +1682,6 @@ public final class SystemServer { 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 cde7f608fa6a..fffc1239a315 100644 --- a/telecomm/java/android/telecom/CallIdentification.java +++ b/telecomm/java/android/telecom/CallIdentification.java @@ -44,7 +44,7 @@ public final class CallIdentification implements Parcelable { * 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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * @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 @@ public final class CallIdentification implements Parcelable { * * @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/Conference.java b/telecomm/java/android/telecom/Conference.java index 7d1f8ce75919..6382acf0511d 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; @@ -571,6 +572,7 @@ public abstract class Conference extends Conferenceable { * @return The primary connection. * @hide */ + @TestApi @SystemApi public Connection getPrimaryConnection() { if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) { diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java index f23f4c9b9e9e..563c2dc9ee5e 100644 --- a/telecomm/java/android/telecom/PhoneAccountSuggestion.java +++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java @@ -18,8 +18,6 @@ package android.telecom; 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 @@ public final class PhoneAccountSuggestion implements Parcelable { 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 c60eb56005eb..84b223826c45 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -17,11 +17,13 @@ package android.telecom; 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; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; @@ -560,6 +562,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_OFF = 0; @@ -569,6 +572,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_FULL = 1; @@ -579,6 +583,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_HCO = 2; @@ -589,6 +594,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_VCO = 3; @@ -804,10 +810,11 @@ public class TelecomManager { * <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( @@ -823,12 +830,14 @@ public class TelecomManager { * 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); @@ -1195,7 +1204,8 @@ public class TelecomManager { /** * 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 @@ -1212,7 +1222,7 @@ public class TelecomManager { @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); @@ -1226,9 +1236,10 @@ public class TelecomManager { /** * 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(); @@ -1527,6 +1538,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public @TtyMode int getCurrentTtyMode() { try { @@ -1975,6 +1987,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall() { try { diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index 1dadaeec2143..4939157cd93b 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -1127,8 +1127,8 @@ public final class Telephony { * Broadcast Action: A debug code has been entered in the dialer. This intent is * broadcast by the system and OEM telephony apps may need to receive these broadcasts. * These "secret codes" are used to activate developer menus by dialing certain codes. - * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data - * URI: {@code android_secret_code://<code>}. It is possible that a manifest + * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data + * URI: {@code android_secret_code://<code>}. It is possible that a manifest * receiver would be woken up even if it is not currently running. * * <p>Requires {@code android.Manifest.permission#CONTROL_INCALL_EXPERIENCE} to @@ -3765,6 +3765,42 @@ public final class Telephony { */ 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 @@ public final class Telephony { }) @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 0d4f09f98b43..2ff2d91348de 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 @@ import java.util.Objects; * @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 @@ public class CallAttributes implements Parcelable { /** * Returns the {@link PreciseCallState} of the call. */ + @NonNull public PreciseCallState getPreciseCallState() { return mPreciseCallState; } @@ -96,6 +98,7 @@ public class CallAttributes implements Parcelable { /** * Returns the {#link CallQuality} of the call. */ + @NonNull public CallQuality getCallQuality() { return mCallQuality; } diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java index d47b55ca4372..b627788c2a8c 100644 --- a/telephony/java/android/telephony/CarrierRestrictionRules.java +++ b/telephony/java/android/telephony/CarrierRestrictionRules.java @@ -177,7 +177,8 @@ public final class CarrierRestrictionRules implements Parcelable { * @return a list of boolean with the same size as input, indicating if each * {@link CarrierIdentifier} is allowed or not. */ - public List<Boolean> isCarrierIdentifiersAllowed(@NonNull List<CarrierIdentifier> carrierIds) { + public @NonNull List<Boolean> areCarrierIdentifiersAllowed( + @NonNull List<CarrierIdentifier> carrierIds) { ArrayList<Boolean> result = new ArrayList<>(carrierIds.size()); // First calculate the result for each slot independently @@ -332,7 +333,7 @@ public final class CarrierRestrictionRules implements Parcelable { /** * Builder for a {@link CarrierRestrictionRules}. */ - public static class Builder { + public static final class Builder { private final CarrierRestrictionRules mRules; /** {@hide} */ @@ -341,14 +342,14 @@ public final class CarrierRestrictionRules implements Parcelable { } /** build command */ - public CarrierRestrictionRules build() { + public @NonNull CarrierRestrictionRules build() { return mRules; } /** * Indicate that all carriers are allowed. */ - public Builder setAllCarriersAllowed() { + public @NonNull Builder setAllCarriersAllowed() { mRules.mAllowedCarriers.clear(); mRules.mExcludedCarriers.clear(); mRules.mCarrierRestrictionDefault = CARRIER_RESTRICTION_DEFAULT_ALLOWED; @@ -360,7 +361,8 @@ public final class CarrierRestrictionRules implements Parcelable { * * @param allowedCarriers list of allowed carriers */ - public Builder setAllowedCarriers(List<CarrierIdentifier> allowedCarriers) { + public @NonNull Builder setAllowedCarriers( + @NonNull List<CarrierIdentifier> allowedCarriers) { mRules.mAllowedCarriers = new ArrayList<CarrierIdentifier>(allowedCarriers); return this; } @@ -370,7 +372,8 @@ public final class CarrierRestrictionRules implements Parcelable { * * @param excludedCarriers list of excluded carriers */ - public Builder setExcludedCarriers(List<CarrierIdentifier> excludedCarriers) { + public @NonNull Builder setExcludedCarriers( + @NonNull List<CarrierIdentifier> excludedCarriers) { mRules.mExcludedCarriers = new ArrayList<CarrierIdentifier>(excludedCarriers); return this; } @@ -380,7 +383,7 @@ public final class CarrierRestrictionRules implements Parcelable { * * @param carrierRestrictionDefault prioritized carrier list */ - public Builder setDefaultCarrierRestriction( + public @NonNull Builder setDefaultCarrierRestriction( @CarrierRestrictionDefault int carrierRestrictionDefault) { mRules.mCarrierRestrictionDefault = carrierRestrictionDefault; return this; @@ -391,7 +394,7 @@ public final class CarrierRestrictionRules implements Parcelable { * * @param multiSimPolicy multi SIM policy */ - public Builder setMultiSimPolicy(@MultiSimPolicy int multiSimPolicy) { + public @NonNull Builder setMultiSimPolicy(@MultiSimPolicy int multiSimPolicy) { mRules.mMultiSimPolicy = multiSimPolicy; return this; } diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index 84d6628d47d2..4d97f8104c26 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 @@ public class NetworkRegistrationState implements Parcelable { @ServiceState.RoamingType private int mRoamingType; + @NetworkType private int mAccessNetworkTechnology; @NRStatus @@ -149,6 +152,7 @@ public class NetworkRegistrationState implements Parcelable { private final boolean mEmergencyOnly; + @ServiceType private final int[] mAvailableServices; @Nullable @@ -167,9 +171,8 @@ public class NetworkRegistrationState implements Parcelable { * @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 @@ public class NetworkRegistrationState implements Parcelable { * 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 @@ public class NetworkRegistrationState implements Parcelable { updateNrStatus(mDataSpecificStates); } - protected NetworkRegistrationState(Parcel source) { + private NetworkRegistrationState(Parcel source) { mDomain = source.readInt(); mTransportType = source.readInt(); mRegState = source.readInt(); @@ -285,6 +289,14 @@ public class NetworkRegistrationState implements Parcelable { } /** + * @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 @@ public class NetworkRegistrationState implements Parcelable { /** * @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 @@ public class NetworkRegistrationState implements Parcelable { /** * @return The cell information. */ + @Nullable public CellIdentity getCellIdentity() { return mCellIdentity; } @@ -539,4 +556,192 @@ public class NetworkRegistrationState implements Parcelable { 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 bec949406b6c..f1240e9fcf34 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 @@ public abstract class NetworkService extends Service { * 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 @@ public abstract class NetworkService extends Service { 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 @@ public abstract class NetworkService extends Service { @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 @@ public abstract class NetworkService extends Service { * 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 @@ public abstract class NetworkService extends Service { return mBinder; } - /** @hide */ @Override public boolean onUnbind(Intent intent) { mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS, 0, @@ -252,6 +258,7 @@ public abstract class NetworkService extends Service { @Override public void onDestroy() { mHandlerThread.quit(); + super.onDestroy(); } /** @@ -261,35 +268,35 @@ public abstract class NetworkService extends Service { 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 dbad02fd5640..c2fcfb7a0759 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 @@ public class NetworkServiceCallback { * {@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 c1786befb096..eb889c6171a0 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -22,6 +22,7 @@ import android.hardware.radio.V1_4.CellInfo.Info; 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 @@ public class RadioAccessFamily implements Parcelable { }; @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 @@ public class RadioAccessFamily implements Parcelable { } @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 f2daace24050..611812996b28 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -438,7 +438,11 @@ public class ServiceState implements Parcelable { /** * 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 6aa4266e9bc8..769d1a4e8bc7 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1539,6 +1539,7 @@ public class TelephonyManager { * 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 @@ public class TelephonyManager { * * @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 @@ public class TelephonyManager { * 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 @@ public class TelephonyManager { * * @param slotIndex of which Type Allocation Code is returned */ + @Nullable public String getManufacturerCode(int slotIndex) { ITelephony telephony = getITelephony(); if (telephony == null) return null; @@ -2762,8 +2766,8 @@ public class TelephonyManager { * (see {@link #hasCarrierPrivileges}). * <p> * These "secret codes" are used to activate developer menus by dialing certain codes. - * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data - * URI: {@code android_secret_code://<code>}. It is possible that a manifest + * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data + * URI: {@code android_secret_code://<code>}. It is possible that a manifest * receiver would be woken up even if it is not currently running. * <p> * It is supposed to replace {@link android.provider.Telephony.Sms.Intents#SECRET_CODE_ACTION} @@ -5981,6 +5985,7 @@ public class TelephonyManager { * @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 @@ public class TelephonyManager { * 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 @@ public class TelephonyManager { @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 0e695309fce2..c802e633b76c 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -19,7 +19,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.content.ContentValues; import android.database.Cursor; -import android.hardware.radio.V1_0.ApnTypes; +import android.hardware.radio.V1_4.ApnTypes; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -61,6 +61,7 @@ public class ApnSetting implements Parcelable { 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. @@ -79,7 +80,7 @@ public class ApnSetting implements Parcelable { * APN type for all APNs. * @hide */ - public static final int TYPE_ALL = ApnTypes.ALL; + public static final int TYPE_ALL = ApnTypes.ALL | ApnTypes.MCX; /** APN type for default data traffic. */ public static final int TYPE_DEFAULT = ApnTypes.DEFAULT | ApnTypes.HIPRI; /** APN type for MMS traffic. */ @@ -103,6 +104,8 @@ public class ApnSetting implements Parcelable { * for access to carrier services in an emergency call situation. */ public static final int TYPE_EMERGENCY = ApnTypes.EMERGENCY; + /** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */ + public static final int TYPE_MCX = ApnTypes.MCX; /** @hide */ @IntDef(flag = true, prefix = { "TYPE_" }, value = { @@ -115,7 +118,8 @@ public class ApnSetting implements Parcelable { TYPE_IMS, TYPE_CBS, TYPE_IA, - TYPE_EMERGENCY + TYPE_EMERGENCY, + TYPE_MCX }) @Retention(RetentionPolicy.SOURCE) public @interface ApnType {} @@ -206,6 +210,7 @@ public class ApnSetting implements Parcelable { APN_TYPE_STRING_MAP.put("cbs", TYPE_CBS); APN_TYPE_STRING_MAP.put("ia", TYPE_IA); APN_TYPE_STRING_MAP.put("emergency", TYPE_EMERGENCY); + APN_TYPE_STRING_MAP.put("mcx", TYPE_MCX); APN_TYPE_INT_MAP = new ArrayMap<Integer, String>(); APN_TYPE_INT_MAP.put(TYPE_DEFAULT, "default"); APN_TYPE_INT_MAP.put(TYPE_MMS, "mms"); @@ -217,6 +222,7 @@ public class ApnSetting implements Parcelable { APN_TYPE_INT_MAP.put(TYPE_CBS, "cbs"); APN_TYPE_INT_MAP.put(TYPE_IA, "ia"); APN_TYPE_INT_MAP.put(TYPE_EMERGENCY, "emergency"); + APN_TYPE_INT_MAP.put(TYPE_MCX, "mcx"); PROTOCOL_STRING_MAP = new ArrayMap<String, Integer>(); PROTOCOL_STRING_MAP.put("IP", PROTOCOL_IP); @@ -281,6 +287,8 @@ public class ApnSetting implements Parcelable { 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. * @@ -618,6 +626,17 @@ public class ApnSetting implements Parcelable { 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; @@ -646,6 +665,7 @@ public class ApnSetting implements Parcelable { this.mMvnoMatchData = builder.mMvnoMatchData; this.mApnSetId = builder.mApnSetId; this.mCarrierId = builder.mCarrierId; + this.mSkip464Xlat = builder.mSkip464Xlat; } /** @@ -657,7 +677,7 @@ public class ApnSetting implements Parcelable { 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) @@ -686,6 +706,7 @@ public class ApnSetting implements Parcelable { .setMvnoMatchData(mvnoMatchData) .setApnSetId(apnSetId) .setCarrierId(carrierId) + .setSkip464Xlat(skip464xlat) .buildWithoutCheck(); } @@ -703,7 +724,8 @@ public class ApnSetting implements Parcelable { 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); } /** @@ -762,7 +784,8 @@ public class ApnSetting implements Parcelable { 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))); } /** @@ -775,7 +798,7 @@ public class ApnSetting implements Parcelable { 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); } /** @@ -824,6 +847,13 @@ public class ApnSetting implements Parcelable { * <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. * @@ -836,7 +866,10 @@ public class ApnSetting implements Parcelable { 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 + ".*")) { @@ -882,6 +915,7 @@ public class ApnSetting implements Parcelable { 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); @@ -928,6 +962,12 @@ public class ApnSetting implements Parcelable { 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 @@ -943,7 +983,7 @@ public class ApnSetting implements Parcelable { getProtocolIntFromString(protocol), getProtocolIntFromString(roamingProtocol), carrierEnabled, networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime, maxConnsTime, mtu, getMvnoTypeIntFromString(mvnoType), mvnoMatchData, apnSetId, - carrierId); + carrierId, skip464xlat); } /** @@ -979,7 +1019,7 @@ public class ApnSetting implements Parcelable { */ public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("[ApnSettingV6] ") + sb.append("[ApnSettingV7] ") .append(mEntryName) .append(", ").append(mId) .append(", ").append(mOperatorNumeric) @@ -1007,6 +1047,7 @@ public class ApnSetting implements Parcelable { sb.append(", ").append(mNetworkTypeBitmask); sb.append(", ").append(mApnSetId); sb.append(", ").append(mCarrierId); + sb.append(", ").append(mSkip464Xlat); return sb.toString(); } @@ -1100,7 +1141,8 @@ public class ApnSetting implements Parcelable { && 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); } /** @@ -1146,7 +1188,8 @@ public class ApnSetting implements Parcelable { && 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); } /** @@ -1174,7 +1217,8 @@ public class ApnSetting implements Parcelable { && 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. @@ -1221,6 +1265,7 @@ public class ApnSetting implements Parcelable { 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; } @@ -1380,6 +1425,7 @@ public class ApnSetting implements Parcelable { dest.writeInt(mNetworkTypeBitmask); dest.writeInt(mApnSetId); dest.writeInt(mCarrierId); + dest.writeInt(mSkip464Xlat); } private static ApnSetting readFromParcel(Parcel in) { @@ -1403,11 +1449,12 @@ public class ApnSetting implements Parcelable { 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 = @@ -1484,6 +1531,7 @@ public class ApnSetting implements Parcelable { private String mMvnoMatchData; private int mApnSetId; private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + private int mSkip464Xlat = Carriers.SKIP_464XLAT_DEFAULT; /** * Default constructor for Builder. @@ -1826,6 +1874,17 @@ public class ApnSetting implements Parcelable { } /** + * 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)} @@ -1833,7 +1892,7 @@ public class ApnSetting implements Parcelable { * {@link ApnSetting} built from this builder otherwise. */ public ApnSetting build() { - if ((mApnTypeBitmask & ApnTypes.ALL) == 0 || TextUtils.isEmpty(mApnName) + if ((mApnTypeBitmask & TYPE_ALL) == 0 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) { return null; } diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 3d2fe5fec14a..6d74deda1ac4 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -25,6 +25,8 @@ import android.os.Parcel; 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 @@ public final class DataCallResponse implements Parcelable { 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 a3fa77bd9b47..59d1e1e7115a 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -116,23 +116,23 @@ public abstract class DataService extends Service { */ 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 abstract class DataService extends Service { 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 @@ public abstract class DataService extends Service { @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 @@ public abstract class DataService extends Service { * 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 @@ public abstract class DataService extends Service { 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 @@ public abstract class DataService extends Service { */ 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 bef11425b470..2d0cfe80366c 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 @@ public class DataServiceCallback { * @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 @@ public class DataServiceCallback { * 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 @@ public class DataServiceCallback { } /** - * 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 d049547cad2f..b8a07e4ed777 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -17,6 +17,7 @@ package android.telephony.euicc; 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 @@ public class EuiccManager { * * @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 337375ac51c3..a09844d6c0e2 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 @@ public class ImsCallSessionListener { * * @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 @@ public class ImsCallSessionListener { * * @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 3a82517955ce..86832bb13f7e 100644 --- a/telephony/java/android/telephony/ims/ImsSsData.java +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -17,6 +17,7 @@ package android.telephony.ims; 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 android.telephony.Rlog; 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 class ImsSsData implements Parcelable { 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 @@ public final class ImsSsData implements Parcelable { * 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 @@ public final class ImsSsData implements Parcelable { * service data. */ public @NonNull Builder setCallForwardingInfo( - @NonNull ImsCallForwardInfo[] imsCallForwardInfos) { + @NonNull List<ImsCallForwardInfo> imsCallForwardInfos) { mImsSsData.mCfInfo = imsCallForwardInfos; return this; } @@ -360,8 +364,8 @@ public final class ImsSsData implements Parcelable { 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 @@ public final class ImsSsData implements Parcelable { 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 @@ public final class ImsSsData implements Parcelable { /** @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 @@ public final class ImsSsData implements Parcelable { 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 @@ public final class ImsSsData implements Parcelable { 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 @@ public final class ImsSsData implements Parcelable { * @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 031f9e10175b..fba390c26242 100644 --- a/telephony/java/android/telephony/ims/ImsSsInfo.java +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -173,7 +173,7 @@ public final class ImsSsInfo implements Parcelable { /** * 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 @@ public final class ImsSsInfo implements Parcelable { /** * @return The Incoming Communication Barring (ICB) number. */ - public String getIncomingCommunicationBarringNumber() { + public @Nullable String getIncomingCommunicationBarringNumber() { return mIcbNum; } diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index e87d28c6f9e9..d5061a32ba6d 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -141,6 +141,8 @@ public class PhoneConstants { /** APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. */ public static final String APN_TYPE_EMERGENCY = "emergency"; + /** APN type for Mission Critical Services */ + public static final String APN_TYPE_MCX = "mcx"; /** Array of all APN types */ public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, APN_TYPE_MMS, @@ -151,7 +153,8 @@ public class PhoneConstants { APN_TYPE_IMS, APN_TYPE_CBS, APN_TYPE_IA, - APN_TYPE_EMERGENCY + APN_TYPE_EMERGENCY, + APN_TYPE_MCX }; public static final int RIL_CARD_MAX_APPS = 8; diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 77b797956cf5..5205973669ac 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -470,6 +470,7 @@ public interface RILConstants { int RIL_REQUEST_START_KEEPALIVE = 144; int RIL_REQUEST_STOP_KEEPALIVE = 145; int RIL_REQUEST_ENABLE_MODEM = 146; + int RIL_REQUEST_GET_MODEM_STATUS = 147; /* The following requests are not defined in RIL.h */ int RIL_REQUEST_HAL_NON_RIL_BASE = 200; diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index b460c904cf99..c25ad5f7bbd5 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -909,11 +909,19 @@ public class ConnectivityServiceTest { 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 @@ public class ConnectivityServiceTest { } @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 295e3de544ee..a91fbe76be8d 100644 --- a/tools/apilint/apilint.py +++ b/tools/apilint/apilint.py @@ -196,8 +196,10 @@ class Class(): 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 Class(): 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 @@ class V2LineParser(object): 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 @@ def notice(clazz): 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 @@ def verify_constants(clazz): 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 @@ def verify_class_names(clazz): 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 @@ def verify_method_names(clazz): 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 @@ def verify_callbacks(clazz): 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 @@ def verify_listeners(clazz): 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 @@ def verify_actions(clazz): 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 @@ def verify_extras(clazz): 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 @@ def verify_equals(clazz): 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 @@ def verify_parcelable(clazz): 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 @@ def verify_protected(clazz): 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 @@ def verify_fields(clazz): 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 @@ def verify_register(clazz): 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 @@ def verify_sync(clazz): 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 @@ def verify_intent_builder(clazz): 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 @@ def verify_helper_classes(clazz): 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 @@ def verify_builder(clazz): 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 @@ LAYERING_PACKAGE_RANKING = layering_build_ranking([ "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 @@ def verify_layering(clazz): 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 @@ def verify_boolean(clazz): 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 @@ def verify_collections(clazz): 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 @@ def verify_flags(clazz): 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 @@ def verify_exception(clazz): 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 @@ def verify_google(clazz): error(clazz, t, None, "Must never reference Google") +@verifier def verify_bitset(clazz): """Verifies that we avoid using heavy BitSet.""" @@ -1322,6 +1369,7 @@ def verify_bitset(clazz): 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 @@ def verify_manager(clazz): 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 @@ def verify_boxed(clazz): 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 @@ def verify_static_utils(clazz): 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 @@ def verify_overload_args(clazz): 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 @@ def verify_callback_handlers(clazz): 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 @@ def verify_context_first(clazz): 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 @@ def verify_listener_last(clazz): 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 @@ def verify_resource_names(clazz): 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 @@ def verify_files(clazz): 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 @@ def verify_manager_list(clazz): 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 @@ def verify_abstract_inner(clazz): 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 @@ def verify_runtime_exceptions(clazz): 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 @@ def verify_error(clazz): 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 @@ def verify_units(clazz): 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 @@ def verify_closable(clazz): return +@verifier def verify_member_name_not_kotlin_keyword(clazz): """Prevent method names which are keywords in Kotlin.""" @@ -1688,6 +1751,7 @@ def verify_member_name_not_kotlin_keyword(clazz): 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 @@ def verify_method_name_not_kotlin_operator(clazz): 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 @@ def verify_collections_over_arrays(clazz): 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 @@ def verify_user_handle(clazz): "or 'queryFooForUser'") +@verifier def verify_params(clazz): """Parameter classes should be 'Params'.""" if clazz.name.endswith("Params"): return @@ -1791,6 +1858,7 @@ def verify_params(clazz): 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 @@ def verify_services(clazz): 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 @@ def verify_tense(clazz): 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 @@ def verify_icu(clazz): 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 @@ def verify_clone(clazz): 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 @@ def verify_pfd(clazz): error(clazz, f, "FW11", "Must use ParcelFileDescriptor") +@verifier def verify_numbers(clazz): """Discourage small numbers types like short and byte.""" @@ -1890,8 +1966,10 @@ def verify_numbers(clazz): 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 verify_nullability_args(clazz, m): 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 @@ def examine_clazz(clazz): 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 f34492d644ce..5cb43db0b00d 100644 --- a/tools/apilint/apilint_test.py +++ b/tools/apilint/apilint_test.py @@ -242,6 +242,10 @@ class V2ParserTests(unittest.TestCase): 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) |