diff options
167 files changed, 3446 insertions, 1198 deletions
diff --git a/Android.bp b/Android.bp index 8e174792f508..d58b48399a8f 100644 --- a/Android.bp +++ b/Android.bp @@ -186,6 +186,7 @@ java_defaults { "core/java/android/hardware/radio/ITunerCallback.aidl", "core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl", "core/java/android/hardware/usb/IUsbManager.aidl", + "core/java/android/net/ICaptivePortal.aidl", "core/java/android/net/IConnectivityManager.aidl", "core/java/android/net/IIpConnectivityMetrics.aidl", "core/java/android/net/IEthernetManager.aidl", @@ -680,7 +681,6 @@ java_defaults { static_libs: [ "apex_aidl_interface-java", - "networkstack-aidl-interfaces-java", "framework-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.0-java", @@ -704,8 +704,8 @@ java_defaults { "android.hardware.vibrator-V1.1-java", "android.hardware.vibrator-V1.2-java", "android.hardware.wifi-V1.0-java-constants", - "networkstack-aidl-interfaces-java", - "netd_aidl_interface-java", + "networkstack-aidl-framework-java", + "netd_aidl_parcelables-java", ], required: [ @@ -816,10 +816,8 @@ aidl_interface { srcs: [ "core/java/android/net/ApfCapabilitiesParcelable.aidl", "core/java/android/net/DhcpResultsParcelable.aidl", - "core/java/android/net/ICaptivePortal.aidl", "core/java/android/net/INetworkMonitor.aidl", "core/java/android/net/INetworkMonitorCallbacks.aidl", - "core/java/android/net/IIpMemoryStore.aidl", "core/java/android/net/INetworkStackConnector.aidl", "core/java/android/net/INetworkStackStatusCallback.aidl", "core/java/android/net/InitialConfigurationParcelable.aidl", @@ -838,6 +836,16 @@ aidl_interface { "core/java/android/net/dhcp/IDhcpServerCallbacks.aidl", "core/java/android/net/ip/IIpClient.aidl", "core/java/android/net/ip/IIpClientCallbacks.aidl", + ], + api_dir: "aidl/networkstack", +} + +aidl_interface { + name: "networkstack-aidl-framework", + local_include_dir: "core/java", + srcs: [ + "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl", + "core/java/android/net/IIpMemoryStore.aidl", "core/java/android/net/ipmemorystore/**/*.aidl", ], api_dir: "aidl/networkstack", @@ -1110,58 +1118,21 @@ packages_to_document = [ "org/apache/http/params", ] -// The since flag (-since N.xml API_LEVEL) is used to add API Level information -// to the reference documentation. Must be in order of oldest to newest. -// -// Conscrypt (com.android.org.conscrypt) is an implementation detail and should -// not be referenced in the documentation. -framework_docs_args = "-android -manifest $(location core/res/AndroidManifest.xml) " + - "-hidePackage com.android.internal " + - "-hidePackage com.android.internal.util " + - "-hidePackage com.android.okhttp " + - "-hidePackage com.android.org.conscrypt " + - "-hidePackage com.android.server " + - "-since $(location 1/public/api/android.xml) 1 " + - "-since $(location 2/public/api/android.xml) 2 " + - "-since $(location 3/public/api/android.xml) 3 " + - "-since $(location 4/public/api/android.xml) 4 " + - "-since $(location 5/public/api/android.xml) 5 " + - "-since $(location 6/public/api/android.xml) 6 " + - "-since $(location 7/public/api/android.xml) 7 " + - "-since $(location 8/public/api/android.xml) 8 " + - "-since $(location 9/public/api/android.xml) 9 " + - "-since $(location 10/public/api/android.xml) 10 " + - "-since $(location 11/public/api/android.xml) 11 " + - "-since $(location 12/public/api/android.xml) 12 " + - "-since $(location 13/public/api/android.xml) 13 " + - "-since $(location 14/public/api/android.txt) 14 " + - "-since $(location 15/public/api/android.txt) 15 " + - "-since $(location 16/public/api/android.txt) 16 " + - "-since $(location 17/public/api/android.txt) 17 " + - "-since $(location 18/public/api/android.txt) 18 " + - "-since $(location 19/public/api/android.txt) 19 " + - "-since $(location 20/public/api/android.txt) 20 " + - "-since $(location 21/public/api/android.txt) 21 " + - "-since $(location 22/public/api/android.txt) 22 " + - "-since $(location 23/public/api/android.txt) 23 " + - "-since $(location 24/public/api/android.txt) 24 " + - "-since $(location 25/public/api/android.txt) 25 " + - "-since $(location 26/public/api/android.txt) 26 " + - "-since $(location 27/public/api/android.txt) 27 " + - "-since $(location 28/public/api/android.txt) 28 " + - "-since $(location api/current.txt) Q " + - "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " + - "-overview $(location core/java/overview.html) " + - // Federate Support Library references against local API file. - "-federate SupportLib https://developer.android.com " + - "-federationapi SupportLib $(location current/support-api.txt) " +// Make the api/current.txt file available for use by modules in other +// directories. +filegroup { + name: "frameworks-base-api-current.txt", + srcs: [ + "api/current.txt", + ], +} framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " + "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " + "-overview $(location core/java/overview.html) " + // Federate Support Library references against local API file. "-federate SupportLib https://developer.android.com " + - "-federationapi SupportLib $(location current/support-api.txt) " + "-federationapi SupportLib $(location :current-support-api) " framework_docs_only_libs = [ "voip-common", diff --git a/Android.mk b/Android.mk index 9c65948f4838..c58f7af1d7d5 100644 --- a/Android.mk +++ b/Android.mk @@ -72,10 +72,11 @@ $(OUT_DOCS)/offline-sdk-timestamp: $(OUT_DOCS)/offline-sdk-docs-docs.zip $(hide) mkdir -p $(OUT_DOCS)/offline-sdk ( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1 +.PHONY: docs offline-sdk-docs +docs offline-sdk-docs: $(OUT_DOCS)/offline-sdk-timestamp + # Run this for checkbuild checkbuild: doc-comment-check-docs -# Check comment when you are updating the API -update-api: doc-comment-check-docs # ==== hiddenapi lists ======================================= ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true) diff --git a/api/current.txt b/api/current.txt index b81e6730fcf9..172140fd653f 100755 --- a/api/current.txt +++ b/api/current.txt @@ -42336,6 +42336,7 @@ package android.telephony { method public int getChannelNumber(); method public String getMccString(); method public String getMncString(); + method public long getNci(); method public int getPci(); method public int getTac(); method public void writeToParcel(android.os.Parcel, int); @@ -42349,6 +42350,7 @@ package android.telephony { method public String getMccString(); method public String getMncString(); method @Nullable public String getMobileNetworkOperator(); + method public int getUarfcn(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityTdscdma> CREATOR; } @@ -43016,12 +43018,12 @@ package android.telephony { method public boolean canChangeDtmfToneLength(); method @Nullable public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle); method public android.telephony.TelephonyManager createForSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo(); + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo(); method public int getCallState(); method public int getCardIdForDefaultEuicc(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @WorkerThread public android.os.PersistableBundle getCarrierConfig(); method public int getCarrierIdFromSimMccMnc(); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.CellLocation getCellLocation(); + method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.telephony.CellLocation getCellLocation(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(int); method public int getDataActivity(); @@ -43051,7 +43053,7 @@ package android.telephony { method public int getPhoneCount(); method public int getPhoneType(); method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription(); - method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.ServiceState getServiceState(); + method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(); method @Nullable public android.telephony.SignalStrength getSignalStrength(); method public int getSimCarrierId(); method @Nullable public CharSequence getSimCarrierIdName(); @@ -43093,8 +43095,8 @@ package android.telephony { method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle); method public boolean isWorldPhone(); method public void listen(android.telephony.PhoneStateListener, int); - method @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); + method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); method public void sendDialerSpecialCode(String); method public String sendEnvelopeWithStatus(String); method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler); @@ -43162,7 +43164,6 @@ package android.telephony { field public static final String EXTRA_STATE_RINGING; field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID"; field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; - field public static final int INVALID_CARD_ID = -1; // 0xffffffff field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU"; field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7 field public static final int NETWORK_TYPE_CDMA = 4; // 0x4 @@ -43198,7 +43199,9 @@ package android.telephony { field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3 field public static final int SIM_STATE_READY = 5; // 0x5 field public static final int SIM_STATE_UNKNOWN = 0; // 0x0 + field public static final int UNINITIALIZED_CARD_ID = -2; // 0xfffffffe field public static final int UNKNOWN_CARRIER_ID = -1; // 0xffffffff + field public static final int UNSUPPORTED_CARD_ID = -1; // 0xffffffff field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff field public static final String VVM_TYPE_CVVM = "vvm_type_cvvm"; @@ -43552,6 +43555,483 @@ package android.telephony.gsm { } +package android.telephony.ims { + + public class Rcs1To1Thread extends android.telephony.ims.RcsThread { + method @WorkerThread public long getFallbackThreadId() throws android.telephony.ims.RcsMessageStoreException; + method @NonNull @WorkerThread public android.telephony.ims.RcsParticipant getRecipient() throws android.telephony.ims.RcsMessageStoreException; + method public boolean isGroup(); + method @WorkerThread public void setFallbackThreadId(long) throws android.telephony.ims.RcsMessageStoreException; + } + + public abstract class RcsEvent { + ctor protected RcsEvent(long); + method public long getTimestamp(); + } + + public final class RcsEventQueryParams implements android.os.Parcelable { + method public int describeContents(); + method @android.telephony.ims.RcsEventQueryParams.EventType public int getEventType(); + method public int getLimit(); + method public boolean getSortDirection(); + method public int getSortingProperty(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int ALL_EVENTS = -1; // 0xffffffff + field public static final int ALL_GROUP_THREAD_EVENTS = 0; // 0x0 + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsEventQueryParams> CREATOR; + field public static final int GROUP_THREAD_ICON_CHANGED_EVENT = 8; // 0x8 + field public static final int GROUP_THREAD_NAME_CHANGED_EVENT = 16; // 0x10 + field public static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT = 2; // 0x2 + field public static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT = 4; // 0x4 + field public static final int PARTICIPANT_ALIAS_CHANGED_EVENT = 1; // 0x1 + field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0 + field public static final int SORT_BY_TIMESTAMP = 1; // 0x1 + } + + public static class RcsEventQueryParams.Builder { + ctor public RcsEventQueryParams.Builder(); + method public android.telephony.ims.RcsEventQueryParams build(); + method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setEventType(@android.telephony.ims.RcsEventQueryParams.EventType int); + method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setGroupThread(@NonNull android.telephony.ims.RcsGroupThread); + method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException; + method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setSortDirection(boolean); + method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setSortProperty(@android.telephony.ims.RcsEventQueryParams.SortingProperty int); + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsEventQueryParams.ALL_EVENTS, android.telephony.ims.RcsEventQueryParams.ALL_GROUP_THREAD_EVENTS, android.telephony.ims.RcsEventQueryParams.PARTICIPANT_ALIAS_CHANGED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_JOINED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_LEFT_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_NAME_CHANGED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_ICON_CHANGED_EVENT}) public static @interface RcsEventQueryParams.EventType { + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsEventQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsEventQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsEventQueryParams.SortingProperty { + } + + public final class RcsEventQueryResult implements android.os.Parcelable { + method public int describeContents(); + method public android.telephony.ims.RcsQueryContinuationToken getContinuationToken(); + method public java.util.List<android.telephony.ims.RcsEvent> getEvents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsEventQueryResult> CREATOR; + } + + public final class RcsFileTransferCreationParams implements android.os.Parcelable { + method public int describeContents(); + method public String getContentMimeType(); + method public android.net.Uri getContentUri(); + method public long getFileSize(); + method @android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus public int getFileTransferStatus(); + method public int getHeight(); + method public long getMediaDuration(); + method public String getPreviewMimeType(); + method public android.net.Uri getPreviewUri(); + method public String getRcsFileTransferSessionId(); + method public long getTransferOffset(); + method public int getWidth(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsFileTransferCreationParams> CREATOR; + } + + public class RcsFileTransferCreationParams.Builder { + ctor public RcsFileTransferCreationParams.Builder(); + method public android.telephony.ims.RcsFileTransferCreationParams build(); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setContentMimeType(String); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setContentUri(android.net.Uri); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileSize(long); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileTransferSessionId(String); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileTransferStatus(@android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus int); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setHeight(int); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setMediaDuration(long); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setPreviewMimeType(String); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setPreviewUri(android.net.Uri); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setTransferOffset(long); + method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setWidth(int); + } + + public class RcsFileTransferPart { + method @WorkerThread @Nullable public String getContentMimeType() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public android.net.Uri getContentUri() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public long getFileSize() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public String getFileTransferSessionId() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus public int getFileTransferStatus() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public int getHeight() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public long getLength() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public String getPreviewMimeType() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public android.net.Uri getPreviewUri() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public long getTransferOffset() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public int getWidth() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setContentMimeType(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setContentUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setFileSize(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setFileTransferSessionId(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setFileTransferStatus(@android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus int) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setHeight(int) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setLength(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setPreviewMimeType(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setPreviewUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setTransferOffset(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setWidth(int) throws android.telephony.ims.RcsMessageStoreException; + field public static final int DOWNLOADING = 6; // 0x6 + field public static final int DOWNLOADING_CANCELLED = 9; // 0x9 + field public static final int DOWNLOADING_FAILED = 8; // 0x8 + field public static final int DOWNLOADING_PAUSED = 7; // 0x7 + field public static final int DRAFT = 1; // 0x1 + field public static final int NOT_SET = 0; // 0x0 + field public static final int SENDING = 2; // 0x2 + field public static final int SENDING_CANCELLED = 5; // 0x5 + field public static final int SENDING_FAILED = 4; // 0x4 + field public static final int SENDING_PAUSED = 3; // 0x3 + field public static final int SUCCEEDED = 10; // 0xa + } + + @IntDef({android.telephony.ims.RcsFileTransferPart.DRAFT, android.telephony.ims.RcsFileTransferPart.SENDING, android.telephony.ims.RcsFileTransferPart.SENDING_PAUSED, android.telephony.ims.RcsFileTransferPart.SENDING_FAILED, android.telephony.ims.RcsFileTransferPart.SENDING_CANCELLED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_PAUSED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_FAILED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_CANCELLED, android.telephony.ims.RcsFileTransferPart.SUCCEEDED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RcsFileTransferPart.RcsFileTransferStatus { + } + + public class RcsGroupThread extends android.telephony.ims.RcsThread { + method @WorkerThread public void addParticipant(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public android.net.Uri getConferenceUri() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable public android.net.Uri getGroupIcon() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public String getGroupName() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public android.telephony.ims.RcsParticipant getOwner() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public java.util.Set<android.telephony.ims.RcsParticipant> getParticipants() throws android.telephony.ims.RcsMessageStoreException; + method public boolean isGroup(); + method @WorkerThread public void removeParticipant(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public void setConferenceUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setGroupIcon(@Nullable android.net.Uri) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setGroupName(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setOwner(@Nullable android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException; + } + + public abstract class RcsGroupThreadEvent extends android.telephony.ims.RcsEvent { + method @NonNull public android.telephony.ims.RcsParticipant getOriginatingParticipant(); + method @NonNull public android.telephony.ims.RcsGroupThread getRcsGroupThread(); + } + + public final class RcsGroupThreadIconChangedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable { + ctor public RcsGroupThreadIconChangedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @Nullable android.net.Uri); + method public int describeContents(); + method @Nullable public android.net.Uri getNewIcon(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadIconChangedEvent> CREATOR; + } + + public final class RcsGroupThreadNameChangedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable { + ctor public RcsGroupThreadNameChangedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @Nullable String); + method public int describeContents(); + method @Nullable public String getNewName(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadNameChangedEvent> CREATOR; + } + + public final class RcsGroupThreadParticipantJoinedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable { + ctor public RcsGroupThreadParticipantJoinedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @NonNull android.telephony.ims.RcsParticipant); + method public int describeContents(); + method public android.telephony.ims.RcsParticipant getJoinedParticipant(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadParticipantJoinedEvent> CREATOR; + } + + public final class RcsGroupThreadParticipantLeftEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable { + ctor public RcsGroupThreadParticipantLeftEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @NonNull android.telephony.ims.RcsParticipant); + method public int describeContents(); + method @NonNull public android.telephony.ims.RcsParticipant getLeavingParticipantId(); + method public void persist() throws android.telephony.ims.RcsMessageStoreException; + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadParticipantLeftEvent> CREATOR; + } + + public class RcsIncomingMessage extends android.telephony.ims.RcsMessage { + method @WorkerThread public long getArrivalTimestamp() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public long getSeenTimestamp() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public android.telephony.ims.RcsParticipant getSenderParticipant() throws android.telephony.ims.RcsMessageStoreException; + method public boolean isIncoming(); + method @WorkerThread public void setArrivalTimestamp(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setSeenTimestamp(long) throws android.telephony.ims.RcsMessageStoreException; + } + + public final class RcsIncomingMessageCreationParams extends android.telephony.ims.RcsMessageCreationParams implements android.os.Parcelable { + method public int describeContents(); + method public long getArrivalTimestamp(); + method public long getSeenTimestamp(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsIncomingMessageCreationParams> CREATOR; + } + + public static class RcsIncomingMessageCreationParams.Builder extends android.telephony.ims.RcsMessageCreationParams.Builder { + ctor public RcsIncomingMessageCreationParams.Builder(long, long, int); + method public android.telephony.ims.RcsIncomingMessageCreationParams build(); + method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setArrivalTimestamp(long); + method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setSeenTimestamp(long); + method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setSenderParticipant(android.telephony.ims.RcsParticipant); + } + + public class RcsManager { + method public android.telephony.ims.RcsMessageStore getRcsMessageStore(); + } + + public abstract class RcsMessage { + method @NonNull @WorkerThread public java.util.Set<android.telephony.ims.RcsFileTransferPart> getFileTransferParts() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public double getLatitude() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public double getLongitude() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public long getOriginationTimestamp() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public String getRcsMessageId() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @android.telephony.ims.RcsMessage.RcsMessageStatus public int getStatus() throws android.telephony.ims.RcsMessageStoreException; + method public int getSubscriptionId() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public String getText() throws android.telephony.ims.RcsMessageStoreException; + method @NonNull @WorkerThread public android.telephony.ims.RcsFileTransferPart insertFileTransfer(android.telephony.ims.RcsFileTransferCreationParams) throws android.telephony.ims.RcsMessageStoreException; + method public abstract boolean isIncoming(); + method @WorkerThread public void removeFileTransferPart(@NonNull android.telephony.ims.RcsFileTransferPart) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setLatitude(double) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setLongitude(double) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setOriginationTimestamp(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setRcsMessageId(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setSubscriptionId(int) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setText(String) throws android.telephony.ims.RcsMessageStoreException; + field public static final int DRAFT = 1; // 0x1 + field public static final int FAILED = 6; // 0x6 + field public static final double LOCATION_NOT_SET = 4.9E-324; + field public static final int NOT_SET = 0; // 0x0 + field public static final int QUEUED = 2; // 0x2 + field public static final int RECEIVED = 7; // 0x7 + field public static final int RETRYING = 5; // 0x5 + field public static final int SEEN = 9; // 0x9 + field public static final int SENDING = 3; // 0x3 + field public static final int SENT = 4; // 0x4 + } + + @IntDef({android.telephony.ims.RcsMessage.DRAFT, android.telephony.ims.RcsMessage.QUEUED, android.telephony.ims.RcsMessage.SENDING, android.telephony.ims.RcsMessage.SENT, android.telephony.ims.RcsMessage.RETRYING, android.telephony.ims.RcsMessage.FAILED, android.telephony.ims.RcsMessage.RECEIVED, android.telephony.ims.RcsMessage.SEEN}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RcsMessage.RcsMessageStatus { + } + + public class RcsMessageCreationParams { + ctor protected RcsMessageCreationParams(android.telephony.ims.RcsMessageCreationParams.Builder); + method public double getLatitude(); + method public double getLongitude(); + method public int getMessageStatus(); + method public long getOriginationTimestamp(); + method @Nullable public String getRcsMessageGlobalId(); + method public int getSubId(); + method @Nullable public String getText(); + } + + public static class RcsMessageCreationParams.Builder { + method public android.telephony.ims.RcsMessageCreationParams build(); + method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setLatitude(double); + method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setLongitude(double); + method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setRcsMessageId(String); + method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int); + method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setText(String); + } + + public final class RcsMessageQueryParams implements android.os.Parcelable { + method public int describeContents(); + method public int getFileTransferPresence(); + method public int getLimit(); + method public String getMessageLike(); + method public int getMessageType(); + method public boolean getSortDirection(); + method @android.telephony.ims.RcsMessageQueryParams.SortingProperty public int getSortingProperty(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageQueryParams> CREATOR; + field public static final int MESSAGES_WITHOUT_FILE_TRANSFERS = 8; // 0x8 + field public static final int MESSAGES_WITH_FILE_TRANSFERS = 4; // 0x4 + field public static final int MESSAGE_TYPE_INCOMING = 1; // 0x1 + field public static final int MESSAGE_TYPE_OUTGOING = 2; // 0x2 + field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0 + field public static final int SORT_BY_TIMESTAMP = 1; // 0x1 + } + + public static class RcsMessageQueryParams.Builder { + ctor public RcsMessageQueryParams.Builder(); + method public android.telephony.ims.RcsMessageQueryParams build(); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setFileTransferPresence(int); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setMessageLike(String); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setMessageType(int); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException; + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setSortDirection(boolean); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setSortProperty(@android.telephony.ims.RcsMessageQueryParams.SortingProperty int); + method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setThread(@Nullable android.telephony.ims.RcsThread); + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsMessageQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsMessageQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsMessageQueryParams.SortingProperty { + } + + public final class RcsMessageQueryResult implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken(); + method @NonNull public java.util.List<android.telephony.ims.RcsMessage> getMessages(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageQueryResult> CREATOR; + } + + public final class RcsMessageSnippet implements android.os.Parcelable { + method public int describeContents(); + method @android.telephony.ims.RcsMessage.RcsMessageStatus public int getSnippetStatus(); + method @Nullable public String getSnippetText(); + method public long getSnippetTimestamp(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageSnippet> CREATOR; + } + + public class RcsMessageStore { + ctor public RcsMessageStore(); + method @WorkerThread @NonNull public android.telephony.ims.RcsGroupThread createGroupThread(@Nullable java.util.List<android.telephony.ims.RcsParticipant>, @Nullable String, @Nullable android.net.Uri) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.Rcs1To1Thread createRcs1To1Thread(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsParticipant createRcsParticipant(String, @Nullable String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void deleteThread(@NonNull android.telephony.ims.RcsThread) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsEventQueryResult getRcsEvents(@Nullable android.telephony.ims.RcsEventQueryParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsEventQueryResult getRcsEvents(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getRcsMessages(@Nullable android.telephony.ims.RcsMessageQueryParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getRcsMessages(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsParticipantQueryResult getRcsParticipants(@Nullable android.telephony.ims.RcsParticipantQueryParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsParticipantQueryResult getRcsParticipants(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsThreadQueryResult getRcsThreads(@Nullable android.telephony.ims.RcsThreadQueryParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsThreadQueryResult getRcsThreads(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public void persistRcsEvent(android.telephony.ims.RcsEvent) throws android.telephony.ims.RcsMessageStoreException; + } + + public class RcsMessageStoreException extends java.lang.Exception { + ctor public RcsMessageStoreException(String); + } + + public class RcsOutgoingMessage extends android.telephony.ims.RcsMessage { + method @NonNull @WorkerThread public java.util.List<android.telephony.ims.RcsOutgoingMessageDelivery> getOutgoingDeliveries() throws android.telephony.ims.RcsMessageStoreException; + method public boolean isIncoming(); + } + + public final class RcsOutgoingMessageCreationParams extends android.telephony.ims.RcsMessageCreationParams implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsOutgoingMessageCreationParams> CREATOR; + } + + public static class RcsOutgoingMessageCreationParams.Builder extends android.telephony.ims.RcsMessageCreationParams.Builder { + ctor public RcsOutgoingMessageCreationParams.Builder(long, int); + method public android.telephony.ims.RcsOutgoingMessageCreationParams build(); + } + + public class RcsOutgoingMessageDelivery { + method @WorkerThread public long getDeliveredTimestamp() throws android.telephony.ims.RcsMessageStoreException; + method @NonNull public android.telephony.ims.RcsOutgoingMessage getMessage(); + method @NonNull public android.telephony.ims.RcsParticipant getRecipient(); + method @WorkerThread public long getSeenTimestamp() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @android.telephony.ims.RcsMessage.RcsMessageStatus public int getStatus() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setDeliveredTimestamp(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setSeenTimestamp(long) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int) throws android.telephony.ims.RcsMessageStoreException; + } + + public class RcsParticipant { + method @Nullable @WorkerThread public String getAlias() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public String getCanonicalAddress() throws android.telephony.ims.RcsMessageStoreException; + method @Nullable @WorkerThread public String getContactId() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setAlias(String) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void setContactId(String) throws android.telephony.ims.RcsMessageStoreException; + } + + public final class RcsParticipantAliasChangedEvent extends android.telephony.ims.RcsEvent implements android.os.Parcelable { + ctor public RcsParticipantAliasChangedEvent(long, @NonNull android.telephony.ims.RcsParticipant, @Nullable String); + method public int describeContents(); + method @Nullable public String getNewAlias(); + method @NonNull public android.telephony.ims.RcsParticipant getParticipantId(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantAliasChangedEvent> CREATOR; + } + + public final class RcsParticipantQueryParams implements android.os.Parcelable { + method public int describeContents(); + method public String getAliasLike(); + method public String getCanonicalAddressLike(); + method public int getLimit(); + method public boolean getSortDirection(); + method public int getSortingProperty(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantQueryParams> CREATOR; + field public static final int SORT_BY_ALIAS = 1; // 0x1 + field public static final int SORT_BY_CANONICAL_ADDRESS = 2; // 0x2 + field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0 + } + + public static class RcsParticipantQueryParams.Builder { + ctor public RcsParticipantQueryParams.Builder(); + method public android.telephony.ims.RcsParticipantQueryParams build(); + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setAliasLike(String); + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setCanonicalAddressLike(String); + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException; + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setSortDirection(boolean); + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setSortProperty(@android.telephony.ims.RcsParticipantQueryParams.SortingProperty int); + method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setThread(android.telephony.ims.RcsThread); + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsParticipantQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsParticipantQueryParams.SORT_BY_ALIAS, android.telephony.ims.RcsParticipantQueryParams.SORT_BY_CANONICAL_ADDRESS}) public static @interface RcsParticipantQueryParams.SortingProperty { + } + + public final class RcsParticipantQueryResult implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken(); + method @NonNull public java.util.List<android.telephony.ims.RcsParticipant> getParticipants(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantQueryResult> CREATOR; + } + + public final class RcsQueryContinuationToken implements android.os.Parcelable { + method public int describeContents(); + method @android.telephony.ims.RcsQueryContinuationToken.ContinuationTokenType public int getQueryType(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsQueryContinuationToken> CREATOR; + field public static final int EVENT_QUERY_CONTINUATION_TOKEN_TYPE = 0; // 0x0 + field public static final int MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE = 1; // 0x1 + field public static final int PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE = 2; // 0x2 + field public static final int THREAD_QUERY_CONTINUATION_TOKEN_TYPE = 3; // 0x3 + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsQueryContinuationToken.EVENT_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.THREAD_QUERY_CONTINUATION_TOKEN_TYPE}) public static @interface RcsQueryContinuationToken.ContinuationTokenType { + } + + public abstract class RcsThread { + method @WorkerThread @NonNull public android.telephony.ims.RcsIncomingMessage addIncomingMessage(@NonNull android.telephony.ims.RcsIncomingMessageCreationParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsOutgoingMessage addOutgoingMessage(@NonNull android.telephony.ims.RcsOutgoingMessageCreationParams) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread public void deleteMessage(@NonNull android.telephony.ims.RcsMessage) throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getMessages() throws android.telephony.ims.RcsMessageStoreException; + method @WorkerThread @NonNull public android.telephony.ims.RcsMessageSnippet getSnippet() throws android.telephony.ims.RcsMessageStoreException; + method public abstract boolean isGroup(); + } + + public final class RcsThreadQueryParams implements android.os.Parcelable { + method public int describeContents(); + method public int getLimit(); + method public boolean getSortDirection(); + method @android.telephony.ims.RcsThreadQueryParams.SortingProperty public int getSortingProperty(); + method public int getThreadType(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsThreadQueryParams> CREATOR; + field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0 + field public static final int SORT_BY_TIMESTAMP = 1; // 0x1 + field public static final int THREAD_TYPE_1_TO_1 = 2; // 0x2 + field public static final int THREAD_TYPE_GROUP = 1; // 0x1 + } + + public static class RcsThreadQueryParams.Builder { + ctor public RcsThreadQueryParams.Builder(); + method public android.telephony.ims.RcsThreadQueryParams build(); + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setParticipant(@NonNull android.telephony.ims.RcsParticipant); + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setParticipants(@NonNull java.util.List<android.telephony.ims.RcsParticipant>); + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException; + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setSortDirection(boolean); + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setSortProperty(@android.telephony.ims.RcsThreadQueryParams.SortingProperty int); + method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setThreadType(int); + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsThreadQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsThreadQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsThreadQueryParams.SortingProperty { + } + + public final class RcsThreadQueryResult implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken(); + method @NonNull public java.util.List<android.telephony.ims.RcsThread> getThreads(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsThreadQueryResult> CREATOR; + } + +} + package android.telephony.mbms { public class DownloadProgressListener { diff --git a/api/removed.txt b/api/removed.txt index 05d52d4e40c0..72202ad9712a 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -540,7 +540,7 @@ package android.telephony { public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo(); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback); + method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback); } } diff --git a/api/system-current.txt b/api/system-current.txt index 981789c735f3..9c45fb4ee5c4 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -862,6 +862,32 @@ package android.content { method public void sendOrderedBroadcast(android.content.Intent, String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle); } + public class DynamicAndroidClient { + ctor public DynamicAndroidClient(@NonNull android.content.Context); + method public void bind(); + method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener, @NonNull java.util.concurrent.Executor); + method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener); + method public void start(String, long); + method public void start(String, long, long); + method public void unbind(); + field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 + field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 + field public static final int CAUSE_ERROR_IO = 3; // 0x3 + field public static final int CAUSE_ERROR_IPC = 5; // 0x5 + field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2 + field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1 + field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0 + field public static final int STATUS_IN_PROGRESS = 2; // 0x2 + field public static final int STATUS_IN_USE = 4; // 0x4 + field public static final int STATUS_NOT_STARTED = 1; // 0x1 + field public static final int STATUS_READY = 3; // 0x3 + field public static final int STATUS_UNKNOWN = 0; // 0x0 + } + + public static interface DynamicAndroidClient.OnStatusChangedListener { + method public void onStatusChanged(int, int, long); + } + public class Intent implements java.lang.Cloneable android.os.Parcelable { field public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED"; field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY"; @@ -3075,7 +3101,7 @@ package android.net { method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); - method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle); + method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.net.Network, android.os.Bundle); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); @@ -5466,6 +5492,7 @@ package android.telecom { 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"; + field public static final String EXTRA_IS_USER_INTENT_EMERGENCY_CALL = "android.telecom.extra.IS_USER_INTENT_EMERGENCY_CALL"; 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 @@ -5529,6 +5556,7 @@ package android.telephony { 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 @@ -6252,10 +6280,13 @@ package android.telephony { public class SubscriptionManager { method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int); method public void requestEmbeddedSubscriptionInfoListRefresh(); method public void requestEmbeddedSubscriptionInfoListRefresh(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); field public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2 @@ -6322,11 +6353,13 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @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 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmap(); method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState(); method public int getSimApplicationState(); method public int getSimCardState(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getSimLocale(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSupportedRadioAccessFamily(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo(); method @Nullable public android.os.Bundle getVisualVoicemailSettings(); @@ -6339,12 +6372,13 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMultisimCarrierRestricted(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isRebootRequiredForModemConfigChange(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled(); method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); method public boolean needsOtaServiceProvisioning(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); - method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); + method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>); @@ -6354,6 +6388,7 @@ package android.telephony { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultisimCarrierRestriction(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmap(long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int); @@ -6381,25 +6416,26 @@ package android.telephony { field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L - field public static final int NETWORK_TYPE_BITMASK_1xRTT = 128; // 0x80 - field public static final int NETWORK_TYPE_BITMASK_CDMA = 16; // 0x10 - field public static final int NETWORK_TYPE_BITMASK_EDGE = 4; // 0x4 - field public static final int NETWORK_TYPE_BITMASK_EHRPD = 16384; // 0x4000 - field public static final int NETWORK_TYPE_BITMASK_EVDO_0 = 32; // 0x20 - field public static final int NETWORK_TYPE_BITMASK_EVDO_A = 64; // 0x40 - field public static final int NETWORK_TYPE_BITMASK_EVDO_B = 4096; // 0x1000 - field public static final int NETWORK_TYPE_BITMASK_GPRS = 2; // 0x2 - field public static final int NETWORK_TYPE_BITMASK_GSM = 65536; // 0x10000 - field public static final int NETWORK_TYPE_BITMASK_HSDPA = 256; // 0x100 - field public static final int NETWORK_TYPE_BITMASK_HSPA = 1024; // 0x400 - field public static final int NETWORK_TYPE_BITMASK_HSPAP = 32768; // 0x8000 - field public static final int NETWORK_TYPE_BITMASK_HSUPA = 512; // 0x200 - field public static final int NETWORK_TYPE_BITMASK_LTE = 8192; // 0x2000 - field public static final int NETWORK_TYPE_BITMASK_LTE_CA = 524288; // 0x80000 - field public static final int NETWORK_TYPE_BITMASK_NR = 1048576; // 0x100000 - field public static final int NETWORK_TYPE_BITMASK_TD_SCDMA = 131072; // 0x20000 - field public static final int NETWORK_TYPE_BITMASK_UMTS = 8; // 0x8 - field public static final int NETWORK_TYPE_BITMASK_UNKNOWN = 1; // 0x1 + field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L + field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L + field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L + field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L + field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L + field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L + field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L + field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L + field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L + field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L + field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L + field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L + field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L + field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L + field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L + field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L + field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L + field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L + field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L + field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L field public static final int RADIO_POWER_OFF = 0; // 0x0 field public static final int RADIO_POWER_ON = 1; // 0x1 field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 @@ -6718,6 +6754,7 @@ package android.telephony.ims { method public int getServiceType(); method public static int getVideoStateFromCallType(int); method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile); + method public boolean hasKnownUserIntentEmergency(); method public boolean isEmergencyCallTesting(); method public boolean isVideoCall(); method public boolean isVideoPaused(); @@ -6730,6 +6767,7 @@ package android.telephony.ims { method public void setEmergencyCallTesting(boolean); method public void setEmergencyServiceCategories(int); method public void setEmergencyUrns(java.util.List<java.lang.String>); + method public void setHasKnownUserIntentEmergency(boolean); method public void updateCallExtras(android.telephony.ims.ImsCallProfile); method public void updateCallType(android.telephony.ims.ImsCallProfile); method public void updateMediaProfile(android.telephony.ims.ImsCallProfile); diff --git a/api/test-current.txt b/api/test-current.txt index 01127249c1fc..c9d176979a65 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -608,7 +608,7 @@ package android.net { } public class ConnectivityManager { - method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle); + method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.net.Network, android.os.Bundle); field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; } @@ -668,6 +668,7 @@ package android.net { method public int[] getCapabilities(); method public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); + field public static final int TRANSPORT_TEST = 7; // 0x7 } public class NetworkStack { diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index c04e61b77274..ca4a184407b4 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -174,6 +174,8 @@ public class Am extends BaseCommand { instrument.noWindowAnimation = true; } else if (opt.equals("--no-hidden-api-checks")) { instrument.disableHiddenApiChecks = true; + } else if (opt.equals("--no-isolated-storage")) { + // NOTE: currently a no-op in this branch } else if (opt.equals("--user")) { instrument.userId = parseUserArg(nextArgRequired()); } else if (opt.equals("--abi")) { diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc index 1b3c32b20503..469c9646a4aa 100644 --- a/cmds/bootanimation/bootanim.rc +++ b/cmds/bootanimation/bootanim.rc @@ -2,7 +2,6 @@ service bootanim /system/bin/bootanimation class core animation user graphics group graphics audio - updatable disabled oneshot writepid /dev/stune/top-app/tasks diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 65ebbed57fef..1d629da2f250 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -161,6 +161,7 @@ message Atom { BluetoothBondStateChanged bluetooth_bond_state_changed = 165; BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported = 166; BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167; + ProcessStartTime process_start_time = 169; BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171; } @@ -2968,3 +2969,59 @@ message SeOmapiReported { optional string package_name = 3; } + +/* +* Logs number of milliseconds it takes to start a process. +* The definition of app process start time is from the app launch time to +* the time that Zygote finished forking the app process and loaded the +* application package's java classes. + +* This metric is different from AppStartOccurred which is for foreground +* activity only. + +* ProcessStartTime can report all processes (both foreground and background) +* start time. +* +* Logged from: +* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java +*/ +message ProcessStartTime { + // The uid of the ProcessRecord. + optional int32 uid = 1 [(is_uid) = true]; + + // The process pid. + optional int32 pid = 2; + + // The process name. + // Usually package name, "system" for system server. + // Provided by ActivityManagerService. + optional string process_name = 3; + + enum StartType { + UNKNOWN = 0; + WARM = 1; + HOT = 2; + COLD = 3; + } + + // The start type. + optional StartType type = 4; + + // The elapsed realtime at the start of the process. + optional int64 process_start_time_millis = 5; + + // Number of milliseconds it takes to reach bind application. + optional int32 bind_application_delay_millis = 6; + + // Number of milliseconds it takes to finish start of the process. + optional int32 process_start_delay_millis = 7; + + // hostingType field in ProcessRecord, the component type such as "activity", + // "service", "content provider", "broadcast" or other strings. + optional string hosting_type = 8; + + // hostingNameStr field in ProcessRecord. The component class name that runs + // in this process. + optional string hosting_name = 9; +} + diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt index dca3b525c06a..b328f2ac1955 100644 --- a/config/hiddenapi-force-blacklist.txt +++ b/config/hiddenapi-force-blacklist.txt @@ -1,4 +1,6 @@ Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V +Ldalvik/system/VMRuntime;->setTargetSdkVersion(I)V +Ldalvik/system/VMRuntime;->setTargetSdkVersionNative(I)V Ljava/lang/invoke/MethodHandles$Lookup;->IMPL_LOOKUP:Ljava/lang/invoke/MethodHandles$Lookup; Ljava/lang/invoke/VarHandle;->acquireFence()V Ljava/lang/invoke/VarHandle;->compareAndExchange([Ljava/lang/Object;)Ljava/lang/Object; diff --git a/config/hiddenapi-greylist-max-o.txt b/config/hiddenapi-greylist-max-o.txt index 4b6cc0ef7795..d9c1cd0313fc 100644 --- a/config/hiddenapi-greylist-max-o.txt +++ b/config/hiddenapi-greylist-max-o.txt @@ -109777,7 +109777,6 @@ Ldalvik/system/VMRuntime;->setHiddenApiAccessLogSamplingRate(I)V Ldalvik/system/VMRuntime;->setNonSdkApiUsageConsumer(Ljava/util/function/Consumer;)V Ldalvik/system/VMRuntime;->setProcessPackageName(Ljava/lang/String;)V Ldalvik/system/VMRuntime;->setSystemDaemonThreadPriority()V -Ldalvik/system/VMRuntime;->setTargetSdkVersionNative(I)V Ldalvik/system/VMRuntime;->startHeapTaskProcessor()V Ldalvik/system/VMRuntime;->startJitCompilation()V Ldalvik/system/VMRuntime;->stopHeapTaskProcessor()V diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 3d5b32a62ca5..e166c31d578a 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -603,8 +603,6 @@ Landroid/net/IConnectivityManager;->getTetherableWifiRegexs()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V -Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd; -Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V Landroid/net/INetworkPolicyListener$Stub;-><init>()V Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager; @@ -2546,7 +2544,6 @@ Lcom/android/internal/telephony/cat/CatService;->isStkAppInstalled()Z Lcom/android/internal/telephony/cat/CatService;->mCmdIf:Lcom/android/internal/telephony/CommandsInterface; Lcom/android/internal/telephony/cat/CatService;->mContext:Landroid/content/Context; Lcom/android/internal/telephony/cat/CatService;->mCurrntCmd:Lcom/android/internal/telephony/cat/CatCmdMessage; -Lcom/android/internal/telephony/cat/CatService;->mHandlerThread:Landroid/os/HandlerThread; Lcom/android/internal/telephony/cat/CatService;->mMenuCmd:Lcom/android/internal/telephony/cat/CatCmdMessage; Lcom/android/internal/telephony/cat/CatService;->mMsgDecoder:Lcom/android/internal/telephony/cat/RilMessageDecoder; Lcom/android/internal/telephony/cat/CatService;->mSlotId:I @@ -2933,7 +2930,6 @@ Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->reset()V Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;-><init>()V Lcom/android/internal/telephony/GsmCdmaCall;->attachFake(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V Lcom/android/internal/telephony/GsmCdmaCallTracker;->clearDisconnected()V -Lcom/android/internal/telephony/GsmCdmaCallTracker;->dialThreeWay(Ljava/lang/String;)Lcom/android/internal/telephony/Connection; Lcom/android/internal/telephony/GsmCdmaCallTracker;->disableDataCallInEmergencyCall(Ljava/lang/String;)V Lcom/android/internal/telephony/GsmCdmaCallTracker;->fakeHoldForegroundBeforeDial()V Lcom/android/internal/telephony/GsmCdmaCallTracker;->getPhone()Lcom/android/internal/telephony/GsmCdmaPhone; diff --git a/core/java/android/accessibilityservice/OWNERS b/core/java/android/accessibilityservice/OWNERS new file mode 100644 index 000000000000..265674a74b7e --- /dev/null +++ b/core/java/android/accessibilityservice/OWNERS @@ -0,0 +1,3 @@ +svetoslavganov@google.com +pweaver@google.com +rhedjao@google.com diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 0d3110cfded8..ac33c169288b 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -850,8 +850,9 @@ public final class LoadedApk { } } - // /vendor/lib, /odm/lib and /product/lib are added to the native lib search - // paths of the classloader. Note that this is done AFTER the classloader is + // /aepx/com.android.runtime/lib, /vendor/lib, /odm/lib and /product/lib + // are added to the native lib search paths of the classloader. + // Note that this is done AFTER the classloader is // created by ApplicationLoaders.getDefault().getClassLoader(...). The // reason is because if we have added the paths when creating the classloader // above, the paths are also added to the search path of the linker namespace @@ -868,8 +869,11 @@ public final class LoadedApk { // System.loadLibrary(). In order to prevent the problem, we explicitly // add the paths only to the classloader, and not to the native loader // (linker namespace). - List<String> extraLibPaths = new ArrayList<>(3); + List<String> extraLibPaths = new ArrayList<>(4); String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : ""; + if (!defaultSearchPaths.contains("/apex/com.android.runtime/lib")) { + extraLibPaths.add("/apex/com.android.runtime/lib" + abiSuffix); + } if (!defaultSearchPaths.contains("/vendor/lib")) { extraLibPaths.add("/vendor/lib" + abiSuffix); } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index c42a2bce2c48..e92efde236c4 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -83,13 +83,11 @@ import android.net.IConnectivityManager; import android.net.IEthernetManager; import android.net.IIpMemoryStore; import android.net.IIpSecService; -import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.IpMemoryStore; import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; -import android.net.NetworkStack; import android.net.NetworkWatchlistManager; import android.net.lowpan.ILowpanManager; import android.net.lowpan.LowpanManager; @@ -290,21 +288,13 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); - registerService(Context.NETD_SERVICE, INetd.class, new StaticServiceFetcher<INetd>() { + registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() { @Override - public INetd createService() throws ServiceNotFoundException { - return INetd.Stub.asInterface( - ServiceManager.getServiceOrThrow(Context.NETD_SERVICE)); + public IBinder createService() throws ServiceNotFoundException { + return ServiceManager.getServiceOrThrow(Context.NETD_SERVICE); } }); - registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class, - new StaticServiceFetcher<NetworkStack>() { - @Override - public NetworkStack createService() { - return new NetworkStack(); - }}); - registerService(Context.IP_MEMORY_STORE_SERVICE, IpMemoryStore.class, new CachedServiceFetcher<IpMemoryStore>() { @Override diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 2803856fb3bc..23f29041487d 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -2175,8 +2175,7 @@ public final class BluetoothDevice implements Parcelable { * encrypted. * <p> Use this socket if an authenticated socket link is possible. Authentication refers * to the authentication of the link key to prevent man-in-the-middle type of attacks. When a - * secure socket connection is not possible, use {#link createInsecureLeL2capCocSocket(int, - * int)}. + * secure socket connection is not possible, use {#link createInsecureL2capChannel(int)}. * * @param psm dynamic PSM value from remote device * @return a CoC #BluetoothSocket ready for an outgoing connection diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 493aac6e5c40..b072740ccfdf 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -49,7 +49,6 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.net.NetworkStack; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -3514,11 +3513,10 @@ public abstract class Context { public static final String NETD_SERVICE = "netd"; /** - * Use with {@link #getSystemService(String)} to retrieve a - * {@link NetworkStack} for communicating with the network stack + * Use with {@link android.os.ServiceManager.getService()} to retrieve a + * {@link NetworkStackClient} IBinder for communicating with the network stack * @hide - * @see #getSystemService(String) - * @see NetworkStack + * @see NetworkStackClient */ public static final String NETWORK_STACK_SERVICE = "network_stack"; diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/content/DynamicAndroidClient.java new file mode 100644 index 000000000000..571cba429ea9 --- /dev/null +++ b/core/java/android/content/DynamicAndroidClient.java @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content; + +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.util.Slog; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.concurrent.Executor; + +/** + * This class contains methods and constants used to start DynamicAndroid + * installation, and a listener for progress update. + * @hide + */ +@SystemApi +public class DynamicAndroidClient { + /** @hide */ + @IntDef(prefix = { "STATUS_" }, value = { + STATUS_UNKNOWN, + STATUS_NOT_STARTED, + STATUS_IN_PROGRESS, + STATUS_READY, + STATUS_IN_USE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface InstallationStatus {} + + /** @hide */ + @IntDef(prefix = { "CAUSE_" }, value = { + CAUSE_NOT_SPECIFIED, + CAUSE_INSTALL_COMPLETED, + CAUSE_INSTALL_CANCELLED, + CAUSE_ERROR_IO, + CAUSE_ERROR_INVALID_URL, + CAUSE_ERROR_IPC, + CAUSE_ERROR_EXCEPTION, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface StatusChangedCause {} + + private static final String TAG = "DynAndroidClient"; + + private static final long DEFAULT_USERDATA_SIZE = (10L << 30); + + + /** Listener for installation status update. */ + public interface OnStatusChangedListener { + /** + * This callback is called when installation status is changed, and when the + * client is {@link #bind} to DynamicAndroid installation service. + * + * @param status status code, also defined in {@code DynamicAndroidClient}. + * @param cause cause code, also defined in {@code DynamicAndroidClient}. + * @param progress number of bytes installed. + */ + void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause, + long progress); + } + + /* + * Status codes + */ + /** We are bound to installation service, but failed to get its status */ + public static final int STATUS_UNKNOWN = 0; + + /** Installation is not started yet. */ + public static final int STATUS_NOT_STARTED = 1; + + /** Installation is in progress. */ + public static final int STATUS_IN_PROGRESS = 2; + + /** Installation is finished but the user has not launched it. */ + public static final int STATUS_READY = 3; + + /** Device is running in Dynamic Android. */ + public static final int STATUS_IN_USE = 4; + + /* + * Causes + */ + /** Cause is not specified. This means the status is not changed. */ + public static final int CAUSE_NOT_SPECIFIED = 0; + + /** Status changed because installation is completed. */ + public static final int CAUSE_INSTALL_COMPLETED = 1; + + /** Status changed because installation is cancelled. */ + public static final int CAUSE_INSTALL_CANCELLED = 2; + + /** Installation failed due to IOException. */ + public static final int CAUSE_ERROR_IO = 3; + + /** Installation failed because the image URL source is not supported. */ + public static final int CAUSE_ERROR_INVALID_URL = 4; + + /** Installation failed due to IPC error. */ + public static final int CAUSE_ERROR_IPC = 5; + + /** Installation failed due to unhandled exception. */ + public static final int CAUSE_ERROR_EXCEPTION = 6; + + /* + * IPC Messages + */ + /** + * Message to register listener. + * @hide + */ + public static final int MSG_REGISTER_LISTENER = 1; + + /** + * Message to unregister listener. + * @hide + */ + public static final int MSG_UNREGISTER_LISTENER = 2; + + /** + * Message for status update. + * @hide + */ + public static final int MSG_POST_STATUS = 3; + + /* + * Messages keys + */ + /** + * Message key, for progress update. + * @hide + */ + public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE"; + + /* + * Intent Actions + */ + /** + * Intent action: start installation. + * @hide + */ + public static final String ACTION_START_INSTALL = + "android.content.action.START_INSTALL"; + + /** + * Intent action: notify user if we are currently running in Dynamic Android. + * @hide + */ + public static final String ACTION_NOTIFY_IF_IN_USE = + "android.content.action.NOTIFY_IF_IN_USE"; + + /* + * Intent Keys + */ + /** + * Intent key: URL to system image. + * @hide + */ + public static final String KEY_SYSTEM_URL = "KEY_SYSTEM_URL"; + + /** + * Intent key: Size of system image, in bytes. + * @hide + */ + public static final String KEY_SYSTEM_SIZE = "KEY_SYSTEM_SIZE"; + + /** + * Intent key: Number of bytes to reserve for userdata. + * @hide + */ + public static final String KEY_USERDATA_SIZE = "KEY_USERDATA_SIZE"; + + + private static class IncomingHandler extends Handler { + private final WeakReference<DynamicAndroidClient> mWeakClient; + + IncomingHandler(DynamicAndroidClient service) { + super(Looper.getMainLooper()); + mWeakClient = new WeakReference<>(service); + } + + @Override + public void handleMessage(Message msg) { + DynamicAndroidClient service = mWeakClient.get(); + + if (service != null) { + service.handleMessage(msg); + } + } + } + + private class DynAndroidServiceConnection implements ServiceConnection { + public void onServiceConnected(ComponentName className, IBinder service) { + Slog.v(TAG, "DynAndroidService connected"); + + mService = new Messenger(service); + + try { + Message msg = Message.obtain(null, MSG_REGISTER_LISTENER); + msg.replyTo = mMessenger; + + mService.send(msg); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to get status from installation service"); + mExecutor.execute(() -> { + mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0); + }); + } + } + + public void onServiceDisconnected(ComponentName className) { + Slog.v(TAG, "DynAndroidService disconnected"); + mService = null; + } + } + + private final Context mContext; + private final DynAndroidServiceConnection mConnection; + private final Messenger mMessenger; + + private boolean mBound; + private Executor mExecutor; + private OnStatusChangedListener mListener; + private Messenger mService; + + /** + * @hide + */ + @SystemApi + public DynamicAndroidClient(@NonNull Context context) { + mContext = context; + mConnection = new DynAndroidServiceConnection(); + mMessenger = new Messenger(new IncomingHandler(this)); + } + + /** + * This method register a listener for status change. The listener is called using + * the executor. + */ + public void setOnStatusChangedListener( + @NonNull OnStatusChangedListener listener, + @NonNull @CallbackExecutor Executor executor) { + mListener = listener; + mExecutor = executor; + } + + /** + * This method register a listener for status change. The listener is called in main + * thread. + */ + public void setOnStatusChangedListener( + @NonNull OnStatusChangedListener listener) { + mListener = listener; + mExecutor = null; + } + + /** + * Bind to DynamicAndroidInstallationService. + */ + public void bind() { + Intent intent = new Intent(); + intent.setClassName("com.android.dynandroid", + "com.android.dynandroid.DynamicAndroidInstallationService"); + + mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + + mBound = true; + } + + /** + * Unbind from DynamicAndroidInstallationService. + */ + public void unbind() { + if (!mBound) { + return; + } + + if (mService != null) { + try { + Message msg = Message.obtain(null, MSG_UNREGISTER_LISTENER); + msg.replyTo = mMessenger; + mService.send(msg); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to unregister from installation service"); + } + } + + // Detach our existing connection. + mContext.unbindService(mConnection); + + mBound = false; + } + + /** + * Start installing DynamicAndroid from URL with default userdata size. + * + * @param systemUrl A network URL or a file URL to system image. + * @param systemSize size of system image. + */ + public void start(String systemUrl, long systemSize) { + start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE); + } + + /** + * Start installing DynamicAndroid from URL. + * + * @param systemUrl A network URL or a file URL to system image. + * @param systemSize size of system image. + * @param userdataSize bytes reserved for userdata. + */ + public void start(String systemUrl, long systemSize, long userdataSize) { + Intent intent = new Intent(); + + intent.setClassName("com.android.dynandroid", + "com.android.dynandroid.VerificationActivity"); + + intent.setAction(ACTION_START_INSTALL); + + intent.putExtra(KEY_SYSTEM_URL, systemUrl); + intent.putExtra(KEY_SYSTEM_SIZE, systemSize); + intent.putExtra(KEY_USERDATA_SIZE, userdataSize); + + mContext.startActivity(intent); + } + + private void handleMessage(Message msg) { + switch (msg.what) { + case MSG_POST_STATUS: + int status = msg.arg1; + int cause = msg.arg2; + // obj is non-null + long progress = ((Bundle) msg.obj).getLong(KEY_INSTALLED_SIZE); + + if (mExecutor != null) { + mExecutor.execute(() -> { + mListener.onStatusChanged(status, cause, progress); + }); + } else { + mListener.onStatusChanged(status, cause, progress); + } + break; + default: + // do nothing + + } + } +} diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 68ac46c874ff..92b30a440d69 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -678,11 +678,20 @@ public class ConnectivityManager { @Deprecated public static final int TYPE_VPN = 17; + /** + * A network that is exclusively meant to be used for testing + * + * @deprecated Use {@link NetworkCapabilities} instead. + * @hide + */ + @Deprecated + public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused. + /** {@hide} */ - public static final int MAX_RADIO_TYPE = TYPE_VPN; + public static final int MAX_RADIO_TYPE = TYPE_TEST; /** {@hide} */ - public static final int MAX_NETWORK_TYPE = TYPE_VPN; + public static final int MAX_NETWORK_TYPE = TYPE_TEST; private static final int MIN_NETWORK_TYPE = TYPE_MOBILE; @@ -3911,15 +3920,16 @@ public class ConnectivityManager { * * <p>This endpoint is exclusively for use by the NetworkStack and is protected by the * corresponding permission. + * @param network Network on which the captive portal was detected. * @param appExtras Extras to include in the app start intent. * @hide */ @SystemApi @TestApi @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) - public void startCaptivePortalApp(Bundle appExtras) { + public void startCaptivePortalApp(Network network, Bundle appExtras) { try { - mService.startCaptivePortalAppInternal(appExtras); + mService.startCaptivePortalAppInternal(network, appExtras); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 92a5839ac2af..83bb3a0c8c15 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -168,7 +168,7 @@ interface IConnectivityManager void setAcceptUnvalidated(in Network network, boolean accept, boolean always); void setAvoidUnvalidated(in Network network); void startCaptivePortalApp(in Network network); - void startCaptivePortalAppInternal(in Bundle appExtras); + void startCaptivePortalAppInternal(in Network network, in Bundle appExtras); boolean getAvoidBadWifi(); int getMultipathPreference(in Network Network); diff --git a/core/java/android/net/INetworkMonitor.aidl b/core/java/android/net/INetworkMonitor.aidl index 41f969acad6f..c94cdde15aa8 100644 --- a/core/java/android/net/INetworkMonitor.aidl +++ b/core/java/android/net/INetworkMonitor.aidl @@ -34,6 +34,7 @@ oneway interface INetworkMonitor { void start(); void launchCaptivePortalApp(); + void notifyCaptivePortalAppFinished(int response); void forceReevaluation(int uid); void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config); void notifyDnsResponse(int returnCode); diff --git a/core/java/android/net/INetworkMonitorCallbacks.aidl b/core/java/android/net/INetworkMonitorCallbacks.aidl index a8682f9ddd3b..2c61511feb72 100644 --- a/core/java/android/net/INetworkMonitorCallbacks.aidl +++ b/core/java/android/net/INetworkMonitorCallbacks.aidl @@ -24,7 +24,6 @@ oneway interface INetworkMonitorCallbacks { void onNetworkMonitorCreated(in INetworkMonitor networkMonitor); void notifyNetworkTested(int testResult, @nullable String redirectUrl); void notifyPrivateDnsConfigResolved(in PrivateDnsConfigParcel config); - void showProvisioningNotification(String action); + void showProvisioningNotification(String action, String packageName); void hideProvisioningNotification(); - void logCaptivePortalLoginEvent(int eventId, String packageName); }
\ No newline at end of file diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java index 62cf7d7ceb25..b9d49c14f6c6 100644 --- a/core/java/android/net/InterfaceConfiguration.java +++ b/core/java/android/net/InterfaceConfiguration.java @@ -36,8 +36,9 @@ public class InterfaceConfiguration implements Parcelable { private LinkAddress mAddr; private HashSet<String> mFlags = Sets.newHashSet(); - private static final String FLAG_UP = INetd.IF_STATE_UP; - private static final String FLAG_DOWN = INetd.IF_STATE_DOWN; + // Must be kept in sync with constant in INetd.aidl + private static final String FLAG_UP = "up"; + private static final String FLAG_DOWN = "down"; private static final String[] EMPTY_STRING_ARRAY = new String[0]; diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 7e9bda14b199..1d2d81dc4fbe 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -597,6 +597,7 @@ public final class NetworkCapabilities implements Parcelable { TRANSPORT_VPN, TRANSPORT_WIFI_AWARE, TRANSPORT_LOWPAN, + TRANSPORT_TEST, }) public @interface Transport { } @@ -635,10 +636,18 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int TRANSPORT_LOWPAN = 6; + /** + * Indicates this network uses a Test-only virtual interface as a transport. + * + * @hide + */ + @TestApi + public static final int TRANSPORT_TEST = 7; + /** @hide */ public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; /** @hide */ - public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN; + public static final int MAX_TRANSPORT = TRANSPORT_TEST; /** @hide */ public static boolean isValidTransport(@Transport int transportType) { @@ -652,7 +661,8 @@ public final class NetworkCapabilities implements Parcelable { "ETHERNET", "VPN", "WIFI_AWARE", - "LOWPAN" + "LOWPAN", + "TEST" }; /** diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 5ab34e9aa6e8..bf272625e713 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -92,16 +92,6 @@ public class NetworkPolicyManager { public static final int MASK_ALL_NETWORKS = 0b11110000; public static final int FIREWALL_RULE_DEFAULT = 0; - public static final int FIREWALL_RULE_ALLOW = INetd.FIREWALL_RULE_ALLOW; - public static final int FIREWALL_RULE_DENY = INetd.FIREWALL_RULE_DENY; - - public static final int FIREWALL_TYPE_WHITELIST = INetd.FIREWALL_WHITELIST; - public static final int FIREWALL_TYPE_BLACKLIST = INetd.FIREWALL_BLACKLIST; - - public static final int FIREWALL_CHAIN_NONE = INetd.FIREWALL_CHAIN_NONE; - public static final int FIREWALL_CHAIN_DOZABLE = INetd.FIREWALL_CHAIN_DOZABLE; - public static final int FIREWALL_CHAIN_STANDBY = INetd.FIREWALL_CHAIN_STANDBY; - public static final int FIREWALL_CHAIN_POWERSAVE = INetd.FIREWALL_CHAIN_POWERSAVE; public static final String FIREWALL_CHAIN_NAME_NONE = "none"; public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable"; diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java index b6cd6359384a..dbb894f92f55 100644 --- a/core/java/android/net/NetworkStack.java +++ b/core/java/android/net/NetworkStack.java @@ -15,44 +15,17 @@ */ package android.net; -import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; -import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; - -import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.SystemService; import android.annotation.TestApi; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.net.dhcp.DhcpServingParamsParcel; -import android.net.dhcp.IDhcpServerCallbacks; -import android.net.ip.IIpClientCallbacks; -import android.os.Binder; -import android.os.IBinder; -import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.util.Slog; - -import com.android.internal.annotations.GuardedBy; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; /** - * Service used to communicate with the network stack, which is running in a separate module. + * + * Constants for client code communicating with the network stack service. * @hide */ -@SystemService(Context.NETWORK_STACK_SERVICE) @SystemApi @TestApi public class NetworkStack { - private static final String TAG = NetworkStack.class.getSimpleName(); - /** * Permission granted only to the NetworkStack APK, defined in NetworkStackStub with signature * protection level. @@ -63,212 +36,5 @@ public class NetworkStack { public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; - /** @hide */ - public static final String NETWORKSTACK_PACKAGE_NAME = "com.android.mainline.networkstack"; - - private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; - - @NonNull - @GuardedBy("mPendingNetStackRequests") - private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>(); - @Nullable - @GuardedBy("mPendingNetStackRequests") - private INetworkStackConnector mConnector; - - private volatile boolean mNetworkStackStartRequested = false; - - private interface NetworkStackCallback { - void onNetworkStackConnected(INetworkStackConnector connector); - } - - /** @hide */ - public NetworkStack() { } - - /** - * Create a DHCP server according to the specified parameters. - * - * <p>The server will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeDhcpServer(final String ifName, final DhcpServingParamsParcel params, - final IDhcpServerCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeDhcpServer(ifName, params, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - /** - * Create an IpClient on the specified interface. - * - * <p>The IpClient will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeIpClient(String ifName, IIpClientCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeIpClient(ifName, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - /** - * Create a NetworkMonitor. - * - * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks. - * @hide - */ - public void makeNetworkMonitor( - NetworkParcelable network, String name, INetworkMonitorCallbacks cb) { - requestConnector(connector -> { - try { - connector.makeNetworkMonitor(network, name, cb); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - }); - } - - private class NetworkStackConnection implements ServiceConnection { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - registerNetworkStackService(service); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - // TODO: crash/reboot the system ? - Slog.wtf(TAG, "Lost network stack connector"); - } - }; - - private void registerNetworkStackService(@NonNull IBinder service) { - final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service); - - ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */, - DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); - - final ArrayList<NetworkStackCallback> requests; - synchronized (mPendingNetStackRequests) { - requests = new ArrayList<>(mPendingNetStackRequests); - mPendingNetStackRequests.clear(); - mConnector = connector; - } - - for (NetworkStackCallback r : requests) { - r.onNetworkStackConnected(connector); - } - } - - /** - * Start the network stack. Should be called only once on device startup. - * - * <p>This method will start the network stack either in the network stack process, or inside - * the system server on devices that do not support the network stack module. The network stack - * connector will then be delivered asynchronously to clients that requested it before it was - * started. - * @hide - */ - public void start(Context context) { - mNetworkStackStartRequested = true; - // Try to bind in-process if the library is available - IBinder connector = null; - try { - final Class service = Class.forName( - "com.android.server.NetworkStackService", - true /* initialize */, - context.getClassLoader()); - connector = (IBinder) service.getMethod("makeConnector", Context.class) - .invoke(null, context); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService"); - // TODO: crash/reboot system here ? - return; - } catch (ClassNotFoundException e) { - // Normal behavior if stack is provided by the app: fall through - } - - // In-process network stack. Add the service to the service manager here. - if (connector != null) { - registerNetworkStackService(connector); - return; - } - // Start the network stack process. The service will be added to the service manager in - // NetworkStackConnection.onServiceConnected(). - final Intent intent = new Intent(INetworkStackConnector.class.getName()); - final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); - intent.setComponent(comp); - - if (comp == null || !context.bindServiceAsUser(intent, new NetworkStackConnection(), - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { - Slog.wtf(TAG, - "Could not bind to network stack in-process, or in app with " + intent); - // TODO: crash/reboot system server if no network stack after a timeout ? - } - } - - /** - * For non-system server clients, get the connector registered by the system server. - */ - private INetworkStackConnector getRemoteConnector() { - // Block until the NetworkStack connector is registered in ServiceManager. - // <p>This is only useful for non-system processes that do not have a way to be notified of - // registration completion. Adding a callback system would be too heavy weight considering - // that the connector is registered on boot, so it is unlikely that a client would request - // it before it is registered. - // TODO: consider blocking boot on registration and simplify much of the logic in this class - IBinder connector; - try { - final long before = System.currentTimeMillis(); - while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) { - Thread.sleep(20); - if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { - Slog.e(TAG, "Timeout waiting for NetworkStack connector"); - return null; - } - } - } catch (InterruptedException e) { - Slog.e(TAG, "Error waiting for NetworkStack connector", e); - return null; - } - - return INetworkStackConnector.Stub.asInterface(connector); - } - - private void requestConnector(@NonNull NetworkStackCallback request) { - // TODO: PID check. - final int caller = Binder.getCallingUid(); - if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) { - // Don't even attempt to obtain the connector and give a nice error message - throw new SecurityException( - "Only the system server should try to bind to the network stack."); - } - - if (!mNetworkStackStartRequested) { - // The network stack is not being started in this process, e.g. this process is not - // the system server. Get a remote connector registered by the system server. - final INetworkStackConnector connector = getRemoteConnector(); - synchronized (mPendingNetStackRequests) { - mConnector = connector; - } - request.onNetworkStackConnected(connector); - return; - } - - final INetworkStackConnector connector; - synchronized (mPendingNetStackRequests) { - connector = mConnector; - if (connector == null) { - mPendingNetStackRequests.add(request); - return; - } - } - - request.onNetworkStackConnected(connector); - } + private NetworkStack() {} } diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 1f3369376b10..a851e04e78ec 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -21,13 +21,14 @@ import android.annotation.Nullable; import android.annotation.WorkerThread; import java.util.ArrayDeque; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -190,13 +191,19 @@ import java.util.concurrent.atomic.AtomicInteger; public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; - private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); - // We want at least 2 threads and at most 4 threads in the core pool, - // preferring to have 1 less than the CPU count to avoid saturating - // the CPU with background work - private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); - private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; - private static final int KEEP_ALIVE_SECONDS = 30; + // We keep only a single pool thread around all the time. + // We let the pool grow to a fairly large number of threads if necessary, + // but let them time out quickly. In the unlikely case that we run out of threads, + // we fall back to a simple unbounded-queue executor. + // This combination ensures that: + // 1. We normally keep few threads (1) around. + // 2. We queue only after launching a significantly larger, but still bounded, set of threads. + // 3. We keep the total number of threads bounded, but still allow an unbounded set + // of tasks to be queued. + private static final int CORE_POOL_SIZE = 1; + private static final int MAXIMUM_POOL_SIZE = 20; + private static final int BACKUP_POOL_SIZE = 5; + private static final int KEEP_ALIVE_SECONDS = 3; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @@ -206,8 +213,29 @@ public abstract class AsyncTask<Params, Progress, Result> { } }; - private static final BlockingQueue<Runnable> sPoolWorkQueue = - new LinkedBlockingQueue<Runnable>(128); + // Used only for rejected executions. + // Initialization protected by sRunOnSerialPolicy lock. + private static ThreadPoolExecutor sBackupExecutor; + private static LinkedBlockingQueue<Runnable> sBackupExecutorQueue; + + private static final RejectedExecutionHandler sRunOnSerialPolicy = + new RejectedExecutionHandler() { + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + android.util.Log.w(LOG_TAG, "Exceeded ThreadPoolExecutor pool size"); + // As a last ditch fallback, run it on an executor with an unbounded queue. + // Create this executor lazily, hopefully almost never. + synchronized (this) { + if (sBackupExecutor == null) { + sBackupExecutorQueue = new LinkedBlockingQueue<Runnable>(); + sBackupExecutor = new ThreadPoolExecutor( + BACKUP_POOL_SIZE, BACKUP_POOL_SIZE, KEEP_ALIVE_SECONDS, + TimeUnit.SECONDS, sBackupExecutorQueue, sThreadFactory); + sBackupExecutor.allowCoreThreadTimeOut(true); + } + } + sBackupExecutor.execute(r); + } + }; /** * An {@link Executor} that can be used to execute tasks in parallel. @@ -217,8 +245,8 @@ public abstract class AsyncTask<Params, Progress, Result> { static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, - sPoolWorkQueue, sThreadFactory); - threadPoolExecutor.allowCoreThreadTimeOut(true); + new SynchronousQueue<Runnable>(), sThreadFactory); + threadPoolExecutor.setRejectedExecutionHandler(sRunOnSerialPolicy); THREAD_POOL_EXECUTOR = threadPoolExecutor; } diff --git a/core/java/android/os/ParcelFileDescriptor.aidl b/core/java/android/os/ParcelFileDescriptor.aidl deleted file mode 100644 index c07b98055d5a..000000000000 --- a/core/java/android/os/ParcelFileDescriptor.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* //device/java/android/android/os/ParcelFileDescriptor.aidl -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -package android.os; - -parcelable ParcelFileDescriptor cpp_header "binder/ParcelFileDescriptor.h"; diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 8492b0cf58e2..3ee54ceebaa9 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -32,6 +32,7 @@ import android.content.pm.PackageManager; import android.provider.Settings; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; +import android.text.format.DateFormat; import android.util.Log; import android.view.Display; import android.view.WindowManager; @@ -762,7 +763,8 @@ public class RecoverySystem { String reasonArg = null; if (!TextUtils.isEmpty(reason)) { - reasonArg = "--reason=" + sanitizeArg(reason); + String timeStamp = DateFormat.format("yyyy-MM-ddTHH:mm:ssZ", System.currentTimeMillis()).toString(); + reasonArg = "--reason=" + sanitizeArg(reason + "," + timeStamp); } final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; diff --git a/core/java/android/os/connectivity/CellularBatteryStats.java b/core/java/android/os/connectivity/CellularBatteryStats.java index 2593c85cff12..c99ecb32d418 100644 --- a/core/java/android/os/connectivity/CellularBatteryStats.java +++ b/core/java/android/os/connectivity/CellularBatteryStats.java @@ -44,6 +44,7 @@ public final class CellularBatteryStats implements Parcelable { private long[] mTimeInRatMs; private long[] mTimeInRxSignalStrengthLevelMs; private long[] mTxTimeMs; + private long mMonitoredRailChargeConsumedMaMs; public static final Parcelable.Creator<CellularBatteryStats> CREATOR = new Parcelable.Creator<CellularBatteryStats>() { @@ -74,6 +75,7 @@ public final class CellularBatteryStats implements Parcelable { out.writeLongArray(mTimeInRatMs); out.writeLongArray(mTimeInRxSignalStrengthLevelMs); out.writeLongArray(mTxTimeMs); + out.writeLong(mMonitoredRailChargeConsumedMaMs); } public void readFromParcel(Parcel in) { @@ -90,6 +92,7 @@ public final class CellularBatteryStats implements Parcelable { in.readLongArray(mTimeInRatMs); in.readLongArray(mTimeInRxSignalStrengthLevelMs); in.readLongArray(mTxTimeMs); + mMonitoredRailChargeConsumedMaMs = in.readLong(); } public long getLoggingDurationMs() { @@ -144,6 +147,10 @@ public final class CellularBatteryStats implements Parcelable { return mTxTimeMs; } + public long getMonitoredRailChargeConsumedMaMs() { + return mMonitoredRailChargeConsumedMaMs; + } + public void setLoggingDurationMs(long t) { mLoggingDurationMs = t; return; @@ -211,6 +218,11 @@ public final class CellularBatteryStats implements Parcelable { return; } + public void setMonitoredRailChargeConsumedMaMs(long monitoredRailEnergyConsumedMaMs) { + mMonitoredRailChargeConsumedMaMs = monitoredRailEnergyConsumedMaMs; + return; + } + public int describeContents() { return 0; } @@ -237,6 +249,7 @@ public final class CellularBatteryStats implements Parcelable { Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0); mTxTimeMs = new long[ModemActivityInfo.TX_POWER_LEVELS]; Arrays.fill(mTxTimeMs, 0); + mMonitoredRailChargeConsumedMaMs = 0; return; } }
\ No newline at end of file diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e904b0713e24..abd7c89a0301 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12862,6 +12862,19 @@ public final class Settings { "user_preferred_sub2","user_preferred_sub3"}; /** + * Which subscription is enabled for a physical slot. + * @hide + */ + public static final String ENABLED_SUBSCRIPTION_FOR_SLOT = "enabled_subscription_for_slot"; + + /** + * Whether corresponding logical modem is enabled for a physical slot. + * The value 1 - enable, 0 - disable + * @hide + */ + public static final String MODEM_STACK_ENABLED_FOR_SLOT = "modem_stack_enabled_for_slot"; + + /** * Whether to enable new contacts aggregator or not. * The value 1 - enable, 0 - disable * @hide diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index b84e556cc552..53cc25b14285 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -76,6 +76,11 @@ import java.util.concurrent.atomic.AtomicInteger; * filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero * priority. * + * <p>Old implementations of EuiccService may support passing in slot IDs equal to + * {@link android.telephony.SubscriptionManager#INVALID_SIM_SLOT_INDEX}, which allows the LPA to + * decide which eUICC to target when there are multiple eUICCs. This behavior is not supported in + * Android Q or later. + * * @hide */ @SystemApi @@ -520,7 +525,7 @@ public abstract class EuiccService extends Service { int resultCode = EuiccService.this.onDownloadSubscription( slotId, subscription, switchAfterDownload, forceDeactivateSim); result = new DownloadSubscriptionResult(resultCode, - 0 /* resolvableErrors */, TelephonyManager.INVALID_CARD_ID); + 0 /* resolvableErrors */, TelephonyManager.UNSUPPORTED_CARD_ID); } try { callback.onComplete(result); diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index fda0a3ee4147..15c14e7bd1ef 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -30,8 +30,7 @@ import android.icu.text.Edits; import android.icu.util.ULocale; import android.os.Parcel; import android.os.Parcelable; -import android.os.SystemProperties; -import android.provider.Settings; +import android.sysprop.DisplayProperties; import android.text.style.AbsoluteSizeSpan; import android.text.style.AccessibilityClickableSpan; import android.text.style.AccessibilityURLSpan; @@ -2001,7 +2000,7 @@ public class TextUtils { return ((locale != null && !locale.equals(Locale.ROOT) && ULocale.forLocale(locale).isRightToLeft()) // If forcing into RTL layout mode, return RTL as default - || SystemProperties.getBoolean(Settings.Global.DEVELOPMENT_FORCE_RTL, false)) + || DisplayProperties.debug_force_rtl().orElse(false)) ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f228773aebf2..efff6d617376 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -74,8 +74,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.Trace; +import android.sysprop.DisplayProperties; import android.text.InputType; import android.text.TextUtils; import android.util.AttributeSet; @@ -790,14 +790,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, protected static final String VIEW_LOG_TAG = "View"; /** - * When set to true, apps will draw debugging information about their layouts. - * - * @hide - */ - @UnsupportedAppUsage - public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout"; - - /** * When set to true, this view will save its attribute data. * * @hide @@ -26855,7 +26847,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Show where the margins, bounds and layout bounds are for each view. */ - boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false); + boolean mDebugLayout = DisplayProperties.debug_layout().orElse(false); /** * Point used to compute visible regions. diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index fd11ef13f9ac..798401d87b5a 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -70,6 +70,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; +import android.sysprop.DisplayProperties; import android.util.AndroidRuntimeException; import android.util.DisplayMetrics; import android.util.Log; @@ -6829,7 +6830,7 @@ public final class ViewRootImpl implements ViewParent, } // Layout debugging - boolean layout = SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false); + boolean layout = DisplayProperties.debug_layout().orElse(false); if (layout != mAttachInfo.mDebugLayout) { mAttachInfo.mDebugLayout = layout; if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) { diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS new file mode 100644 index 000000000000..265674a74b7e --- /dev/null +++ b/core/java/android/view/accessibility/OWNERS @@ -0,0 +1,3 @@ +svetoslavganov@google.com +pweaver@google.com +rhedjao@google.com diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index a8ad8102c610..c46f86792764 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -137,6 +137,7 @@ public class DividerSnapAlgorithm { mDismissStartTarget = mTargets.get(0); mDismissEndTarget = mTargets.get(mTargets.size() - 1); mMiddleTarget = mTargets.get(mTargets.size() / 2); + mMiddleTarget.isMiddleTarget = true; } /** @@ -438,6 +439,8 @@ public class DividerSnapAlgorithm { public final int flag; + public boolean isMiddleTarget; + /** * Multiplier used to calculate distance to snap position. The lower this value, the harder * it's to snap on this target diff --git a/core/jni/Android.bp b/core/jni/Android.bp index c81a77d4c16e..c385ca11611c 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -41,7 +41,7 @@ cc_library_shared { "com_google_android_gles_jni_EGLImpl.cpp", "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm "android_app_Activity.cpp", - "android_app_ActivityThread.cpp", + "android_app_ActivityThread.cpp", "android_app_NativeActivity.cpp", "android_app_admin_SecurityLog.cpp", "android_opengl_EGL14.cpp", @@ -225,6 +225,7 @@ cc_library_shared { ], static_libs: [ + "libasync_safe", "libgif", "libseccomp_policy", "libgrallocusage", @@ -278,8 +279,8 @@ cc_library_shared { "libsoundtrigger", "libminikin", "libprocessgroup", - "libnativebridge", - "libnativeloader", + "libnativebridge_lazy", + "libnativeloader_lazy", "libmemunreachable", "libhidlbase", "libhidltransport", diff --git a/core/jni/OWNERS b/core/jni/OWNERS index 774c2242e144..7ff15f2e182d 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -6,4 +6,4 @@ per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhij per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com # Zygote -per-file com_android_inernal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com +per-file com_android_internal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 3012c906df7b..bc1332adacbc 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -25,6 +25,8 @@ #define LOG_TAG "Zygote" +#include <async_safe/log.h> + // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc #include <sys/mount.h> #include <linux/fs.h> @@ -296,27 +298,23 @@ static void SigChldHandler(int /*signal_number*/) { int saved_errno = errno; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - // Log process-death status that we care about. In general it is - // not safe to call LOG(...) from a signal handler because of - // possible reentrancy. However, we know a priori that the - // current implementation of LOG() is safe to call from a SIGCHLD - // handler in the zygote process. If the LOG() implementation - // changes its locking strategy or its use of syscalls within the - // lazy-init critical section, its use here may become unsafe. + // Log process-death status that we care about. if (WIFEXITED(status)) { - ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status)); + async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG, + "Process %d exited cleanly (%d)", pid, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { - ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status)); - if (WCOREDUMP(status)) { - ALOGI("Process %d dumped core.", pid); - } + async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG, + "Process %d exited due to signal %d (%s)%s", pid, + WTERMSIG(status), strsignal(WTERMSIG(status)), + WCOREDUMP(status) ? "; core dumped" : ""); } // If the just-crashed process is the system_server, bring down zygote // so that it is restarted by init and system server will be restarted // from there. if (pid == gSystemServerPid) { - ALOGE("Exit zygote because system server (%d) has terminated", pid); + async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, + "Exit zygote because system server (pid %d) has terminated", pid); kill(getpid(), SIGKILL); } @@ -329,14 +327,17 @@ static void SigChldHandler(int /*signal_number*/) { // Note that we shouldn't consider ECHILD an error because // the secondary zygote might have no children left to wait for. if (pid < 0 && errno != ECHILD) { - ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, + "Zygote SIGCHLD error in waitpid: %s", strerror(errno)); } if (blastulas_removed > 0) { if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) { // If this write fails something went terribly wrong. We will now kill // the zygote and let the system bring it back up. - ALOGE("Zygote failed to write to blastula pool event FD: %s", strerror(errno)); + async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, + "Zygote failed to write to blastula pool event FD: %s", + strerror(errno)); kill(getpid(), SIGKILL); } } @@ -1115,8 +1116,8 @@ static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gi RuntimeAbort(env, __LINE__, "Bad gids array"); } - for (int gid_index = gids_num; --gids_num >= 0;) { - if (native_gid_proxy[gid_index] == AID_WAKELOCK) { + for (int gids_index = 0; gids_index < gids_num; ++gids_index) { + if (native_gid_proxy[gids_index] == AID_WAKELOCK) { gid_wakelock_found = true; break; } diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp new file mode 100644 index 000000000000..c0ac2cb8f800 --- /dev/null +++ b/core/proto/android/server/connectivity/Android.bp @@ -0,0 +1,25 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +java_library_static { + name: "datastallprotosnano", + proto: { + type: "nano", + }, + srcs: [ + "data_stall_event.proto", + ], + sdk_version: "system_current", + no_framework_libs: true, +}
\ No newline at end of file diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java index ea0347d67ad7..f1d5600b9650 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -181,8 +181,7 @@ public class UriTest extends TestCase { uri = Uri.parse("http://bob%40lee%3ajr@local%68ost:4%32"); assertEquals("bob@lee:jr", uri.getUserInfo()); - assertEquals("localhost", uri.getHost()); - assertEquals(42, uri.getPort()); + assertEquals("localhost:42", uri.getHost()); uri = Uri.parse("http://localhost"); assertEquals("localhost", uri.getHost()); diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 212c7235f27b..94ba172fc676 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -505,7 +505,9 @@ public class SettingsBackupTest { Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION, Settings.Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED, Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS, - Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS); + Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, + Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT, + Settings.Global.MODEM_STACK_ENABLED_FOR_SLOT); private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS = newHashSet( Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 9a148e4e7b79..78bbcf137f2a 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -158,6 +158,7 @@ applications that come with the platform <permission name="android.permission.WRITE_APN_SETTINGS"/> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/> + <permission name="android.permission.READ_PRECISE_PHONE_STATE"/> <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/> <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/> </privapp-permissions> @@ -199,23 +200,16 @@ applications that come with the platform <permission name="android.permission.USE_RESERVED_DISK"/> </privapp-permissions> - <privapp-permissions package="com.android.mainline.networkstack"> + <privapp-permissions package="com.android.networkstack"> <permission name="android.permission.ACCESS_NETWORK_CONDITIONS"/> - <permission name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"/> <permission name="android.permission.CONNECTIVITY_INTERNAL"/> <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/> <permission name="android.permission.CONTROL_VPN"/> + <permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.LOCAL_MAC_ADDRESS"/> - <permission name="android.permission.MANAGE_IPSEC_TUNNELS"/> - <permission name="android.permission.MANAGE_NETWORK_POLICY"/> <permission name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/> <permission name="android.permission.MANAGE_USB"/> - <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/> - <permission name="android.permission.NETWORK_SETTINGS"/> - <permission name="android.permission.NETWORK_STACK" /> - <permission name="android.permission.NET_TUNNELING"/> <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/> - <permission name="android.permission.PEERS_MAC_ADDRESS"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> <permission name="android.permission.READ_PRECISE_PHONE_STATE"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> @@ -253,6 +247,7 @@ applications that come with the platform <permission name="android.permission.CHANGE_LOWPAN_STATE"/> <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/> <permission name="android.permission.CLEAR_APP_CACHE"/> + <permission name="android.permission.ACCESS_INSTANT_APPS" /> <permission name="android.permission.CONNECTIVITY_INTERNAL"/> <permission name="android.permission.DELETE_CACHE_FILES"/> <permission name="android.permission.DELETE_PACKAGES"/> diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index aa2917484a05..3dc884eb38ad 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -17,7 +17,6 @@ package android.security.keystore; import android.security.Credentials; -import android.security.GateKeeper; import android.security.KeyStore; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; @@ -204,7 +203,12 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } } - + if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_3DES) { + if (mKeySizeBits != 168) { + throw new InvalidAlgorithmParameterException( + "3DES key size must be 168 bits."); + } + } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (mKeySizeBits < 64) { throw new InvalidAlgorithmParameterException( diff --git a/libs/hwui/FrameMetricsObserver.h b/libs/hwui/FrameMetricsObserver.h index ba72e937095f..0b9ae5cb4b7b 100644 --- a/libs/hwui/FrameMetricsObserver.h +++ b/libs/hwui/FrameMetricsObserver.h @@ -23,7 +23,7 @@ namespace uirenderer { class FrameMetricsObserver : public VirtualLightRefBase { public: - virtual void notify(const int64_t* buffer); + virtual void notify(const int64_t* buffer) = 0; }; }; // namespace uirenderer diff --git a/media/OWNERS b/media/OWNERS index 03b751c07c6c..eb26367d3d29 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -11,3 +11,6 @@ lajos@google.com marcone@google.com sungsoo@google.com wjia@google.com + +# For maintaining sync with AndroidX code +per-file ExifInterface.java = jinpark@google.com, sungsoo@google.com diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java index ad25a06fabe2..5f324f7f97ed 100644 --- a/media/java/android/media/MediaHTTPConnection.java +++ b/media/java/android/media/MediaHTTPConnection.java @@ -16,6 +16,8 @@ package android.media; +import static android.media.MediaPlayer.MEDIA_ERROR_UNSUPPORTED; + import android.annotation.UnsupportedAppUsage; import android.net.NetworkUtils; import android.os.IBinder; @@ -23,21 +25,19 @@ import android.os.StrictMode; import android.util.Log; import java.io.BufferedInputStream; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.net.CookieHandler; -import java.net.CookieManager; -import java.net.Proxy; -import java.net.URL; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.NoRouteToHostException; import java.net.ProtocolException; +import java.net.Proxy; +import java.net.URL; import java.net.UnknownServiceException; import java.util.HashMap; import java.util.Map; - -import static android.media.MediaPlayer.MEDIA_ERROR_UNSUPPORTED; +import java.util.concurrent.atomic.AtomicBoolean; /** @hide */ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @@ -67,6 +67,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { // from com.squareup.okhttp.internal.http private final static int HTTP_TEMP_REDIRECT = 307; private final static int MAX_REDIRECTS = 20; + private AtomicBoolean mIsConnected = new AtomicBoolean(false); @UnsupportedAppUsage public MediaHTTPConnection() { @@ -90,6 +91,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { mAllowCrossDomainRedirect = true; mURL = new URL(uri); mHeaders = convertHeaderStringToMap(headers); + mIsConnected.set(true); } catch (MalformedURLException e) { return null; } @@ -140,7 +142,14 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage public void disconnect() { - teardownConnection(); + if (mIsConnected.getAndSet(false)) { + (new Thread() { + @Override + public void run() { + teardownConnection(); + } + }).start(); + } mHeaders = null; mURL = null; } @@ -325,7 +334,14 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage public int readAt(long offset, int size) { - return native_readAt(offset, size); + if (!mIsConnected.get()) { + return -1; + } + int result = native_readAt(offset, size); + if (!mIsConnected.get()) { + return -1; + } + return result; } private int readAt(long offset, byte[] data, int size) { diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp index 4ac652acb18f..9c31b4d4374f 100644 --- a/packages/CaptivePortalLogin/Android.bp +++ b/packages/CaptivePortalLogin/Android.bp @@ -18,7 +18,7 @@ android_app { name: "CaptivePortalLogin", srcs: ["src/**/*.java"], sdk_version: "system_current", - certificate: "platform", + certificate: "networkstack", static_libs: [ "android-support-v4", "metrics-constants-protos", diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml index e15dca046006..0894ee576a2d 100644 --- a/packages/CaptivePortalLogin/AndroidManifest.xml +++ b/packages/CaptivePortalLogin/AndroidManifest.xml @@ -23,8 +23,8 @@ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> <uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" /> + <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" /> <application android:label="@string/app_name" android:usesCleartextTraffic="true" diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 9b70ff368afb..2c9b6eb72b4d 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -174,6 +174,7 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); webSettings.setDisplayZoomControls(false); + webSettings.setDomStorageEnabled(true); mWebViewClient = new MyWebViewClient(); webview.setWebViewClient(mWebViewClient); webview.setWebChromeClient(new MyWebChromeClient()); diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java index 4f67350b5adc..31549fa0d1bb 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java @@ -106,6 +106,7 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setLoadWithOverviewMode(true); webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); + webSettings.setDomStorageEnabled(true); mWebViewClient = new MyWebViewClient(); mWebView.setWebViewClient(mWebViewClient); mWebView.setWebChromeClient(new MyWebChromeClient()); diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp index d6565936c860..b700bf324817 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -35,11 +35,12 @@ java_library { android_app { name: "NetworkStack", sdk_version: "system_current", - certificate: "platform", + certificate: "networkstack", privileged: true, static_libs: [ "NetworkStackLib" ], + jarjar_rules: "jarjar-rules-shared.txt", manifest: "AndroidManifest.xml", required: ["NetworkStackPermissionStub"], }
\ No newline at end of file diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index ac55bfa1aed7..52c209e5f247 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -17,20 +17,19 @@ */ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.mainline.networkstack" + package="com.android.networkstack" android:sharedUserId="android.uid.networkstack"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> - <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> <!-- Signature permission defined in NetworkStackStub --> <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" /> - <!-- Launch captive portal app as specific user --> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> - <uses-permission android:name="android.permission.NETWORK_STACK" /> + <!-- Send latency broadcast as current user --> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> <application android:label="NetworkStack" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/NetworkStack/jarjar-rules-shared.txt b/packages/NetworkStack/jarjar-rules-shared.txt new file mode 100644 index 000000000000..a8c712a3336d --- /dev/null +++ b/packages/NetworkStack/jarjar-rules-shared.txt @@ -0,0 +1,19 @@ +rule com.android.internal.util.** android.net.networkstack.util.@1 + +rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1 +rule android.net.shared.InetAddressUtils* android.net.networkstack.shared.InetAddressUtils@1 + +# Ignore DhcpResultsParcelable, but jarjar DhcpResults +# TODO: move DhcpResults into services.net and delete from here +rule android.net.DhcpResultsParcelable* @0 +rule android.net.DhcpResults* android.net.networkstack.DhcpResults@1 +rule android.net.LocalLog* android.net.networkstack.LocalLog@1 + +# TODO: remove from framework dependencies, then remove here +rule android.net.InterfaceConfigurationParcel* android.net.networkstack.InterfaceConfigurationParcel@1 +rule android.net.TetherStatsParcel* android.net.networkstack.TetherStatsParcel@1 + +# Used by UidRange, which is used by framework classes such as NetworkCapabilities. +rule android.net.UidRangeParcel* android.net.networkstack.UidRangeParcel@1 +# TODO: move TcpKeepalivePacketData to services.net and delete +rule android.net.TcpKeepalivePacketDataParcelable* android.net.networkstack.TcpKeepalivePacketDataParcelable@1
\ No newline at end of file diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java index 96d1a287ef09..97d26c7c9c1f 100644 --- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java +++ b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java @@ -18,7 +18,7 @@ package android.net.dhcp; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.shared.FdEventsReader; +import android.net.util.FdEventsReader; import android.os.Handler; import android.system.Os; diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java index 9e5991298834..b1f6d246563e 100644 --- a/packages/NetworkStack/src/android/net/ip/IpClient.java +++ b/packages/NetworkStack/src/android/net/ip/IpClient.java @@ -46,6 +46,7 @@ import android.net.shared.ProvisioningConfiguration; import android.net.util.InterfaceParams; import android.net.util.SharedLog; import android.os.ConditionVariable; +import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; @@ -380,6 +381,13 @@ public class IpClient extends StateMachine { public InterfaceParams getInterfaceParams(String ifname) { return InterfaceParams.getByName(ifname); } + + /** + * Get a INetd connector. + */ + public INetd getNetd(Context context) { + return INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)); + } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, @@ -413,7 +421,7 @@ public class IpClient extends StateMachine { // TODO: Consider creating, constructing, and passing in some kind of // InterfaceController.Dependencies class. - mNetd = mContext.getSystemService(INetd.class); + mNetd = deps.getNetd(mContext); mInterfaceCtrl = new InterfaceController(mInterfaceName, mNetd, mLog); mLinkObserver = new IpClientLinkObserver( diff --git a/core/java/android/net/shared/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java index bffbfb115886..1380ea720d40 100644 --- a/core/java/android/net/shared/FdEventsReader.java +++ b/packages/NetworkStack/src/android/net/util/FdEventsReader.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package android.net.shared; +package android.net.util; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.util.SocketUtils; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; diff --git a/packages/NetworkStack/src/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java index 94b1e9f2e14e..4aec6b6753a6 100644 --- a/packages/NetworkStack/src/android/net/util/PacketReader.java +++ b/packages/NetworkStack/src/android/net/util/PacketReader.java @@ -18,7 +18,6 @@ package android.net.util; import static java.lang.Math.max; -import android.net.shared.FdEventsReader; import android.os.Handler; import android.system.Os; diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java index cedcb84e9d08..90db207c9902 100644 --- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java +++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java @@ -114,7 +114,8 @@ public class NetworkStackService extends Service { NetworkStackConnector(Context context) { mContext = context; - mNetd = (INetd) context.getSystemService(Context.NETD_SERVICE); + mNetd = INetd.Stub.asInterface( + (IBinder) context.getSystemService(Context.NETD_SERVICE)); mObserverRegistry = new NetworkObserverRegistry(); mCm = context.getSystemService(ConnectivityManager.class); @@ -246,6 +247,12 @@ public class NetworkStackService extends Service { } @Override + public void notifyCaptivePortalAppFinished(int response) { + checkNetworkStackCallingPermission(); + mNm.notifyCaptivePortalAppFinished(response); + } + + @Override public void forceReevaluation(int uid) { checkNetworkStackCallingPermission(); mNm.forceReevaluation(uid); diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index 0d6d080b6dc2..ec4a47930fad 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -39,9 +39,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.net.CaptivePortal; import android.net.ConnectivityManager; -import android.net.ICaptivePortal; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; import android.net.LinkProperties; @@ -67,15 +65,9 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; -import android.telephony.CellIdentityCdma; -import android.telephony.CellIdentityGsm; -import android.telephony.CellIdentityLte; -import android.telephony.CellIdentityWcdma; -import android.telephony.CellInfo; -import android.telephony.CellInfoCdma; -import android.telephony.CellInfoGsm; -import android.telephony.CellInfoLte; -import android.telephony.CellInfoWcdma; +import android.telephony.AccessNetworkConstants; +import android.telephony.NetworkRegistrationState; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -466,6 +458,13 @@ public class NetworkMonitor extends StateMachine { sendMessage(CMD_LAUNCH_CAPTIVE_PORTAL_APP); } + /** + * Notify that the captive portal app was closed with the provided response code. + */ + public void notifyCaptivePortalAppFinished(int response) { + sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response); + } + @Override protected void log(String s) { if (DBG) Log.d(TAG + "/" + mNetwork.toString(), s); @@ -500,7 +499,7 @@ public class NetworkMonitor extends StateMachine { private void showProvisioningNotification(String action) { try { - mCallback.showProvisioningNotification(action); + mCallback.showProvisioningNotification(action, mContext.getPackageName()); } catch (RemoteException e) { Log.e(TAG, "Error showing provisioning notification", e); } @@ -677,29 +676,8 @@ public class NetworkMonitor extends StateMachine { case CMD_LAUNCH_CAPTIVE_PORTAL_APP: final Bundle appExtras = new Bundle(); // OneAddressPerFamilyNetwork is not parcelable across processes. - appExtras.putParcelable( - ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork)); - appExtras.putParcelable(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, - new CaptivePortal(new ICaptivePortal.Stub() { - @Override - public void appResponse(int response) { - if (response == APP_RETURN_WANTED_AS_IS) { - mContext.enforceCallingPermission( - PERMISSION_NETWORK_SETTINGS, - "CaptivePortal"); - } - sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response); - } - - @Override - public void logEvent(int eventId, String packageName) - throws RemoteException { - mContext.enforceCallingPermission( - PERMISSION_NETWORK_SETTINGS, - "CaptivePortal"); - mCallback.logCaptivePortalLoginEvent(eventId, packageName); - } - })); + final Network network = new Network(mNetwork); + appExtras.putParcelable(ConnectivityManager.EXTRA_NETWORK, network); final CaptivePortalProbeResult probeRes = mLastPortalProbeResult; appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl); if (probeRes.probeSpec != null) { @@ -708,7 +686,7 @@ public class NetworkMonitor extends StateMachine { } appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT, mCaptivePortalUserAgent); - mCm.startCaptivePortalApp(appExtras); + mCm.startCaptivePortalApp(network, appExtras); return HANDLED; default: return NOT_HANDLED; @@ -1312,6 +1290,7 @@ public class NetworkMonitor extends StateMachine { urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC); urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS); urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS); + urlConnection.setRequestProperty("Connection", "close"); urlConnection.setUseCaches(false); if (mCaptivePortalUserAgent != null) { urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent); @@ -1485,10 +1464,6 @@ public class NetworkMonitor extends StateMachine { */ private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal, long requestTimestampMs, long responseTimestampMs) { - if (!mWifiManager.isScanAlwaysAvailable()) { - return; - } - if (!mSystemReady) { return; } @@ -1496,6 +1471,10 @@ public class NetworkMonitor extends StateMachine { Intent latencyBroadcast = new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED); if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) { + if (!mWifiManager.isScanAlwaysAvailable()) { + return; + } + WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo(); if (currentWifiInfo != null) { // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not @@ -1515,39 +1494,21 @@ public class NetworkMonitor extends StateMachine { } latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_WIFI); } else if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { + // TODO(b/123893112): Support multi-sim. latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType()); - List<CellInfo> info = mTelephonyManager.getAllCellInfo(); - if (info == null) return; - int numRegisteredCellInfo = 0; - for (CellInfo cellInfo : info) { - if (cellInfo.isRegistered()) { - numRegisteredCellInfo++; - if (numRegisteredCellInfo > 1) { - if (VDBG) { - logw("more than one registered CellInfo." - + " Can't tell which is active. Bailing."); - } - return; - } - if (cellInfo instanceof CellInfoCdma) { - CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoGsm) { - CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoLte) { - CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoWcdma) { - CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else { - if (VDBG) logw("Registered cellinfo is unrecognized"); - return; - } - } + final ServiceState dataSs = mTelephonyManager.getServiceState(); + if (dataSs == null) { + logw("failed to retrieve ServiceState"); + return; } + // See if the data sub is registered for PS services on cell. + final NetworkRegistrationState nrs = dataSs.getNetworkRegistrationState( + NetworkRegistrationState.DOMAIN_PS, + AccessNetworkConstants.TransportType.WWAN); + latencyBroadcast.putExtra( + NetworkMonitorUtils.EXTRA_CELL_ID, + nrs == null ? null : nrs.getCellIdentity()); latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE); } else { return; diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp index 4a09b3e205a6..5c7b514834cb 100644 --- a/packages/NetworkStack/tests/Android.bp +++ b/packages/NetworkStack/tests/Android.bp @@ -18,6 +18,7 @@ android_test { name: "NetworkStackTests", certificate: "platform", srcs: ["src/**/*.java"], + test_suites: ["device-tests"], resource_dirs: ["res"], static_libs: [ "android-support-test", diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java index a4a100000d12..3414397d73c3 100644 --- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java +++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java @@ -22,6 +22,7 @@ import static android.system.OsConstants.ETH_P_ARP; import static android.system.OsConstants.ETH_P_IP; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; +import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.SOCK_STREAM; @@ -39,9 +40,7 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.net.LinkAddress; import android.net.LinkProperties; -import android.net.SocketKeepalive; -import android.net.TcpKeepalivePacketData; -import android.net.TcpKeepalivePacketData.TcpSocketInfo; +import android.net.TcpKeepalivePacketDataParcelable; import android.net.apf.ApfFilter.ApfConfiguration; import android.net.apf.ApfGenerator.IllegalInstructionException; import android.net.apf.ApfGenerator.Register; @@ -1017,6 +1016,7 @@ public class ApfTest { private static final int IPV4_TCP_SEQ_NUM_OFFSET = IPV4_TCP_HEADER_OFFSET + 4; private static final int IPV4_TCP_ACK_NUM_OFFSET = IPV4_TCP_HEADER_OFFSET + 8; private static final int IPV4_TCP_HEADER_LENGTH_OFFSET = IPV4_TCP_HEADER_OFFSET + 12; + private static final int IPV4_TCP_HEADER_FLAG_OFFSET = IPV4_TCP_HEADER_OFFSET + 13; private static final byte[] IPV4_BROADCAST_ADDRESS = {(byte) 255, (byte) 255, (byte) 255, (byte) 255}; @@ -1544,12 +1544,15 @@ public class ApfTest { InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR); InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR); - final TcpSocketInfo v4Tsi = new TcpSocketInfo( - srcAddr, srcPort, dstAddr, dstPort, seqNum, ackNum, window, windowScale); - final TcpKeepalivePacketData ipv4TcpKeepalivePacket = - TcpKeepalivePacketData.tcpKeepalivePacket(v4Tsi); + final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable(); + parcel.srcAddress = srcAddr.getAddress(); + parcel.srcPort = srcPort; + parcel.dstAddress = dstAddr.getAddress(); + parcel.dstPort = dstPort; + parcel.seq = seqNum; + parcel.ack = ackNum; - apfFilter.addKeepalivePacketFilter(slot1, ipv4TcpKeepalivePacket.toStableParcelable()); + apfFilter.addKeepalivePacketFilter(slot1, parcel); program = cb.getApfProgram(); // Verify IPv4 keepalive ack packet is dropped @@ -1568,7 +1571,7 @@ public class ApfTest { // Verify IPv4 packet from another address is passed assertPass(program, ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort, - anotherDstPort, anotherSeqNum, anotherAckNum)); + anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */)); // Remove IPv4 keepalive filter apfFilter.removeKeepalivePacketFilter(slot1); @@ -1578,11 +1581,17 @@ public class ApfTest { // dst: 2404:0:0:0:0:0:faf2, port: 54321 srcAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_SRC_ADDR); dstAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_DST_ADDR); - final TcpSocketInfo v6Tsi = new TcpSocketInfo( - srcAddr, srcPort, dstAddr, dstPort, seqNum, ackNum, window, windowScale); - final TcpKeepalivePacketData ipv6TcpKeepalivePacket = - TcpKeepalivePacketData.tcpKeepalivePacket(v6Tsi); - apfFilter.addKeepalivePacketFilter(slot1, ipv6TcpKeepalivePacket.toStableParcelable()); + + final TcpKeepalivePacketDataParcelable ipv6Parcel = + new TcpKeepalivePacketDataParcelable(); + ipv6Parcel.srcAddress = srcAddr.getAddress(); + ipv6Parcel.srcPort = srcPort; + ipv6Parcel.dstAddress = dstAddr.getAddress(); + ipv6Parcel.dstPort = dstPort; + ipv6Parcel.seq = seqNum; + ipv6Parcel.ack = ackNum; + + apfFilter.addKeepalivePacketFilter(slot1, ipv6Parcel); program = cb.getApfProgram(); // Verify IPv6 keepalive ack packet is dropped @@ -1604,8 +1613,8 @@ public class ApfTest { apfFilter.removeKeepalivePacketFilter(slot1); // Verify multiple filters - apfFilter.addKeepalivePacketFilter(slot1, ipv4TcpKeepalivePacket.toStableParcelable()); - apfFilter.addKeepalivePacketFilter(slot2, ipv6TcpKeepalivePacket.toStableParcelable()); + apfFilter.addKeepalivePacketFilter(slot1, parcel); + apfFilter.addKeepalivePacketFilter(slot2, ipv6Parcel); program = cb.getApfProgram(); // Verify IPv4 keepalive ack packet is dropped @@ -1613,15 +1622,15 @@ public class ApfTest { // dst: 10.0.0.5, port: 12345 assertDrop(program, ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR, - dstPort, srcPort, ackNum, seqNum + 1)); + dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */)); // Verify IPv4 non-keepalive ack packet from the same source address is passed assertPass(program, ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR, - dstPort, srcPort, ackNum + 100, seqNum)); + dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */)); // Verify IPv4 packet from another address is passed assertPass(program, ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort, - anotherDstPort, anotherSeqNum, anotherAckNum)); + anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */)); // Verify IPv6 keepalive ack packet is dropped // src: 2404:0:0:0:0:0:faf2, port: 54321 @@ -1641,7 +1650,7 @@ public class ApfTest { // Remove keepalive filters apfFilter.removeKeepalivePacketFilter(slot1); apfFilter.removeKeepalivePacketFilter(slot2); - } catch (SocketKeepalive.InvalidPacketException e) { + } catch (UnsupportedOperationException e) { // TODO: support V6 packets } @@ -1650,13 +1659,13 @@ public class ApfTest { // Verify IPv4, IPv6 packets are passed assertPass(program, ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR, - dstPort, srcPort, ackNum, seqNum + 1)); + dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */)); assertPass(program, ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR, dstPort, srcPort, ackNum, seqNum + 1)); assertPass(program, ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, srcPort, - dstPort, anotherSeqNum, anotherAckNum)); + dstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */)); assertPass(program, ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, srcPort, dstPort, anotherSeqNum, anotherAckNum)); @@ -1664,28 +1673,30 @@ public class ApfTest { apfFilter.shutdown(); } - private static byte[] ipv4Packet(byte[] sip, byte[] tip, int sport, - int dport, int seq, int ack) { - ByteBuffer packet = ByteBuffer.wrap(new byte[100]); + private static byte[] ipv4Packet(byte[] sip, byte[] dip, int sport, + int dport, int seq, int ack, int dataLength) { + final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN; + + ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]); + + // ether type packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP); + + // IPv4 header packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45); + packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength); + packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_TCP); put(packet, IPV4_SRC_ADDR_OFFSET, sip); - put(packet, IPV4_DEST_ADDR_OFFSET, tip); + put(packet, IPV4_DEST_ADDR_OFFSET, dip); packet.putShort(IPV4_TCP_SRC_PORT_OFFSET, (short) sport); packet.putShort(IPV4_TCP_DEST_PORT_OFFSET, (short) dport); packet.putInt(IPV4_TCP_SEQ_NUM_OFFSET, seq); packet.putInt(IPV4_TCP_ACK_NUM_OFFSET, ack); - return packet.array(); - } - private static byte[] ipv4Packet(byte[] sip, byte[] tip, int sport, - int dport, int seq, int ack, int dataLength) { - final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN; - - ByteBuffer packet = ByteBuffer.wrap(ipv4Packet(sip, tip, sport, dport, seq, ack)); - packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength); - // TCP header length 5, reserved 3 bits, NS=0 + // TCP header length 5(20 bytes), reserved 3 bits, NS=0 packet.put(IPV4_TCP_HEADER_LENGTH_OFFSET, (byte) 0x50); + // TCP flags: ACK set + packet.put(IPV4_TCP_HEADER_FLAG_OFFSET, (byte) 0x10); return packet.array(); } diff --git a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java index 7e57d1eb00b0..aaaff0279fed 100644 --- a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java +++ b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java @@ -104,8 +104,8 @@ public class IpClientTest { when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm); when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm); - when(mContext.getSystemService(INetd.class)).thenReturn(mNetd); when(mContext.getResources()).thenReturn(mResources); + when(mDependencies.getNetd(any())).thenReturn(mNetd); when(mResources.getInteger(R.integer.config_networkAvoidBadWifi)) .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE); 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 d11bb64213c3..9a16bb77182e 100644 --- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java @@ -16,8 +16,7 @@ package com.android.server.connectivity; -import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; -import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL; +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; @@ -41,8 +40,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.content.Intent; -import android.net.CaptivePortal; import android.net.ConnectivityManager; import android.net.INetworkMonitorCallbacks; import android.net.InetAddresses; @@ -54,10 +51,10 @@ import android.net.captiveportal.CaptivePortalProbeResult; import android.net.metrics.IpConnectivityLog; import android.net.util.SharedLog; import android.net.wifi.WifiManager; +import android.os.Bundle; import android.os.ConditionVariable; import android.os.Handler; import android.os.SystemClock; -import android.os.UserHandle; import android.provider.Settings; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -482,24 +479,28 @@ public class NetworkMonitorTest { nm.notifyNetworkConnected(); verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) - .showProvisioningNotification(any()); + .showProvisioningNotification(any(), any()); // Check that startCaptivePortalApp sends the expected intent. nm.launchCaptivePortalApp(); - final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mContext, timeout(HANDLER_TIMEOUT_MS).times(1)) - .startActivityAsUser(intentCaptor.capture(), eq(UserHandle.CURRENT)); - final Intent intent = intentCaptor.getValue(); - assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, intent.getAction()); - final Network network = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK); - assertEquals(TEST_NETID, network.netId); + final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); + final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class); + verify(mCm, timeout(HANDLER_TIMEOUT_MS).times(1)) + .startCaptivePortalApp(networkCaptor.capture(), bundleCaptor.capture()); + final Bundle bundle = bundleCaptor.getValue(); + final Network bundleNetwork = bundle.getParcelable(ConnectivityManager.EXTRA_NETWORK); + assertEquals(TEST_NETID, bundleNetwork.netId); + // network is passed both in bundle and as parameter, as the bundle is opaque to the + // framework and only intended for the captive portal app, but the framework needs + // the network to identify the right NetworkMonitor. + assertEquals(TEST_NETID, networkCaptor.getValue().netId); // Have the app report that the captive portal is dismissed, and check that we revalidate. setStatus(mHttpsConnection, 204); setStatus(mHttpConnection, 204); - final CaptivePortal captivePortal = intent.getParcelableExtra(EXTRA_CAPTIVE_PORTAL); - captivePortal.reportCaptivePortalDismissed(); + + nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED); verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null); } diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkStackPermissionStub/Android.bp index 94870c919dfa..dd70cf56b51b 100644 --- a/packages/NetworkStackPermissionStub/Android.bp +++ b/packages/NetworkStackPermissionStub/Android.bp @@ -21,7 +21,7 @@ android_app { // a classes.dex. srcs: ["src/**/*.java"], platform_apis: true, - certificate: "platform", + certificate: "networkstack", privileged: true, manifest: "AndroidManifest.xml", } diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkStackPermissionStub/AndroidManifest.xml index 2ccf5ff1a01a..a8742d7ab34f 100644 --- a/packages/NetworkStackPermissionStub/AndroidManifest.xml +++ b/packages/NetworkStackPermissionStub/AndroidManifest.xml @@ -17,7 +17,8 @@ */ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.mainline.networkstack.permissionstub"> + package="com.android.networkstack.permissionstub" + android:sharedUserId="android.uid.networkstack"> <!-- This package only exists to define the below permissions, and enforce that they are only granted to apps sharing the same signature. diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 9f3401ea7463..6cd2f45213e3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -16,6 +16,7 @@ package com.android.settingslib.bluetooth; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; @@ -28,7 +29,7 @@ import android.os.ParcelUuid; import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; -import android.bluetooth.BluetoothAdapter; + import androidx.annotation.VisibleForTesting; import com.android.settingslib.R; @@ -205,7 +206,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // This is to ensure all the profiles are disconnected as some CK/Hs do not // disconnect PBAP connection when HF connection is brought down PbapServerProfile PbapProfile = mProfileManager.getPbapProfile(); - if (PbapProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED) + if (PbapProfile != null && isConnectedProfile(PbapProfile)) { PbapProfile.disconnect(mDevice); } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 9306219415cd..b277666411f9 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -78,6 +78,7 @@ <uses-permission android:name="android.permission.MOVE_PACKAGE" /> <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" /> <uses-permission android:name="android.permission.CLEAR_APP_CACHE" /> + <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" /> <uses-permission android:name="android.permission.DELETE_CACHE_FILES" /> <uses-permission android:name="android.permission.DELETE_PACKAGES" /> <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 5b3164e3c1fd..7d0291f643cf 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -78,6 +78,7 @@ android_app { static_libs: [ "SystemUI-core", ], + resource_dirs: [], platform_apis: true, product_specific: true, diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 98925b9ba9e5..1feef8763dfe 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -464,6 +464,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mSnapAlgorithm == null) { mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth, mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide); + if (mSnapTargetBeforeMinimized != null && mSnapTargetBeforeMinimized.isMiddleTarget) { + mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget(); + } } if (mMinimizedSnapAlgorithm == null) { mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), diff --git a/sax/tests/saxtests/Android.bp b/sax/tests/saxtests/Android.bp new file mode 100644 index 000000000000..5889f769a645 --- /dev/null +++ b/sax/tests/saxtests/Android.bp @@ -0,0 +1,11 @@ +android_test { + name: "FrameworksSaxTests", + // Include all test java files. + srcs: ["src/**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + static_libs: ["junit"], + platform_apis: true, +} diff --git a/sax/tests/saxtests/Android.mk b/sax/tests/saxtests/Android.mk deleted file mode 100644 index c4517a9a954a..000000000000 --- a/sax/tests/saxtests/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -# Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base -LOCAL_STATIC_JAVA_LIBRARIES := junit -LOCAL_PACKAGE_NAME := FrameworksSaxTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_PACKAGE) - diff --git a/services/accessibility/OWNERS b/services/accessibility/OWNERS new file mode 100644 index 000000000000..265674a74b7e --- /dev/null +++ b/services/accessibility/OWNERS @@ -0,0 +1,3 @@ +svetoslavganov@google.com +pweaver@google.com +rhedjao@google.com diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f2d4ae24c047..b5fcde4bf203 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -38,7 +38,6 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkPolicyManager.RULE_NONE; import static android.net.NetworkPolicyManager.uidRulesToString; -import static android.net.NetworkStack.NETWORKSTACK_PACKAGE_NAME; import static android.net.shared.NetworkMonitorUtils.isValidationRequired; import static android.net.shared.NetworkParcelableUtil.toStableParcelable; import static android.os.Process.INVALID_UID; @@ -58,8 +57,10 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.database.ContentObserver; +import android.net.CaptivePortal; import android.net.ConnectionInfo; import android.net.ConnectivityManager; +import android.net.ICaptivePortal; import android.net.IConnectivityManager; import android.net.IIpConnectivityMetrics; import android.net.INetd; @@ -86,6 +87,7 @@ import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.NetworkWatchlistManager; @@ -917,7 +919,8 @@ public class ConnectivityService extends IConnectivityManager.Stub mPermissionMonitor = new PermissionMonitor(mContext, mNMS); - //set up the listener for user state for creating user VPNs + // Set up the listener for user state for creating user VPNs. + // Should run on mHandler to avoid any races. IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_STARTED); intentFilter.addAction(Intent.ACTION_USER_STOPPED); @@ -925,7 +928,11 @@ public class ConnectivityService extends IConnectivityManager.Stub intentFilter.addAction(Intent.ACTION_USER_REMOVED); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); mContext.registerReceiverAsUser( - mIntentReceiver, UserHandle.ALL, intentFilter, null, null); + mIntentReceiver, + UserHandle.ALL, + intentFilter, + null /* broadcastPermission */, + mHandler); mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM, new IntentFilter(Intent.ACTION_USER_PRESENT), null, null); @@ -936,7 +943,11 @@ public class ConnectivityService extends IConnectivityManager.Stub intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiverAsUser( - mIntentReceiver, UserHandle.ALL, intentFilter, null, null); + mIntentReceiver, + UserHandle.ALL, + intentFilter, + null /* broadcastPermission */, + mHandler); try { mNMS.registerObserver(mTethering); @@ -2666,9 +2677,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - public void showProvisioningNotification(String action) { + public void showProvisioningNotification(String action, String packageName) { final Intent intent = new Intent(action); - intent.setPackage(NETWORKSTACK_PACKAGE_NAME); + intent.setPackage(packageName); final PendingIntent pendingIntent; // Only the system server can register notifications with package "android" @@ -2690,11 +2701,6 @@ public class ConnectivityService extends IConnectivityManager.Stub EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNai.network.netId)); } - - @Override - public void logCaptivePortalLoginEvent(int eventId, String packageName) { - new MetricsLogger().action(eventId, packageName); - } } private boolean networkRequiresValidation(NetworkAgentInfo nai) { @@ -2833,6 +2839,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) { log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); } + // Clear all notifications of this network. + mNotifier.clearNotification(nai.network.netId); // A network agent has disconnected. // TODO - if we move the logic to the network agent (have them disconnect // because they lost all their requests or because their score isn't good) @@ -3238,22 +3246,63 @@ public class ConnectivityService extends IConnectivityManager.Stub /** * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself. + * @param network Network on which the captive portal was detected. * @param appExtras Bundle to use as intent extras for the captive portal application. * Must be treated as opaque to avoid preventing the captive portal app to * update its arguments. */ @Override - public void startCaptivePortalAppInternal(Bundle appExtras) { + public void startCaptivePortalAppInternal(Network network, Bundle appExtras) { mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); appIntent.putExtras(appExtras); + appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL, + new CaptivePortal(new CaptivePortalImpl(network).asBinder())); appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); Binder.withCleanCallingIdentity(() -> mContext.startActivityAsUser(appIntent, UserHandle.CURRENT)); } + private class CaptivePortalImpl extends ICaptivePortal.Stub { + private final Network mNetwork; + + private CaptivePortalImpl(Network network) { + mNetwork = network; + } + + @Override + public void appResponse(final int response) throws RemoteException { + if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) { + enforceSettingsPermission(); + } + + // getNetworkAgentInfoForNetwork is thread-safe + final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork); + if (nai == null) return; + + // nai.networkMonitor() is thread-safe + final INetworkMonitor nm = nai.networkMonitor(); + if (nm == null) return; + + final long token = Binder.clearCallingIdentity(); + try { + nm.notifyCaptivePortalAppFinished(response); + } finally { + // Not using Binder.withCleanCallingIdentity() to keep the checked RemoteException + Binder.restoreCallingIdentity(token); + } + } + + @Override + public void logEvent(int eventId, String packageName) { + enforceSettingsPermission(); + + new MetricsLogger().action(eventId, packageName); + } + } + public boolean avoidBadWifi() { return mMultinetworkPolicyTracker.getAvoidBadWifi(); } @@ -4088,17 +4137,27 @@ public class ConnectivityService extends IConnectivityManager.Stub * handler thread through their agent, this is asynchronous. When the capabilities objects * are computed they will be up-to-date as they are computed synchronously from here and * this is running on the ConnectivityService thread. - * TODO : Fix this and call updateCapabilities inline to remove out-of-order events. */ private void updateAllVpnsCapabilities() { + Network defaultNetwork = getNetwork(getDefaultNetwork()); synchronized (mVpns) { for (int i = 0; i < mVpns.size(); i++) { final Vpn vpn = mVpns.valueAt(i); - vpn.updateCapabilities(); + NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); + updateVpnCapabilities(vpn, nc); } } } + private void updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc) { + ensureRunningOnConnectivityServiceThread(); + NetworkAgentInfo vpnNai = getNetworkAgentInfoForNetId(vpn.getNetId()); + if (vpnNai == null || nc == null) { + return; + } + updateCapabilities(vpnNai.getCurrentScore(), vpnNai, nc); + } + @Override public boolean updateLockdownVpn() { if (Binder.getCallingUid() != Process.SYSTEM_UID) { @@ -4439,22 +4498,28 @@ public class ConnectivityService extends IConnectivityManager.Stub private void onUserAdded(int userId) { mPermissionMonitor.onUserAdded(userId); + Network defaultNetwork = getNetwork(getDefaultNetwork()); synchronized (mVpns) { final int vpnsSize = mVpns.size(); for (int i = 0; i < vpnsSize; i++) { Vpn vpn = mVpns.valueAt(i); vpn.onUserAdded(userId); + NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); + updateVpnCapabilities(vpn, nc); } } } private void onUserRemoved(int userId) { mPermissionMonitor.onUserRemoved(userId); + Network defaultNetwork = getNetwork(getDefaultNetwork()); synchronized (mVpns) { final int vpnsSize = mVpns.size(); for (int i = 0; i < vpnsSize; i++) { Vpn vpn = mVpns.valueAt(i); vpn.onUserRemoved(userId); + NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); + updateVpnCapabilities(vpn, nc); } } } @@ -4523,6 +4588,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + ensureRunningOnConnectivityServiceThread(); final String action = intent.getAction(); final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); @@ -5027,6 +5093,19 @@ public class ConnectivityService extends IConnectivityManager.Stub return getNetworkForRequest(mDefaultRequest.requestId); } + @Nullable + private Network getNetwork(@Nullable NetworkAgentInfo nai) { + return nai != null ? nai.network : null; + } + + private void ensureRunningOnConnectivityServiceThread() { + if (mHandler.getLooper().getThread() != Thread.currentThread()) { + throw new IllegalStateException( + "Not running on ConnectivityService thread: " + + Thread.currentThread().getName()); + } + } + private boolean isDefaultNetwork(NetworkAgentInfo nai) { return nai == getDefaultNetwork(); } @@ -5056,7 +5135,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("registerNetworkAgent " + nai); final long token = Binder.clearCallingIdentity(); try { - mContext.getSystemService(NetworkStack.class).makeNetworkMonitor( + getNetworkStack().makeNetworkMonitor( toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai)); } finally { Binder.restoreCallingIdentity(token); @@ -5068,6 +5147,11 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai.network.netId; } + @VisibleForTesting + protected NetworkStackClient getNetworkStack() { + return NetworkStackClient.getInstance(); + } + private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { nai.onNetworkMonitorCreated(networkMonitor); if (VDBG) log("Got NetworkAgent Messenger"); @@ -5620,6 +5704,8 @@ public class ConnectivityService extends IConnectivityManager.Stub updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes()); mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); notifyIfacesChangedForNetworkStats(); + // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks. + updateAllVpnsCapabilities(); } private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) { @@ -6059,6 +6145,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // doing. updateSignalStrengthThresholds(networkAgent, "CONNECT", null); + if (networkAgent.isVPN()) { + updateAllVpnsCapabilities(); + } + // Consider network even though it is not yet validated. final long now = SystemClock.elapsedRealtime(); rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now); @@ -6320,7 +6410,11 @@ public class ConnectivityService extends IConnectivityManager.Stub success = mVpns.get(user).setUnderlyingNetworks(networks); } if (success) { - mHandler.post(() -> notifyIfacesChangedForNetworkStats()); + mHandler.post(() -> { + // Update VPN's capabilities based on updated underlying network set. + updateAllVpnsCapabilities(); + notifyIfacesChangedForNetworkStats(); + }); } return success; } diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index da4df22d7b02..a4fda8e9f57b 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -20,18 +20,18 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.SHUTDOWN; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_BLACKLIST; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_NONE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; +import static android.net.INetd.FIREWALL_WHITELIST; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; -import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST; -import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.STATS_PER_UID; import static android.net.NetworkStats.TAG_ALL; @@ -1941,7 +1941,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub int numUids = 0; if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName); - if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { + if (getFirewallType(chain) == FIREWALL_WHITELIST) { // Close all sockets on all non-system UIDs... ranges = new UidRange[] { // TODO: is there a better way of finding all existing users? If so, we could @@ -1953,7 +1953,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub final SparseIntArray rules = getUidFirewallRulesLR(chain); exemptUids = new int[rules.size()]; for (int i = 0; i < exemptUids.length; i++) { - if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { + if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) { exemptUids[numUids] = rules.keyAt(i); numUids++; } @@ -1975,7 +1975,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub final SparseIntArray rules = getUidFirewallRulesLR(chain); ranges = new UidRange[rules.size()]; for (int i = 0; i < ranges.length; i++) { - if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_DENY) { + if (rules.valueAt(i) == FIREWALL_RULE_DENY) { int uid = rules.keyAt(i); ranges[numUids] = new UidRange(uid, uid); numUids++; @@ -2047,13 +2047,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub private int getFirewallType(int chain) { switch (chain) { case FIREWALL_CHAIN_STANDBY: - return FIREWALL_TYPE_BLACKLIST; + return FIREWALL_BLACKLIST; case FIREWALL_CHAIN_DOZABLE: - return FIREWALL_TYPE_WHITELIST; + return FIREWALL_WHITELIST; case FIREWALL_CHAIN_POWERSAVE: - return FIREWALL_TYPE_WHITELIST; + return FIREWALL_WHITELIST; default: - return isFirewallEnabled() ? FIREWALL_TYPE_WHITELIST : FIREWALL_TYPE_BLACKLIST; + return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST; } } @@ -2155,14 +2155,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub private @NonNull String getFirewallRuleName(int chain, int rule) { String ruleName; - if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { - if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { + if (getFirewallType(chain) == FIREWALL_WHITELIST) { + if (rule == FIREWALL_RULE_ALLOW) { ruleName = "allow"; } else { ruleName = "deny"; } } else { // Blacklist mode - if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) { + if (rule == FIREWALL_RULE_DENY) { ruleName = "deny"; } else { ruleName = "allow"; @@ -2188,7 +2188,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub private int getFirewallRuleType(int chain, int rule) { if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { - return getFirewallType(chain) == FIREWALL_TYPE_WHITELIST + return getFirewallType(chain) == FIREWALL_WHITELIST ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW; } return rule; diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 43af36f86f3d..3b5c9f53d9a1 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -246,7 +247,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private PreciseDataConnectionState mPreciseDataConnectionState = new PreciseDataConnectionState(); - static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = + // Nothing here yet, but putting it here in case we want to add more in the future. + static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0; + + static final int ENFORCE_FINE_LOCATION_PERMISSION_MASK = PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_CELL_INFO; @@ -637,8 +641,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { try { if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); - r.callback.onServiceStateChanged( - new ServiceState(mServiceState[phoneId])); + ServiceState rawSs = new ServiceState(mServiceState[phoneId]); + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged(rawSs); + } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(false)); + } else { + r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(true)); + } } catch (RemoteException ex) { remove(r.binder); } @@ -673,7 +683,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellLocationChanged( new Bundle(mCellLocation[phoneId])); } @@ -722,7 +732,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " + mCellInfo.get(phoneId)); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } } catch (RemoteException ex) { @@ -1009,13 +1019,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && idMatch(r.subId, subId, phoneId)) { + try { + ServiceState stateToSend; + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + stateToSend = new ServiceState(state); + } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { + stateToSend = state.sanitizeLocationInfo(false); + } else { + stateToSend = state.sanitizeLocationInfo(true); + } if (DBG) { log("notifyServiceStateForSubscriber: callback.onSSC r=" + r + " subId=" + subId + " phoneId=" + phoneId + " state=" + state); } - r.callback.onServiceStateChanged(new ServiceState(state)); + r.callback.onServiceStateChanged(stateToSend); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -1198,7 +1217,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { try { if (DBG_LOC) { log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); @@ -1500,7 +1519,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { try { if (DBG_LOC) { log("notifyCellLocation: cellLocation=" + cellLocation @@ -2109,12 +2128,35 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private boolean checkListenerPermission( int events, int subId, String callingPackage, String message) { + LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(callingPackage) + .setMethod(message + " events: " + events) + .setCallingPid(Binder.getCallingPid()) + .setCallingUid(Binder.getCallingUid()); + + boolean shouldCheckLocationPermissions = false; if ((events & ENFORCE_COARSE_LOCATION_PERMISSION_MASK) != 0) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.ACCESS_COARSE_LOCATION, null); - if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { - return false; + locationQueryBuilder.setMinSdkVersionForCoarse(0); + shouldCheckLocationPermissions = true; + } + + if ((events & ENFORCE_FINE_LOCATION_PERMISSION_MASK) != 0) { + // Everything that requires fine location started in Q. So far... + locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q); + shouldCheckLocationPermissions = true; + } + + if (shouldCheckLocationPermissions) { + LocationAccessPolicy.LocationPermissionResult result = + LocationAccessPolicy.checkLocationPermission( + mContext, locationQueryBuilder.build()); + switch (result) { + case DENIED_HARD: + throw new SecurityException("Unable to listen for events " + events + " due to " + + "insufficient location permissions."); + case DENIED_SOFT: + return false; } } @@ -2229,15 +2271,38 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private boolean checkLocationAccess(Record r) { - long token = Binder.clearCallingIdentity(); - try { - return LocationAccessPolicy.canAccessCellLocation(mContext, - r.callingPackage, r.callerUid, r.callerPid, - /*throwOnDeniedPermission*/ false); - } finally { - Binder.restoreCallingIdentity(token); - } + private boolean checkFineLocationAccess(Record r, int minSdk) { + LocationAccessPolicy.LocationPermissionQuery query = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(r.callingPackage) + .setCallingPid(r.callerPid) + .setCallingUid(r.callerUid) + .setMethod("TelephonyRegistry push") + .setMinSdkVersionForFine(minSdk) + .build(); + + return Binder.withCleanCallingIdentity(() -> { + LocationAccessPolicy.LocationPermissionResult locationResult = + LocationAccessPolicy.checkLocationPermission(mContext, query); + return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; + }); + } + + private boolean checkCoarseLocationAccess(Record r, int minSdk) { + LocationAccessPolicy.LocationPermissionQuery query = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(r.callingPackage) + .setCallingPid(r.callerPid) + .setCallingUid(r.callerUid) + .setMethod("TelephonyRegistry push") + .setMinSdkVersionForCoarse(minSdk) + .build(); + + return Binder.withCleanCallingIdentity(() -> { + LocationAccessPolicy.LocationPermissionResult locationResult = + LocationAccessPolicy.checkLocationPermission(mContext, query); + return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; + }); } private void checkPossibleMissNotify(Record r, int phoneId) { @@ -2287,7 +2352,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " + mCellInfo.get(phoneId)); } - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } } catch (RemoteException ex) { @@ -2337,7 +2402,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); } } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 8e80c744b75b..06d1ca632363 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -365,6 +365,7 @@ import android.provider.Downloads; import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; +import android.sysprop.DisplayProperties; import android.sysprop.VoldProperties; import android.telecom.TelecomManager; import android.text.TextUtils; @@ -7435,6 +7436,7 @@ public class ActivityManagerService extends IActivityManager.Stub // next app record if we are emulating process with anonymous threads. ProcessRecord app; long startTime = SystemClock.uptimeMillis(); + long bindApplicationTimeMillis; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); @@ -7665,6 +7667,7 @@ public class ActivityManagerService extends IActivityManager.Stub } checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); + bindApplicationTimeMillis = SystemClock.elapsedRealtime(); mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app); if (app.isolatedEntryPoint != null) { // This is an isolated process which should just call an entry point instead of @@ -7783,6 +7786,18 @@ public class ActivityManagerService extends IActivityManager.Stub checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked"); } + StatsLog.write( + StatsLog.PROCESS_START_TIME, + app.info.uid, + app.pid, + app.info.packageName, + StatsLog.PROCESS_START_TIME__TYPE__COLD, + app.startTime, + (int) (bindApplicationTimeMillis - app.startTime), + (int) (SystemClock.elapsedRealtime() - app.startTime), + app.hostingType, + (app.hostingNameStr != null ? app.hostingNameStr : "")); + return true; } @@ -14937,8 +14952,8 @@ public class ActivityManagerService extends IActivityManager.Stub mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY); mHiddenApiBlacklist.registerObserver(); - // Transfer any global setting for forcing RTL layout, into a System Property - SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); + // Transfer any global setting for forcing RTL layout, into a Display Property + DisplayProperties.debug_force_rtl(forceRtl); final Configuration configuration = new Configuration(); Settings.System.getConfiguration(resolver, configuration); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 455a3e302480..e698b841a2fd 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3260,6 +3260,21 @@ public class AudioService extends IAudioService.Stub if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { return; } + + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_PHONE_STATE) + != PackageManager.PERMISSION_GRANTED) { + synchronized (mSetModeDeathHandlers) { + for (SetModeDeathHandler h : mSetModeDeathHandlers) { + if (h.getMode() == AudioSystem.MODE_IN_CALL) { + Log.w(TAG, "getMode is call, Permission Denial: setSpeakerphoneOn from pid=" + + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); + return; + } + } + } + } + // for logging only final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) .append(") from u/pid:").append(Binder.getCallingUid()).append("/") diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index a14fd17209e8..c91e1a12078e 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -96,6 +96,7 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; @@ -180,6 +181,7 @@ public class Tethering extends BaseNetworkObserver { // into a single coherent structure. private final HashSet<IpServer> mForwardedDownstreams; private final VersionedBroadcastListener mCarrierConfigChange; + private final VersionedBroadcastListener mDefaultSubscriptionChange; private final TetheringDependencies mDeps; private final EntitlementManager mEntitlementMgr; @@ -232,6 +234,15 @@ public class Tethering extends BaseNetworkObserver { mEntitlementMgr.reevaluateSimCardProvisioning(); }); + filter = new IntentFilter(); + filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); + mDefaultSubscriptionChange = new VersionedBroadcastListener( + "DefaultSubscriptionChangeListener", mContext, smHandler, filter, + (Intent ignored) -> { + mLog.log("OBSERVED default data subscription change"); + updateConfiguration(); + mEntitlementMgr.reevaluateSimCardProvisioning(); + }); mStateReceiver = new StateReceiver(); // Load tethering configuration. @@ -242,6 +253,7 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters() { mCarrierConfigChange.startListening(); + mDefaultSubscriptionChange.startListening(); final Handler handler = mTetherMasterSM.getHandler(); IntentFilter filter = new IntentFilter(); @@ -270,7 +282,8 @@ public class Tethering extends BaseNetworkObserver { // NOTE: This is always invoked on the mLooper thread. private void updateConfiguration() { - mConfig = new TetheringConfiguration(mContext, mLog); + final int subId = mDeps.getDefaultDataSubscriptionId(); + mConfig = new TetheringConfiguration(mContext, mLog, subId); mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); mEntitlementMgr.updateConfiguration(mConfig); } @@ -1846,7 +1859,7 @@ public class Tethering extends BaseNetworkObserver { final TetherState tetherState = new TetherState( new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService, makeControlCallback(), mConfig.enableLegacyDhcpServer, - mDeps.getIpServerDependencies(mContext))); + mDeps.getIpServerDependencies())); mTetherStates.put(iface, tetherState); tetherState.ipServer.start(); } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 9141ccb387bd..a7d16d8cd6ec 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -240,7 +240,7 @@ public class Vpn { mNetworkCapabilities = new NetworkCapabilities(); mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN); mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); - updateCapabilities(); + updateCapabilities(null /* defaultNetwork */); loadAlwaysOnPackage(); } @@ -267,22 +267,44 @@ public class Vpn { updateAlwaysOnNotification(detailedState); } - public void updateCapabilities() { - final Network[] underlyingNetworks = (mConfig != null) ? mConfig.underlyingNetworks : null; - // Only apps targeting Q and above can explicitly declare themselves as metered. - final boolean isAlwaysMetered = - mIsPackageTargetingAtLeastQ && (mConfig == null || mConfig.isMetered); - updateCapabilities(mContext.getSystemService(ConnectivityManager.class), underlyingNetworks, - mNetworkCapabilities, isAlwaysMetered); + /** + * Updates {@link #mNetworkCapabilities} based on current underlying networks and returns a + * defensive copy. + * + * <p>Does not propagate updated capabilities to apps. + * + * @param defaultNetwork underlying network for VPNs following platform's default + */ + public synchronized NetworkCapabilities updateCapabilities( + @Nullable Network defaultNetwork) { + if (mConfig == null) { + // VPN is not running. + return null; + } - if (mNetworkAgent != null) { - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); + Network[] underlyingNetworks = mConfig.underlyingNetworks; + if (underlyingNetworks == null && defaultNetwork != null) { + // null underlying networks means to track the default. + underlyingNetworks = new Network[] { defaultNetwork }; } + // Only apps targeting Q and above can explicitly declare themselves as metered. + final boolean isAlwaysMetered = mIsPackageTargetingAtLeastQ && mConfig.isMetered; + + applyUnderlyingCapabilities( + mContext.getSystemService(ConnectivityManager.class), + underlyingNetworks, + mNetworkCapabilities, + isAlwaysMetered); + + return new NetworkCapabilities(mNetworkCapabilities); } @VisibleForTesting - public static void updateCapabilities(ConnectivityManager cm, Network[] underlyingNetworks, - NetworkCapabilities caps, boolean isAlwaysMetered) { + public static void applyUnderlyingCapabilities( + ConnectivityManager cm, + Network[] underlyingNetworks, + NetworkCapabilities caps, + boolean isAlwaysMetered) { int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN }; int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; @@ -295,6 +317,7 @@ public class Vpn { boolean hadUnderlyingNetworks = false; if (null != underlyingNetworks) { for (Network underlying : underlyingNetworks) { + // TODO(b/124469351): Get capabilities directly from ConnectivityService instead. final NetworkCapabilities underlyingCaps = cm.getNetworkCapabilities(underlying); if (underlyingCaps == null) continue; hadUnderlyingNetworks = true; @@ -1005,9 +1028,8 @@ public class Vpn { } /** - * Establish a VPN network and return the file descriptor of the VPN - * interface. This methods returns {@code null} if the application is - * revoked or not prepared. + * Establish a VPN network and return the file descriptor of the VPN interface. This methods + * returns {@code null} if the application is revoked or not prepared. * * @param config The parameters to configure the network. * @return The file descriptor of the VPN interface. @@ -1099,8 +1121,6 @@ public class Vpn { // as rules are deleted. This prevents data leakage as the rules are moved over. agentDisconnect(oldNetworkAgent); } - // Set up VPN's capabilities such as meteredness. - updateCapabilities(); if (oldConnection != null) { mContext.unbindService(oldConnection); @@ -1256,6 +1276,11 @@ public class Vpn { return ranges; } + /** + * Updates UID ranges for this VPN and also updates its internal capabilities. + * + * <p>Should be called on primary ConnectivityService thread. + */ public void onUserAdded(int userHandle) { // If the user is restricted tie them to the parent user's VPN UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); @@ -1266,8 +1291,9 @@ public class Vpn { try { addUserToRanges(existingRanges, userHandle, mConfig.allowedApplications, mConfig.disallowedApplications); + // ConnectivityService will call {@link #updateCapabilities} and apply + // those for VPN network. mNetworkCapabilities.setUids(existingRanges); - updateCapabilities(); } catch (Exception e) { Log.wtf(TAG, "Failed to add restricted user to owner", e); } @@ -1277,6 +1303,11 @@ public class Vpn { } } + /** + * Updates UID ranges for this VPN and also updates its capabilities. + * + * <p>Should be called on primary ConnectivityService thread. + */ public void onUserRemoved(int userHandle) { // clean up if restricted UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); @@ -1288,8 +1319,9 @@ public class Vpn { final List<UidRange> removedRanges = uidRangesForUser(userHandle, existingRanges); existingRanges.removeAll(removedRanges); + // ConnectivityService will call {@link #updateCapabilities} and + // apply those for VPN network. mNetworkCapabilities.setUids(existingRanges); - updateCapabilities(); } catch (Exception e) { Log.wtf(TAG, "Failed to remove restricted user to owner", e); } @@ -1502,6 +1534,12 @@ public class Vpn { return success; } + /** + * Updates underlying network set. + * + * <p>Note: Does not updates capabilities. Call {@link #updateCapabilities} from + * ConnectivityService thread to get updated capabilities. + */ public synchronized boolean setUnderlyingNetworks(Network[] networks) { if (!isCallerEstablishedOwnerLocked()) { return false; @@ -1518,7 +1556,6 @@ public class Vpn { } } } - updateCapabilities(); return true; } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java index 1e6bb04858a1..8a46ff18979f 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -26,8 +26,8 @@ import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static com.android.internal.R.array.config_mobile_hotspot_provision_app; import static com.android.internal.R.array.config_tether_bluetooth_regexs; import static com.android.internal.R.array.config_tether_dhcp_range; -import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_upstream_types; +import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.bool.config_tether_upstream_automatic; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; @@ -38,6 +38,7 @@ import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.util.SharedLog; import android.provider.Settings; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -100,29 +101,34 @@ public class TetheringConfiguration { public final String[] provisioningApp; public final String provisioningAppNoUi; - public TetheringConfiguration(Context ctx, SharedLog log) { + public final int subId; + + public TetheringConfiguration(Context ctx, SharedLog log, int id) { final SharedLog configLog = log.forSubComponent("config"); - tetherableUsbRegexs = getResourceStringArray(ctx, config_tether_usb_regexs); + subId = id; + Resources res = getResources(ctx, subId); + + tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs); // TODO: Evaluate deleting this altogether now that Wi-Fi always passes // us an interface name. Careful consideration needs to be given to // implications for Settings and for provisioning checks. - tetherableWifiRegexs = getResourceStringArray(ctx, config_tether_wifi_regexs); - tetherableBluetoothRegexs = getResourceStringArray(ctx, config_tether_bluetooth_regexs); + tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs); + tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); dunCheck = checkDunRequired(ctx); configLog.log("DUN check returned: " + dunCheckString(dunCheck)); - chooseUpstreamAutomatically = getResourceBoolean(ctx, config_tether_upstream_automatic); - preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck); + chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic); + preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, dunCheck); isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN); - legacyDhcpRanges = getLegacyDhcpRanges(ctx); + legacyDhcpRanges = getLegacyDhcpRanges(res); defaultIPv4DNS = copy(DEFAULT_IPV4_DNS); enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx); - provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app); - provisioningAppNoUi = getProvisioningAppNoUi(ctx); + provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); + provisioningAppNoUi = getProvisioningAppNoUi(res); configLog.log(toString()); } @@ -144,6 +150,9 @@ public class TetheringConfiguration { } public void dump(PrintWriter pw) { + pw.print("subId: "); + pw.println(subId); + dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs); dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs); dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs); @@ -169,6 +178,7 @@ public class TetheringConfiguration { public String toString() { final StringJoiner sj = new StringJoiner(" "); + sj.add(String.format("subId:%d", subId)); sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs))); sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs))); sj.add(String.format("tetherableBluetoothRegexs:%s", @@ -235,8 +245,8 @@ public class TetheringConfiguration { } } - private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) { - final int ifaceTypes[] = ctx.getResources().getIntArray(config_tether_upstream_types); + private static Collection<Integer> getUpstreamIfaceTypes(Resources res, int dunCheck) { + final int[] ifaceTypes = res.getIntArray(config_tether_upstream_types); final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length); for (int i : ifaceTypes) { switch (i) { @@ -286,33 +296,33 @@ public class TetheringConfiguration { return false; } - private static String[] getLegacyDhcpRanges(Context ctx) { - final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range); + private static String[] getLegacyDhcpRanges(Resources res) { + final String[] fromResource = getResourceStringArray(res, config_tether_dhcp_range); if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) { return fromResource; } return copy(LEGACY_DHCP_DEFAULT_RANGE); } - private static String getProvisioningAppNoUi(Context ctx) { + private static String getProvisioningAppNoUi(Resources res) { try { - return ctx.getResources().getString(config_mobile_hotspot_provision_app_no_ui); + return res.getString(config_mobile_hotspot_provision_app_no_ui); } catch (Resources.NotFoundException e) { return ""; } } - private static boolean getResourceBoolean(Context ctx, int resId) { + private static boolean getResourceBoolean(Resources res, int resId) { try { - return ctx.getResources().getBoolean(resId); + return res.getBoolean(resId); } catch (Resources.NotFoundException e404) { return false; } } - private static String[] getResourceStringArray(Context ctx, int resId) { + private static String[] getResourceStringArray(Resources res, int resId) { try { - final String[] strArray = ctx.getResources().getStringArray(resId); + final String[] strArray = res.getStringArray(resId); return (strArray != null) ? strArray : EMPTY_STRING_ARRAY; } catch (Resources.NotFoundException e404) { return EMPTY_STRING_ARRAY; @@ -325,6 +335,19 @@ public class TetheringConfiguration { return intVal != 0; } + private Resources getResources(Context ctx, int subId) { + if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return getResourcesForSubIdWrapper(ctx, subId); + } else { + return ctx.getResources(); + } + } + + @VisibleForTesting + protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { + return SubscriptionManager.getResourcesForSubId(ctx, subId); + } + private static String[] copy(String[] strarray) { return Arrays.copyOf(strarray, strarray.length); } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index 6d6f81eb98e6..173d7860e4ac 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -21,6 +21,7 @@ import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.os.Handler; +import android.telephony.SubscriptionManager; import com.android.internal.util.StateMachine; import com.android.server.connectivity.MockableSystemProperties; @@ -60,8 +61,8 @@ public class TetheringDependencies { /** * Get dependencies to be used by IpServer. */ - public IpServer.Dependencies getIpServerDependencies(Context context) { - return new IpServer.Dependencies(context); + public IpServer.Dependencies getIpServerDependencies() { + return new IpServer.Dependencies(); } /** @@ -85,4 +86,11 @@ public class TetheringDependencies { SharedLog log, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, systemProperties); } + + /** + * Get default data subscription id to build TetheringConfiguration. + */ + public int getDefaultDataSubscriptionId() { + return SubscriptionManager.getDefaultDataSubscriptionId(); + } } diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 9e5b92a6b944..3f15b381c18b 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -17,9 +17,6 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.provider.Settings.ACTION_VPN_SETTINGS; import android.app.Notification; @@ -30,17 +27,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; -import android.net.LinkProperties; import android.net.LinkAddress; +import android.net.LinkProperties; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; -import android.net.NetworkPolicyManager; import android.os.INetworkManagementService; -import android.os.RemoteException; import android.security.Credentials; import android.security.KeyStore; -import android.system.Os; import android.text.TextUtils; import android.util.Slog; diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index 31fdc01b8d4d..7cc357c3661c 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -15,15 +15,15 @@ */ package com.android.server.net; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import android.app.ActivityManager; import android.net.NetworkPolicyManager; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index e539ffd5a85f..863ef67d4f0f 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -38,6 +38,11 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -45,12 +50,7 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index f1b03d1fc9d6..81d6b63d9d85 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -344,6 +344,11 @@ public final class OverlayManagerService extends SystemService { private final class PackageReceiver extends BroadcastReceiver { @Override public void onReceive(@NonNull final Context context, @NonNull final Intent intent) { + final String action = intent.getAction(); + if (action == null) { + Slog.e(TAG, "Cannot handle package broadcast with null action"); + return; + } final Uri data = intent.getData(); if (data == null) { Slog.e(TAG, "Cannot handle package broadcast with null data"); @@ -361,7 +366,7 @@ public final class OverlayManagerService extends SystemService { userIds = new int[] { UserHandle.getUserId(extraUid) }; } - switch (intent.getAction()) { + switch (action) { case ACTION_PACKAGE_ADDED: if (replacing) { onPackageUpgraded(packageName, userIds); diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index 33b8641c145e..640b155e69d5 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -19,6 +19,9 @@ per-file BackgroundDexOptService.java = ngeoffray@google.com per-file CompilerStats.java = agampe@google.com per-file CompilerStats.java = calin@google.com per-file CompilerStats.java = ngeoffray@google.com +per-file DynamicCodeLoggingService.java = agampe@google.com +per-file DynamicCodeLoggingService.java = calin@google.com +per-file DynamicCodeLoggingService.java = ngeoffray@google.com per-file InstructionSets.java = agampe@google.com per-file InstructionSets.java = calin@google.com per-file InstructionSets.java = ngeoffray@google.com diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 2338fffbf26a..406822c774ca 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -37,6 +37,7 @@ import android.content.res.Resources.Theme; import android.database.sqlite.SQLiteCompatibilityWalFlags; import android.database.sqlite.SQLiteGlobal; import android.hardware.display.DisplayManagerInternal; +import android.net.NetworkStackClient; import android.os.BaseBundle; import android.os.Binder; import android.os.Build; @@ -1240,9 +1241,7 @@ public final class SystemServer { traceBeginAndSlog("StartNetworkStack"); try { - final android.net.NetworkStack networkStack = - context.getSystemService(android.net.NetworkStack.class); - networkStack.start(context); + NetworkStackClient.getInstance().start(context); } catch (Throwable e) { reportWtf("starting Network Stack", e); } diff --git a/services/net/Android.bp b/services/net/Android.bp index 638ec95ec544..8ad4d7679107 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -1,6 +1,10 @@ java_library_static { name: "services.net", srcs: ["java/**/*.java"], + static_libs: [ + "netd_aidl_interface-java", + "networkstack-aidl-interfaces-java", + ] } filegroup { diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java new file mode 100644 index 000000000000..1eb7b98d801a --- /dev/null +++ b/services/net/java/android/net/NetworkStackClient.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net; + +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.net.dhcp.DhcpServingParamsParcel; +import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; +import android.os.Binder; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** + * Service used to communicate with the network stack, which is running in a separate module. + * @hide + */ +public class NetworkStackClient { + private static final String TAG = NetworkStackClient.class.getSimpleName(); + + private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; + + private static NetworkStackClient sInstance; + + @NonNull + @GuardedBy("mPendingNetStackRequests") + private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>(); + @Nullable + @GuardedBy("mPendingNetStackRequests") + private INetworkStackConnector mConnector; + + private volatile boolean mNetworkStackStartRequested = false; + + private interface NetworkStackCallback { + void onNetworkStackConnected(INetworkStackConnector connector); + } + + private NetworkStackClient() { } + + /** + * Get the NetworkStackClient singleton instance. + */ + public static synchronized NetworkStackClient getInstance() { + if (sInstance == null) { + sInstance = new NetworkStackClient(); + } + return sInstance; + } + + /** + * Create a DHCP server according to the specified parameters. + * + * <p>The server will be returned asynchronously through the provided callbacks. + */ + public void makeDhcpServer(final String ifName, final DhcpServingParamsParcel params, + final IDhcpServerCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeDhcpServer(ifName, params, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + /** + * Create an IpClient on the specified interface. + * + * <p>The IpClient will be returned asynchronously through the provided callbacks. + */ + public void makeIpClient(String ifName, IIpClientCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeIpClient(ifName, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + /** + * Create a NetworkMonitor. + * + * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks. + */ + public void makeNetworkMonitor( + NetworkParcelable network, String name, INetworkMonitorCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeNetworkMonitor(network, name, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + + private class NetworkStackConnection implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + registerNetworkStackService(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // TODO: crash/reboot the system ? + Slog.wtf(TAG, "Lost network stack connector"); + } + }; + + private void registerNetworkStackService(@NonNull IBinder service) { + final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service); + + ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */, + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); + + final ArrayList<NetworkStackCallback> requests; + synchronized (mPendingNetStackRequests) { + requests = new ArrayList<>(mPendingNetStackRequests); + mPendingNetStackRequests.clear(); + mConnector = connector; + } + + for (NetworkStackCallback r : requests) { + r.onNetworkStackConnected(connector); + } + } + + /** + * Start the network stack. Should be called only once on device startup. + * + * <p>This method will start the network stack either in the network stack process, or inside + * the system server on devices that do not support the network stack module. The network stack + * connector will then be delivered asynchronously to clients that requested it before it was + * started. + */ + public void start(Context context) { + mNetworkStackStartRequested = true; + // Try to bind in-process if the library is available + IBinder connector = null; + try { + final Class service = Class.forName( + "com.android.server.NetworkStackService", + true /* initialize */, + context.getClassLoader()); + connector = (IBinder) service.getMethod("makeConnector", Context.class) + .invoke(null, context); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService"); + // TODO: crash/reboot system here ? + return; + } catch (ClassNotFoundException e) { + // Normal behavior if stack is provided by the app: fall through + } + + // In-process network stack. Add the service to the service manager here. + if (connector != null) { + registerNetworkStackService(connector); + return; + } + // Start the network stack process. The service will be added to the service manager in + // NetworkStackConnection.onServiceConnected(). + final Intent intent = new Intent(INetworkStackConnector.class.getName()); + final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); + intent.setComponent(comp); + + if (comp == null) { + Slog.wtf(TAG, "Could not resolve the network stack with " + intent); + // TODO: crash/reboot system server ? + return; + } + final PackageManager pm = context.getPackageManager(); + int uid = -1; + try { + uid = pm.getPackageUid(comp.getPackageName(), UserHandle.USER_SYSTEM); + } catch (PackageManager.NameNotFoundException e) { + Slog.wtf("Network stack package not found", e); + // Fall through + } + if (uid != Process.NETWORK_STACK_UID) { + throw new SecurityException("Invalid network stack UID: " + uid); + } + + final int hasPermission = + pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); + if (hasPermission != PERMISSION_GRANTED) { + throw new SecurityException( + "Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); + } + + if (!context.bindServiceAsUser(intent, new NetworkStackConnection(), + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { + Slog.wtf(TAG, + "Could not bind to network stack in-process, or in app with " + intent); + // TODO: crash/reboot system server if no network stack after a timeout ? + } + } + + /** + * For non-system server clients, get the connector registered by the system server. + */ + private INetworkStackConnector getRemoteConnector() { + // Block until the NetworkStack connector is registered in ServiceManager. + // <p>This is only useful for non-system processes that do not have a way to be notified of + // registration completion. Adding a callback system would be too heavy weight considering + // that the connector is registered on boot, so it is unlikely that a client would request + // it before it is registered. + // TODO: consider blocking boot on registration and simplify much of the logic in this class + IBinder connector; + try { + final long before = System.currentTimeMillis(); + while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) { + Thread.sleep(20); + if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { + Slog.e(TAG, "Timeout waiting for NetworkStack connector"); + return null; + } + } + } catch (InterruptedException e) { + Slog.e(TAG, "Error waiting for NetworkStack connector", e); + return null; + } + + return INetworkStackConnector.Stub.asInterface(connector); + } + + private void requestConnector(@NonNull NetworkStackCallback request) { + // TODO: PID check. + final int caller = Binder.getCallingUid(); + if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) { + // Don't even attempt to obtain the connector and give a nice error message + throw new SecurityException( + "Only the system server should try to bind to the network stack."); + } + + if (!mNetworkStackStartRequested) { + // The network stack is not being started in this process, e.g. this process is not + // the system server. Get a remote connector registered by the system server. + final INetworkStackConnector connector = getRemoteConnector(); + synchronized (mPendingNetStackRequests) { + mConnector = connector; + } + request.onNetworkStackConnected(connector); + return; + } + + final INetworkStackConnector connector; + synchronized (mPendingNetStackRequests) { + connector = mConnector; + if (connector == null) { + mPendingNetStackRequests.add(request); + return; + } + } + + request.onNetworkStackConnected(connector); + } +} diff --git a/core/java/android/net/dhcp/DhcpServerCallbacks.java b/services/net/java/android/net/dhcp/DhcpServerCallbacks.java index bb56876c77f5..bb56876c77f5 100644 --- a/core/java/android/net/dhcp/DhcpServerCallbacks.java +++ b/services/net/java/android/net/dhcp/DhcpServerCallbacks.java diff --git a/core/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java index db01ae4d4d9c..db01ae4d4d9c 100644 --- a/core/java/android/net/ip/IpClientCallbacks.java +++ b/services/net/java/android/net/ip/IpClientCallbacks.java diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index 2a2a67a92a86..bf917bf88b2d 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -23,8 +23,7 @@ import android.content.Context; import android.net.DhcpResultsParcelable; import android.net.LinkProperties; import android.net.LinkPropertiesParcelable; -import android.net.NetworkStack; -import android.net.ip.IIpClientCallbacks; +import android.net.NetworkStackClient; import android.os.ConditionVariable; import java.io.FileDescriptor; @@ -76,30 +75,17 @@ public class IpClientUtil { * * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of * {@link IIpClientCallbacks}. - * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} + * @see {@link NetworkStackClient#makeIpClient(String, IIpClientCallbacks)} */ public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { - context.getSystemService(NetworkStack.class) - .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); - } - - /** - * Create a new IpClient. - * - * <p>This is a convenience method to allow clients to use {@link IpClientCallbacksProxy} - * instead of {@link IIpClientCallbacks}. - * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} - */ - public static void makeIpClient( - Context context, String ifName, IpClientCallbacksProxy callback) { - context.getSystemService(NetworkStack.class) - .makeIpClient(ifName, callback); + // TODO: migrate clients and remove context argument + NetworkStackClient.getInstance().makeIpClient(ifName, new IpClientCallbacksProxy(callback)); } /** * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}. */ - public static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { + private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { protected final IpClientCallbacks mCb; /** diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java index 7910c9a69310..34fc7354d63e 100644 --- a/services/net/java/android/net/ip/IpServer.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -22,7 +22,6 @@ import static android.net.util.NetworkConstants.FF; import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.asByte; -import android.content.Context; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetworkStackStatusCallback; @@ -31,7 +30,7 @@ import android.net.InterfaceConfiguration; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; -import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.RouteInfo; import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; @@ -132,10 +131,6 @@ public class IpServer extends StateMachine { } public static class Dependencies { - private final Context mContext; - public Dependencies(Context context) { - mContext = context; - } public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { return new RouterAdvertisementDaemon(ifParams); } @@ -153,7 +148,7 @@ public class IpServer extends StateMachine { */ public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb) { - mContext.getSystemService(NetworkStack.class).makeDhcpServer(ifName, params, cb); + NetworkStackClient.getInstance().makeDhcpServer(ifName, params, cb); } } diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java index c9180a99c98d..a5ac20e951ec 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java @@ -16,12 +16,12 @@ package com.android.server; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import static android.util.DebugUtils.valueToString; import static org.junit.Assert.assertEquals; diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 7ea61e30dafe..da682c6df621 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -69,6 +69,7 @@ import android.os.storage.StorageVolume; import android.provider.Settings; import android.service.usb.UsbDeviceManagerProto; import android.service.usb.UsbHandlerProto; +import android.sysprop.AdbProperties; import android.sysprop.VoldProperties; import android.util.Pair; import android.util.Slog; @@ -285,7 +286,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver } mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); - boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false); + boolean secureAdbEnabled = AdbProperties.secure().orElse(false); boolean dataEncrypted = "1".equals(VoldProperties.decrypt().orElse("")); if (secureAdbEnabled && !dataEncrypted) { mDebuggingManager = new UsbDebuggingManager(context); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 268e70fe5d12..c60eb56005eb 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -289,6 +289,19 @@ public class TelecomManager { "android.telecom.extra.OUTGOING_CALL_EXTRAS"; /** + * An optional boolean extra on {@link android.content.Intent#ACTION_CALL_EMERGENCY} to tell + * whether the user's dial intent is emergency; this is required to specify when the dialed + * number is ambiguous, identified as both emergency number and any other non-emergency number; + * e.g. in some situation, 611 could be both an emergency number in a country and a + * non-emergency number of a carrier's customer service hotline. + * + * @hide + */ + @SystemApi + public static final String EXTRA_IS_USER_INTENT_EMERGENCY_CALL = + "android.telecom.extra.IS_USER_INTENT_EMERGENCY_CALL"; + + /** * @hide */ public static final String EXTRA_UNKNOWN_CALL_HANDLE = diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index ac34cea30f55..50b8f79892fd 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -2059,6 +2059,11 @@ public final class Telephony { * @hide - not meant for public use */ public interface RcsColumns { + // TODO(sahinc): Turn this to true once the schema finalizes, so that people can update + // their messaging databases. NOTE: move the switch/case update in MmsSmsDatabaseHelper to + // the latest version of the database before turning this flag to true. + boolean IS_RCS_TABLE_SCHEMA_CODE_COMPLETE = false; + /** * The authority for the content provider */ @@ -2653,6 +2658,41 @@ public final class Telephony { Uri RCS_EVENT_QUERY_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY, RCS_EVENT_QUERY_URI_PATH); } + + /** + * Allows RCS specific canonical address handling. + */ + interface RcsCanonicalAddressHelper { + /** + * Returns the canonical address ID for a canonical address, if now row exists, this + * will add a row and return its ID. This helper works against the same table used by + * the SMS and MMS threads, but is accessible only by the phone process for use by RCS + * message storage. + * + * @throws IllegalArgumentException if unable to retrieve or create the canonical + * address entry. + */ + static long getOrCreateCanonicalAddressId( + ContentResolver contentResolver, String canonicalAddress) { + + Uri.Builder uriBuilder = CONTENT_AND_AUTHORITY.buildUpon(); + uriBuilder.appendPath("canonical-address"); + uriBuilder.appendQueryParameter("address", canonicalAddress); + Uri uri = uriBuilder.build(); + + try (Cursor cursor = contentResolver.query(uri, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndex(CanonicalAddressesColumns._ID)); + } else { + Rlog.e(TAG, "getOrCreateCanonicalAddressId returned no rows"); + } + } + + Rlog.e(TAG, "getOrCreateCanonicalAddressId failed"); + throw new IllegalArgumentException( + "Unable to find or allocate a canonical address ID"); + } + } } /** diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 190e82b6cc5b..5c5d8569f3e8 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2371,6 +2371,14 @@ public class CarrierConfigManager { "support_emergency_dialer_shortcut_bool"; /** + * Support ASCII 7-BIT encoding for long SMS. This carrier config is used to enable + * this feature. + * @hide + */ + public static final String KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL = + "ascii_7_bit_support_for_long_message_bool"; + + /** * Controls RSRP threshold at which OpportunisticNetworkService will decide whether * the opportunistic network is good enough for internet data. */ @@ -2780,6 +2788,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CALL_WAITING_OVER_UT_WARNING_BOOL, false); sDefaults.putBoolean(KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_DIALER_SHORTCUT_BOOL, true); + sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */ diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java index 37847aef9167..d47b55ca4372 100644 --- a/telephony/java/android/telephony/CarrierRestrictionRules.java +++ b/telephony/java/android/telephony/CarrierRestrictionRules.java @@ -27,6 +27,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * Contains the list of carrier restrictions. @@ -93,6 +94,9 @@ public final class CarrierRestrictionRules implements Parcelable { value = {CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED, CARRIER_RESTRICTION_DEFAULT_ALLOWED}) public @interface CarrierRestrictionDefault {} + /* Wild character for comparison */ + private static final char WILD_CHARACTER = '?'; + private List<CarrierIdentifier> mAllowedCarriers; private List<CarrierIdentifier> mExcludedCarriers; @CarrierRestrictionDefault @@ -166,6 +170,124 @@ public final class CarrierRestrictionRules implements Parcelable { } /** + * Tests an array of carriers with the carrier restriction configuration. The list of carrier + * ids passed as argument does not need to be the same as currently present in the device. + * + * @param carrierIds list of {@link CarrierIdentifier}, one for each SIM slot on the device + * @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) { + ArrayList<Boolean> result = new ArrayList<>(carrierIds.size()); + + // First calculate the result for each slot independently + for (int i = 0; i < carrierIds.size(); i++) { + boolean inAllowedList = isCarrierIdInList(carrierIds.get(i), mAllowedCarriers); + boolean inExcludedList = isCarrierIdInList(carrierIds.get(i), mExcludedCarriers); + if (mCarrierRestrictionDefault == CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED) { + result.add((inAllowedList && !inExcludedList) ? true : false); + } else { + result.add((inExcludedList && !inAllowedList) ? false : true); + } + } + // Apply the multi-slot policy, if needed. + if (mMultiSimPolicy == MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT) { + for (boolean b : result) { + if (b) { + result.replaceAll(x -> true); + break; + } + } + } + return result; + } + + /** + * Indicates if a certain carrier {@code id} is present inside a {@code list} + * + * @return true if the carrier {@code id} is present, false otherwise + */ + private static boolean isCarrierIdInList(CarrierIdentifier id, List<CarrierIdentifier> list) { + for (CarrierIdentifier listItem : list) { + // Compare MCC and MNC + if (!patternMatch(id.getMcc(), listItem.getMcc()) + || !patternMatch(id.getMnc(), listItem.getMnc())) { + continue; + } + + // Compare SPN. Comparison is on the complete strings, case insensitive and with wild + // characters. + String listItemValue = convertNullToEmpty(listItem.getSpn()); + String idValue = convertNullToEmpty(id.getSpn()); + if (!listItemValue.isEmpty()) { + if (!patternMatch(idValue, listItemValue)) { + continue; + } + } + + // The IMSI of the configuration can be shorter than actual IMSI in the SIM card. + listItemValue = convertNullToEmpty(listItem.getImsi()); + idValue = convertNullToEmpty(id.getImsi()); + if (!patternMatch( + idValue.substring(0, Math.min(idValue.length(), listItemValue.length())), + listItemValue)) { + continue; + } + + // The GID1 of the configuration can be shorter than actual GID1 in the SIM card. + listItemValue = convertNullToEmpty(listItem.getGid1()); + idValue = convertNullToEmpty(id.getGid1()); + if (!patternMatch( + idValue.substring(0, Math.min(idValue.length(), listItemValue.length())), + listItemValue)) { + continue; + } + + // The GID2 of the configuration can be shorter than actual GID2 in the SIM card. + listItemValue = convertNullToEmpty(listItem.getGid2()); + idValue = convertNullToEmpty(id.getGid2()); + if (!patternMatch( + idValue.substring(0, Math.min(idValue.length(), listItemValue.length())), + listItemValue)) { + continue; + } + + // Valid match was found in the list + return true; + } + return false; + } + + private static String convertNullToEmpty(String value) { + return Objects.toString(value, ""); + } + + /** + * Performs a case insensitive string comparison against a given pattern. The character '?' + * is used in the pattern as wild character in the comparison. The string must have the same + * length as the pattern. + * + * @param str string to match + * @param pattern string containing the pattern + * @return true in case of match, false otherwise + */ + private static boolean patternMatch(String str, String pattern) { + if (str.length() != pattern.length()) { + return false; + } + String lowerCaseStr = str.toLowerCase(); + String lowerCasePattern = pattern.toLowerCase(); + + for (int i = 0; i < lowerCasePattern.length(); i++) { + if (lowerCasePattern.charAt(i) != lowerCaseStr.charAt(i) + && lowerCasePattern.charAt(i) != WILD_CHARACTER) { + return false; + } + } + return true; + } + + /** * {@link Parcelable#writeToParcel} */ @Override diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index 6b1b84cd3458..856f08107fd7 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -30,6 +30,7 @@ public final class CellIdentityNr extends CellIdentity { private final int mNrArfcn; private final int mPci; private final int mTac; + private final long mNci; /** * @@ -44,11 +45,12 @@ public final class CellIdentityNr extends CellIdentity { * @hide */ public CellIdentityNr(int pci, int tac, int nrArfcn, String mccStr, String mncStr, - String alphal, String alphas) { + long nci, String alphal, String alphas) { super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas); mPci = pci; mTac = tac; mNrArfcn = nrArfcn; + mNci = nci; } /** @@ -62,7 +64,7 @@ public final class CellIdentityNr extends CellIdentity { @Override public int hashCode() { - return Objects.hash(super.hashCode(), mPci, mTac, mNrArfcn); + return Objects.hash(super.hashCode(), mPci, mTac, mNrArfcn, mNci); } @Override @@ -72,7 +74,17 @@ public final class CellIdentityNr extends CellIdentity { } CellIdentityNr o = (CellIdentityNr) other; - return super.equals(o) && mPci == o.mPci && mTac == o.mTac && mNrArfcn == o.mNrArfcn; + return super.equals(o) && mPci == o.mPci && mTac == o.mTac && mNrArfcn == o.mNrArfcn + && mNci == o.mNci; + } + + /** + * Get the NR Cell Identity. + * + * @return The NR Cell Identity in range [0, 68719476735] or Long.MAX_VALUE if unknown. + */ + public long getNci() { + return mNci; } /** @@ -122,6 +134,7 @@ public final class CellIdentityNr extends CellIdentity { .append(" mNrArfcn = ").append(mNrArfcn) .append(" mMcc = ").append(mMccStr) .append(" mMnc = ").append(mMncStr) + .append(" mNci = ").append(mNci) .append(" mAlphaLong = ").append(mAlphaLong) .append(" mAlphaShort = ").append(mAlphaShort) .append(" }") @@ -134,6 +147,7 @@ public final class CellIdentityNr extends CellIdentity { dest.writeInt(mPci); dest.writeInt(mTac); dest.writeInt(mNrArfcn); + dest.writeLong(mNci); } /** Construct from Parcel, type has already been processed */ @@ -142,6 +156,7 @@ public final class CellIdentityNr extends CellIdentity { mPci = in.readInt(); mTac = in.readInt(); mNrArfcn = in.readInt(); + mNci = in.readLong(); } /** Implement the Parcelable interface */ diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 38143335dbf1..dba437a3a007 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -141,6 +141,14 @@ public final class CellIdentityTdscdma extends CellIdentity { return mCpid; } + /** + * @return 16-bit UMTS Absolute RF Channel Number, + * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. + */ + public int getUarfcn() { + return mUarfcn; + } + /** @hide */ @Override public int getChannelNumber() { diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index 53d69f447a56..24db438580c9 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -26,11 +26,12 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.location.LocationManager; import android.os.Binder; +import android.os.Build; import android.os.Process; -import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; +import android.widget.Toast; import java.util.List; @@ -41,61 +42,236 @@ import java.util.List; public final class LocationAccessPolicy { private static final String TAG = "LocationAccessPolicy"; private static final boolean DBG = false; + public static final int MAX_SDK_FOR_ANY_ENFORCEMENT = Build.VERSION_CODES.P; - /** - * API to determine if the caller has permissions to get cell location. - * - * @param pkgName Package name of the application requesting access - * @param uid The uid of the package - * @param pid The pid of the package - * @param throwOnDeniedPermission Whether to throw if the location permission is denied. - * @return boolean true or false if permissions is granted - */ - public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName, - int uid, int pid, boolean throwOnDeniedPermission) throws SecurityException { - Trace.beginSection("TelephonyLocationCheck"); - try { - // Always allow the phone process and system server to access location. This avoid - // breaking legacy code that rely on public-facing APIs to access cell location, and - // it doesn't create an info leak risk because the cell location is stored in the phone - // process anyway, and the system server already has location access. - if (uid == Process.PHONE_UID || uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) { - return true; + public enum LocationPermissionResult { + ALLOWED, + /** + * Indicates that the denial is due to a transient device state + * (e.g. app-ops, location master switch) + */ + DENIED_SOFT, + /** + * Indicates that the denial is due to a misconfigured app (e.g. missing entry in manifest) + */ + DENIED_HARD, + } + + public static class LocationPermissionQuery { + public final String callingPackage; + public final int callingUid; + public final int callingPid; + public final int minSdkVersionForCoarse; + public final int minSdkVersionForFine; + public final String method; + + private LocationPermissionQuery(String callingPackage, int callingUid, int callingPid, + int minSdkVersionForCoarse, int minSdkVersionForFine, String method) { + this.callingPackage = callingPackage; + this.callingUid = callingUid; + this.callingPid = callingPid; + this.minSdkVersionForCoarse = minSdkVersionForCoarse; + this.minSdkVersionForFine = minSdkVersionForFine; + this.method = method; + } + + public static class Builder { + private String mCallingPackage; + private int mCallingUid; + private int mCallingPid; + private int mMinSdkVersionForCoarse = Integer.MAX_VALUE; + private int mMinSdkVersionForFine = Integer.MAX_VALUE; + private String mMethod; + + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingPackage(String callingPackage) { + mCallingPackage = callingPackage; + return this; } - // We always require the location permission and also require the - // location mode to be on for non-legacy apps. Legacy apps are - // required to be in the foreground to at least mitigate the case - // where a legacy app the user is not using tracks their location. - // Granting ACCESS_FINE_LOCATION to an app automatically grants it - // ACCESS_COARSE_LOCATION. - if (throwOnDeniedPermission) { - context.enforcePermission(Manifest.permission.ACCESS_COARSE_LOCATION, - pid, uid, "canAccessCellLocation"); - } else if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, - pid, uid) == PackageManager.PERMISSION_DENIED) { - if (DBG) Log.w(TAG, "Permission checked failed (" + pid + "," + uid + ")"); - return false; + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingUid(int callingUid) { + mCallingUid = callingUid; + return this; } - final int opCode = AppOpsManager.permissionToOpCode( - Manifest.permission.ACCESS_COARSE_LOCATION); - if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class) - .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) { - if (DBG) Log.w(TAG, "AppOp check failed (" + uid + "," + pkgName + ")"); - return false; + + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingPid(int callingPid) { + mCallingPid = callingPid; + return this; } - if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) { - if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")"); - return false; + + /** + * Apps that target at least this sdk version will be checked for coarse location + * permission. Defaults to INT_MAX (which means don't check) + */ + public Builder setMinSdkVersionForCoarse( + int minSdkVersionForCoarse) { + mMinSdkVersionForCoarse = minSdkVersionForCoarse; + return this; } - // If the user or profile is current, permission is granted. - // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. - return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context); - } finally { - Trace.endSection(); + + /** + * Apps that target at least this sdk version will be checked for fine location + * permission. Defaults to INT_MAX (which means don't check) + */ + public Builder setMinSdkVersionForFine( + int minSdkVersionForFine) { + mMinSdkVersionForFine = minSdkVersionForFine; + return this; + } + + /** + * Optional, for logging purposes only. + */ + public Builder setMethod(String method) { + mMethod = method; + return this; + } + + public LocationPermissionQuery build() { + return new LocationPermissionQuery(mCallingPackage, mCallingUid, + mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine, mMethod); + } + } + } + + private static void logError(Context context, String errorMsg) { + Log.e(TAG, errorMsg); + try { + if (Build.IS_DEBUGGABLE) { + Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show(); + } + } catch (Throwable t) { + // whatever, not important + } + } + + private static LocationPermissionResult appOpsModeToPermissionResult(int appOpsMode) { + switch (appOpsMode) { + case AppOpsManager.MODE_ALLOWED: + return LocationPermissionResult.ALLOWED; + case AppOpsManager.MODE_ERRORED: + return LocationPermissionResult.DENIED_HARD; + default: + return LocationPermissionResult.DENIED_SOFT; } } + private static LocationPermissionResult checkAppLocationPermissionHelper(Context context, + LocationPermissionQuery query, String permissionToCheck) { + String locationTypeForLog = + Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck) + ? "fine" : "coarse"; + + // Do the app-ops and the manifest check without any of the allow-overrides first. + boolean hasManifestPermission = checkManifestPermission(context, query.callingPid, + query.callingUid, permissionToCheck); + + int appOpMode = context.getSystemService(AppOpsManager.class) + .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck), + query.callingUid, query.callingPackage); + + if (hasManifestPermission && appOpMode == AppOpsManager.MODE_ALLOWED) { + // If the app did everything right, return without logging. + return LocationPermissionResult.ALLOWED; + } + + // If the app has the manifest permission but not the app-op permission, it means that + // it's aware of the requirement and the user denied permission explicitly. If we see + // this, don't let any of the overrides happen. + if (hasManifestPermission) { + Log.i(TAG, query.callingPackage + " is aware of " + locationTypeForLog + " but the" + + " app-ops permission is specifically denied."); + return appOpsModeToPermissionResult(appOpMode); + } + + int minSdkVersion = Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck) + ? query.minSdkVersionForFine : query.minSdkVersionForCoarse; + + // If the app fails for some reason, see if it should be allowed to proceed. + if (minSdkVersion > MAX_SDK_FOR_ANY_ENFORCEMENT) { + String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog + + " because we're not enforcing API " + query.minSdkVersionForFine + " yet." + + " Please fix this app because it will break in the future. Called from " + + query.method; + logError(context, errorMsg); + return null; + } else if (!isAppAtLeastSdkVersion(context, query.callingPackage, minSdkVersion)) { + String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog + + " because it doesn't target API " + query.minSdkVersionForFine + " yet." + + " Please fix this app. Called from " + query.method; + logError(context, errorMsg); + return null; + } else { + // If we're not allowing it due to the above two conditions, this means that the app + // did not declare the permission in their manifest. + return LocationPermissionResult.DENIED_HARD; + } + } + + public static LocationPermissionResult checkLocationPermission( + Context context, LocationPermissionQuery query) { + // Always allow the phone process and system server to access location. This avoid + // breaking legacy code that rely on public-facing APIs to access cell location, and + // it doesn't create an info leak risk because the cell location is stored in the phone + // process anyway, and the system server already has location access. + if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID + || query.callingUid == Process.ROOT_UID) { + return LocationPermissionResult.ALLOWED; + } + + // Check the system-wide requirements. If the location master switch is off or + // the app's profile isn't in foreground, return a soft denial. + if (!checkSystemLocationAccess(context, query.callingUid, query.callingPid)) { + return LocationPermissionResult.DENIED_SOFT; + } + + // Do the check for fine, then for coarse. + if (query.minSdkVersionForFine < Integer.MAX_VALUE) { + LocationPermissionResult resultForFine = checkAppLocationPermissionHelper( + context, query, Manifest.permission.ACCESS_FINE_LOCATION); + if (resultForFine != null) { + return resultForFine; + } + } + + if (query.minSdkVersionForCoarse < Integer.MAX_VALUE) { + LocationPermissionResult resultForCoarse = checkAppLocationPermissionHelper( + context, query, Manifest.permission.ACCESS_COARSE_LOCATION); + if (resultForCoarse != null) { + return resultForCoarse; + } + } + + // At this point, we're out of location checks to do. If the app bypassed all the previous + // ones due to the SDK grandfathering schemes, allow it access. + return LocationPermissionResult.ALLOWED; + } + + + private static boolean checkManifestPermission(Context context, int pid, int uid, + String permissionToCheck) { + return context.checkPermission(permissionToCheck, pid, uid) + == PackageManager.PERMISSION_GRANTED; + } + + private static boolean checkSystemLocationAccess(@NonNull Context context, int uid, int pid) { + if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) { + if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")"); + return false; + } + // If the user or profile is current, permission is granted. + // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. + return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context, uid, pid); + } + private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) { LocationManager locationManager = context.getSystemService(LocationManager.class); if (locationManager == null) { @@ -105,10 +281,10 @@ public final class LocationAccessPolicy { return locationManager.isLocationEnabledForUser(UserHandle.of(userId)); } - private static boolean checkInteractAcrossUsersFull(@NonNull Context context) { - return context.checkCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) - == PackageManager.PERMISSION_GRANTED; + private static boolean checkInteractAcrossUsersFull( + @NonNull Context context, int pid, int uid) { + return checkManifestPermission(context, pid, uid, + Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private static boolean isCurrentProfile(@NonNull Context context, int uid) { @@ -132,4 +308,18 @@ public final class LocationAccessPolicy { Binder.restoreCallingIdentity(token); } } -} + + private static boolean isAppAtLeastSdkVersion(Context context, String pkgName, int sdkVersion) { + try { + if (context.getPackageManager().getApplicationInfo(pkgName, 0).targetSdkVersion + >= sdkVersion) { + return true; + } + } catch (PackageManager.NameNotFoundException e) { + // In case of exception, assume known app (more strict checking) + // Note: This case will never happen since checkPackage is + // called to verify validity before checking app's version. + } + return false; + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index ceb76b57ae0c..6e6d59e62148 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -27,6 +27,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Objects; +import java.util.stream.Collectors; /** * Description of a mobile network registration state @@ -151,7 +152,7 @@ public class NetworkRegistrationState implements Parcelable { private final int[] mAvailableServices; @Nullable - private final CellIdentity mCellIdentity; + private CellIdentity mCellIdentity; @Nullable private VoiceSpecificRegistrationStates mVoiceSpecificStates; @@ -360,7 +361,34 @@ public class NetworkRegistrationState implements Parcelable { return 0; } - private static String regStateToString(int regState) { + /** + * Convert service type to string + * + * @hide + * + * @param serviceType The service type + * @return The service type in string format + */ + public static String serviceTypeToString(@ServiceType int serviceType) { + switch (serviceType) { + case SERVICE_TYPE_VOICE: return "VOICE"; + case SERVICE_TYPE_DATA: return "DATA"; + case SERVICE_TYPE_SMS: return "SMS"; + case SERVICE_TYPE_VIDEO: return "VIDEO"; + case SERVICE_TYPE_EMERGENCY: return "EMERGENCY"; + } + return "Unknown service type " + serviceType; + } + + /** + * Convert registration state to string + * + * @hide + * + * @param regState The registration state + * @return The reg state in string + */ + public static String regStateToString(@RegState int regState) { switch (regState) { case REG_STATE_NOT_REG_NOT_SEARCHING: return "NOT_REG_NOT_SEARCHING"; case REG_STATE_HOME: return "HOME"; @@ -389,14 +417,17 @@ public class NetworkRegistrationState implements Parcelable { public String toString() { return new StringBuilder("NetworkRegistrationState{") .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS") - .append("transportType=").append(mTransportType) + .append(" transportType=").append(TransportType.toString(mTransportType)) .append(" regState=").append(regStateToString(mRegState)) - .append(" roamingType=").append(mRoamingType) + .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType)) .append(" accessNetworkTechnology=") .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) .append(" rejectCause=").append(mRejectCause) .append(" emergencyEnabled=").append(mEmergencyOnly) - .append(" supportedServices=").append(mAvailableServices) + .append(" availableServices=").append("[" + (mAvailableServices != null + ? Arrays.stream(mAvailableServices) + .mapToObj(type -> serviceTypeToString(type)) + .collect(Collectors.joining(",")) : null) + "]") .append(" cellIdentity=").append(mCellIdentity) .append(" voiceSpecificStates=").append(mVoiceSpecificStates) .append(" dataSpecificStates=").append(mDataSpecificStates) @@ -490,4 +521,22 @@ public class NetworkRegistrationState implements Parcelable { return new NetworkRegistrationState[size]; } }; + + /** + * @hide + */ + public NetworkRegistrationState sanitizeLocationInfo() { + NetworkRegistrationState result = copy(); + result.mCellIdentity = null; + return result; + } + + private NetworkRegistrationState copy() { + Parcel p = Parcel.obtain(); + this.writeToParcel(p, 0); + p.setDataPosition(0); + NetworkRegistrationState result = new NetworkRegistrationState(p); + p.recycle(); + return result; + } } diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java index 2ebfa53ead23..21dad77d29b7 100644 --- a/telephony/java/android/telephony/PhoneCapability.java +++ b/telephony/java/android/telephony/PhoneCapability.java @@ -33,15 +33,17 @@ public class PhoneCapability implements Parcelable { public final int maxActiveVoiceCalls; public final int maxActiveData; public final int max5G; + public final boolean validationBeforeSwitchSupported; public final List<ModemInfo> logicalModemList; public PhoneCapability(int maxActiveVoiceCalls, int maxActiveData, int max5G, - List<ModemInfo> logicalModemList) { + List<ModemInfo> logicalModemList, boolean validationBeforeSwitchSupported) { this.maxActiveVoiceCalls = maxActiveVoiceCalls; this.maxActiveData = maxActiveData; this.max5G = max5G; // Make sure it's not null. this.logicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList; + this.validationBeforeSwitchSupported = validationBeforeSwitchSupported; } @Override @@ -55,13 +57,15 @@ public class PhoneCapability implements Parcelable { maxActiveVoiceCalls = in.readInt(); maxActiveData = in.readInt(); max5G = in.readInt(); + validationBeforeSwitchSupported = in.readBoolean(); logicalModemList = new ArrayList<>(); in.readList(logicalModemList, ModemInfo.class.getClassLoader()); } @Override public int hashCode() { - return Objects.hash(maxActiveVoiceCalls, maxActiveData, max5G, logicalModemList); + return Objects.hash(maxActiveVoiceCalls, maxActiveData, max5G, logicalModemList, + validationBeforeSwitchSupported); } @Override @@ -79,6 +83,7 @@ public class PhoneCapability implements Parcelable { return (maxActiveVoiceCalls == s.maxActiveVoiceCalls && maxActiveData == s.maxActiveData && max5G == s.max5G + && validationBeforeSwitchSupported == s.validationBeforeSwitchSupported && logicalModemList.equals(s.logicalModemList)); } @@ -96,6 +101,7 @@ public class PhoneCapability implements Parcelable { dest.writeInt(maxActiveVoiceCalls); dest.writeInt(maxActiveData); dest.writeInt(max5G); + dest.writeBoolean(validationBeforeSwitchSupported); dest.writeList(logicalModemList); } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index fea1b7b08a20..3ce646cb400b 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -45,7 +45,8 @@ import java.util.concurrent.Executor; * <p> * Override the methods for the state that you wish to receive updates for, and * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ - * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. + * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are + * called when the state changes, as well as once on initial registration. * <p> * Note that access to some telephony information is * permission-protected. Your application won't receive updates for protected diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index 0d94c4dd3686..c1786befb096 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -17,12 +17,15 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.hardware.radio.V1_0.RadioTechnology; +import android.hardware.radio.V1_4.CellInfo.Info; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.telephony.RILConstants; + /** * Object to indicate the phone radio type and access technology. * @@ -33,32 +36,34 @@ public class RadioAccessFamily implements Parcelable { /** * TODO: get rid of RAF definition in RadioAccessFamily and * use {@link TelephonyManager.NetworkTypeBitMask} + * TODO: public definition {@link TelephonyManager.NetworkTypeBitMask} is long. + * TODO: Convert from int to long everywhere including HAL definitions. */ // 2G - public static final int RAF_UNKNOWN = TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN; - public static final int RAF_GSM = TelephonyManager.NETWORK_TYPE_BITMASK_GSM; - public static final int RAF_GPRS = TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; - public static final int RAF_EDGE = TelephonyManager.NETWORK_TYPE_BITMASK_EDGE; - public static final int RAF_IS95A = TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; - public static final int RAF_IS95B = TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; - public static final int RAF_1xRTT = TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT; + public static final int RAF_UNKNOWN = (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN; + public static final int RAF_GSM = (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM; + public static final int RAF_GPRS = (int) TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; + public static final int RAF_EDGE = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EDGE; + public static final int RAF_IS95A = (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; + public static final int RAF_IS95B = (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; + public static final int RAF_1xRTT = (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT; // 3G - public static final int RAF_EVDO_0 = TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0; - public static final int RAF_EVDO_A = TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A; - public static final int RAF_EVDO_B = TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B; - public static final int RAF_EHRPD = TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD; - public static final int RAF_HSUPA = TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA; - public static final int RAF_HSDPA = TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA; - public static final int RAF_HSPA = TelephonyManager.NETWORK_TYPE_BITMASK_HSPA; - public static final int RAF_HSPAP = TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP; - public static final int RAF_UMTS = TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; - public static final int RAF_TD_SCDMA = TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA; + public static final int RAF_EVDO_0 = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0; + public static final int RAF_EVDO_A = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A; + public static final int RAF_EVDO_B = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B; + public static final int RAF_EHRPD = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD; + public static final int RAF_HSUPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA; + public static final int RAF_HSDPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA; + public static final int RAF_HSPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPA; + public static final int RAF_HSPAP = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP; + public static final int RAF_UMTS = (int) TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; + public static final int RAF_TD_SCDMA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA; // 4G - public static final int RAF_LTE = TelephonyManager.NETWORK_TYPE_BITMASK_LTE; - public static final int RAF_LTE_CA = TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; + public static final int RAF_LTE = (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE; + public static final int RAF_LTE_CA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; // 5G - public static final int RAF_NR = TelephonyManager.NETWORK_TYPE_BITMASK_NR; + public static final int RAF_NR = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR; // Grouping of RAFs // 2G @@ -147,20 +152,20 @@ public class RadioAccessFamily implements Parcelable { /** * Implement the Parcelable interface. */ - public static final Creator<RadioAccessFamily> CREATOR = - new Creator<RadioAccessFamily>() { + public static final Creator<android.telephony.RadioAccessFamily> CREATOR = + new Creator<android.telephony.RadioAccessFamily>() { @Override - public RadioAccessFamily createFromParcel(Parcel in) { + public android.telephony.RadioAccessFamily createFromParcel(Parcel in) { int phoneId = in.readInt(); int radioAccessFamily = in.readInt(); - return new RadioAccessFamily(phoneId, radioAccessFamily); + return new android.telephony.RadioAccessFamily(phoneId, radioAccessFamily); } @Override - public RadioAccessFamily[] newArray(int size) { - return new RadioAccessFamily[size]; + public android.telephony.RadioAccessFamily[] newArray(int size) { + return new android.telephony.RadioAccessFamily[size]; } }; @@ -391,76 +396,78 @@ public class RadioAccessFamily implements Parcelable { } /** - * convert RAF from {@link ServiceState.RilRadioTechnology} bitmask to + * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by - * {@link TelephonyManager.NetworkType}. Reasons are {@link TelephonyManager.NetworkType} are - * public while {@link ServiceState.RilRadioTechnology} are hidden. We - * don't want to expose two sets of definition to public. + * {@link TelephonyManager.NetworkType}. * - * @param raf bitmask represented by {@link ServiceState.RilRadioTechnology} + * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily} * @return {@link TelephonyManager.NetworkTypeBitMask} */ public static int convertToNetworkTypeBitMask(int raf) { int networkTypeRaf = 0; - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_GSM)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_GPRS)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_EDGE)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE; } // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IS95A)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IS95B)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_HSPA)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_UMTS)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_LTE)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA)) != 0) { + if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; } - if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_NR)) != 0) { + if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) { networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR; } + // TODO: need hal definition + if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) { + networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN; + } return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 33178766f3a3..a1aee6d8217f 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; /** * Contains phone state and service related information. @@ -887,6 +888,24 @@ public class ServiceState implements Parcelable { } /** + * Convert roaming type to string + * + * @param roamingType roaming type + * @return The roaming type in string format + * + * @hide + */ + public static String roamingTypeToString(@RoamingType int roamingType) { + switch (roamingType) { + case ROAMING_TYPE_NOT_ROAMING: return "NOT_ROAMING"; + case ROAMING_TYPE_UNKNOWN: return "UNKNOWN"; + case ROAMING_TYPE_DOMESTIC: return "DOMESTIC"; + case ROAMING_TYPE_INTERNATIONAL: return "INTERNATIONAL"; + } + return "Unknown roaming type " + roamingType; + } + + /** * Convert radio technology to String * * @param rt radioTechnology @@ -1867,4 +1886,29 @@ public class ServiceState implements Parcelable { ? range1 : range2; } + + /** + * Returns a copy of self with location-identifying information removed. + * Always clears the NetworkRegistrationState's CellIdentity fields, but if removeCoarseLocation + * is true, clears other info as well. + * @hide + */ + public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) { + ServiceState state = new ServiceState(this); + if (state.mNetworkRegistrationStates != null) { + state.mNetworkRegistrationStates = state.mNetworkRegistrationStates.stream() + .map(NetworkRegistrationState::sanitizeLocationInfo) + .collect(Collectors.toList()); + } + if (!removeCoarseLocation) return state; + + state.mDataOperatorAlphaLong = null; + state.mDataOperatorAlphaShort = null; + state.mDataOperatorNumeric = null; + state.mVoiceOperatorAlphaLong = null; + state.mVoiceOperatorAlphaShort = null; + state.mVoiceOperatorNumeric = null; + + return state; + } } diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index 52a2085f03bd..2a73a5cdef54 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -981,4 +981,13 @@ public class SmsMessage { return false; } + + /** + * {@hide} + * Returns the recipient address(receiver) of this SMS message in String form or null if + * unavailable. + */ + public String getRecipientAddress() { + return mWrappedSmsMessage.getRecipientAddress(); + } } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index d5a153acf112..5b9e23228dcb 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -865,7 +865,8 @@ public class SubscriptionManager { } /** - * Callback invoked when there is any change to any SubscriptionInfo. Typically + * Callback invoked when there is any change to any SubscriptionInfo, as well as once on + * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} */ public void onSubscriptionsChanged() { @@ -917,7 +918,9 @@ public class SubscriptionManager { /** * Register for changes to the list of active {@link SubscriptionInfo} records or to the * individual records themselves. When a change occurs the onSubscriptionsChanged method of - * the listener will be invoked immediately if there has been a notification. + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. * * @param listener an instance of {@link OnSubscriptionsChangedListener} with * onSubscriptionsChanged overridden. @@ -1860,7 +1863,7 @@ public class SubscriptionManager { iSub.setDefaultSmsSubId(subscriptionId); } } catch (RemoteException ex) { - // ignore it + ex.rethrowFromSystemServer(); } } @@ -2862,6 +2865,95 @@ public class SubscriptionManager { } } + /** + * Enabled or disable a subscription. This is currently used in the settings page. + * + * <p> + * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * + * @param enable whether user is turning it on or off. + * @param subscriptionId Subscription to be enabled or disabled. + * It could be a eSIM or pSIM subscription. + * + * @return whether the operation is successful. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) { + if (VDBG) { + logd("setSubscriptionActivated subId= " + subscriptionId + " enable " + enable); + } + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + return iSub.setSubscriptionEnabled(enable, subscriptionId); + } + } catch (RemoteException ex) { + // ignore it + } + + return false; + } + + /** + * Returns whether the subscription is enabled or not. This is different from activated + * or deactivated for two aspects. 1) For when user disables a physical subscription, we + * actually disable the modem because we can't switch off the subscription. 2) For eSIM, + * user may enable one subscription but the system may activate another temporarily. In this + * case, user enabled one is different from current active one. + + * @param subscriptionId The subscription it asks about. + * @return whether it's enabled or not. {@code true} if user set this subscription enabled + * earlier, or user never set subscription enable / disable on this slot explicitly, and + * this subscription is currently active. Otherwise, it returns {@code false}. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public boolean isSubscriptionEnabled(int subscriptionId) { + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + return iSub.isSubscriptionEnabled(subscriptionId); + } + } catch (RemoteException ex) { + // ignore it + } + + return false; + } + + /** + * Get which subscription is enabled on this slot. See {@link #isSubscriptionEnabled(int)} + * for more details. + * + * @param slotIndex which slot it asks about. + * @return which subscription is enabled on this slot. If there's no enabled subscription + * in this slot, it will return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public int getEnabledSubscriptionId(int slotIndex) { + int subId = INVALID_SUBSCRIPTION_ID; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + subId = iSub.getEnabledSubscriptionId(slotIndex); + } + } catch (RemoteException ex) { + // ignore it + } + + if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId); + return subId; + } + private interface CallISubMethodHelper { int callMethod(ISub iSub) throws RemoteException; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 6ac092923ec3..1433b2ac9280 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -23,6 +23,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.IntDef; +import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -71,6 +72,7 @@ import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.VisibleForTesting; @@ -227,10 +229,19 @@ public class TelephonyManager { public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; /** - * An invalid UICC card identifier. See {@link #getCardIdForDefaultEuicc()} and - * {@link UiccCardInfo#getCardId()}. + * A UICC card identifier used if the device does not support the operation. + * For example, {@link #getCardIdForDefaultEuicc()} returns this value if the device has no + * eUICC, or the eUICC cannot be read. */ - public static final int INVALID_CARD_ID = -1; + public static final int UNSUPPORTED_CARD_ID = -1; + + /** + * A UICC card identifier used before the UICC card is loaded. See + * {@link #getCardIdForDefaultEuicc()} and {@link UiccCardInfo#getCardId()}. + * <p> + * Note that once the UICC card is loaded, the card ID may become {@link #UNSUPPORTED_CARD_ID}. + */ + public static final int UNINITIALIZED_CARD_ID = -2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -1653,10 +1664,7 @@ public class TelephonyManager { * @deprecated use {@link #getAllCellInfo} instead, which returns a superset of this API. */ @Deprecated - @RequiresPermission(anyOf = { - android.Manifest.permission.ACCESS_COARSE_LOCATION, - android.Manifest.permission.ACCESS_FINE_LOCATION - }) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public CellLocation getCellLocation() { try { ITelephony telephony = getITelephony(); @@ -3131,24 +3139,25 @@ public class TelephonyManager { } /** - * Get the card ID of the default eUICC card. If there is no eUICC, returns - * {@link #INVALID_CARD_ID}. + * Get the card ID of the default eUICC card. If the eUICCs have not yet been loaded, returns + * {@link #UNINITIALIZED_CARD_ID}. If there is no eUICC or the device does not support card IDs + * for eUICCs, returns {@link #UNSUPPORTED_CARD_ID}. * * <p>The card ID is a unique identifier associated with a UICC or eUICC card. Card IDs are * unique to a device, and always refer to the same UICC or eUICC card unless the device goes * through a factory reset. * - * @return card ID of the default eUICC card. + * @return card ID of the default eUICC card, if loaded. */ public int getCardIdForDefaultEuicc() { try { ITelephony telephony = getITelephony(); if (telephony == null) { - return INVALID_CARD_ID; + return UNINITIALIZED_CARD_ID; } return telephony.getCardIdForDefaultEuicc(mSubId, mContext.getOpPackageName()); } catch (RemoteException e) { - return INVALID_CARD_ID; + return UNINITIALIZED_CARD_ID; } } @@ -3251,6 +3260,35 @@ public class TelephonyManager { } } + /** + * Get the mapping from logical slots to physical slots. The mapping represent by a pair list. + * The key of the piar is the logical slot id and the value of the pair is the physical + * slots id mapped to this logical slot id. + * + * @return an pair list indicates the mapping from logical slots to physical slots. The size of + * the list should be {@link #getPhoneCount()} if success, otherwise return an empty list. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @NonNull + public List<Pair<Integer, Integer>> getLogicalToPhysicalSlotMapping() { + List<Pair<Integer, Integer>> slotMapping = new ArrayList<>(); + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + int[] slotMappingArray = telephony.getSlotsMapping(); + for (int i = 0; i < slotMappingArray.length; i++) { + slotMapping.add(new Pair(i, slotMappingArray[i])); + } + } + } catch (RemoteException e) { + Log.e(TAG, "getSlotsMapping RemoteException", e); + } + return slotMapping; + } + // // // Subscriber Info @@ -4887,7 +4925,7 @@ public class TelephonyManager { * @return List of {@link android.telephony.CellInfo}; null if cell * information is unavailable. */ - @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public List<CellInfo> getAllCellInfo() { try { ITelephony telephony = getITelephony(); @@ -4964,7 +5002,7 @@ public class TelephonyManager { * @param executor the executor on which callback will be invoked. * @param callback a callback to receive CellInfo. */ - @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate( @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { try { @@ -5003,7 +5041,7 @@ public class TelephonyManager { * @hide */ @SystemApi - @RequiresPermission(allOf = {android.Manifest.permission.ACCESS_COARSE_LOCATION, + @RequiresPermission(allOf = {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull WorkSource workSource, @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { @@ -6530,6 +6568,37 @@ public class TelephonyManager { } /** + * Get the preferred network type bitmap. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @return The bitmap of preferred network types. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi + public @NetworkTypeBitMask long getPreferredNetworkTypeBitmap() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return (long) RadioAccessFamily.getRafFromNetworkType( + telephony.getPreferredNetworkType(getSubId())); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getPreferredNetworkTypeBitmap RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getPreferredNetworkTypeBitmap NPE", ex); + } + return 0; + } + + /** * Sets the network selection mode to automatic. * * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the @@ -6562,9 +6631,10 @@ public class TelephonyManager { * * <p> Note that this scan can take a long time (sometimes minutes) to happen. * - * <p>Requires Permission: + * <p>Requires Permissions: * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier * privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. * * @return {@link CellNetworkScanResult} with the status * {@link CellNetworkScanResult#STATUS_SUCCESS} and a list of @@ -6573,12 +6643,15 @@ public class TelephonyManager { * * @hide */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION + }) public CellNetworkScanResult getAvailableNetworks() { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getCellNetworkScanResults(getSubId()); + return telephony.getCellNetworkScanResults(getSubId(), getOpPackageName()); } } catch (RemoteException ex) { Rlog.e(TAG, "getAvailableNetworks RemoteException", ex); @@ -6597,7 +6670,8 @@ public class TelephonyManager { * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling - * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * app has carrier privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_FINE_LOCATION}. * * @param request Contains all the RAT with bands/channels that need to be scanned. * @param executor The executor through which the callback should be invoked. Since the scan @@ -6608,7 +6682,10 @@ public class TelephonyManager { * @return A NetworkScan obj which contains a callback which can be used to stop the scan. */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) public NetworkScan requestNetworkScan( NetworkScanRequest request, Executor executor, TelephonyScanManager.NetworkScanCallback callback) { @@ -6617,7 +6694,8 @@ public class TelephonyManager { mTelephonyScanManager = new TelephonyScanManager(); } } - return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback); + return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback, + getOpPackageName()); } /** @@ -6627,7 +6705,10 @@ public class TelephonyManager { * @removed */ @Deprecated - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) public NetworkScan requestNetworkScan( NetworkScanRequest request, TelephonyScanManager.NetworkScanCallback callback) { return requestNetworkScan(request, AsyncTask.SERIAL_EXECUTOR, callback); @@ -6744,6 +6825,38 @@ public class TelephonyManager { } /** + * Set the preferred network type bitmap. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling + * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @param networkTypeBitmap The bitmap of preferred network types. + * @return true on success; false on any failure. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi + public boolean setPreferredNetworkTypeBitmap(@NetworkTypeBitMask long networkTypeBitmap) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setPreferredNetworkType( + getSubId(), RadioAccessFamily.getNetworkTypeFromRaf( + (int) networkTypeBitmap)); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setPreferredNetworkType NPE", ex); + } + return false; + } + + /** * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA. * * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). @@ -8595,10 +8708,14 @@ public class TelephonyManager { * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} - * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @RequiresPermission(allOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION + }) public ServiceState getServiceState() { return getServiceStateForSubscriber(getSubId()); } @@ -9622,7 +9739,7 @@ public class TelephonyManager { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = {"NETWORK_TYPE_BITMASK_"}, + @LongDef(flag = true, prefix = {"NETWORK_TYPE_BITMASK_"}, value = {NETWORK_TYPE_BITMASK_UNKNOWN, NETWORK_TYPE_BITMASK_GSM, NETWORK_TYPE_BITMASK_GPRS, @@ -9651,118 +9768,125 @@ public class TelephonyManager { * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_UNKNOWN = (1 << NETWORK_TYPE_UNKNOWN); + public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; /** * network type bitmask indicating the support of radio tech GSM. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_GSM = (1 << NETWORK_TYPE_GSM); + public static final long NETWORK_TYPE_BITMASK_GSM = (1 << (NETWORK_TYPE_GSM -1)); /** * network type bitmask indicating the support of radio tech GPRS. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_GPRS = (1 << NETWORK_TYPE_GPRS); + public static final long NETWORK_TYPE_BITMASK_GPRS = (1 << (NETWORK_TYPE_GPRS -1)); /** * network type bitmask indicating the support of radio tech EDGE. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_EDGE = (1 << NETWORK_TYPE_EDGE); + public static final long NETWORK_TYPE_BITMASK_EDGE = (1 << (NETWORK_TYPE_EDGE -1)); /** * network type bitmask indicating the support of radio tech CDMA(IS95A/IS95B). * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_CDMA = (1 << NETWORK_TYPE_CDMA); + public static final long NETWORK_TYPE_BITMASK_CDMA = (1 << (NETWORK_TYPE_CDMA -1)); /** * network type bitmask indicating the support of radio tech 1xRTT. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_1xRTT = (1 << NETWORK_TYPE_1xRTT); + public static final long NETWORK_TYPE_BITMASK_1xRTT = (1 << (NETWORK_TYPE_1xRTT - 1)); // 3G /** * network type bitmask indicating the support of radio tech EVDO 0. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_EVDO_0 = (1 << NETWORK_TYPE_EVDO_0); + public static final long NETWORK_TYPE_BITMASK_EVDO_0 = (1 << (NETWORK_TYPE_EVDO_0 -1)); /** * network type bitmask indicating the support of radio tech EVDO A. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_EVDO_A = (1 << NETWORK_TYPE_EVDO_A); + public static final long NETWORK_TYPE_BITMASK_EVDO_A = (1 << (NETWORK_TYPE_EVDO_A - 1)); /** * network type bitmask indicating the support of radio tech EVDO B. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_EVDO_B = (1 << NETWORK_TYPE_EVDO_B); + public static final long NETWORK_TYPE_BITMASK_EVDO_B = (1 << (NETWORK_TYPE_EVDO_B -1)); /** * network type bitmask indicating the support of radio tech EHRPD. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_EHRPD = (1 << NETWORK_TYPE_EHRPD); + public static final long NETWORK_TYPE_BITMASK_EHRPD = (1 << (NETWORK_TYPE_EHRPD -1)); /** * network type bitmask indicating the support of radio tech HSUPA. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_HSUPA = (1 << NETWORK_TYPE_HSUPA); + public static final long NETWORK_TYPE_BITMASK_HSUPA = (1 << (NETWORK_TYPE_HSUPA -1)); /** * network type bitmask indicating the support of radio tech HSDPA. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_HSDPA = (1 << NETWORK_TYPE_HSDPA); + public static final long NETWORK_TYPE_BITMASK_HSDPA = (1 << (NETWORK_TYPE_HSDPA -1)); /** * network type bitmask indicating the support of radio tech HSPA. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_HSPA = (1 << NETWORK_TYPE_HSPA); + public static final long NETWORK_TYPE_BITMASK_HSPA = (1 << (NETWORK_TYPE_HSPA -1)); /** * network type bitmask indicating the support of radio tech HSPAP. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_HSPAP = (1 << NETWORK_TYPE_HSPAP); + public static final long NETWORK_TYPE_BITMASK_HSPAP = (1 << (NETWORK_TYPE_HSPAP -1)); /** * network type bitmask indicating the support of radio tech UMTS. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_UMTS = (1 << NETWORK_TYPE_UMTS); + public static final long NETWORK_TYPE_BITMASK_UMTS = (1 << (NETWORK_TYPE_UMTS -1)); /** * network type bitmask indicating the support of radio tech TD_SCDMA. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_TD_SCDMA = (1 << NETWORK_TYPE_TD_SCDMA); + public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = (1 << (NETWORK_TYPE_TD_SCDMA -1)); // 4G /** * network type bitmask indicating the support of radio tech LTE. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_LTE = (1 << NETWORK_TYPE_LTE); + public static final long NETWORK_TYPE_BITMASK_LTE = (1 << (NETWORK_TYPE_LTE -1)); /** * network type bitmask indicating the support of radio tech LTE CA (carrier aggregation). * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_LTE_CA = (1 << NETWORK_TYPE_LTE_CA); + public static final long NETWORK_TYPE_BITMASK_LTE_CA = (1 << (NETWORK_TYPE_LTE_CA -1)); /** * network type bitmask indicating the support of radio tech NR(New Radio) 5G. * @hide */ @SystemApi - public static final int NETWORK_TYPE_BITMASK_NR = (1 << NETWORK_TYPE_NR); + public static final long NETWORK_TYPE_BITMASK_NR = (1 << (NETWORK_TYPE_NR -1)); + + /** + * network type bitmask indicating the support of radio tech IWLAN. + * @hide + */ + @SystemApi + public static final long NETWORK_TYPE_BITMASK_IWLAN = (1 << (NETWORK_TYPE_IWLAN -1)); /** * @return Modem supported radio access family bitmask @@ -9773,11 +9897,11 @@ public class TelephonyManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public @NetworkTypeBitMask int getSupportedRadioAccessFamily() { + public @NetworkTypeBitMask long getSupportedRadioAccessFamily() { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getRadioAccessFamily(getSlotIndex(), getOpPackageName()); + return (long) telephony.getRadioAccessFamily(getSlotIndex(), getOpPackageName()); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_BITMASK_UNKNOWN; @@ -10166,11 +10290,14 @@ public class TelephonyManager { /** * Get whether reboot is required or not after making changes to modem configurations. - * @Return {@code True} if reboot is required after making changes to modem configurations, - * otherwise return {@code False}. + * The modem configuration change refers to switching from single SIM configuration to DSDS + * or the other way around. + * @Return {@code true} if reboot is required after making changes to modem configurations, + * otherwise return {@code false}. * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isRebootRequiredForModemConfigChange() { try { diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index 96ff33255b53..91f74b867fa0 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -29,14 +29,14 @@ import android.os.Messenger; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; -import android.util.Log; import android.util.SparseArray; + +import com.android.internal.telephony.ITelephony; + import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; -import com.android.internal.telephony.ITelephony; - /** * Manages the radio access network scan requests and callbacks. */ @@ -183,6 +183,7 @@ public final class TelephonyScanManager { * * <p> * Requires Permission: + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * Or the calling app has carrier privileges. @see #hasCarrierPrivileges * @@ -192,11 +193,13 @@ public final class TelephonyScanManager { * @hide */ public NetworkScan requestNetworkScan(int subId, - NetworkScanRequest request, Executor executor, NetworkScanCallback callback) { + NetworkScanRequest request, Executor executor, NetworkScanCallback callback, + String callingPackage) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - int scanId = telephony.requestNetworkScan(subId, request, mMessenger, new Binder()); + int scanId = telephony.requestNetworkScan( + subId, request, mMessenger, new Binder(), callingPackage); saveScanInfo(scanId, request, executor, callback); return new NetworkScan(scanId, subId); } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 40c6f70f5112..828e3e93b7a4 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -305,7 +305,7 @@ public class EuiccManager { */ @Nullable public String getEid() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return null; } try { @@ -328,7 +328,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return EUICC_OTA_STATUS_UNAVAILABLE; } try { @@ -363,7 +363,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void downloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -425,7 +425,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { PendingIntent callbackIntent = resolutionIntent.getParcelableExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); @@ -462,7 +462,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata( DownloadableSubscription subscription, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -492,7 +492,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -511,7 +511,7 @@ public class EuiccManager { */ @Nullable public EuiccInfo getEuiccInfo() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return null; } try { @@ -536,7 +536,7 @@ public class EuiccManager { */ @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -576,7 +576,7 @@ public class EuiccManager { */ @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -602,7 +602,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void updateSubscriptionNickname( int subscriptionId, String nickname, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -626,7 +626,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -656,7 +656,7 @@ public class EuiccManager { * @hide */ public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -667,16 +667,24 @@ public class EuiccManager { } } - private boolean refreshCardIdIfInvalid() { - if (!isEnabled()) { - return false; - } - // Refresh mCardId if it's invalid. - if (mCardId == TelephonyManager.INVALID_CARD_ID) { + /** + * Refreshes the cardId if its uninitialized, and returns whether we should continue the + * operation. + * <p> + * Note that after a successful refresh, the mCardId may be TelephonyManager.UNSUPPORTED_CARD_ID + * on older HALs. For backwards compatability, we continue to the LPA and let it decide which + * card to use. + */ + private boolean refreshCardIdIfUninitialized() { + // Refresh mCardId if its UNINITIALIZED_CARD_ID + if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); mCardId = tm.getCardIdForDefaultEuicc(); } + if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { + return false; + } return true; } diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index 59167b7d5bba..73f055649b3f 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -350,6 +350,9 @@ public final class ImsCallProfile implements Parcelable { /** Indicates if the call is for testing purpose */ private boolean mEmergencyCallTesting = false; + /** Indicates if we have known the intent of the user for the call is emergency */ + private boolean mHasKnownUserIntentEmergency = false; + /** * Extras associated with this {@link ImsCallProfile}. * <p> @@ -789,12 +792,13 @@ public final class ImsCallProfile implements Parcelable { * * @hide */ - public void setEmergencyCallInfo(EmergencyNumber num) { + public void setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency) { setEmergencyServiceCategories(num.getEmergencyServiceCategoryBitmaskInternalDial()); setEmergencyUrns(num.getEmergencyUrns()); setEmergencyCallRouting(num.getEmergencyCallRouting()); setEmergencyCallTesting(num.getEmergencyNumberSourceBitmask() == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST); + setHasKnownUserIntentEmergency(hasKnownUserIntentEmergency); } /** @@ -860,6 +864,19 @@ public final class ImsCallProfile implements Parcelable { } /** + * Set if we have known the user intent of the call is emergency. + * + * This is only used to specify when the dialed number is ambiguous when it can be identified + * as both emergency number and any other non-emergency number; e.g. in some situation, 611 + * could be both an emergency number in a country and a non-emergency number of a carrier's + * customer service hotline. + */ + @VisibleForTesting + public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) { + mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency; + } + + /** * Get the emergency service categories, only valid if {@link #getServiceType} returns * {@link #SERVICE_TYPE_EMERGENCY} * @@ -916,4 +933,16 @@ public final class ImsCallProfile implements Parcelable { public boolean isEmergencyCallTesting() { return mEmergencyCallTesting; } + + /** + * Checks if we have known the user intent of the call is emergency. + * + * This is only used to specify when the dialed number is ambiguous when it can be identified + * as both emergency number and any other non-emergency number; e.g. in some situation, 611 + * could be both an emergency number in a country and a non-emergency number of a carrier's + * customer service hotline. + */ + public boolean hasKnownUserIntentEmergency() { + return mHasKnownUserIntentEmergency; + } } diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java index 3255f8d0786d..d4a78ffb77db 100644 --- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java +++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java @@ -22,8 +22,6 @@ import android.annotation.WorkerThread; * Rcs1To1Thread represents a single RCS conversation thread with a total of two * {@link RcsParticipant}s. Please see Section 5 (1-to-1 Messaging) - GSMA RCC.71 (RCS Universal * Profile Service Definition Document) - * - * @hide - TODO: make public */ public class Rcs1To1Thread extends RcsThread { private int mThreadId; diff --git a/telephony/java/android/telephony/ims/RcsEvent.java b/telephony/java/android/telephony/ims/RcsEvent.java index ef359a124d47..df62277f9ac1 100644 --- a/telephony/java/android/telephony/ims/RcsEvent.java +++ b/telephony/java/android/telephony/ims/RcsEvent.java @@ -19,8 +19,6 @@ import android.os.Parcel; /** * The base class for events that can happen on {@link RcsParticipant}s and {@link RcsThread}s. - * - * @hide - TODO: make public */ public abstract class RcsEvent { /** diff --git a/telephony/java/android/telephony/ims/RcsEventQueryParams.java b/telephony/java/android/telephony/ims/RcsEventQueryParams.java index 5249becd476e..9dbfe4393213 100644 --- a/telephony/java/android/telephony/ims/RcsEventQueryParams.java +++ b/telephony/java/android/telephony/ims/RcsEventQueryParams.java @@ -37,8 +37,6 @@ import java.security.InvalidParameterException; * The parameters to pass into * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} in order to select a * subset of {@link RcsEvent}s present in the message store. - * - * @hide - TODO: make public */ public final class RcsEventQueryParams implements Parcelable { /** @@ -152,8 +150,8 @@ public final class RcsEventQueryParams implements Parcelable { } /** - * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParams} is - * set to query for. + * @return Returns the number of {@link RcsEvent}s to be returned from the query. A value of + * 0 means there is no set limit. */ public int getLimit() { return mLimit; diff --git a/telephony/java/android/telephony/ims/RcsEventQueryResult.java b/telephony/java/android/telephony/ims/RcsEventQueryResult.java index f8d57fa5c09d..c30e4ccd7aa2 100644 --- a/telephony/java/android/telephony/ims/RcsEventQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsEventQueryResult.java @@ -25,8 +25,6 @@ import java.util.List; * The result of a {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} * call. This class allows getting the token for querying the next batch of events in order to * prevent handling large amounts of data at once. - * - * @hide - TODO: make public */ public final class RcsEventQueryResult implements Parcelable { private RcsQueryContinuationToken mContinuationToken; diff --git a/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java index 663def5df50f..14af8ea63a67 100644 --- a/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java +++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java @@ -24,8 +24,6 @@ import android.os.Parcelable; * Pass an instance of this class to * {@link RcsMessage#insertFileTransfer(RcsFileTransferCreationParams)} create an * {@link RcsFileTransferPart} and save it into storage. - * - * @hide - TODO: make public */ public final class RcsFileTransferCreationParams implements Parcelable { private String mRcsFileTransferSessionId; diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.java b/telephony/java/android/telephony/ims/RcsFileTransferPart.java index 1ce799919e09..9531c2e2f981 100644 --- a/telephony/java/android/telephony/ims/RcsFileTransferPart.java +++ b/telephony/java/android/telephony/ims/RcsFileTransferPart.java @@ -26,8 +26,6 @@ import java.lang.annotation.RetentionPolicy; /** * A part of a composite {@link RcsMessage} that holds a file transfer. Please see Section 7 * (File Transfer) - GSMA RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public class RcsFileTransferPart { /** diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java index 2c42494ee924..6e17bc2a685f 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThread.java +++ b/telephony/java/android/telephony/ims/RcsGroupThread.java @@ -29,8 +29,6 @@ import java.util.Set; * RcsGroupThread represents a single RCS conversation thread where {@link RcsParticipant}s can join * or leave. Please see Section 6 (Group Chat) - GSMA RCC.71 (RCS Universal Profile Service * Definition Document) - * - * @hide - TODO: make public */ public class RcsGroupThread extends RcsThread { /** diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java index bc61877a81d6..609b1740a536 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java @@ -20,8 +20,6 @@ import android.os.Parcel; /** * An event that happened on an {@link RcsGroupThread}. - * - * @hide - TODO: make public */ public abstract class RcsGroupThreadEvent extends RcsEvent { private final int mRcsGroupThreadId; diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java index 74af9738e976..e768439d6cfa 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java @@ -24,8 +24,6 @@ import android.os.Parcelable; /** * An event that indicates an {@link RcsGroupThread}'s icon was changed. Please see R6-2-5 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public final class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java index 06f4d5b10bb4..02030bc6a2ec 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java @@ -23,8 +23,6 @@ import android.os.Parcelable; /** * An event that indicates an {@link RcsGroupThread}'s name was changed. Please see R6-2-5 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public final class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java index 493270795e01..0d1a5730f0a0 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java @@ -22,8 +22,6 @@ import android.os.Parcelable; /** * An event that indicates an RCS participant has joined an {@link RcsThread}. Please see US6-3 - * GSMA RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public final class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java index 970a046e1105..cd525086749a 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java @@ -22,8 +22,6 @@ import android.os.Parcelable; /** * An event that indicates an RCS participant has left an {@link RcsThread}. Please see US6-23 - * GSMA RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public final class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.java b/telephony/java/android/telephony/ims/RcsIncomingMessage.java index f3b7815c2453..61911abd00c5 100644 --- a/telephony/java/android/telephony/ims/RcsIncomingMessage.java +++ b/telephony/java/android/telephony/ims/RcsIncomingMessage.java @@ -19,8 +19,6 @@ import android.annotation.WorkerThread; /** * This is a single instance of a message received over RCS. - * - * @hide - TODO: make public */ public class RcsIncomingMessage extends RcsMessage { /** diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java index 64b2339905eb..61dedbc1578a 100644 --- a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java +++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java @@ -24,8 +24,6 @@ import android.os.Parcelable; * {@link RcsIncomingMessageCreationParams} is a collection of parameters that should be passed * into {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams)} to generate an * {@link RcsIncomingMessage} on that {@link RcsThread} - * - * @hide - TODO: make public */ public final class RcsIncomingMessageCreationParams extends RcsMessageCreationParams implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java index 90bd0446d6f3..22e4b2249c36 100644 --- a/telephony/java/android/telephony/ims/RcsManager.java +++ b/telephony/java/android/telephony/ims/RcsManager.java @@ -20,8 +20,6 @@ import android.content.Context; /** * The manager class for RCS related utilities. - * - * @hide - TODO: make public */ @SystemService(Context.TELEPHONY_RCS_SERVICE) public class RcsManager { diff --git a/telephony/java/android/telephony/ims/RcsMessage.java b/telephony/java/android/telephony/ims/RcsMessage.java index 1700941b94ed..32274131a5ad 100644 --- a/telephony/java/android/telephony/ims/RcsMessage.java +++ b/telephony/java/android/telephony/ims/RcsMessage.java @@ -27,8 +27,6 @@ import java.util.Set; /** * This is a single instance of a message sent or received over RCS. - * - * @hide - TODO: make public */ public abstract class RcsMessage { /** diff --git a/telephony/java/android/telephony/ims/RcsMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java index 9ac4dcdf2d74..c46c605d861d 100644 --- a/telephony/java/android/telephony/ims/RcsMessageCreationParams.java +++ b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java @@ -27,8 +27,6 @@ import android.os.Parcel; * {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams)} and * {@link RcsThread#addOutgoingMessage(RcsOutgoingMessageCreationParams)} to create and persist * {@link RcsMessage}s on an {@link RcsThread} - * - * @hide - TODO: make public */ public class RcsMessageCreationParams { // The globally unique id of the RcsMessage to be created. diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryParams.java b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java index fae0d97cd722..535a597f5e1e 100644 --- a/telephony/java/android/telephony/ims/RcsMessageQueryParams.java +++ b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java @@ -31,8 +31,6 @@ import java.security.InvalidParameterException; * The parameters to pass into * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} in order to select a * subset of {@link RcsMessage}s present in the message store. - * - * @hide - TODO: make public */ public final class RcsMessageQueryParams implements Parcelable { /** diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java index 5adab760d594..3514b48e80a1 100644 --- a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java @@ -32,8 +32,6 @@ import java.util.List; * The result of a {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} * call. This class allows getting the token for querying the next batch of messages in order to * prevent handling large amounts of data at once. - * - * @hide - TODO: make public */ public final class RcsMessageQueryResult implements Parcelable { // The token to continue the query to get the next batch of results diff --git a/telephony/java/android/telephony/ims/RcsMessageSnippet.java b/telephony/java/android/telephony/ims/RcsMessageSnippet.java index 565bb99de89a..b0b930c56e91 100644 --- a/telephony/java/android/telephony/ims/RcsMessageSnippet.java +++ b/telephony/java/android/telephony/ims/RcsMessageSnippet.java @@ -23,8 +23,6 @@ import android.telephony.ims.RcsMessage.RcsMessageStatus; /** * An immutable summary of the latest {@link RcsMessage} on an {@link RcsThread} - * - * @hide - TODO: make public */ public final class RcsMessageSnippet implements Parcelable { private final String mText; diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java index eca5ed518521..d811c6e93a56 100644 --- a/telephony/java/android/telephony/ims/RcsMessageStore.java +++ b/telephony/java/android/telephony/ims/RcsMessageStore.java @@ -26,8 +26,6 @@ import java.util.List; /** * RcsMessageStore is the application interface to RcsProvider and provides access methods to * RCS related database tables. - * - * @hide - TODO: make public */ public class RcsMessageStore { /** diff --git a/telephony/java/android/telephony/ims/RcsMessageStoreException.java b/telephony/java/android/telephony/ims/RcsMessageStoreException.java index 7c00749b1690..f25bb173be37 100644 --- a/telephony/java/android/telephony/ims/RcsMessageStoreException.java +++ b/telephony/java/android/telephony/ims/RcsMessageStoreException.java @@ -19,8 +19,6 @@ package android.telephony.ims; /** * An exception that happened on {@link RcsMessageStore} or one of the derived storage classes in * {@link android.telephony.ims} - * - * @hide - TODO: make public */ public class RcsMessageStoreException extends Exception { diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java index dfcdee4a803d..06fb83268afb 100644 --- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java @@ -23,8 +23,6 @@ import java.util.List; /** * This is a single instance of a message sent over RCS. - * - * @hide - TODO: make public */ public class RcsOutgoingMessage extends RcsMessage { RcsOutgoingMessage(int id) { diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java index ca466e8c9d3e..979634a069df 100644 --- a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java @@ -23,8 +23,6 @@ import android.os.Parcelable; * {@link RcsOutgoingMessageCreationParams} is a collection of parameters that should be passed * into {@link RcsThread#addOutgoingMessage(RcsOutgoingMessageCreationParams)} to generate an * {@link RcsOutgoingMessage} on that {@link RcsThread} - * - * @hide - TODO: make public */ public final class RcsOutgoingMessageCreationParams extends RcsMessageCreationParams implements Parcelable { diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java index 5a3062a69e3f..1c87b13f0dfb 100644 --- a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java @@ -21,8 +21,6 @@ import android.annotation.WorkerThread; /** * This class holds the delivery information of an {@link RcsOutgoingMessage} for each * {@link RcsParticipant} that the message was intended for. - * - * @hide - TODO: make public */ public class RcsOutgoingMessageDelivery { // The participant that this delivery is intended for diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java index 37b827b8e83c..7ba5d8e65f76 100644 --- a/telephony/java/android/telephony/ims/RcsParticipant.java +++ b/telephony/java/android/telephony/ims/RcsParticipant.java @@ -20,8 +20,6 @@ import android.annotation.WorkerThread; /** * RcsParticipant is an RCS capable contact that can participate in {@link RcsThread}s. - * - * @hide - TODO: make public */ public class RcsParticipant { // The row ID of this participant in the database diff --git a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java index aa278b38cf81..c9a2b0d07bc8 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java @@ -23,8 +23,6 @@ import android.os.Parcelable; /** * An event that indicates an {@link RcsParticipant}'s alias was changed. Please see US18-2 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) - * - * @hide - TODO: make public */ public final class RcsParticipantAliasChangedEvent extends RcsEvent implements Parcelable { // The ID of the participant that changed their alias diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java index 57c67fa7aa03..d24d079d7038 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java +++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java @@ -30,8 +30,6 @@ import java.security.InvalidParameterException; * The parameters to pass into * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} in order to select a * subset of {@link RcsThread}s present in the message store. - * - * @hide - TODO: make public */ public final class RcsParticipantQueryParams implements Parcelable { /** diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java index 4eae39d1a2c6..505f1a55d1f0 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java @@ -28,8 +28,6 @@ import java.util.List; * The result of a {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} * call. This class allows getting the token for querying the next batch of participants in order to * prevent handling large amounts of data at once. - * - * @hide - TODO: make public */ public final class RcsParticipantQueryResult implements Parcelable { // A token for the caller to continue their query for the next batch of results diff --git a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java index c1ff39652397..08643de51d40 100644 --- a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java +++ b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java @@ -31,8 +31,6 @@ import java.lang.annotation.RetentionPolicy; * @see RcsMessageQueryResult#getContinuationToken() * @see RcsParticipantQueryResult#getContinuationToken() * @see RcsThreadQueryResult#getContinuationToken() - * - * @hide - TODO: make public */ public final class RcsQueryContinuationToken implements Parcelable { /** diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java index 88655865f47b..e015dd3e9c0a 100644 --- a/telephony/java/android/telephony/ims/RcsThread.java +++ b/telephony/java/android/telephony/ims/RcsThread.java @@ -27,8 +27,6 @@ import com.android.internal.annotations.VisibleForTesting; /** * RcsThread represents a single RCS conversation thread. It holds messages that were sent and * received and events that occurred on that thread. - * - * @hide - TODO: make public */ public abstract class RcsThread { /** diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParams.java b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java index ba32e320c95b..05a5a3917691 100644 --- a/telephony/java/android/telephony/ims/RcsThreadQueryParams.java +++ b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java @@ -35,8 +35,6 @@ import java.util.Set; /** * The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} in * order to select a subset of {@link RcsThread}s present in the message store. - * - * @hide - TODO: make public */ public final class RcsThreadQueryParams implements Parcelable { /** diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java index a91126b89cce..1cac61d1aa64 100644 --- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java @@ -32,8 +32,6 @@ import java.util.List; * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} * call. This class allows getting the token for querying the next batch of threads in order to * prevent handling large amounts of data at once. - * - * @hide - TODO: make public */ public final class RcsThreadQueryResult implements Parcelable { // A token for the caller to continue their query for the next batch of results diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 04ec3d1a3df3..a49d2d976d16 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -276,6 +276,11 @@ interface ISub { String getSubscriptionProperty(int subId, String propKey, String callingPackage); + boolean setSubscriptionEnabled(boolean enable, int subId); + + boolean isSubscriptionEnabled(int subId); + + int getEnabledSubscriptionId(int slotIndex); /** * Get the SIM state for the slot index * @return SIM state as the ordinal of IccCardConstants.State diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index c7061dfe25f1..e6a55585506c 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -765,7 +765,7 @@ interface ITelephony { * @param subId the id of the subscription. * @return CellNetworkScanResult containing status of scan and networks. */ - CellNetworkScanResult getCellNetworkScanResults(int subId); + CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage); /** * Perform a radio network scan and return the id of this scan. @@ -774,10 +774,11 @@ interface ITelephony { * @param request Defines all the configs for network scan. * @param messenger Callback messages will be sent using this messenger. * @param binder the binder object instantiated in TelephonyManager. + * @param callingPackage the calling package * @return An id for this scan. */ int requestNetworkScan(int subId, in NetworkScanRequest request, in Messenger messenger, - in IBinder binder); + in IBinder binder, in String callingPackage); /** * Stop an existing radio network scan. @@ -1829,7 +1830,7 @@ interface ITelephony { * @hide */ boolean isMultisimCarrierRestricted(); - + /** * Switch configs to enable multi-sim or switch back to single-sim * @hide @@ -1840,8 +1841,15 @@ interface ITelephony { * @hide */ int getNumOfActiveSims(); + /** * Get if reboot is required upon altering modems configurations + * @hide */ boolean isRebootRequiredForModemConfigChange(); + + /** + * Get the mapping from logical slots to physical slots. + */ + int[] getSlotsMapping(); } diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 190eac4d8c02..ffdc4b676f90 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -41,6 +41,9 @@ public abstract class SmsMessageBase { @UnsupportedAppUsage protected SmsAddress mOriginatingAddress; + /** {@hide} The address of the receiver */ + protected SmsAddress mRecipientAddress; + /** {@hide} The message body as a string. May be null if the message isn't text */ @UnsupportedAppUsage protected String mMessageBody; @@ -457,4 +460,17 @@ public abstract class SmsMessageBase { return ted; } + + /** + * {@hide} + * Returns the receiver address of this SMS message in String + * form or null if unavailable + */ + public String getRecipientAddress() { + if (mRecipientAddress == null) { + return null; + } + + return mRecipientAddress.getAddressString(); + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/BearerData.java index a4cd56b9e3e2..694cc69c2b3f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/BearerData.java @@ -596,6 +596,45 @@ public final class BearerData { System.arraycopy(payload, 0, uData.payload, udhBytes, payload.length); } + private static void encode7bitAsciiEms(UserData uData, byte[] udhData, boolean force) + throws CodingException + { + try { + Rlog.d(LOG_TAG, "encode7bitAsciiEms"); + int udhBytes = udhData.length + 1; // Add length octet. + int udhSeptets = ((udhBytes * 8) + 6) / 7; + int paddingBits = (udhSeptets * 7) - (udhBytes * 8); + String msg = uData.payloadStr; + byte[] payload ; + int msgLen = msg.length(); + BitwiseOutputStream outStream = new BitwiseOutputStream(msgLen + + (paddingBits > 0 ? 1 : 0)); + outStream.write(paddingBits, 0); + for (int i = 0; i < msgLen; i++) { + int charCode = UserData.charToAscii.get(msg.charAt(i), -1); + if (charCode == -1) { + if (force) { + outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR); + } else { + throw new CodingException("cannot ASCII encode (" + msg.charAt(i) + ")"); + } + } else { + outStream.write(7, charCode); + } + } + payload = outStream.toByteArray(); + uData.msgEncoding = UserData.ENCODING_7BIT_ASCII; + uData.msgEncodingSet = true; + uData.numFields = udhSeptets + uData.payloadStr.length(); + uData.payload = new byte[udhBytes + payload.length]; + uData.payload[0] = (byte)udhData.length; + System.arraycopy(udhData, 0, uData.payload, 1, udhData.length); + System.arraycopy(payload, 0, uData.payload, udhBytes, payload.length); + } catch (BitwiseOutputStream.AccessException ex) { + throw new CodingException("7bit ASCII encode failed: " + ex); + } + } + private static void encodeEmsUserDataPayload(UserData uData) throws CodingException { @@ -605,6 +644,8 @@ public final class BearerData { encode7bitEms(uData, headerData, true); } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) { encode16bitEms(uData, headerData); + } else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) { + encode7bitAsciiEms(uData, headerData, true); } else { throw new CodingException("unsupported EMS user data encoding (" + uData.msgEncoding + ")"); @@ -1056,15 +1097,18 @@ public final class BearerData { throws CodingException { try { - offset *= 8; + int offsetBits = offset * 8; + int offsetSeptets = (offsetBits + 6) / 7; + numFields -= offsetSeptets; + StringBuffer strBuf = new StringBuffer(numFields); BitwiseInputStream inStream = new BitwiseInputStream(data); - int wantedBits = (offset * 8) + (numFields * 7); + int wantedBits = (offsetSeptets * 7) + (numFields * 7); if (inStream.available() < wantedBits) { throw new CodingException("insufficient data (wanted " + wantedBits + " bits, but only have " + inStream.available() + ")"); } - inStream.skip(offset); + inStream.skip(offsetSeptets * 7); for (int i = 0; i < numFields; i++) { int charCode = inStream.read(7); if ((charCode >= UserData.ASCII_MAP_BASE_INDEX) && diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 9080e23eb88f..a31fa0b6a725 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -601,18 +601,24 @@ public class SmsMessage extends SmsMessageBase { } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { if (numberType == 2) - Rlog.e(LOG_TAG, "TODO: Originating Addr is email id"); + Rlog.e(LOG_TAG, "TODO: Addr is email id"); else Rlog.e(LOG_TAG, - "TODO: Originating Addr is data network address"); + "TODO: Addr is data network address"); } else { - Rlog.e(LOG_TAG, "Originating Addr is of incorrect type"); + Rlog.e(LOG_TAG, "Addr is of incorrect type"); } } else { Rlog.e(LOG_TAG, "Incorrect Digit mode"); } addr.origBytes = data; - Rlog.i(LOG_TAG, "Originating Addr=" + addr.toString()); + Rlog.pii(LOG_TAG, "Addr=" + addr.toString()); + mOriginatingAddress = addr; + if (parameterId == DESTINATION_ADDRESS) { + // Original address awlays indicates one sender's address for 3GPP2 + // Here add recipient address support along with 3GPP + mRecipientAddress = addr; + } break; case ORIGINATING_SUB_ADDRESS: case DESTINATION_SUB_ADDRESS: @@ -667,7 +673,7 @@ public class SmsMessage extends SmsMessageBase { } /** - * Parses a SMS message from its BearerData stream. (mobile-terminated only) + * Parses a SMS message from its BearerData stream. */ public void parseSms() { // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 @@ -697,16 +703,15 @@ public class SmsMessage extends SmsMessageBase { } if (mOriginatingAddress != null) { - mOriginatingAddress.address = new String(mOriginatingAddress.origBytes); - if (mOriginatingAddress.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) { - if (mOriginatingAddress.address.charAt(0) != '+') { - mOriginatingAddress.address = "+" + mOriginatingAddress.address; - } - } + decodeSmsDisplayAddress(mOriginatingAddress); if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: " + mOriginatingAddress.address); } + if (mRecipientAddress != null) { + decodeSmsDisplayAddress(mRecipientAddress); + } + if (mBearerData.msgCenterTimeStamp != null) { mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); } @@ -731,7 +736,8 @@ public class SmsMessage extends SmsMessageBase { status = mBearerData.errorClass << 8; status |= mBearerData.messageStatus; } - } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { + } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER + && mBearerData.messageType != BearerData.MESSAGE_TYPE_SUBMIT) { throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); } @@ -743,6 +749,16 @@ public class SmsMessage extends SmsMessageBase { } } + private void decodeSmsDisplayAddress(SmsAddress addr) { + addr.address = new String(addr.origBytes); + if (addr.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) { + if (addr.address.charAt(0) != '+') { + addr.address = "+" + addr.address; + } + } + Rlog.pii(LOG_TAG, " decodeSmsDisplayAddress = " + addr.address); + } + /** * Parses a broadcast SMS, possibly containing a CMAS alert. * @@ -864,8 +880,9 @@ public class SmsMessage extends SmsMessageBase { Rlog.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'"); } - int teleservice = bearerData.hasUserDataHeader ? - SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; + int teleservice = (bearerData.hasUserDataHeader + && userData.msgEncoding != UserData.ENCODING_7BIT_ASCII) + ? SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; SmsEnvelope envelope = new SmsEnvelope(); envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 015efa6a0c7d..19465a44e4e8 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -71,9 +71,6 @@ public class SmsMessage extends SmsMessageBase { // e.g. 23.040 9.2.2.1 private boolean mReplyPathPresent = false; - /** The address of the receiver. */ - private GsmSmsAddress mRecipientAddress; - /** * TP-Status - status of a previously submitted SMS. * This field applies to SMS-STATUS-REPORT messages. 0 indicates success; diff --git a/test-runner/Android.mk b/test-runner/Android.mk deleted file mode 100644 index 18bde8517351..000000000000 --- a/test-runner/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH:= $(call my-dir) - -# additionally, build unit tests in a separate .apk -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/test-runner/tests/Android.bp b/test-runner/tests/Android.bp new file mode 100644 index 000000000000..03c73986118d --- /dev/null +++ b/test-runner/tests/Android.bp @@ -0,0 +1,40 @@ +// Copyright 2010, The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test { + name: "FrameworkTestRunnerTests", + + // We only want this apk build for tests. + // + // Run the tests using the following commands: + // adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk + // adb shell am instrument \ + // -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \ + // -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner \ + // + + libs: [ + "android.test.runner", + "android.test.base", + "android.test.mock", + ], + static_libs: ["junit"], + + // Include all test java files. + srcs: ["src/**/*.java"], + + // Because of android.test.mock. + platform_apis: true, + +} diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk deleted file mode 100644 index f97d1c986b1c..000000000000 --- a/test-runner/tests/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2010, The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -# -# Run the tests using the following commands: -# adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk -# adb shell am instrument \ - -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \ - -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner -# -LOCAL_MODULE_TAGS := tests - -LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock -LOCAL_STATIC_JAVA_LIBRARIES := junit - -# Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := FrameworkTestRunnerTests -# Because of android.test.mock. -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_PACKAGE) - diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 1548a76cc443..d1a06925a902 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -20,6 +20,7 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; +import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; @@ -123,7 +124,7 @@ import android.net.NetworkMisc; import android.net.NetworkParcelable; import android.net.NetworkRequest; import android.net.NetworkSpecifier; -import android.net.NetworkStack; +import android.net.NetworkStackClient; import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.RouteInfo; @@ -245,7 +246,7 @@ public class ConnectivityServiceTest { @Mock INetworkStatsService mStatsService; @Mock INetworkPolicyManager mNpm; @Mock INetd mMockNetd; - @Mock NetworkStack mNetworkStack; + @Mock NetworkStackClient mNetworkStack; private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class); @@ -554,7 +555,7 @@ public class ConnectivityServiceTest { if (mNmValidationRedirectUrl != null) { mNmCallbacks.showProvisioningNotification( - "test_provisioning_notif_action"); + "test_provisioning_notif_action", "com.android.test.package"); mNmProvNotificationRequested = true; } } catch (RemoteException e) { @@ -885,11 +886,14 @@ public class ConnectivityServiceTest { public void setUids(Set<UidRange> uids) { mNetworkCapabilities.setUids(uids); - updateCapabilities(); + updateCapabilities(null /* defaultNetwork */); } @Override public int getNetId() { + if (mMockNetworkAgent == null) { + return NETID_UNSET; + } return mMockNetworkAgent.getNetwork().netId; } @@ -911,12 +915,13 @@ public class ConnectivityServiceTest { } @Override - public void updateCapabilities() { - if (!mConnected) return; - super.updateCapabilities(); - // Because super.updateCapabilities will update the capabilities of the agent but not - // the mock agent, the mock agent needs to know about them. + public NetworkCapabilities updateCapabilities(Network defaultNetwork) { + if (!mConnected) return null; + super.updateCapabilities(defaultNetwork); + // Because super.updateCapabilities will update the capabilities of the agent but + // not the mock agent, the mock agent needs to know about them. copyCapabilitiesToNetworkAgent(); + return new NetworkCapabilities(mNetworkCapabilities); } private void copyCapabilitiesToNetworkAgent() { @@ -1061,6 +1066,11 @@ public class ConnectivityServiceTest { } @Override + protected NetworkStackClient getNetworkStack() { + return mNetworkStack; + } + + @Override public WakeupMessage makeWakeupMessage( Context context, Handler handler, String cmdName, int cmd, Object obj) { return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj); @@ -3791,11 +3801,14 @@ public class ConnectivityServiceTest { } @Test - public void testNattSocketKeepalives() throws Exception { + public void testNattSocketKeepalives_SingleThreadExecutor() throws Exception { final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); doTestNattSocketKeepalivesWithExecutor(executorSingleThread); executorSingleThread.shutdown(); + } + @Test + public void testNattSocketKeepalives_InlineExecutor() throws Exception { final Executor executorInline = (Runnable r) -> r.run(); doTestNattSocketKeepalivesWithExecutor(executorInline); } @@ -3937,6 +3950,7 @@ public class ConnectivityServiceTest { testSocket2.close(); mWiFiNetworkAgent.disconnect(); + waitFor(mWiFiNetworkAgent.getDisconnectedCV()); } @Test @@ -4660,6 +4674,7 @@ public class ConnectivityServiceTest { vpnNetworkAgent.connect(false); mMockVpn.connect(); + mMockVpn.setUnderlyingNetworks(new Network[0]); genericNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); genericNotVpnNetworkCallback.assertNoCallback(); @@ -4692,6 +4707,7 @@ public class ConnectivityServiceTest { ranges.add(new UidRange(uid, uid)); mMockVpn.setUids(ranges); + vpnNetworkAgent.setUids(ranges); genericNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent); genericNotVpnNetworkCallback.assertNoCallback(); @@ -4725,12 +4741,11 @@ public class ConnectivityServiceTest { } @Test - public void testVpnWithAndWithoutInternet() { + public void testVpnWithoutInternet() { final int uid = Process.myUid(); final TestNetworkCallback defaultCallback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(defaultCallback); - defaultCallback.assertNoCallback(); mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(true); @@ -4752,11 +4767,30 @@ public class ConnectivityServiceTest { vpnNetworkAgent.disconnect(); defaultCallback.assertNoCallback(); - vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN); + mCm.unregisterNetworkCallback(defaultCallback); + } + + @Test + public void testVpnWithInternet() { + final int uid = Process.myUid(); + + final TestNetworkCallback defaultCallback = new TestNetworkCallback(); + mCm.registerDefaultNetworkCallback(defaultCallback); + + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(true); + + defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); + assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); + + MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN); + final ArraySet<UidRange> ranges = new ArraySet<>(); + ranges.add(new UidRange(uid, uid)); mMockVpn.setNetworkAgent(vpnNetworkAgent); mMockVpn.setUids(ranges); vpnNetworkAgent.connect(true /* validated */, true /* hasInternet */); mMockVpn.connect(); + defaultCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); @@ -4764,14 +4798,6 @@ public class ConnectivityServiceTest { defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent); defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN); - ranges.clear(); - mMockVpn.setNetworkAgent(vpnNetworkAgent); - mMockVpn.setUids(ranges); - vpnNetworkAgent.connect(false /* validated */, true /* hasInternet */); - mMockVpn.connect(); - defaultCallback.assertNoCallback(); - mCm.unregisterNetworkCallback(defaultCallback); } @@ -4874,6 +4900,70 @@ public class ConnectivityServiceTest { } @Test + public void testNullUnderlyingNetworks() { + final int uid = Process.myUid(); + + final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); + final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() + .removeCapability(NET_CAPABILITY_NOT_VPN) + .addTransportType(TRANSPORT_VPN) + .build(); + NetworkCapabilities nc; + mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); + vpnNetworkCallback.assertNoCallback(); + + final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN); + final ArraySet<UidRange> ranges = new ArraySet<>(); + ranges.add(new UidRange(uid, uid)); + mMockVpn.setNetworkAgent(vpnNetworkAgent); + mMockVpn.connect(); + mMockVpn.setUids(ranges); + vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */); + + vpnNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); + nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); + assertTrue(nc.hasTransport(TRANSPORT_VPN)); + assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); + assertFalse(nc.hasTransport(TRANSPORT_WIFI)); + // By default, VPN is set to track default network (i.e. its underlying networks is null). + // In case of no default network, VPN is considered metered. + assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); + + // Connect to Cell; Cell is the default network. + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + mCellNetworkAgent.connect(true); + + vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED), + vpnNetworkAgent); + + // Connect to WiFi; WiFi is the new default. + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); + mWiFiNetworkAgent.connect(true); + + vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN) + && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) + && caps.hasCapability(NET_CAPABILITY_NOT_METERED), + vpnNetworkAgent); + + // Disconnect Cell. The default network did not change, so there shouldn't be any changes in + // the capabilities. + mCellNetworkAgent.disconnect(); + + // Disconnect wifi too. Now we have no default network. + mWiFiNetworkAgent.disconnect(); + + vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN) + && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED), + vpnNetworkAgent); + + mMockVpn.disconnect(); + } + + @Test public void testNetworkBlockedStatus() { final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); final NetworkRequest cellRequest = new NetworkRequest.Builder() diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 9578ded1a089..aa6cbda0479d 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -37,7 +37,6 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkMisc; -import android.net.NetworkStack; import android.os.INetworkManagementService; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -74,16 +73,12 @@ public class LingerMonitorTest { @Mock NetworkMisc mMisc; @Mock NetworkNotificationManager mNotifier; @Mock Resources mResources; - @Mock NetworkStack mNetworkStack; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mCtx.getResources()).thenReturn(mResources); when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity"); - when(mCtx.getSystemServiceName(NetworkStack.class)) - .thenReturn(Context.NETWORK_STACK_SERVICE); - when(mCtx.getSystemService(Context.NETWORK_STACK_SERVICE)).thenReturn(mNetworkStack); mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT); } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index b6356076db60..533d7ad2a472 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -35,6 +35,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -194,10 +195,6 @@ public class TetheringTest { } public class MockIpServerDependencies extends IpServer.Dependencies { - MockIpServerDependencies() { - super(null); - } - @Override public RouterAdvertisementDaemon getRouterAdvertisementDaemon( InterfaceParams ifParams) { @@ -265,7 +262,7 @@ public class TetheringTest { } @Override - public IpServer.Dependencies getIpServerDependencies(Context context) { + public IpServer.Dependencies getIpServerDependencies() { return mIpServerDependencies; } @@ -274,6 +271,11 @@ public class TetheringTest { isTetheringSupportedCalls++; return true; } + + @Override + public int getDefaultDataSubscriptionId() { + return INVALID_SUBSCRIPTION_ID; + } } private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 46de3d0608ff..f169d6b5bee3 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -566,7 +566,7 @@ public class VpnTest { final NetworkCapabilities caps = new NetworkCapabilities(); - Vpn.updateCapabilities( + Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {}, caps, false /* isAlwaysMetered */); assertTrue(caps.hasTransport(TRANSPORT_VPN)); assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); @@ -577,7 +577,7 @@ public class VpnTest { assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - Vpn.updateCapabilities( + Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {mobile}, caps, @@ -591,7 +591,7 @@ public class VpnTest { assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - Vpn.updateCapabilities( + Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */); assertTrue(caps.hasTransport(TRANSPORT_VPN)); assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); @@ -602,7 +602,7 @@ public class VpnTest { assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - Vpn.updateCapabilities( + Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */); assertTrue(caps.hasTransport(TRANSPORT_VPN)); assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); @@ -613,7 +613,7 @@ public class VpnTest { assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - Vpn.updateCapabilities( + Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {mobile, wifi}, caps, diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java index ec286759354a..193f3806dbf6 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -140,7 +141,8 @@ public final class EntitlementManagerTest { mMockContext = new MockContext(mContext); mSM = new TestStateMachine(); mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); } @After @@ -168,7 +170,8 @@ public final class EntitlementManagerTest { @Test public void canRequireProvisioning() { setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertTrue(mEnMgr.isTetherProvisioningRequired()); } @@ -177,7 +180,8 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) .thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // Couldn't get the CarrierConfigManager, but still had a declared provisioning app. // Therefore provisioning still be required. assertTrue(mEnMgr.isTetherProvisioningRequired()); @@ -187,7 +191,8 @@ public final class EntitlementManagerTest { public void toleratesCarrierConfigMissing() { setupForRequiredProvisioning(); when(mCarrierConfigManager.getConfig()).thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // We still have a provisioning app configured, so still require provisioning. assertTrue(mEnMgr.isTetherProvisioningRequired()); } @@ -197,11 +202,13 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertFalse(mEnMgr.isTetherProvisioningRequired()); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(new String[] {"malformedApp"}); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertFalse(mEnMgr.isTetherProvisioningRequired()); } @@ -223,7 +230,8 @@ public final class EntitlementManagerTest { assertFalse(mEnMgr.everRunUiEntitlement); setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); // 2. No cache value and don't need to run entitlement check. mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java index 521778484d91..01b904d8f088 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java @@ -22,10 +22,12 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -44,26 +46,39 @@ import android.test.mock.MockContentResolver; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; -import java.util.Iterator; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Iterator; @RunWith(AndroidJUnit4.class) @SmallTest public class TetheringConfigurationTest { private final SharedLog mLog = new SharedLog("TetheringConfigurationTest"); + + private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; @Mock private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private Resources mResources; + @Mock private Resources mResourcesForSubId; private MockContentResolver mContentResolver; private Context mMockContext; private boolean mHasTelephonyManager; + private class MockTetheringConfiguration extends TetheringConfiguration { + MockTetheringConfiguration(Context ctx, SharedLog log, int id) { + super(ctx, log, id); + } + + @Override + protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { + return mResourcesForSubId; + } + } + private class MockContext extends BroadcastInterceptingContext { MockContext(Context base) { super(base); @@ -99,6 +114,9 @@ public class TetheringConfigurationTest { .thenReturn(new String[0]); when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) .thenReturn(new int[0]); + when(mResources.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(new String[0]); mContentResolver = new MockContentResolver(); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mMockContext = new MockContext(mContext); @@ -111,7 +129,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = true; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.isDunRequired); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); @@ -127,7 +146,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = true; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertFalse(cfg.isDunRequired); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); @@ -143,7 +163,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.isDunRequired); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); // Just to prove we haven't clobbered Wi-Fi: @@ -160,7 +181,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); @@ -181,7 +203,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); @@ -199,7 +222,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_WIFI, upstreamIterator.next().intValue()); @@ -214,7 +238,8 @@ public class TetheringConfigurationTest { public void testNewDhcpServerDisabled() { Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.enableLegacyDhcpServer); } @@ -222,7 +247,41 @@ public class TetheringConfigurationTest { public void testNewDhcpServerEnabled() { Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertFalse(cfg.enableLegacyDhcpServer); } + + @Test + public void testGetResourcesBySubId() { + setUpResourceForSubId(); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertTrue(cfg.provisioningApp.length == 0); + final int anyValidSubId = 1; + final MockTetheringConfiguration mockCfg = + new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId); + assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]); + assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]); + } + + private void setUpResourceForSubId() { + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_dhcp_range)).thenReturn(new String[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_usb_regexs)).thenReturn(new String[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_wifi_regexs)) + .thenReturn(new String[]{ "test_wlan\\d" }); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_bluetooth_regexs)) + .thenReturn(new String[0]); + when(mResourcesForSubId.getIntArray( + com.android.internal.R.array.config_tether_upstream_types)) + .thenReturn(new int[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(PROVISIONING_APP_NAME); + } + } diff --git a/tools/preload/Android.bp b/tools/preload/Android.bp new file mode 100644 index 000000000000..809ee474969a --- /dev/null +++ b/tools/preload/Android.bp @@ -0,0 +1,17 @@ +java_library_host { + name: "preload", + srcs: [ + "Compile.java", + "LoadedClass.java", + "MemoryUsage.java", + "Operation.java", + "Policy.java", + "PrintCsv.java", + "PrintHtmlDiff.java", + "PrintPsTree.java", + "Proc.java", + "Record.java", + "Root.java", + "WritePreloadedClassFile.java", + ], +} diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk deleted file mode 100644 index 14a4547cccbf..000000000000 --- a/tools/preload/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - Compile.java \ - LoadedClass.java \ - MemoryUsage.java \ - Operation.java \ - Policy.java \ - PrintCsv.java \ - PrintHtmlDiff.java \ - PrintPsTree.java \ - Proc.java \ - Record.java \ - Root.java \ - WritePreloadedClassFile.java - -LOCAL_MODULE:= preload - -include $(BUILD_HOST_JAVA_LIBRARY) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/preload/loadclass/Android.bp b/tools/preload/loadclass/Android.bp new file mode 100644 index 000000000000..6f12015dae2b --- /dev/null +++ b/tools/preload/loadclass/Android.bp @@ -0,0 +1,4 @@ +java_test { + name: "loadclass", + srcs: ["**/*.java"], +} diff --git a/tools/preload/loadclass/Android.mk b/tools/preload/loadclass/Android.mk deleted file mode 100644 index 65828be617df..000000000000 --- a/tools/preload/loadclass/Android.mk +++ /dev/null @@ -1,9 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_MODULE_TAGS := tests - -LOCAL_MODULE := loadclass - -include $(BUILD_JAVA_LIBRARY) |