diff options
71 files changed, 2059 insertions, 743 deletions
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java index 5f13a5ce3aae..90c8c0358549 100644 --- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java +++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java @@ -66,6 +66,7 @@ public final class Telecom extends BaseCommand { private static final String COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT = "set-phone-acct-suggestion-component"; private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account"; + private static final String COMMAND_SET_CALL_DIAGNOSTIC_SERVICE = "set-call-diagnostic-service"; private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer"; private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer"; private static final String COMMAND_STOP_BLOCK_SUPPRESSION = "stop-block-suppression"; @@ -111,6 +112,7 @@ public final class Telecom extends BaseCommand { + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN>" + " <LABEL> <ADDRESS>\n" + "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n" + + "usage: telecom set-call-diagnostic-service <PACKAGE>\n" + "usage: telecom set-default-dialer <PACKAGE>\n" + "usage: telecom get-default-dialer\n" + "usage: telecom get-system-dialer\n" @@ -130,6 +132,7 @@ public final class Telecom extends BaseCommand { + "telecom set-phone-account-disabled: Disables the given phone account, if it" + " has already been registered with telecom.\n" + "\n" + + "telecom set-call-diagnostic-service: overrides call diagnostic service.\n" + "telecom set-default-dialer: Sets the override default dialer to the given" + " component; this will override whatever the dialer role is set to.\n" + "\n" @@ -205,6 +208,9 @@ public final class Telecom extends BaseCommand { case COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT: runSetTestPhoneAcctSuggestionComponent(); break; + case COMMAND_SET_CALL_DIAGNOSTIC_SERVICE: + runSetCallDiagnosticService(); + break; case COMMAND_REGISTER_SIM_PHONE_ACCOUNT: runRegisterSimPhoneAccount(); break; @@ -319,6 +325,13 @@ public final class Telecom extends BaseCommand { mTelecomService.addOrRemoveTestCallCompanionApp(packageName, isAddedBool); } + private void runSetCallDiagnosticService() throws RemoteException { + String packageName = nextArg(); + if ("default".equals(packageName)) packageName = null; + mTelecomService.setTestCallDiagnosticService(packageName); + System.out.println("Success - " + packageName + " set as call diagnostic service."); + } + private void runSetTestPhoneAcctSuggestionComponent() throws RemoteException { final String componentName = nextArg(); mTelecomService.setTestPhoneAcctSuggestionComponent(componentName); diff --git a/core/api/current.txt b/core/api/current.txt index 3bba4b34e73c..d90b9d405fc3 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -24875,6 +24875,7 @@ package android.net { method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms(); method public int getTruncationLengthBits(); method public void writeToParcel(android.os.Parcel, int); + field public static final String AUTH_AES_CMAC = "cmac(aes)"; field public static final String AUTH_AES_XCBC = "xcbc(aes)"; field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))"; field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)"; @@ -37885,6 +37886,10 @@ package android.telecom { method public void unhold(); method public void unregisterCallback(android.telecom.Call.Callback); field @Deprecated public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; + field public static final String EVENT_CLEAR_DIAGNOSTIC_MESSAGE = "android.telecom.event.CLEAR_DIAGNOSTIC_MESSAGE"; + field public static final String EVENT_DISPLAY_DIAGNOSTIC_MESSAGE = "android.telecom.event.DISPLAY_DIAGNOSTIC_MESSAGE"; + field public static final String EXTRA_DIAGNOSTIC_MESSAGE = "android.telecom.extra.DIAGNOSTIC_MESSAGE"; + field public static final String EXTRA_DIAGNOSTIC_MESSAGE_ID = "android.telecom.extra.DIAGNOSTIC_MESSAGE_ID"; field public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS"; field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED"; field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; @@ -41026,6 +41031,11 @@ package android.telephony { method public void unregisterPhoneStateListener(@NonNull android.telephony.PhoneStateListener); method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE"; + field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE"; + field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "android.telephony.action.CARRIER_SIGNAL_REDIRECTED"; + field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + field public static final String ACTION_CARRIER_SIGNAL_RESET = "android.telephony.action.CARRIER_SIGNAL_RESET"; field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED"; field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED"; @@ -41072,16 +41082,23 @@ package android.telephony { field public static final int ERI_OFF = 1; // 0x1 field public static final int ERI_ON = 0; // 0x0 field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; + field public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL"; + field public static final String EXTRA_APN_TYPE = "android.telephony.extra.APN_TYPE"; field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID"; field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME"; + field public static final String EXTRA_DATA_FAIL_CAUSE = "android.telephony.extra.DATA_FAIL_CAUSE"; + field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "android.telephony.extra.DEFAULT_NETWORK_AVAILABLE"; field public static final String EXTRA_HIDE_PUBLIC_SETTINGS = "android.telephony.extra.HIDE_PUBLIC_SETTINGS"; field @Deprecated public static final String EXTRA_INCOMING_NUMBER = "incoming_number"; field public static final String EXTRA_IS_REFRESH = "android.telephony.extra.IS_REFRESH"; field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY"; field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; + field public static final String EXTRA_PCO_ID = "android.telephony.extra.PCO_ID"; + field public static final String EXTRA_PCO_VALUE = "android.telephony.extra.PCO_VALUE"; field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE"; + field public static final String EXTRA_REDIRECTION_URL = "android.telephony.extra.REDIRECTION_URL"; field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID"; field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME"; field public static final String EXTRA_STATE = "state"; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 32782d29f50b..24adb7d61978 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -14,6 +14,18 @@ package android.net { method public int getResourceId(); } + public final class NetworkStateSnapshot implements android.os.Parcelable { + ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR; + field public final int legacyType; + field @NonNull public final android.net.LinkProperties linkProperties; + field @NonNull public final android.net.Network network; + field @NonNull public final android.net.NetworkCapabilities networkCapabilities; + field @Nullable public final String subscriberId; + } + public class NetworkWatchlistManager { method @Nullable public byte[] getWatchlistConfigHash(); } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index d214be3ba19a..801b08e76231 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -30,6 +30,7 @@ package android { field public static final String BACKUP = "android.permission.BACKUP"; field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE"; field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE"; + field public static final String BIND_CALL_DIAGNOSTIC_SERVICE = "android.permission.BIND_CALL_DIAGNOSTIC_SERVICE"; field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE"; field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE"; @@ -4309,9 +4310,10 @@ package android.media { } public static class AudioTrack.TunerConfiguration { - ctor @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public AudioTrack.TunerConfiguration(@IntRange(from=1) int, @IntRange(from=1) int); + ctor @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public AudioTrack.TunerConfiguration(@IntRange(from=0) int, @IntRange(from=1) int); method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getContentId(); method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getSyncId(); + field public static final int CONTENT_ID_NONE = 0; // 0x0 } public class HwAudioSource { @@ -8942,6 +8944,16 @@ package android.telecom { ctor @Deprecated public Call.Listener(); } + public abstract class CallDiagnosticService extends android.app.Service { + ctor public CallDiagnosticService(); + method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); + method public abstract void onBluetoothCallQualityReportReceived(@NonNull android.telecom.BluetoothCallQualityReport); + method public abstract void onCallAudioStateChanged(@NonNull android.telecom.CallAudioState); + method @NonNull public abstract android.telecom.DiagnosticCall onInitializeDiagnosticCall(@NonNull android.telecom.Call.Details); + method public abstract void onRemoveDiagnosticCall(@NonNull android.telecom.DiagnosticCall); + field public static final String SERVICE_INTERFACE = "android.telecom.CallDiagnosticService"; + } + public static class CallScreeningService.CallResponse.Builder { method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); } @@ -8973,6 +8985,9 @@ package android.telecom { method public void setTelecomCallId(@NonNull String); field public static final int CAPABILITY_CONFERENCE_HAS_NO_CHILDREN = 2097152; // 0x200000 field public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 262144; // 0x40000 + field public static final String EVENT_DEVICE_TO_DEVICE_MESSAGE = "android.telecom.event.DEVICE_TO_DEVICE_MESSAGE"; + field public static final String EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE = "android.telecom.extra.DEVICE_TO_DEVICE_MESSAGE_TYPE"; + field public static final String EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE = "android.telecom.extra.DEVICE_TO_DEVICE_MESSAGE_VALUE"; field public static final String EXTRA_DISABLE_ADD_CALL = "android.telecom.extra.DISABLE_ADD_CALL"; field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 1; // 0x1 field public static final int PROPERTY_GENERIC_CONFERENCE = 2; // 0x2 @@ -8988,6 +9003,34 @@ package android.telecom { method public final void addExistingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.Connection, @NonNull android.telecom.Conference); } + public abstract class DiagnosticCall { + ctor public DiagnosticCall(); + method public final void clearDiagnosticMessage(int); + method public final void displayDiagnosticMessage(int, @NonNull CharSequence); + method @NonNull public android.telecom.Call.Details getCallDetails(); + method public abstract void onCallDetailsChanged(@NonNull android.telecom.Call.Details); + method @Nullable public abstract CharSequence onCallDisconnected(int, int); + method @Nullable public abstract CharSequence onCallDisconnected(@NonNull android.telephony.ims.ImsReasonInfo); + method public abstract void onCallQualityReceived(@NonNull android.telephony.CallQuality); + method public abstract void onReceiveDeviceToDeviceMessage(int, int); + method public final void sendDeviceToDeviceMessage(int, int); + field public static final int AUDIO_CODEC_AMR_NB = 3; // 0x3 + field public static final int AUDIO_CODEC_AMR_WB = 2; // 0x2 + field public static final int AUDIO_CODEC_EVS = 1; // 0x1 + field public static final int BATTERY_STATE_CHARGING = 3; // 0x3 + field public static final int BATTERY_STATE_GOOD = 2; // 0x2 + field public static final int BATTERY_STATE_LOW = 1; // 0x1 + field public static final int COVERAGE_GOOD = 2; // 0x2 + field public static final int COVERAGE_POOR = 1; // 0x1 + field public static final int MESSAGE_CALL_AUDIO_CODEC = 2; // 0x2 + field public static final int MESSAGE_CALL_NETWORK_TYPE = 1; // 0x1 + field public static final int MESSAGE_DEVICE_BATTERY_STATE = 3; // 0x3 + field public static final int MESSAGE_DEVICE_NETWORK_COVERAGE = 4; // 0x4 + field public static final int NETWORK_TYPE_IWLAN = 2; // 0x2 + field public static final int NETWORK_TYPE_LTE = 1; // 0x1 + field public static final int NETWORK_TYPE_NR = 3; // 0x3 + } + public abstract class InCallService extends android.app.Service { method @Deprecated public android.telecom.Phone getPhone(); method @Deprecated public void onPhoneCreated(android.telecom.Phone); @@ -10349,6 +10392,24 @@ package android.telephony.cdma { package android.telephony.data { + public class ApnSetting implements android.os.Parcelable { + method public static int getApnTypeInt(@NonNull String); + method @NonNull public static String getApnTypeString(int); + field public static final String TYPE_ALL_STRING = "*"; + field public static final String TYPE_CBS_STRING = "cbs"; + field public static final String TYPE_DEFAULT_STRING = "default"; + field public static final String TYPE_DUN_STRING = "dun"; + field public static final String TYPE_EMERGENCY_STRING = "emergency"; + field public static final String TYPE_FOTA_STRING = "fota"; + field public static final String TYPE_HIPRI_STRING = "hipri"; + field public static final String TYPE_IA_STRING = "ia"; + field public static final String TYPE_IMS_STRING = "ims"; + field public static final String TYPE_MCX_STRING = "mcx"; + field public static final String TYPE_MMS_STRING = "mms"; + field public static final String TYPE_SUPL_STRING = "supl"; + field public static final String TYPE_XCAP_STRING = "xcap"; + } + public final class DataCallResponse implements android.os.Parcelable { method public int describeContents(); method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); diff --git a/core/java/android/content/pm/permission/OWNERS b/core/java/android/content/pm/permission/OWNERS index d302b0ae1ea8..cf7e6890876a 100644 --- a/core/java/android/content/pm/permission/OWNERS +++ b/core/java/android/content/pm/permission/OWNERS @@ -1,10 +1,8 @@ # Bug component: 137825 +include platform/frameworks/base:/core/java/android/permission/OWNERS + toddke@android.com toddke@google.com patb@google.com -svetoslavganov@android.com -svetoslavganov@google.com -zhanghai@google.com -evanseverson@google.com -ntmyren@google.com + diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 0baf11e850c7..dc3b88a7c3be 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -19,7 +19,7 @@ package android.net; import android.net.DataUsageRequest; import android.net.INetworkStatsSession; import android.net.Network; -import android.net.NetworkState; +import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; @@ -68,7 +68,7 @@ interface INetworkStatsService { /** Force update of ifaces. */ void forceUpdateIfaces( in Network[] defaultNetworks, - in NetworkState[] networkStates, + in NetworkStateSnapshot[] snapshots, in String activeIface, in UnderlyingNetworkInfo[] underlyingNetworkInfos); /** Force update of statistics. */ diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java index e89451e4f4ef..8f1e2defd215 100644 --- a/core/java/android/net/IpSecAlgorithm.java +++ b/core/java/android/net/IpSecAlgorithm.java @@ -146,6 +146,25 @@ public final class IpSecAlgorithm implements Parcelable { public static final String AUTH_AES_XCBC = "xcbc(aes)"; /** + * AES-CMAC Authentication/Integrity Algorithm. + * + * <p>Keys for this algorithm must be 128 bits in length. + * + * <p>The only valid truncation length is 96 bits. + * + * <p>This algorithm may be available on the device. Caller MUST check if it is supported before + * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is + * included in the returned algorithm set. The returned algorithm set will not change unless the + * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is + * requested on an unsupported device. + * + * <p>@see {@link #getSupportedAlgorithms()} + */ + // This algorithm may be available on devices released before Android 12, and is guaranteed + // to be available on devices first shipped with Android 12 or later. + public static final String AUTH_AES_CMAC = "cmac(aes)"; + + /** * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm. * * <p>Valid lengths for keying material are {160, 224, 288}. @@ -191,6 +210,7 @@ public final class IpSecAlgorithm implements Parcelable { AUTH_HMAC_SHA384, AUTH_HMAC_SHA512, AUTH_AES_XCBC, + AUTH_AES_CMAC, AUTH_CRYPT_AES_GCM, AUTH_CRYPT_CHACHA20_POLY1305 }) @@ -215,6 +235,7 @@ public final class IpSecAlgorithm implements Parcelable { // STOPSHIP: b/170424293 Use Build.VERSION_CODES.S when it is defined ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1); ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1); + ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1); ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1); } @@ -383,6 +404,10 @@ public final class IpSecAlgorithm implements Parcelable { isValidLen = keyLen == 128; isValidTruncLen = truncLen == 96; break; + case AUTH_AES_CMAC: + isValidLen = keyLen == 128; + isValidTruncLen = truncLen == 96; + break; case AUTH_CRYPT_AES_GCM: // The keying material for GCM is a key plus a 32-bit salt isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32; @@ -416,6 +441,7 @@ public final class IpSecAlgorithm implements Parcelable { case AUTH_HMAC_SHA384: case AUTH_HMAC_SHA512: case AUTH_AES_XCBC: + case AUTH_AES_CMAC: return true; default: return false; diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 303a40755d4e..a5ece7b713c7 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -18,7 +18,6 @@ package android.net; import static android.net.ConnectivityManager.TYPE_WIFI; -import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.net.wifi.WifiInfo; @@ -180,29 +179,42 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType}, - * assuming that any mobile networks are using the current IMSI. The subType if applicable, - * should be set as one of the TelephonyManager.NETWORK_TYPE_* constants, or - * {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. + * Build a {@link NetworkIdentity} from the given {@link NetworkState} and + * {@code subType}, assuming that any mobile networks are using the current IMSI. + * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_* + * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. */ - public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state, - boolean defaultNetwork, @NetworkType int subType) { - final int legacyType = state.legacyNetworkType; + // TODO: Delete this function after NetworkPolicyManagerService finishes the migration. + public static NetworkIdentity buildNetworkIdentity(Context context, + NetworkState state, boolean defaultNetwork, @NetworkType int subType) { + final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network, + state.networkCapabilities, state.linkProperties, state.subscriberId, + state.legacyNetworkType); + return buildNetworkIdentity(context, snapshot, defaultNetwork, subType); + } - String subscriberId = null; + /** + * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and + * {@code subType}, assuming that any mobile networks are using the current IMSI. + * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_* + * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. + */ + public static NetworkIdentity buildNetworkIdentity(Context context, + NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) { + final int legacyType = snapshot.legacyType; + + final String subscriberId = snapshot.subscriberId; String networkId = null; - boolean roaming = !state.networkCapabilities.hasCapability( + boolean roaming = !snapshot.networkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); - boolean metered = !state.networkCapabilities.hasCapability( + boolean metered = !snapshot.networkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - subscriberId = state.subscriberId; - - final int oemManaged = getOemBitfield(state.networkCapabilities); + final int oemManaged = getOemBitfield(snapshot.networkCapabilities); if (legacyType == TYPE_WIFI) { - if (state.networkCapabilities.getSsid() != null) { - networkId = state.networkCapabilities.getSsid(); + if (snapshot.networkCapabilities.getSsid() != null) { + networkId = snapshot.networkCapabilities.getSsid(); if (networkId == null) { // TODO: Figure out if this code path never runs. If so, remove them. final WifiManager wifi = (WifiManager) context.getSystemService( diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java index 881b373fa241..b3d8d4e614da 100644 --- a/core/java/android/net/NetworkStateSnapshot.java +++ b/core/java/android/net/NetworkStateSnapshot.java @@ -16,8 +16,11 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -28,31 +31,49 @@ import java.util.Objects; * * @hide */ +@SystemApi(client = MODULE_LIBRARIES) public final class NetworkStateSnapshot implements Parcelable { + /** The network associated with this snapshot. */ @NonNull - public final LinkProperties linkProperties; + public final Network network; + + /** The {@link NetworkCapabilities} of the network associated with this snapshot. */ @NonNull public final NetworkCapabilities networkCapabilities; + + /** The {@link LinkProperties} of the network associated with this snapshot. */ @NonNull - public final Network network; + public final LinkProperties linkProperties; + + /** + * The Subscriber Id of the network associated with this snapshot. See + * {@link android.telephony.TelephonyManager#getSubscriberId()}. + */ @Nullable public final String subscriberId; + + /** + * The legacy type of the network associated with this snapshot. See + * {@code ConnectivityManager#TYPE_*}. + */ public final int legacyType; - public NetworkStateSnapshot(@NonNull LinkProperties linkProperties, - @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network, + public NetworkStateSnapshot(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities, + @NonNull LinkProperties linkProperties, @Nullable String subscriberId, int legacyType) { - this.linkProperties = Objects.requireNonNull(linkProperties); - this.networkCapabilities = Objects.requireNonNull(networkCapabilities); this.network = Objects.requireNonNull(network); + this.networkCapabilities = Objects.requireNonNull(networkCapabilities); + this.linkProperties = Objects.requireNonNull(linkProperties); this.subscriberId = subscriberId; this.legacyType = legacyType; } + /** @hide */ public NetworkStateSnapshot(@NonNull Parcel in) { - linkProperties = in.readParcelable(null); - networkCapabilities = in.readParcelable(null); network = in.readParcelable(null); + networkCapabilities = in.readParcelable(null); + linkProperties = in.readParcelable(null); subscriberId = in.readString(); legacyType = in.readInt(); } @@ -64,9 +85,9 @@ public final class NetworkStateSnapshot implements Parcelable { @Override public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeParcelable(linkProperties, flags); - out.writeParcelable(networkCapabilities, flags); out.writeParcelable(network, flags); + out.writeParcelable(networkCapabilities, flags); + out.writeParcelable(linkProperties, flags); out.writeString(subscriberId); out.writeInt(legacyType); } @@ -93,14 +114,14 @@ public final class NetworkStateSnapshot implements Parcelable { if (!(o instanceof NetworkStateSnapshot)) return false; NetworkStateSnapshot that = (NetworkStateSnapshot) o; return legacyType == that.legacyType - && Objects.equals(linkProperties, that.linkProperties) - && Objects.equals(networkCapabilities, that.networkCapabilities) && Objects.equals(network, that.network) + && Objects.equals(networkCapabilities, that.networkCapabilities) + && Objects.equals(linkProperties, that.linkProperties) && Objects.equals(subscriberId, that.subscriberId); } @Override public int hashCode() { - return Objects.hash(linkProperties, networkCapabilities, network, subscriberId, legacyType); + return Objects.hash(network, networkCapabilities, linkProperties, subscriberId, legacyType); } } diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index f2d67411ef3a..91d6a9bf69cb 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -23,7 +23,6 @@ import android.net.ITetheringStatsProvider; import android.net.Network; import android.net.NetworkStats; import android.net.RouteInfo; -import android.net.UidRange; /** * @hide diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index c9da6418471d..9ffc5aa0022c 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -657,16 +657,8 @@ public class ZygoteProcess { argsForZygote.add("--runtime-flags=" + runtimeFlags); if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) { argsForZygote.add("--mount-external-default"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) { - argsForZygote.add("--mount-external-read"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) { - argsForZygote.add("--mount-external-write"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) { - argsForZygote.add("--mount-external-full"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) { argsForZygote.add("--mount-external-installer"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) { - argsForZygote.add("--mount-external-legacy"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { argsForZygote.add("--mount-external-pass-through"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) { diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS index b32346848a69..19a3a8bd514a 100644 --- a/core/java/android/permission/OWNERS +++ b/core/java/android/permission/OWNERS @@ -1,7 +1,13 @@ # Bug component: 137825 +eugenesusla@google.com evanseverson@google.com +evanxinchen@google.com +ewol@google.com +guojing@google.com +jaysullivan@google.com ntmyren@google.com -zhanghai@google.com svetoslavganov@android.com svetoslavganov@google.com +theianchen@google.com +zhanghai@google.com diff --git a/core/java/android/permissionpresenterservice/OWNERS b/core/java/android/permissionpresenterservice/OWNERS index b32346848a69..fb6099cf7e5a 100644 --- a/core/java/android/permissionpresenterservice/OWNERS +++ b/core/java/android/permissionpresenterservice/OWNERS @@ -1,7 +1,3 @@ # Bug component: 137825 -evanseverson@google.com -ntmyren@google.com -zhanghai@google.com -svetoslavganov@android.com -svetoslavganov@google.com +include platform/frameworks/base:/core/java/android/permission/OWNERS diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 0f7365dcfd90..4b9de3678424 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -15093,30 +15093,6 @@ public final class Settings { /** * Performs a strict and comprehensive check of whether a calling package is allowed to - * change the state of network, as the condition differs for pre-M, M+, and - * privileged/preinstalled apps. The caller is expected to have either the - * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these - * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and - * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal - * permission and cannot be revoked. See http://b/23597341 - * - * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation - * of this app will be updated to the current time. - * @hide - */ - public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid, - String callingPackage, boolean throwException) { - if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) - == PackageManager.PERMISSION_GRANTED) { - return true; - } - return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, - callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, - PM_CHANGE_NETWORK_STATE, true); - } - - /** - * Performs a strict and comprehensive check of whether a calling package is allowed to * draw on top of other apps, as the conditions differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the callingPackage, * a negative result will be returned. diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS index 14aa38682d2b..5425c214de1f 100644 --- a/core/java/android/util/OWNERS +++ b/core/java/android/util/OWNERS @@ -2,5 +2,7 @@ per-file FeatureFlagUtils.java = sbasi@google.com per-file FeatureFlagUtils.java = tmfang@google.com per-file FeatureFlagUtils.java = asapperstein@google.com -per-file TypedValue.java = file:/core/java/android/content/res/OWNERS per-file AttributeSet.java = file:/core/java/android/content/res/OWNERS +per-file TypedValue.java = file:/core/java/android/content/res/OWNERS + +per-file PackageUtils.java = file:/core/java/android/content/pm/OWNERS diff --git a/core/java/android/util/apk/OWNERS b/core/java/android/util/apk/OWNERS new file mode 100644 index 000000000000..52c95501e541 --- /dev/null +++ b/core/java/android/util/apk/OWNERS @@ -0,0 +1 @@ +include /core/java/android/content/pm/OWNERS diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index c43c410ab995..a86984f44a41 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -57,6 +57,7 @@ per-file ViewRootImpl.java = file:/graphics/java/android/graphics/OWNERS per-file ViewRootImpl.java = file:/services/core/java/com/android/server/input/OWNERS per-file ViewRootImpl.java = file:/services/core/java/com/android/server/wm/OWNERS per-file ViewRootImpl.java = file:/core/java/android/view/inputmethod/OWNERS +per-file AccessibilityInteractionController.java = file:/services/accessibility/OWNERS # WindowManager per-file DisplayCutout.aidl = file:/services/core/java/com/android/server/wm/OWNERS diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index d99f30567311..1c4e4a2b119e 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -179,23 +179,11 @@ public final class Zygote { public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE; /** Default external storage should be mounted. */ public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT; - /** Read-only external storage should be mounted. */ - public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ; - /** Read-write external storage should be mounted. */ - public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE; - /** - * Mount mode for apps that are already installed on the device before the isolated_storage - * feature is enabled. - */ - public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY; /** * Mount mode for package installers which should give them access to * all obb dirs in addition to their package sandboxes */ public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER; - /** Read-write external storage should be mounted instead of package sandbox */ - public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL; - /** The lower file system should be bind mounted directly on external storage */ public static final int MOUNT_EXTERNAL_PASS_THROUGH = IVold.REMOUNT_MODE_PASS_THROUGH; diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java index 5a1c1710d32b..65b454d47db2 100644 --- a/core/java/com/android/internal/os/ZygoteArguments.java +++ b/core/java/com/android/internal/os/ZygoteArguments.java @@ -395,16 +395,8 @@ class ZygoteArguments { mNiceName = getAssignmentValue(arg); } else if (arg.equals("--mount-external-default")) { mMountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT; - } else if (arg.equals("--mount-external-read")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_READ; - } else if (arg.equals("--mount-external-write")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_WRITE; - } else if (arg.equals("--mount-external-full")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_FULL; - } else if (arg.equals("--mount-external-installer")) { + } else if (arg.equals("--mount-external-installer")) { mMountExternal = Zygote.MOUNT_EXTERNAL_INSTALLER; - } else if (arg.equals("--mount-external-legacy")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_LEGACY; } else if (arg.equals("--mount-external-pass-through")) { mMountExternal = Zygote.MOUNT_EXTERNAL_PASS_THROUGH; } else if (arg.equals("--mount-external-android-writable")) { diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index bcd203b6ca77..c9062d8a50bc 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -115,7 +115,6 @@ typedef const std::function<void(std::string)>& fail_fn_t; static pid_t gSystemServerPid = 0; static constexpr const char* kVoldAppDataIsolation = "persist.sys.vold_app_data_isolation_enabled"; -static constexpr const char* kPropFuse = "persist.sys.fuse"; static const char kZygoteClassName[] = "com/android/internal/os/Zygote"; static jclass gZygoteClass; static jmethodID gCallPostForkSystemServerHooks; @@ -305,31 +304,15 @@ static std::array<UsapTableEntry, USAP_POOL_SIZE_MAX_LIMIT> gUsapTable; static FileDescriptorTable* gOpenFdTable = nullptr; // Must match values in com.android.internal.os.Zygote. -// The order of entries here must be kept in sync with ExternalStorageViews array values. +// Note that there are gaps in the constants: +// This is to further keep the values consistent with IVold.aidl enum MountExternalKind { - MOUNT_EXTERNAL_NONE = 0, - MOUNT_EXTERNAL_DEFAULT = 1, - MOUNT_EXTERNAL_READ = 2, - MOUNT_EXTERNAL_WRITE = 3, - MOUNT_EXTERNAL_LEGACY = 4, - MOUNT_EXTERNAL_INSTALLER = 5, - MOUNT_EXTERNAL_FULL = 6, - MOUNT_EXTERNAL_PASS_THROUGH = 7, - MOUNT_EXTERNAL_ANDROID_WRITABLE = 8, - MOUNT_EXTERNAL_COUNT = 9 -}; - -// The order of entries here must be kept in sync with MountExternalKind enum values. -static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorageViews = { - "", // MOUNT_EXTERNAL_NONE - "/mnt/runtime/default", // MOUNT_EXTERNAL_DEFAULT - "/mnt/runtime/read", // MOUNT_EXTERNAL_READ - "/mnt/runtime/write", // MOUNT_EXTERNAL_WRITE - "/mnt/runtime/write", // MOUNT_EXTERNAL_LEGACY - "/mnt/runtime/write", // MOUNT_EXTERNAL_INSTALLER - "/mnt/runtime/full", // MOUNT_EXTERNAL_FULL - "/mnt/runtime/full", // MOUNT_EXTERNAL_PASS_THROUGH (only used w/ FUSE) - "/mnt/runtime/full", // MOUNT_EXTERNAL_ANDROID_WRITABLE (only used w/ FUSE) + MOUNT_EXTERNAL_NONE = 0, + MOUNT_EXTERNAL_DEFAULT = 1, + MOUNT_EXTERNAL_INSTALLER = 5, + MOUNT_EXTERNAL_PASS_THROUGH = 7, + MOUNT_EXTERNAL_ANDROID_WRITABLE = 8, + MOUNT_EXTERNAL_COUNT = 9 }; // Must match values in com.android.internal.os.Zygote. @@ -832,29 +815,20 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode, PrepareDir(user_source, 0710, user_id ? AID_ROOT : AID_SHELL, multiuser_get_uid(user_id, AID_EVERYBODY), fail_fn); - bool isFuse = GetBoolProperty(kPropFuse, false); bool isAppDataIsolationEnabled = GetBoolProperty(kVoldAppDataIsolation, false); - if (isFuse) { - if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) { + if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) { const std::string pass_through_source = StringPrintf("/mnt/pass_through/%d", user_id); PrepareDir(pass_through_source, 0710, AID_ROOT, AID_MEDIA_RW, fail_fn); BindMount(pass_through_source, "/storage", fail_fn); - } else if (mount_mode == MOUNT_EXTERNAL_INSTALLER) { + } else if (mount_mode == MOUNT_EXTERNAL_INSTALLER) { const std::string installer_source = StringPrintf("/mnt/installer/%d", user_id); BindMount(installer_source, "/storage", fail_fn); - } else if (isAppDataIsolationEnabled && mount_mode == MOUNT_EXTERNAL_ANDROID_WRITABLE) { + } else if (isAppDataIsolationEnabled && mount_mode == MOUNT_EXTERNAL_ANDROID_WRITABLE) { const std::string writable_source = StringPrintf("/mnt/androidwritable/%d", user_id); BindMount(writable_source, "/storage", fail_fn); - } else { - BindMount(user_source, "/storage", fail_fn); - } } else { - const std::string& storage_source = ExternalStorageViews[mount_mode]; - BindMount(storage_source, "/storage", fail_fn); - - // Mount user-specific symlink helper into place - BindMount(user_source, "/storage/self", fail_fn); + BindMount(user_source, "/storage", fail_fn); } } diff --git a/core/proto/OWNERS b/core/proto/OWNERS index 99fd21592411..e62b5c102a59 100644 --- a/core/proto/OWNERS +++ b/core/proto/OWNERS @@ -15,6 +15,7 @@ per-file settings_enums.proto=tmfang@google.com ogunwale@google.com jjaggi@google.com roosa@google.com +per-file package_item_info.proto = toddke@google.com per-file usagestatsservice.proto, usagestatsservice_v2.proto = mwachens@google.com per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index dc935c09ad8f..3a0a032e3f15 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2267,6 +2267,15 @@ <permission android:name="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE" android:protectionLevel="signature" /> + <!-- Must be required by a {@link android.telecom.CallDiagnosticService}, + to ensure that only the system can bind to it. + <p>Protection level: signature + @SystemApi + @hide + --> + <permission android:name="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE" + android:protectionLevel="signature" /> + <!-- Must be required by a {@link android.telecom.CallRedirectionService}, to ensure that only the system can bind to it. <p>Protection level: signature|privileged diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 93758b6d66d6..22a79ed12c24 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1691,7 +1691,7 @@ * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)", "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))" * SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))", - "xcbc(aes)", "rfc7539esp(chacha20,poly1305)" + "xcbc(aes)", "cmac(aes)", "rfc7539esp(chacha20,poly1305)" --> <string-array name="config_optionalIpSecAlgorithms" translatable="false"> <!-- Add algorithm here --> diff --git a/core/tests/coretests/src/android/view/accessibility/OWNERS b/core/tests/coretests/src/android/view/accessibility/OWNERS new file mode 100644 index 000000000000..b74281edbf52 --- /dev/null +++ b/core/tests/coretests/src/android/view/accessibility/OWNERS @@ -0,0 +1 @@ +include /core/java/android/view/accessibility/OWNERS diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index d7ef4549ca3f..1b05c3b57256 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -922,12 +922,21 @@ public class AudioTrack extends PlayerBase private final int mSyncId; /** + * A special content id for {@link #TunerConfiguration(int, int)} + * indicating audio is delivered + * from an {@code AudioTrack} write, not tunneled from the tuner stack. + */ + public static final int CONTENT_ID_NONE = 0; + + /** * Constructs a TunerConfiguration instance for use in {@link AudioTrack.Builder} * * @param contentId selects the audio stream to use. * The contentId may be obtained from - * {@link android.media.tv.tuner.filter.Filter#getId()}. - * This is always a positive number. + * {@link android.media.tv.tuner.filter.Filter#getId()}, + * such obtained id is always a positive number. + * If audio is to be delivered through an {@code AudioTrack} write + * then {@code CONTENT_ID_NONE} may be used. * @param syncId selects the clock to use for synchronization * of audio with other streams such as video. * The syncId may be obtained from @@ -936,10 +945,10 @@ public class AudioTrack extends PlayerBase */ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public TunerConfiguration( - @IntRange(from = 1) int contentId, @IntRange(from = 1)int syncId) { - if (contentId < 1) { + @IntRange(from = 0) int contentId, @IntRange(from = 1)int syncId) { + if (contentId < 0) { throw new IllegalArgumentException( - "contentId " + contentId + " must be positive"); + "contentId " + contentId + " must be positive or CONTENT_ID_NONE"); } if (syncId < 1) { throw new IllegalArgumentException("syncId " + syncId + " must be positive"); diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java index c7f5e9a5ceec..f11febc15d04 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.TelephonyManager; +import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.Log; @@ -85,8 +86,8 @@ public class CustomConfigLoader { case TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED: configs = b.getStringArray(CarrierConfigManager .KEY_CARRIER_DEFAULT_ACTIONS_ON_DCFAILURE_STRING_ARRAY); - arg1 = intent.getStringExtra(TelephonyManager.EXTRA_APN_TYPE); - arg2 = intent.getStringExtra(TelephonyManager.EXTRA_ERROR_CODE); + arg1 = String.valueOf(intent.getIntExtra(TelephonyManager.EXTRA_APN_TYPE, -1)); + arg2 = intent.getStringExtra(TelephonyManager.EXTRA_DATA_FAIL_CAUSE); break; case TelephonyManager.ACTION_CARRIER_SIGNAL_RESET: configs = b.getStringArray(CarrierConfigManager @@ -141,10 +142,24 @@ public class CustomConfigLoader { // case 1 actionStr = splitStr[0]; } else if (splitStr.length == 2 && arg1 != null && arg2 != null) { - // case 2 + // case 2. The only thing that uses this is CARRIER_SIGNAL_REQUEST_NETWORK_FAILED, + // and the carrier config for that can provide either an int or string for the apn type, + // depending on when it was introduced. Therefore, return a positive match if either + // the int version or the string version of the apn type in the broadcast matches. + String apnInIntFormat = arg1; + String apnInStringFormat = null; + try { + int apnInt = Integer.parseInt(apnInIntFormat); + apnInStringFormat = ApnSetting.getApnTypeString(apnInt); + } catch (NumberFormatException e) { + Log.e(TAG, "Got invalid apn type from broadcast: " + apnInIntFormat); + } + String[] args = splitStr[0].split(INTRA_GROUP_DELIMITER); - if (args.length == 2 && TextUtils.equals(arg1, args[0]) && - TextUtils.equals(arg2, args[1])) { + boolean doesArg1Match = TextUtils.equals(apnInIntFormat, args[0]) + || (apnInStringFormat != null && TextUtils.equals(apnInStringFormat, args[0])); + if (args.length == 2 && doesArg1Match + && TextUtils.equals(arg2, args[1])) { actionStr = splitStr[1]; } } else if ((splitStr.length == 2) && (arg1 != null) && (arg2 == null)) { diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index 6273f4bb577b..66e7da43cb66 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -2245,31 +2245,6 @@ public class ConnectivityManager { } } - /* TODO: These permissions checks don't belong in client-side code. Move them to - * services.jar, possibly in com.android.server.net. */ - - /** {@hide} */ - public static final void enforceChangePermission(Context context, - String callingPkg, String callingAttributionTag) { - int uid = Binder.getCallingUid(); - checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg, - callingAttributionTag, true /* throwException */); - } - - /** - * Check if the package is a allowed to change the network state. This also accounts that such - * an access happened. - * - * @return {@code true} iff the package is allowed to change the network state. - */ - // TODO: Remove method and replace with direct call once R code is pushed to AOSP - private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context, - int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag, - boolean throwException) { - return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage, - throwException); - } - /** * Check if the package is a allowed to write settings. This also accounts that such an access * happened. diff --git a/core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl b/packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl index 7979afc54f90..7979afc54f90 100644 --- a/core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl +++ b/packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl diff --git a/core/java/android/net/UidRange.aidl b/packages/Connectivity/framework/src/android/net/UidRange.aidl index f70fc8e2fefd..f70fc8e2fefd 100644 --- a/core/java/android/net/UidRange.aidl +++ b/packages/Connectivity/framework/src/android/net/UidRange.aidl diff --git a/core/java/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java index be5964dca36e..26518d32edcb 100644 --- a/core/java/android/net/UidRange.java +++ b/packages/Connectivity/framework/src/android/net/UidRange.java @@ -16,8 +16,6 @@ package android.net; -import static android.os.UserHandle.PER_USER_RANGE; - import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; @@ -60,6 +58,7 @@ public final class UidRange implements Parcelable { return UserHandle.getUserHandleForUid(stop).getIdentifier(); } + /** Returns whether the UidRange contains the specified UID. */ public boolean contains(int uid) { return start <= uid && uid <= stop; } @@ -72,7 +71,7 @@ public final class UidRange implements Parcelable { } /** - * @return {@code true} if this range contains every UID contained by the {@param other} range. + * @return {@code true} if this range contains every UID contained by the {@code other} range. */ public boolean containsRange(UidRange other) { return start <= other.start && other.stop <= stop; @@ -118,18 +117,18 @@ public final class UidRange implements Parcelable { } public static final @android.annotation.NonNull Creator<UidRange> CREATOR = - new Creator<UidRange>() { - @Override - public UidRange createFromParcel(Parcel in) { - int start = in.readInt(); - int stop = in.readInt(); + new Creator<UidRange>() { + @Override + public UidRange createFromParcel(Parcel in) { + int start = in.readInt(); + int stop = in.readInt(); - return new UidRange(start, stop); - } - @Override - public UidRange[] newArray(int size) { - return new UidRange[size]; - } + return new UidRange(start, stop); + } + @Override + public UidRange[] newArray(int size) { + return new UidRange[size]; + } }; /** diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index cb0bf6fcbae7..d1cd3be35af8 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -120,6 +120,7 @@ import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; import android.net.NetworkState; +import android.net.NetworkStateSnapshot; import android.net.NetworkTestResultParcelable; import android.net.NetworkUtils; import android.net.NetworkWatchlistManager; @@ -141,10 +142,13 @@ import android.net.UnderlyingNetworkInfo; import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; -import android.net.metrics.INetdEventListener; import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; +import android.net.resolv.aidl.DnsHealthEventParcel; +import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; +import android.net.resolv.aidl.Nat64PrefixEventParcel; +import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; @@ -2036,25 +2040,24 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } - private class NetdEventCallback extends INetdEventListener.Stub { + class DnsResolverUnsolicitedEventCallback extends + IDnsResolverUnsolicitedEventListener.Stub { @Override - public void onPrivateDnsValidationEvent(int netId, String ipAddress, - String hostname, boolean validated) { + public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { try { mHandler.sendMessage(mHandler.obtainMessage( EVENT_PRIVATE_DNS_VALIDATION_UPDATE, - new PrivateDnsValidationUpdate(netId, - InetAddresses.parseNumericAddress(ipAddress), - hostname, validated))); + new PrivateDnsValidationUpdate(event.netId, + InetAddresses.parseNumericAddress(event.ipAddress), + event.hostname, event.validation))); } catch (IllegalArgumentException e) { loge("Error parsing ip address in validation event"); } } @Override - public void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, - String hostname, String[] ipAddresses, int ipAddressesCount, int uid) { - NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); + public void onDnsHealthEvent(final DnsHealthEventParcel event) { + NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); // Netd event only allow registrants from system. Each NetworkMonitor thread is under // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd // event callback for certain nai. e.g. cellular. Register here to pass to @@ -2063,34 +2066,18 @@ public class ConnectivityService extends IConnectivityManager.Stub // callback from each caller type. Need to re-factor NetdEventListenerService to allow // multiple NetworkMonitor registrants. if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { - nai.networkMonitor().notifyDnsResponse(returnCode); + nai.networkMonitor().notifyDnsResponse(event.healthResult); } } @Override - public void onNat64PrefixEvent(int netId, boolean added, - String prefixString, int prefixLength) { - mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength)); + public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { + mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, + event.prefixAddress, event.prefixLength)); } @Override - public void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, - int uid) { - } - - @Override - public void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, - byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, - long timestampNs) { - } - - @Override - public void onTcpSocketStatsEvent(int[] networkIds, int[] sentPackets, int[] lostPackets, - int[] rttsUs, int[] sentAckDiffsMs) { - } - - @Override - public int getInterfaceVersion() throws RemoteException { + public int getInterfaceVersion() { return this.VERSION; } @@ -2098,16 +2085,17 @@ public class ConnectivityService extends IConnectivityManager.Stub public String getInterfaceHash() { return this.HASH; } - }; + } @VisibleForTesting - protected final INetdEventListener mNetdEventCallback = new NetdEventCallback(); + protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = + new DnsResolverUnsolicitedEventCallback(); - private void registerNetdEventCallback() { + private void registerDnsResolverUnsolicitedEventListener() { try { - mDnsResolver.registerEventListener(mNetdEventCallback); + mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); } catch (Exception e) { - loge("Error registering DnsResolver callback: " + e); + loge("Error registering DnsResolver unsolicited event callback: " + e); } } @@ -2197,8 +2185,45 @@ public class ConnectivityService extends IConnectivityManager.Stub "ConnectivityService"); } + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * change the state of network, as the condition differs for pre-M, M+, and + * privileged/preinstalled apps. The caller is expected to have either the + * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these + * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and + * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal + * permission and cannot be revoked. See http://b/23597341 + * + * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation + * of this app will be updated to the current time. + */ private void enforceChangePermission(String callingPkg, String callingAttributionTag) { - ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag); + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) + == PackageManager.PERMISSION_GRANTED) { + return; + } + + if (callingPkg == null) { + throw new SecurityException("Calling package name is null."); + } + + final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class); + final int uid = mDeps.getCallingUid(); + final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid, + callingPkg, callingAttributionTag, null /* message */); + + if (mode == AppOpsManager.MODE_ALLOWED) { + return; + } + + if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) { + return; + } + + throw new SecurityException(callingPkg + " was not granted either of these permissions:" + + android.Manifest.permission.CHANGE_NETWORK_STATE + "," + + android.Manifest.permission.WRITE_SETTINGS + "."); } private void enforceSettingsPermission() { @@ -2401,7 +2426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // to ensure the tracking will be initialized correctly. mPermissionMonitor.startMonitoring(); mProxyTracker.loadGlobalProxy(); - registerNetdEventCallback(); + registerDnsResolverUnsolicitedEventListener(); synchronized (this) { mSystemReady = true; @@ -3329,21 +3354,21 @@ public class ConnectivityService extends IConnectivityManager.Stub handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); } - private void handleNat64PrefixEvent(int netId, boolean added, String prefixString, + private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, int prefixLength) { NetworkAgentInfo nai = mNetworkForNetId.get(netId); if (nai == null) return; - log(String.format("NAT64 prefix %s on netId %d: %s/%d", - (added ? "added" : "removed"), netId, prefixString, prefixLength)); + log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", + netId, operation, prefixAddress, prefixLength)); IpPrefix prefix = null; - if (added) { + if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { try { - prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString), + prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), prefixLength); } catch (IllegalArgumentException e) { - loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength); + loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); return; } } @@ -7916,8 +7941,16 @@ public class ConnectivityService extends IConnectivityManager.Stub final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo(); try { - mStatsService.forceUpdateIfaces(getDefaultNetworks(), getAllNetworkState(), activeIface, - underlyingNetworkInfos); + final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>(); + // TODO: Directly use NetworkStateSnapshot when feasible. + for (final NetworkState state : getAllNetworkState()) { + final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network, + state.networkCapabilities, state.linkProperties, state.subscriberId, + state.legacyNetworkType); + snapshots.add(snapshot); + } + mStatsService.forceUpdateIfaces(getDefaultNetworks(), snapshots.toArray( + new NetworkStateSnapshot[0]), activeIface, underlyingNetworkInfos); } catch (Exception ignored) { } } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 4e2519b47a47..c65b8e5cf75b 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -18,9 +18,7 @@ package com.android.server; import static android.Manifest.permission.ACCESS_MTP; import static android.Manifest.permission.INSTALL_PACKAGES; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; -import static android.Manifest.permission.WRITE_MEDIA_STORAGE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_LEGACY_STORAGE; @@ -4328,19 +4326,9 @@ class StorageManagerService extends IStorageManager.Stub } // Determine if caller is holding runtime permission - final boolean hasRead = StorageManager.checkPermissionAndCheckOp(mContext, false, 0, - uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE); final boolean hasWrite = StorageManager.checkPermissionAndCheckOp(mContext, false, 0, uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE); - // We're only willing to give out broad access if they also hold - // runtime permission; this is a firm CDD requirement - final boolean hasFull = mIPackageManager.checkUidPermission(WRITE_MEDIA_STORAGE, - uid) == PERMISSION_GRANTED; - if (hasFull && hasWrite) { - return Zygote.MOUNT_EXTERNAL_FULL; - } - // We're only willing to give out installer access if they also hold // runtime permission; this is a firm CDD requirement final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES, @@ -4360,19 +4348,7 @@ class StorageManagerService extends IStorageManager.Stub if ((hasInstall || hasInstallOp) && hasWrite) { return Zygote.MOUNT_EXTERNAL_INSTALLER; } - - // Otherwise we're willing to give out sandboxed or non-sandboxed if - // they hold the runtime permission - boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, - uid, packageName) == MODE_ALLOWED; - - if (hasLegacy && hasWrite) { - return Zygote.MOUNT_EXTERNAL_WRITE; - } else if (hasLegacy && hasRead) { - return Zygote.MOUNT_EXTERNAL_READ; - } else { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } + return Zygote.MOUNT_EXTERNAL_DEFAULT; } catch (RemoteException e) { // Should not happen } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 93f14328b50b..c02e1deb484e 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -77,6 +77,7 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LocalLog; @@ -2656,12 +2657,33 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { TelephonyUtils.dataStateToString(pdcs.getState())); intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName()); intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, - ApnSetting.getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask())); + getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask())); intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex); intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); } + /** + * Reimplementation of {@link ApnSetting#getApnTypesStringFromBitmask}. + */ + @VisibleForTesting + public static String getApnTypesStringFromBitmask(int apnTypeBitmask) { + List<String> types = new ArrayList<>(); + int remainingApnTypes = apnTypeBitmask; + // special case for DEFAULT since it's not a pure bit + if ((remainingApnTypes & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) { + types.add(ApnSetting.TYPE_DEFAULT_STRING); + remainingApnTypes &= ~ApnSetting.TYPE_DEFAULT; + } + while (remainingApnTypes != 0) { + int highestApnTypeBit = Integer.highestOneBit(remainingApnTypes); + String apnString = ApnSetting.getApnTypeString(highestApnTypeBit); + if (!TextUtils.isEmpty(apnString)) types.add(apnString); + remainingApnTypes &= ~highestApnTypeBit; + } + return TextUtils.join(",", types); + } + private void enforceNotifyPermissionOrCarrierPrivilege(String method) { if (checkNotifyPermission()) { return; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e4d2382574ba..fd8e1bc8a457 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -19834,7 +19834,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int getStorageMountMode(int pid, int uid) { if (uid == SHELL_UID || uid == ROOT_UID) { - return Zygote.MOUNT_EXTERNAL_FULL; + return Zygote.MOUNT_EXTERNAL_DEFAULT; } synchronized (mPidsSelfLocked) { final ProcessRecord pr = mPidsSelfLocked.get(pid); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index c5a6e7b83859..45cf95d0dff2 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -92,7 +92,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; -import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.system.Os; import android.text.TextUtils; @@ -1854,14 +1853,10 @@ public final class ProcessList { final IPackageManager pm = AppGlobals.getPackageManager(); permGids = pm.getPackageGids(app.info.packageName, MATCH_DIRECT_BOOT_AUTO, app.userId); - if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) { - mountExternal = Zygote.MOUNT_EXTERNAL_FULL; - } else { - StorageManagerInternal storageManagerInternal = LocalServices.getService( - StorageManagerInternal.class); - mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, - app.info.packageName); - } + StorageManagerInternal storageManagerInternal = LocalServices.getService( + StorageManagerInternal.class); + mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, + app.info.packageName); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 640d99f71ebe..cb631e0028eb 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1725,24 +1725,13 @@ public class AppOpsService extends IAppOpsService.Stub { if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } - if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, - packageName, null, true, "External storage policy", true) - != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, - packageName, null, true, "External storage policy", true) - != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_READ; - } - return Zygote.MOUNT_EXTERNAL_WRITE; + return Zygote.MOUNT_EXTERNAL_DEFAULT; } @Override public boolean hasExternalStorage(int uid, String packageName) { final int mountMode = getMountMode(uid, packageName); - return mountMode == Zygote.MOUNT_EXTERNAL_READ - || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; + return mountMode != Zygote.MOUNT_EXTERNAL_NONE; } }); } diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index 43d9ade67a11..4f6b5301e56f 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -19,6 +19,8 @@ package com.android.server.connectivity; import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_MIN_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS; @@ -147,17 +149,18 @@ public class DnsManager { } public static class PrivateDnsValidationUpdate { - final public int netId; - final public InetAddress ipAddress; - final public String hostname; - final public boolean validated; + public final int netId; + public final InetAddress ipAddress; + public final String hostname; + // Refer to IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_*. + public final int validationResult; public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress, - String hostname, boolean validated) { + String hostname, int validationResult) { this.netId = netId; this.ipAddress = ipAddress; this.hostname = hostname; - this.validated = validated; + this.validationResult = validationResult; } } @@ -216,10 +219,13 @@ public class DnsManager { if (!mValidationMap.containsKey(p)) { return; } - if (update.validated) { + if (update.validationResult == VALIDATION_RESULT_SUCCESS) { mValidationMap.put(p, ValidationStatus.SUCCEEDED); - } else { + } else if (update.validationResult == VALIDATION_RESULT_FAILURE) { mValidationMap.put(p, ValidationStatus.FAILED); + } else { + Log.e(TAG, "Unknown private dns validation operation=" + + update.validationResult); } } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 5b9a11bc5a31..3a5e10ed951a 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -97,7 +97,7 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkIdentity; import android.net.NetworkStack; -import android.net.NetworkState; +import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; @@ -296,7 +296,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** Last states of all networks sent from ConnectivityService. */ @GuardedBy("mStatsLock") @Nullable - private NetworkState[] mLastNetworkStates = null; + private NetworkStateSnapshot[] mLastNetworkStateSnapshots = null; private final DropBoxNonMonotonicObserver mNonMonotonicObserver = new DropBoxNonMonotonicObserver(); @@ -378,8 +378,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } case MSG_UPDATE_IFACES: { // If no cached states, ignore. - if (mLastNetworkStates == null) break; - updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface); + if (mLastNetworkStateSnapshots == null) break; + updateIfaces(mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface); break; } case MSG_PERFORM_POLL_REGISTER_ALERT: { @@ -967,10 +967,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - @Override public void forceUpdateIfaces( Network[] defaultNetworks, - NetworkState[] networkStates, + NetworkStateSnapshot[] networkStates, String activeIface, UnderlyingNetworkInfo[] underlyingNetworkInfos) { checkNetworkStackPermission(mContext); @@ -1248,13 +1247,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private void updateIfaces( Network[] defaultNetworks, - NetworkState[] networkStates, + NetworkStateSnapshot[] snapshots, String activeIface) { synchronized (mStatsLock) { mWakeLock.acquire(); try { mActiveIface = activeIface; - updateIfacesLocked(defaultNetworks, networkStates); + updateIfacesLocked(defaultNetworks, snapshots); } finally { mWakeLock.release(); } @@ -1262,13 +1261,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** - * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link - * NetworkStatsHistory}. When multiple networks are active on a single {@code iface}, + * Inspect all current {@link NetworkStateSnapshot}s to derive mapping from {@code iface} to + * {@link NetworkStatsHistory}. When multiple networks are active on a single {@code iface}, * they are combined under a single {@link NetworkIdentitySet}. */ @GuardedBy("mStatsLock") private void updateIfacesLocked(@Nullable Network[] defaultNetworks, - @NonNull NetworkState[] states) { + @NonNull NetworkStateSnapshot[] snapshots) { if (!mSystemReady) return; if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); @@ -1288,21 +1287,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDefaultNetworks = defaultNetworks; } - mLastNetworkStates = states; + mLastNetworkStateSnapshots = snapshots; final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled(); final ArraySet<String> mobileIfaces = new ArraySet<>(); - for (NetworkState state : states) { - final boolean isMobile = isNetworkTypeMobile(state.legacyNetworkType); - final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network); + for (NetworkStateSnapshot snapshot : snapshots) { + final boolean isMobile = isNetworkTypeMobile(snapshot.legacyType); + final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network); final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED - : getSubTypeForState(state); - final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state, + : getSubTypeForStateSnapshot(snapshot); + final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot, isDefault, subType); // Traffic occurring on the base interface is always counted for // both total usage and UID details. - final String baseIface = state.linkProperties.getInterfaceName(); + final String baseIface = snapshot.linkProperties.getInterfaceName(); if (baseIface != null) { findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident); @@ -1312,7 +1311,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // If IMS is metered, then the IMS network usage has already included VT usage. // VT is considered always metered in framework's layer. If VT is not metered // per carrier's policy, modem will report 0 usage for VT calls. - if (state.networkCapabilities.hasCapability( + if (snapshot.networkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) { // Copy the identify from IMS one but mark it as metered. @@ -1358,7 +1357,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // (or non eBPF offloaded) TX they would appear on both, however egress interface // accounting is explicitly bypassed for traffic from the clat uid. // - final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); + final List<LinkProperties> stackedLinks = snapshot.linkProperties.getStackedLinks(); for (LinkProperties stackedLink : stackedLinks) { final String stackedIface = stackedLink.getInterfaceName(); if (stackedIface != null) { @@ -1381,7 +1380,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different * transport types do not actually fill this value. */ - private int getSubTypeForState(@NonNull NetworkState state) { + private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) { if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { return 0; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 4896fd91fb6c..5607167078c8 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20,10 +20,8 @@ import static android.Manifest.permission.DELETE_PACKAGES; import static android.Manifest.permission.INSTALL_PACKAGES; import static android.Manifest.permission.MANAGE_DEVICE_ADMINS; import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS; -import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.MODE_IGNORED; @@ -92,7 +90,6 @@ import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER; import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; -import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; @@ -21603,24 +21600,18 @@ public class PackageManagerService extends IPackageManager.Stub mInjector.getStorageManagerInternal().addExternalStoragePolicy( new StorageManagerInternal.ExternalStorageMountPolicy() { - @Override - public int getMountMode(int uid, String packageName) { - if (Process.isIsolated(uid)) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } - if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { - return Zygote.MOUNT_EXTERNAL_READ; - } - return Zygote.MOUNT_EXTERNAL_WRITE; - } + @Override + public int getMountMode(int uid, String packageName) { + if (Process.isIsolated(uid)) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + return Zygote.MOUNT_EXTERNAL_DEFAULT; + } - @Override - public boolean hasExternalStorage(int uid, String packageName) { - return true; - } + @Override + public boolean hasExternalStorage(int uid, String packageName) { + return true; + } }); // Now that we're mostly running, clean up stale users and apps diff --git a/services/core/java/com/android/server/pm/permission/OWNERS b/services/core/java/com/android/server/pm/permission/OWNERS index e05ef482ec08..8c1a90c13513 100644 --- a/services/core/java/com/android/server/pm/permission/OWNERS +++ b/services/core/java/com/android/server/pm/permission/OWNERS @@ -1,9 +1,7 @@ -zhanghai@google.com +include platform/frameworks/base:/core/java/android/permission/OWNERS + per-file DefaultPermissionGrantPolicy.java = hackbod@android.com per-file DefaultPermissionGrantPolicy.java = jsharkey@android.com -per-file DefaultPermissionGrantPolicy.java = svetoslavganov@google.com per-file DefaultPermissionGrantPolicy.java = toddke@google.com per-file DefaultPermissionGrantPolicy.java = yamasani@google.com per-file DefaultPermissionGrantPolicy.java = patb@google.com -per-file DefaultPermissionGrantPolicy.java = eugenesusla@google.com -per-file DefaultPermissionGrantPolicy.java = zhanghai@google.com diff --git a/services/core/java/com/android/server/role/OWNERS b/services/core/java/com/android/server/role/OWNERS index 31e3549d9111..dafdf0f8075c 100644 --- a/services/core/java/com/android/server/role/OWNERS +++ b/services/core/java/com/android/server/role/OWNERS @@ -1,5 +1 @@ -svetoslavganov@google.com -zhanghai@google.com -evanseverson@google.com -eugenesusla@google.com -ntmyren@google.com +include platform/frameworks/base:/core/java/android/permission/OWNERS diff --git a/services/core/java/com/android/server/servicewatcher/OWNERS b/services/core/java/com/android/server/servicewatcher/OWNERS new file mode 100644 index 000000000000..ced619f05f1d --- /dev/null +++ b/services/core/java/com/android/server/servicewatcher/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 25692 + +sooniln@google.com +wyattriley@google.com + diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 7d7af03ecd3d..752da31638dd 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -2043,7 +2043,8 @@ public class NetworkPolicyManagerServiceTest { final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); networkCapabilities.addTransportType(TRANSPORT_WIFI); networkCapabilities.setSSID(TEST_SSID); - return new NetworkState(TYPE_WIFI, prop, networkCapabilities, null, null); + return new NetworkState(TYPE_WIFI, prop, networkCapabilities, new Network(TEST_NET_ID), + null); } private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception { diff --git a/telecomm/java/android/telecom/BluetoothCallQualityReport.aidl b/telecomm/java/android/telecom/BluetoothCallQualityReport.aidl new file mode 100644 index 000000000000..685fe9c927b1 --- /dev/null +++ b/telecomm/java/android/telecom/BluetoothCallQualityReport.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2021, 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.telecom; + +/** + * {@hide} + */ +parcelable BluetoothCallQualityReport; diff --git a/telecomm/java/android/telecom/BluetoothCallQualityReport.java b/telecomm/java/android/telecom/BluetoothCallQualityReport.java index 10339a818205..8703d84831ff 100644 --- a/telecomm/java/android/telecom/BluetoothCallQualityReport.java +++ b/telecomm/java/android/telecom/BluetoothCallQualityReport.java @@ -24,6 +24,8 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + /** * This class represents the quality report that bluetooth framework sends * whenever there's a bad voice quality is detected from their side. @@ -145,6 +147,26 @@ public final class BluetoothCallQualityReport implements Parcelable { } }; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BluetoothCallQualityReport that = (BluetoothCallQualityReport) o; + return mSentTimestampMillis == that.mSentTimestampMillis + && mChoppyVoice == that.mChoppyVoice && mRssiDbm == that.mRssiDbm + && mSnrDb == that.mSnrDb + && mRetransmittedPacketsCount == that.mRetransmittedPacketsCount + && mPacketsNotReceivedCount == that.mPacketsNotReceivedCount + && mNegativeAcknowledgementCount == that.mNegativeAcknowledgementCount; + } + + @Override + public int hashCode() { + return Objects.hash(mSentTimestampMillis, mChoppyVoice, mRssiDbm, mSnrDb, + mRetransmittedPacketsCount, mPacketsNotReceivedCount, + mNegativeAcknowledgementCount); + } + /** * Builder class for {@link ConnectionRequest} */ diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 1238e7b69a87..4679b9c497bd 100755 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -267,6 +267,64 @@ public final class Call { public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; + /** + * Event reported from the Telecom stack to report an in-call diagnostic message which the + * dialer app may opt to display to the user. A diagnostic message is used to communicate + * scenarios the device has detected which may impact the quality of the ongoing call. + * <p> + * For example a problem with a bluetooth headset may generate a recommendation for the user to + * try using the speakerphone instead, or if the device detects it has entered a poor service + * area, the user might be warned so that they can finish their call prior to it dropping. + * <p> + * A diagnostic message is considered persistent in nature. When the user enters a poor service + * area, for example, the accompanying diagnostic message persists until they leave the area + * of poor service. Each message is accompanied with a {@link #EXTRA_DIAGNOSTIC_MESSAGE_ID} + * which uniquely identifies the diagnostic condition being reported. The framework raises a + * call event of type {@link #EVENT_CLEAR_DIAGNOSTIC_MESSAGE} when the condition reported has + * been cleared. The dialer app should display the diagnostic message until it is cleared. + * If multiple diagnostic messages are sent with different IDs (which have not yet been cleared) + * the dialer app should prioritize the most recently received message, but still provide the + * user with a means to review past messages. + * <p> + * The text of the message is found in {@link #EXTRA_DIAGNOSTIC_MESSAGE} in the form of a human + * readable {@link CharSequence} which is intended for display in the call UX. + * <p> + * The telecom framework audibly notifies the user of the presence of a diagnostic message, so + * the dialer app needs only to concern itself with visually displaying the message. + * <p> + * The dialer app receives this event via + * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)}. + */ + public static final String EVENT_DISPLAY_DIAGNOSTIC_MESSAGE = + "android.telecom.event.DISPLAY_DIAGNOSTIC_MESSAGE"; + + /** + * Event reported from the telecom framework when a diagnostic message previously raised with + * {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE} has cleared and is no longer pertinent. + * <p> + * The {@link #EXTRA_DIAGNOSTIC_MESSAGE_ID} indicates the diagnostic message which has been + * cleared. + * <p> + * The dialer app receives this event via + * {@link Call.Callback#onConnectionEvent(Call, String, Bundle)}. + */ + public static final String EVENT_CLEAR_DIAGNOSTIC_MESSAGE = + "android.telecom.event.CLEAR_DIAGNOSTIC_MESSAGE"; + + /** + * Integer extra representing a message ID for a message posted via + * {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE}. Used to ensure that the dialer app knows when + * the message in question has cleared via {@link #EVENT_CLEAR_DIAGNOSTIC_MESSAGE}. + */ + public static final String EXTRA_DIAGNOSTIC_MESSAGE_ID = + "android.telecom.extra.DIAGNOSTIC_MESSAGE_ID"; + + /** + * {@link CharSequence} extra used with {@link #EVENT_DISPLAY_DIAGNOSTIC_MESSAGE}. This is the + * diagnostic message the dialer app should display. + */ + public static final String EXTRA_DIAGNOSTIC_MESSAGE = + "android.telecom.extra.DIAGNOSTIC_MESSAGE"; /** * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this diff --git a/telecomm/java/android/telecom/CallDiagnosticService.java b/telecomm/java/android/telecom/CallDiagnosticService.java new file mode 100644 index 000000000000..201c5db74e16 --- /dev/null +++ b/telecomm/java/android/telecom/CallDiagnosticService.java @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2021 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.telecom; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.ArrayMap; + +import com.android.internal.telecom.ICallDiagnosticService; +import com.android.internal.telecom.ICallDiagnosticServiceAdapter; + +import java.util.Map; + +/** + * The platform supports a single OEM provided {@link CallDiagnosticService}, as defined by the + * {@code call_diagnostic_service_package_name} key in the + * {@code packages/services/Telecomm/res/values/config.xml} file. An OEM can use this API to help + * provide more actionable information about calling issues the user encounters during and after + * a call. + * + * <h1>Manifest Declaration</h1> + * The following is an example of how to declare the service entry in the + * {@link CallDiagnosticService} manifest file: + * <pre> + * {@code + * <service android:name="your.package.YourCallDiagnosticServiceImplementation" + * android:permission="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE"> + * <intent-filter> + * <action android:name="android.telecom.CallDiagnosticService"/> + * </intent-filter> + * </service> + * } + * </pre> + * @hide + */ +@SystemApi +public abstract class CallDiagnosticService extends Service { + + /** + * Binder stub implementation which handles incoming requests from Telecom. + */ + private final class CallDiagnosticServiceBinder extends ICallDiagnosticService.Stub { + + @Override + public void setAdapter(ICallDiagnosticServiceAdapter adapter) throws RemoteException { + handleSetAdapter(adapter); + } + + @Override + public void initializeDiagnosticCall(ParcelableCall call) throws RemoteException { + handleCallAdded(call); + } + + @Override + public void updateCall(ParcelableCall call) throws RemoteException { + handleCallUpdated(call); + } + + @Override + public void removeDiagnosticCall(String callId) throws RemoteException { + handleCallRemoved(callId); + } + + @Override + public void updateCallAudioState(CallAudioState callAudioState) throws RemoteException { + onCallAudioStateChanged(callAudioState); + } + + @Override + public void receiveDeviceToDeviceMessage(String callId, int message, int value) { + handleReceivedD2DMessage(callId, message, value); + } + + @Override + public void receiveBluetoothCallQualityReport(BluetoothCallQualityReport qualityReport) + throws RemoteException { + handleBluetoothCallQualityReport(qualityReport); + } + } + + /** + * Listens to events raised by a {@link DiagnosticCall}. + */ + private android.telecom.DiagnosticCall.Listener mDiagnosticCallListener = + new android.telecom.DiagnosticCall.Listener() { + + @Override + public void onSendDeviceToDeviceMessage(DiagnosticCall diagnosticCall, + @DiagnosticCall.MessageType int message, int value) { + handleSendDeviceToDeviceMessage(diagnosticCall, message, value); + } + + @Override + public void onDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId, + CharSequence message) { + handleDisplayDiagnosticMessage(diagnosticCall, messageId, message); + } + + @Override + public void onClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId) { + handleClearDiagnosticMessage(diagnosticCall, messageId); + } + }; + + /** + * The {@link Intent} that must be declared as handled by the service. + */ + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String SERVICE_INTERFACE = "android.telecom.CallDiagnosticService"; + + /** + * Map which tracks the Telecom calls received from the Telecom stack. + */ + private final Map<String, Call.Details> mCallByTelecomCallId = new ArrayMap<>(); + private final Map<String, DiagnosticCall> mDiagnosticCallByTelecomCallId = new ArrayMap<>(); + private ICallDiagnosticServiceAdapter mAdapter; + + @Nullable + @Override + public IBinder onBind(@NonNull Intent intent) { + Log.i(this, "onBind!"); + return new CallDiagnosticServiceBinder(); + } + + /** + * Telecom calls this method on the {@link CallDiagnosticService} with details about a new call + * which was added to Telecom. + * <p> + * The {@link CallDiagnosticService} returns an implementation of {@link DiagnosticCall} to be + * used for the lifespan of this call. + * + * @param call The details of the new call. + * @return An instance of {@link DiagnosticCall} which the {@link CallDiagnosticService} + * provides to be used for the lifespan of the call. + * @throws IllegalArgumentException if a {@code null} {@link DiagnosticCall} is returned. + */ + public abstract @NonNull DiagnosticCall onInitializeDiagnosticCall(@NonNull + android.telecom.Call.Details call); + + /** + * Telecom calls this method when a previous created {@link DiagnosticCall} is no longer needed. + * This happens when Telecom is no longer tracking the call in question. + * @param call The diagnostic call which is no longer tracked by Telecom. + */ + public abstract void onRemoveDiagnosticCall(@NonNull DiagnosticCall call); + + /** + * Telecom calls this method when the audio routing or available audio route information + * changes. + * <p> + * Audio state is common to all calls. + * + * @param audioState The new audio state. + */ + public abstract void onCallAudioStateChanged( + @NonNull CallAudioState audioState); + + /** + * Telecom calls this method when a {@link BluetoothCallQualityReport} is received from the + * bluetooth stack. + * @param qualityReport the {@link BluetoothCallQualityReport}. + */ + public abstract void onBluetoothCallQualityReportReceived( + @NonNull BluetoothCallQualityReport qualityReport); + + /** + * Handles a request from Telecom to set the adapater used to communicate back to Telecom. + * @param adapter + */ + private void handleSetAdapter(@NonNull ICallDiagnosticServiceAdapter adapter) { + mAdapter = adapter; + } + + /** + * Handles a request from Telecom to add a new call. + * @param parcelableCall + */ + private void handleCallAdded(@NonNull ParcelableCall parcelableCall) { + String telecomCallId = parcelableCall.getId(); + Log.i(this, "handleCallAdded: callId=%s - added", telecomCallId); + Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall); + mCallByTelecomCallId.put(telecomCallId, newCallDetails); + + DiagnosticCall diagnosticCall = onInitializeDiagnosticCall(newCallDetails); + if (diagnosticCall == null) { + throw new IllegalArgumentException("A valid DiagnosticCall instance was not provided."); + } + diagnosticCall.setListener(mDiagnosticCallListener); + diagnosticCall.setCallId(telecomCallId); + mDiagnosticCallByTelecomCallId.put(telecomCallId, diagnosticCall); + } + + /** + * Handles an update to {@link Call.Details} notified by Telecom. + * Caches the call details and notifies the {@link DiagnosticCall} of the change via + * {@link DiagnosticCall#onCallDetailsChanged(Call.Details)}. + * @param parcelableCall the new parceled call details from Telecom. + */ + private void handleCallUpdated(@NonNull ParcelableCall parcelableCall) { + String telecomCallId = parcelableCall.getId(); + Log.i(this, "handleCallUpdated: callId=%s - updated", telecomCallId); + Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall); + + DiagnosticCall diagnosticCall = mDiagnosticCallByTelecomCallId.get(telecomCallId); + mCallByTelecomCallId.put(telecomCallId, newCallDetails); + diagnosticCall.handleCallUpdated(newCallDetails); + } + + /** + * Handles a request from Telecom to remove an existing call. + * @param telecomCallId + */ + private void handleCallRemoved(@NonNull String telecomCallId) { + Log.i(this, "handleCallRemoved: callId=%s - removed", telecomCallId); + + if (mCallByTelecomCallId.containsKey(telecomCallId)) { + mCallByTelecomCallId.remove(telecomCallId); + } + if (mDiagnosticCallByTelecomCallId.containsKey(telecomCallId)) { + DiagnosticCall call = mDiagnosticCallByTelecomCallId.remove(telecomCallId); + // Inform the service of the removed call. + onRemoveDiagnosticCall(call); + } + } + + /** + * Handles an incoming device to device message received from Telecom. Notifies the + * {@link DiagnosticCall} via {@link DiagnosticCall#onReceiveDeviceToDeviceMessage(int, int)}. + * @param callId + * @param message + * @param value + */ + private void handleReceivedD2DMessage(@NonNull String callId, int message, int value) { + Log.i(this, "handleReceivedD2DMessage: callId=%s, msg=%d/%d", callId, message, value); + DiagnosticCall diagnosticCall = mDiagnosticCallByTelecomCallId.get(callId); + diagnosticCall.onReceiveDeviceToDeviceMessage(message, value); + } + + /** + * Handles an incoming bluetooth call quality report from Telecom. Notifies via + * {@link CallDiagnosticService#onBluetoothCallQualityReportReceived( + * BluetoothCallQualityReport)}. + * @param qualityReport The bluetooth call quality remote. + */ + private void handleBluetoothCallQualityReport(@NonNull BluetoothCallQualityReport + qualityReport) { + Log.i(this, "handleBluetoothCallQualityReport; report=%s", qualityReport); + onBluetoothCallQualityReportReceived(qualityReport); + } + + /** + * Handles a request from a {@link DiagnosticCall} to send a device to device message (received + * via {@link DiagnosticCall#sendDeviceToDeviceMessage(int, int)}. + * @param diagnosticCall + * @param message + * @param value + */ + private void handleSendDeviceToDeviceMessage(@NonNull DiagnosticCall diagnosticCall, + int message, int value) { + String callId = diagnosticCall.getCallId(); + try { + mAdapter.sendDeviceToDeviceMessage(callId, message, value); + Log.i(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d", callId, message, + value); + } catch (RemoteException e) { + Log.w(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d failed %s", + callId, message, value, e); + } + } + + /** + * Handles a request from a {@link DiagnosticCall} to display an in-call diagnostic message. + * Originates from {@link DiagnosticCall#displayDiagnosticMessage(int, CharSequence)}. + * @param diagnosticCall + * @param messageId + * @param message + */ + private void handleDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId, + CharSequence message) { + String callId = diagnosticCall.getCallId(); + try { + mAdapter.displayDiagnosticMessage(callId, messageId, message); + Log.i(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s", callId, messageId, + message); + } catch (RemoteException e) { + Log.w(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s failed %s", + callId, messageId, message, e); + } + } + + /** + * Handles a request from a {@link DiagnosticCall} to clear a previously shown diagnostic + * message. + * Originates from {@link DiagnosticCall#clearDiagnosticMessage(int)}. + * @param diagnosticCall + * @param messageId + */ + private void handleClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId) { + String callId = diagnosticCall.getCallId(); + try { + mAdapter.clearDiagnosticMessage(callId, messageId); + Log.i(this, "handleClearDiagnosticMessage: call=%s; msg=%d", callId, messageId); + } catch (RemoteException e) { + Log.w(this, "handleClearDiagnosticMessage: call=%s; msg=%d failed %s", + callId, messageId, e); + } + } +} diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 335a10221d06..973b20ad0713 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -926,6 +926,46 @@ public abstract class Connection extends Conferenceable { public static final String EVENT_RTT_AUDIO_INDICATION_CHANGED = "android.telecom.event.RTT_AUDIO_INDICATION_CHANGED"; + /** + * Connection event used to signal between the telephony {@link ConnectionService} and Telecom + * when device to device messages are sent/received. + * <p> + * Device to device messages originating from the network are sent by telephony using + * {@link Connection#sendConnectionEvent(String, Bundle)} and are routed up to any active + * {@link CallDiagnosticService} implementation which is active. + * <p> + * Likewise, if a {@link CallDiagnosticService} sends a message using + * {@link DiagnosticCall#sendDeviceToDeviceMessage(int, int)}, it will be routed to telephony + * via {@link Connection#onCallEvent(String, Bundle)}. The telephony stack will relay the + * message to the other device. + * @hide + */ + @SystemApi + public static final String EVENT_DEVICE_TO_DEVICE_MESSAGE = + "android.telecom.event.DEVICE_TO_DEVICE_MESSAGE"; + + /** + * Sent along with {@link #EVENT_DEVICE_TO_DEVICE_MESSAGE} to indicate the device to device + * message type. + * + * See {@link DiagnosticCall} for more information. + * @hide + */ + @SystemApi + public static final String EXTRA_DEVICE_TO_DEVICE_MESSAGE_TYPE = + "android.telecom.extra.DEVICE_TO_DEVICE_MESSAGE_TYPE"; + + /** + * Sent along with {@link #EVENT_DEVICE_TO_DEVICE_MESSAGE} to indicate the device to device + * message value. + * <p> + * See {@link DiagnosticCall} for more information. + * @hide + */ + @SystemApi + public static final String EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE = + "android.telecom.extra.DEVICE_TO_DEVICE_MESSAGE_VALUE"; + // Flag controlling whether PII is emitted into the logs private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG); diff --git a/telecomm/java/android/telecom/DiagnosticCall.java b/telecomm/java/android/telecom/DiagnosticCall.java new file mode 100644 index 000000000000..a4952899eb46 --- /dev/null +++ b/telecomm/java/android/telecom/DiagnosticCall.java @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2021 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.telecom; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.telephony.Annotation; +import android.telephony.CallQuality; +import android.telephony.ims.ImsReasonInfo; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A {@link DiagnosticCall} provides a way for a {@link CallDiagnosticService} to receive diagnostic + * information about a mobile call on the device. The {@link CallDiagnosticService} can generate + * mid-call diagnostic messages using the {@link #displayDiagnosticMessage(int, CharSequence)} API + * which provides the user with valuable information about conditions impacting their call and + * corrective actions. For example, if the {@link CallDiagnosticService} determines that conditions + * on the call are degrading, it can inform the user that the call may soon drop and that they + * can try using a different calling method (e.g. VOIP or WIFI). + * @hide + */ +@SystemApi +public abstract class DiagnosticCall { + + /** + * @hide + */ + public interface Listener { + void onSendDeviceToDeviceMessage(DiagnosticCall diagnosticCall, int message, int value); + void onDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId, + CharSequence message); + void onClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId); + } + + /** + * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via + * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the radio access type + * used for the current call. Based loosely on the + * {@link android.telephony.TelephonyManager#getNetworkType(int)} for the call, provides a + * high level summary of the call radio access type. + * <p> + * Valid values: + * <UL> + * <LI>{@link #NETWORK_TYPE_LTE}</LI> + * <LI>{@link #NETWORK_TYPE_IWLAN}</LI> + * <LI>{@link #NETWORK_TYPE_NR}</LI> + * </UL> + */ + public static final int MESSAGE_CALL_NETWORK_TYPE = 1; + + /** + * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via + * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the call audio codec + * used for the current call. Based loosely on the {@link Connection#EXTRA_AUDIO_CODEC} for a + * call. + * <p> + * Valid values: + * <UL> + * <LI>{@link #AUDIO_CODEC_EVS}</LI> + * <LI>{@link #AUDIO_CODEC_AMR_WB}</LI> + * <LI>{@link #AUDIO_CODEC_AMR_NB}</LI> + * </UL> + */ + public static final int MESSAGE_CALL_AUDIO_CODEC = 2; + + /** + * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via + * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the battery state of + * the device. Will typically mirror battery state reported via intents such as + * {@link android.content.Intent#ACTION_BATTERY_LOW}. + * <p> + * Valid values: + * <UL> + * <LI>{@link #BATTERY_STATE_LOW}</LI> + * <LI>{@link #BATTERY_STATE_GOOD}</LI> + * <LI>{@link #BATTERY_STATE_CHARGING}</LI> + * </UL> + */ + public static final int MESSAGE_DEVICE_BATTERY_STATE = 3; + + /** + * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via + * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the overall network + * coverage as it pertains to the current call. A {@link CallDiagnosticService} should signal + * poor coverage if the network coverage reaches a level where there is a high probability of + * the call dropping as a result. + * <p> + * Valid values: + * <UL> + * <LI>{@link #COVERAGE_POOR}</LI> + * <LI>{@link #COVERAGE_GOOD}</LI> + * </UL> + */ + public static final int MESSAGE_DEVICE_NETWORK_COVERAGE = 4; + + /**@hide*/ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "MESSAGE_", value = { + MESSAGE_CALL_NETWORK_TYPE, + MESSAGE_CALL_AUDIO_CODEC, + MESSAGE_DEVICE_BATTERY_STATE, + MESSAGE_DEVICE_NETWORK_COVERAGE + }) + public @interface MessageType {} + + /** + * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate an LTE network is being used for the + * call. + */ + public static final int NETWORK_TYPE_LTE = 1; + + /** + * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate WIFI calling is in use for the call. + */ + public static final int NETWORK_TYPE_IWLAN = 2; + + /** + * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate a 5G NR (new radio) network is in + * used for the call. + */ + public static final int NETWORK_TYPE_NR = 3; + + /** + * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the + * Enhanced Voice Services (EVS) codec for the call. + */ + public static final int AUDIO_CODEC_EVS = 1; + + /** + * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the AMR + * (adaptive multi-rate) WB (wide band) audio codec. + */ + public static final int AUDIO_CODEC_AMR_WB = 2; + + /** + * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the AMR + * (adaptive multi-rate) NB (narrow band) audio codec. + */ + public static final int AUDIO_CODEC_AMR_NB = 3; + + /** + * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is low. + */ + public static final int BATTERY_STATE_LOW = 1; + + /** + * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is not low. + */ + public static final int BATTERY_STATE_GOOD = 2; + + /** + * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is charging. + */ + public static final int BATTERY_STATE_CHARGING = 3; + + /** + * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is poor. + */ + public static final int COVERAGE_POOR = 1; + + /** + * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is good. + */ + public static final int COVERAGE_GOOD = 2; + + private Listener mListener; + private String mCallId; + private Call.Details mCallDetails; + + /** + * @hide + */ + public void setListener(@NonNull Listener listener) { + mListener = listener; + } + + /** + * Sets the call ID for this {@link DiagnosticCall}. + * @param callId + * @hide + */ + public void setCallId(@NonNull String callId) { + mCallId = callId; + } + + /** + * @return the Telecom call ID for this {@link DiagnosticCall}. + * @hide + */ + public @NonNull String getCallId() { + return mCallId; + } + + /** + * Returns the latest {@link Call.Details} associated with this {@link DiagnosticCall} as + * reported by {@link #onCallDetailsChanged(Call.Details)}. + * @return The latest {@link Call.Details}. + */ + public @NonNull Call.Details getCallDetails() { + return mCallDetails; + } + + /** + * Telecom calls this method when the details of a call changes. + */ + public abstract void onCallDetailsChanged(@NonNull android.telecom.Call.Details details); + + /** + * The {@link CallDiagnosticService} implements this method to handle messages received via + * device to device communication. + * <p> + * See {@link #sendDeviceToDeviceMessage(int, int)} for background on device to device + * communication. + * <p> + * The underlying device to device communication protocol assumes that where there the two + * devices communicating are using a different version of the protocol, messages the recipient + * are not aware of are silently discarded. This means an older client talking to a new client + * will not receive newer messages and values sent by the new client. + */ + public abstract void onReceiveDeviceToDeviceMessage( + @MessageType int message, + int value); + + /** + * Sends a device to device message to the device on the other end of this call. + * <p> + * Device to device communication is an Android platform feature which supports low bandwidth + * communication between Android devices while they are in a call. The device to device + * communication leverages DTMF tones or RTP header extensions to pass messages. The + * messages are unacknowledged and sent in a best-effort manner. The protocols assume that the + * nature of the message are informational only and are used only to convey basic state + * information between devices. + * <p> + * Device to device messages are intentional simplifications of more rich indicators in the + * platform due to the extreme bandwidth constraints inherent with underlying device to device + * communication transports used by the telephony framework. Device to device communication is + * either accomplished by adding RFC8285 compliant RTP header extensions to the audio packets + * for a call, or using the DTMF digits A-D as a communication pathway. Signalling requirements + * for DTMF digits place a significant limitation on the amount of information which can be + * communicated during a call. + * <p> + * Allowed message types and values are: + * <ul> + * <li>{@link #MESSAGE_CALL_NETWORK_TYPE} + * <ul> + * <li>{@link #NETWORK_TYPE_LTE}</li> + * <li>{@link #NETWORK_TYPE_IWLAN}</li> + * <li>{@link #NETWORK_TYPE_NR}</li> + * </ul> + * </li> + * <li>{@link #MESSAGE_CALL_AUDIO_CODEC} + * <ul> + * <li>{@link #AUDIO_CODEC_EVS}</li> + * <li>{@link #AUDIO_CODEC_AMR_WB}</li> + * <li>{@link #AUDIO_CODEC_AMR_NB}</li> + * </ul> + * </li> + * <li>{@link #MESSAGE_DEVICE_BATTERY_STATE} + * <ul> + * <li>{@link #BATTERY_STATE_LOW}</li> + * <li>{@link #BATTERY_STATE_GOOD}</li> + * <li>{@link #BATTERY_STATE_CHARGING}</li> + * </ul> + * </li> + * <li>{@link #MESSAGE_DEVICE_NETWORK_COVERAGE} + * <ul> + * <li>{@link #COVERAGE_POOR}</li> + * <li>{@link #COVERAGE_GOOD}</li> + * </ul> + * </li> + * </ul> + * @param message The message type to send. + * @param value The message value corresponding to the type. + */ + public final void sendDeviceToDeviceMessage(int message, int value) { + if (mListener != null) { + mListener.onSendDeviceToDeviceMessage(this, message, value); + } + } + + /** + * Telecom calls this method when a GSM or CDMA call disconnects. + * The CallDiagnosticService can return a human readable disconnect message which will be passed + * to the Dialer app as the {@link DisconnectCause#getDescription()}. A dialer app typically + * shows this message at the termination of the call. If {@code null} is returned, the + * disconnect message generated by the telephony stack will be shown instead. + * <p> + * @param disconnectCause the disconnect cause for the call. + * @param preciseDisconnectCause the precise disconnect cause for the call. + * @return the disconnect message to use in place of the default Telephony message, or + * {@code null} if the default message will not be overridden. + */ + // TODO: Wire in Telephony support for this. + public abstract @Nullable CharSequence onCallDisconnected( + @Annotation.DisconnectCauses int disconnectCause, + @Annotation.PreciseDisconnectCauses int preciseDisconnectCause); + + /** + * Telecom calls this method when an IMS call disconnects and Telephony has already + * provided the disconnect reason info and disconnect message for the call. The + * {@link CallDiagnosticService} can intercept the raw IMS disconnect reason at this point and + * combine it with other call diagnostic information it is aware of to override the disconnect + * call message if desired. + * + * @param disconnectReason The {@link ImsReasonInfo} associated with the call disconnection. + * @return A user-readable call disconnect message to use in place of the platform-generated + * disconnect message, or {@code null} if the disconnect message should not be overridden. + */ + // TODO: Wire in Telephony support for this. + public abstract @Nullable CharSequence onCallDisconnected( + @NonNull ImsReasonInfo disconnectReason); + + /** + * Telecom calls this method when a {@link CallQuality} report is received from the telephony + * stack for a call. + * @param callQuality The call quality report for this call. + */ + public abstract void onCallQualityReceived(@NonNull CallQuality callQuality); + + /** + * Signals the active default dialer app to display a call diagnostic message. This can be + * used to report problems encountered during the span of a call. + * <p> + * The {@link CallDiagnosticService} provides a unique client-specific identifier used to + * identify the specific diagnostic message type. + * <p> + * The {@link CallDiagnosticService} should call {@link #clearDiagnosticMessage(int)} when the + * diagnostic condition has cleared. + * @param messageId the unique message identifier. + * @param message a human-readable, localized message to be shown to the user indicating a + * call issue which has occurred, along with potential mitigating actions. + */ + public final void displayDiagnosticMessage(int messageId, @NonNull + CharSequence message) { + if (mListener != null) { + mListener.onDisplayDiagnosticMessage(this, messageId, message); + } + } + + /** + * Signals to the active default dialer that the diagnostic message previously signalled using + * {@link #displayDiagnosticMessage(int, CharSequence)} with the specified messageId is no + * longer applicable (e.g. service has improved, for example. + * @param messageId the message identifier for a message previously shown via + * {@link #displayDiagnosticMessage(int, CharSequence)}. + */ + public final void clearDiagnosticMessage(int messageId) { + if (mListener != null) { + mListener.onClearDiagnosticMessage(this, messageId); + } + } + + /** + * Called by the {@link CallDiagnosticService} to update the call details for this + * {@link DiagnosticCall} based on an update received from Telecom. + * @param newDetails the new call details. + * @hide + */ + public void handleCallUpdated(@NonNull Call.Details newDetails) { + mCallDetails = newDetails; + onCallDetailsChanged(newDetails); + } +} diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index 2a4fdcb1475d..922eddb6ac3e 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -522,7 +522,7 @@ public class Log { return ""; } return Arrays.stream(packageName.split("\\.")) - .map(s -> s.substring(0,1)) + .map(s -> s.length() == 0 ? "" : s.substring(0, 1)) .collect(Collectors.joining("")); } } diff --git a/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl b/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl new file mode 100644 index 000000000000..65b4d19b3d9b --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telecom; + +import android.telecom.BluetoothCallQualityReport; +import android.telecom.CallAudioState; +import android.telecom.ParcelableCall; +import com.android.internal.telecom.ICallDiagnosticServiceAdapter; + +/** + * Internal remote interface for a call diagnostic service. + * @see android.telecom.CallDiagnosticService + * @hide + */ +oneway interface ICallDiagnosticService { + void setAdapter(in ICallDiagnosticServiceAdapter adapter); + void initializeDiagnosticCall(in ParcelableCall call); + void updateCall(in ParcelableCall call); + void updateCallAudioState(in CallAudioState callAudioState); + void removeDiagnosticCall(in String callId); + void receiveDeviceToDeviceMessage(in String callId, int message, int value); + void receiveBluetoothCallQualityReport(in BluetoothCallQualityReport qualityReport); +} diff --git a/telecomm/java/com/android/internal/telecom/ICallDiagnosticServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallDiagnosticServiceAdapter.aidl new file mode 100644 index 000000000000..92eec2a95430 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/ICallDiagnosticServiceAdapter.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telecom; + +import android.telecom.CallAudioState; +import android.telecom.ParcelableCall; + +/** + * Remote interface for messages from the CallDiagnosticService to the platform. + * @see android.telecom.CallDiagnosticService + * @hide + */ +oneway interface ICallDiagnosticServiceAdapter { + void displayDiagnosticMessage(in String callId, int messageId, in CharSequence message); + void clearDiagnosticMessage(in String callId, int messageId); + void sendDeviceToDeviceMessage(in String callId, int message, int value); + void overrideDisconnectMessage(in String callId, in CharSequence message); +} diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 5afac2ec239a..0d190d89645a 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -351,4 +351,8 @@ interface ITelecomService { */ void setTestDefaultDialer(in String packageName); + /** + * @see TelecomServiceImpl#setTestCallDiagnosticService + */ + void setTestCallDiagnosticService(in String packageName); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 04e8f6345dee..18846c456027 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1881,9 +1881,8 @@ public class CarrierConfigManager { * "APN_1, ERROR_CODE_1 : CARRIER_ACTION_IDX_1, CARRIER_ACTION_IDX_2...", * "APN_1, ERROR_CODE_2 : CARRIER_ACTION_IDX_1 " * } - * Where {@code APN_1} is a string defined in - * com.android.internal.telephony.PhoneConstants - * Example: "default" + * Where {@code APN_1} is an integer defined in {@link android.telephony.data.ApnSetting} + * (e.g. {@link android.telephony.data.ApnSetting#TYPE_DEFAULT} * * {@code ERROR_CODE_1} is an integer defined in android.telephony.DataFailCause * Example: diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 403d1d01903c..716317d0f810 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1585,177 +1585,157 @@ public class TelephonyManager { "android.telephony.extra.PHONE_IN_ECM_STATE"; /** - * <p>Broadcast Action: when data connections get redirected with validation failure. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection is redirected with validation failure. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>redirection url string</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>A string indicating the redirection url</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the validation failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = - "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + "android.telephony.action.CARRIER_SIGNAL_REDIRECTED"; /** - * <p>Broadcast Action: when data connections setup fails. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection setup fails. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_ERROR_CODE}</li><dd>A integer with dataFailCause.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_DATA_FAIL_CAUSE}</li><dd>A integer indicating the data fail cause.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the data setup failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = - "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; /** - * <p>Broadcast Action: when pco value is available. - * intended for sim/account status checks and only sent to the specified carrier app + * Broadcast action sent when a PCO value becomes available from the modem. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>A string with the protocol of the apn connection - * (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_APN_PROTOCOL_INT}</li><dd>A integer with the protocol of the apn - * connection (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the pco id for the data.</dd> - * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of pco data read from modem.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>An integer indicating the protocol of the apn + * connection</dd> + * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the PCO id for the data.</dd> + * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of PCO data read from modem.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which the PCO info was received.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = - "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE"; /** - * <p>Broadcast Action: when system default network available/unavailable with - * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when - * other network becomes system default network, Wi-Fi for example. + * Broadcast action sent when the availability of the system default network changes. + * + * @see ConnectivityManager#registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) + * + * This action is intended for carrier apps to set/reset carrier actions. It is only sent to the + * carrier apps specified in the carrier config for the subscription ID attached to this intent. + * * The intent will have the following extra values:</p> * <ul> * <li>{@link #EXTRA_DEFAULT_NETWORK_AVAILABLE}</li> - * <dd>A boolean indicates default network available.</dd> - * <li>subId</li><dd>Sub Id which associated the default data.</dd> + * <dd>{@code true} if the default network is now available, {@code false} otherwise.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the default network availability changed.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = - "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; /** - * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent. - * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app + * Broadcast action sent when carrier apps should reset their internal state. + * + * Sent when certain events such as turning on/off mobile data, removing the SIM, etc. require + * carrier apps to reset their state. + * + * This action is intended to signal carrier apps to perform cleanup operations. It is only sent + * to the carrier apps specified in the carrier config for the subscription ID attached to + * this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which state should be reset.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_RESET = - "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + "android.telephony.action.CARRIER_SIGNAL_RESET"; - // CARRIER_SIGNAL_ACTION extra keys /** - * An string extra of redirected url upon {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. - * @hide + * String extra containing the redirection URL sent with + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. */ - @SuppressLint("ActionValue") - public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + public static final String EXTRA_REDIRECTION_URL = "android.telephony.extra.REDIRECTION_URL"; /** - * An integer extra of error code upon {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. - * Check {@link DataFailCause} for all possible values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_ERROR_CODE = "errorCode"; - - /** - * An string extra of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. Use {@link #EXTRA_APN_TYPE_INT} - * instead. + * An integer extra containing the data fail cause. * - * @hide + * Sent with {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. See {@link DataFailCause} + * for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE = "apnType"; + public static final String EXTRA_DATA_FAIL_CAUSE = "android.telephony.extra.DATA_FAIL_CAUSE"; /** - * An string integer of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} TYPE_* for its values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; - - /** - * An string extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. - * Use {@link #EXTRA_APN_PROTOCOL_INT} instead. + * An integer extra containing the APN type. * - * @hide + * Sent with the {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}, and {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} + * broadcasts. + * See the {@code TYPE_} constants in {@link ApnSetting} for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL = "apnProto"; + public static final String EXTRA_APN_TYPE = "android.telephony.extra.APN_TYPE"; /** - * An integer extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} PROTOCOL_* for its values. - * @hide + * An integer extra containing the protocol of the apn connection. + * + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. + * See the {@code PROTOCOL_*} constants in {@link ApnSetting} for a list of possible values. */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL"; /** - * An integer extra indicating the pco id for the data upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * An integer extra indicating the ID for the PCO data. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_ID = "pcoId"; + public static final String EXTRA_PCO_ID = "android.telephony.extra.PCO_ID"; /** - * An extra of byte array of pco data read from modem upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * A byte array extra containing PCO data read from the modem. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_VALUE = "pcoValue"; + public static final String EXTRA_PCO_VALUE = "android.telephony.extra.PCO_VALUE"; /** - * An boolean extra indicating default network available upon - * {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcasts. - * @hide + * A boolean extra indicating the availability of the default network. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; + public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = + "android.telephony.extra.DEFAULT_NETWORK_AVAILABLE"; /** * <p>Broadcast Action: The emergency call state is changed. diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index ff9329ef9742..d58fa912dce2 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -18,6 +18,8 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.StringDef; +import android.annotation.SystemApi; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_5.ApnTypes; @@ -26,6 +28,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony; import android.provider.Telephony.Carriers; +import android.telephony.Annotation; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.NetworkType; import android.telephony.ServiceState; @@ -133,6 +136,25 @@ public class ApnSetting implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface Skip464XlatStatus {} + /** @hide */ + @StringDef(value = { + TYPE_ALL_STRING, + TYPE_CBS_STRING, + TYPE_DEFAULT_STRING, + TYPE_DUN_STRING, + TYPE_EMERGENCY_STRING, + TYPE_FOTA_STRING, + TYPE_HIPRI_STRING, + TYPE_IA_STRING, + TYPE_IMS_STRING, + TYPE_MCX_STRING, + TYPE_MMS_STRING, + TYPE_SUPL_STRING, + TYPE_XCAP_STRING, + }, prefix = "TYPE_", suffix = "_STRING") + @Retention(RetentionPolicy.SOURCE) + public @interface ApnTypeString {} + /** * APN types for data connections. These are usage categories for an APN * entry. One APN entry may support multiple APN types, eg, a single APN @@ -140,99 +162,133 @@ public class ApnSetting implements Parcelable { * connections.<br/> * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. - * <p> - * Note: The goal is to deprecate this. Due to the Carrier Table being used - * directly, this isn't feasible right now. * * @hide */ + @SystemApi public static final String TYPE_ALL_STRING = "*"; /** * APN type for default data traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_DEFAULT_STRING = "default"; /** - * APN type for MMS traffic + * APN type for MMS (Multimedia Messaging Service) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_MMS_STRING = "mms"; /** - * APN type for SUPL assisted GPS + * APN type for SUPL (Secure User Plane Location) assisted GPS. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_SUPL_STRING = "supl"; /** - * APN type for DUN traffic + * APN type for DUN (Dial-up networking) traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_DUN_STRING = "dun"; /** - * APN type for HiPri traffic + * APN type for high-priority traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_HIPRI_STRING = "hipri"; /** - * APN type for FOTA + * APN type for FOTA (Firmware over-the-air) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_FOTA_STRING = "fota"; /** - * APN type for IMS + * APN type for IMS (IP Multimedia Subsystem) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_IMS_STRING = "ims"; /** - * APN type for CBS + * APN type for CBS (Carrier Branded Services) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_CBS_STRING = "cbs"; /** - * APN type for IA Initial Attach APN + * APN type for the IA (Initial Attach) APN * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_IA_STRING = "ia"; /** * APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_EMERGENCY_STRING = "emergency"; /** - * APN type for Mission Critical Services + * APN type for Mission Critical Services. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_MCX_STRING = "mcx"; /** - * APN type for XCAP + * APN type for XCAP (XML Configuration Access Protocol) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_XCAP_STRING = "xcap"; @@ -1426,16 +1482,43 @@ public class ApnSetting implements Parcelable { } /** - * @param apnType APN type - * @return APN type in string format + * Converts the integer representation of APN type to its string representation. + * + * @param apnType APN type as an integer + * @return String representation of the APN type, or an empty string if the provided integer is + * not a valid APN type. * @hide */ - public static String getApnTypeString(int apnType) { + @SystemApi + public static @NonNull @ApnTypeString String getApnTypeString(@Annotation.ApnType int apnType) { if (apnType == TYPE_ALL) { return "*"; } String apnTypeString = APN_TYPE_INT_MAP.get(apnType); - return apnTypeString == null ? "Unknown" : apnTypeString; + return apnTypeString == null ? "" : apnTypeString; + } + + /** + * Same as {@link #getApnTypeString(int)}, but returns "Unknown" instead of an empty string + * when provided with an invalid int for compatibility purposes. + * @hide + */ + public static @NonNull String getApnTypeStringInternal(@Annotation.ApnType int apnType) { + String result = getApnTypeString(apnType); + return TextUtils.isEmpty(result) ? "Unknown" : result; + } + + /** + * Converts the string representation of an APN type to its integer representation. + * + * @param apnType APN type as a string + * @return Integer representation of the APN type, or 0 if the provided string is not a valid + * APN type. + * @hide + */ + @SystemApi + public static @Annotation.ApnType int getApnTypeInt(@NonNull @ApnTypeString String apnType) { + return APN_TYPE_STRING_MAP.getOrDefault(apnType.toLowerCase(), 0); } /** diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 46940dc6a0a5..1edacd9429f1 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -136,7 +136,7 @@ public final class DataCallResponse implements Parcelable { private final @HandoverFailureMode int mHandoverFailureMode; private final int mPduSessionId; private final Qos mDefaultQos; - private final List<QosSession> mQosSessions; + private final List<QosBearerSession> mQosBearerSessions; private final SliceInfo mSliceInfo; /** @@ -187,7 +187,7 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY; mPduSessionId = PDU_SESSION_ID_NOT_SET; mDefaultQos = null; - mQosSessions = new ArrayList<>(); + mQosBearerSessions = new ArrayList<>(); mSliceInfo = null; } @@ -197,7 +197,7 @@ public final class DataCallResponse implements Parcelable { @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, @HandoverFailureMode int handoverFailureMode, int pduSessionId, - @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions, + @Nullable Qos defaultQos, @Nullable List<QosBearerSession> qosBearerSessions, @Nullable SliceInfo sliceInfo) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; @@ -219,7 +219,7 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = handoverFailureMode; mPduSessionId = pduSessionId; mDefaultQos = defaultQos; - mQosSessions = qosSessions; + mQosBearerSessions = qosBearerSessions; mSliceInfo = sliceInfo; } @@ -246,8 +246,8 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = source.readInt(); mPduSessionId = source.readInt(); mDefaultQos = source.readParcelable(Qos.class.getClassLoader()); - mQosSessions = new ArrayList<>(); - source.readList(mQosSessions, QosSession.class.getClassLoader()); + mQosBearerSessions = new ArrayList<>(); + source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader()); mSliceInfo = source.readParcelable(SliceInfo.class.getClassLoader()); } @@ -393,8 +393,8 @@ public final class DataCallResponse implements Parcelable { * @hide */ @NonNull - public List<QosSession> getQosSessions() { - return mQosSessions; + public List<QosBearerSession> getQosBearerSessions() { + return mQosBearerSessions; } /** @@ -426,7 +426,7 @@ public final class DataCallResponse implements Parcelable { .append(" handoverFailureMode=").append(getHandoverFailureMode()) .append(" pduSessionId=").append(getPduSessionId()) .append(" defaultQos=").append(mDefaultQos) - .append(" qosSessions=").append(mQosSessions) + .append(" qosBearerSessions=").append(mQosBearerSessions) .append(" sliceInfo=").append(mSliceInfo) .append("}"); return sb.toString(); @@ -446,10 +446,10 @@ public final class DataCallResponse implements Parcelable { mDefaultQos == other.mDefaultQos : mDefaultQos.equals(other.mDefaultQos); - final boolean isQosSessionsSame = (mQosSessions == null || mQosSessions == null) ? - mQosSessions == other.mQosSessions : - mQosSessions.size() == other.mQosSessions.size() - && mQosSessions.containsAll(other.mQosSessions); + final boolean isQosBearerSessionsSame = (mQosBearerSessions == null || mQosBearerSessions == null) ? + mQosBearerSessions == other.mQosBearerSessions : + mQosBearerSessions.size() == other.mQosBearerSessions.size() + && mQosBearerSessions.containsAll(other.mQosBearerSessions); return mCause == other.mCause && mSuggestedRetryTime == other.mSuggestedRetryTime @@ -471,7 +471,7 @@ public final class DataCallResponse implements Parcelable { && mHandoverFailureMode == other.mHandoverFailureMode && mPduSessionId == other.mPduSessionId && isQosSame - && isQosSessionsSame + && isQosBearerSessionsSame && Objects.equals(mSliceInfo, other.mSliceInfo); } @@ -480,7 +480,7 @@ public final class DataCallResponse implements Parcelable { return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, - mQosSessions, mSliceInfo); + mQosBearerSessions, mSliceInfo); } @Override @@ -510,7 +510,7 @@ public final class DataCallResponse implements Parcelable { } else { dest.writeParcelable((NrQos)mDefaultQos, flags); } - dest.writeList(mQosSessions); + dest.writeList(mQosBearerSessions); dest.writeParcelable(mSliceInfo, flags); } @@ -593,7 +593,7 @@ public final class DataCallResponse implements Parcelable { private Qos mDefaultQos; - private List<QosSession> mQosSessions = new ArrayList<>(); + private List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); private SliceInfo mSliceInfo; @@ -807,15 +807,16 @@ public final class DataCallResponse implements Parcelable { /** * Set the dedicated bearer QOS sessions for this data connection. * - * @param qosSessions Dedicated bearer QOS (Quality Of Service) sessions received + * @param qosBearerSessions Dedicated bearer QOS (Quality Of Service) sessions received * from network. * * @return The same instance of the builder. * * @hide */ - public @NonNull Builder setQosSessions(@NonNull List<QosSession> qosSessions) { - mQosSessions = qosSessions; + public @NonNull Builder setQosBearerSessions( + @NonNull List<QosBearerSession> qosBearerSessions) { + mQosBearerSessions = qosBearerSessions; return this; } @@ -843,7 +844,7 @@ public final class DataCallResponse implements Parcelable { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, - mDefaultQos, mQosSessions, mSliceInfo); + mDefaultQos, mQosBearerSessions, mSliceInfo); } } } diff --git a/telephony/java/android/telephony/data/EpsQos.java b/telephony/java/android/telephony/data/EpsQos.java index ad43068b2f11..22c8b0a0a74f 100644 --- a/telephony/java/android/telephony/data/EpsQos.java +++ b/telephony/java/android/telephony/data/EpsQos.java @@ -48,6 +48,10 @@ public final class EpsQos extends Qos implements Parcelable { qosClassId = source.readInt(); } + public int getQci() { + return qosClassId; + } + public static @NonNull EpsQos createFromParcelBody(@NonNull Parcel in) { return new EpsQos(in); } diff --git a/telephony/java/android/telephony/data/Qos.java b/telephony/java/android/telephony/data/Qos.java index c8bb91e28bf2..c286c6217450 100644 --- a/telephony/java/android/telephony/data/Qos.java +++ b/telephony/java/android/telephony/data/Qos.java @@ -56,7 +56,15 @@ public abstract class Qos { this.uplink = new QosBandwidth(uplink.maxBitrateKbps, uplink.guaranteedBitrateKbps); } - static class QosBandwidth implements Parcelable { + public QosBandwidth getDownlinkBandwidth() { + return downlink; + } + + public QosBandwidth getUplinkBandwidth() { + return uplink; + } + + public static class QosBandwidth implements Parcelable { int maxBitrateKbps; int guaranteedBitrateKbps; @@ -73,6 +81,14 @@ public abstract class Qos { guaranteedBitrateKbps = source.readInt(); } + public int getMaxBitrateKbps() { + return maxBitrateKbps; + } + + public int getGuaranteedBitrateKbps() { + return guaranteedBitrateKbps; + } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(maxBitrateKbps); diff --git a/telephony/java/android/telephony/data/QosFilter.java b/telephony/java/android/telephony/data/QosBearerFilter.java index 69277445634d..6c1c653f13d0 100644 --- a/telephony/java/android/telephony/data/QosFilter.java +++ b/telephony/java/android/telephony/data/QosBearerFilter.java @@ -38,7 +38,7 @@ import java.util.Objects; * * @hide */ -public final class QosFilter implements Parcelable { +public final class QosBearerFilter implements Parcelable { private List<LinkAddress> localAddresses; private List<LinkAddress> remoteAddresses; @@ -74,7 +74,7 @@ public final class QosFilter implements Parcelable { @IntDef(prefix = "QOS_FILTER_DIRECTION_", value = {QOS_FILTER_DIRECTION_DOWNLINK, QOS_FILTER_DIRECTION_UPLINK, QOS_FILTER_DIRECTION_BIDIRECTIONAL}) - public @interface QosFilterDirection {} + public @interface QosBearerFilterDirection {} public static final int QOS_FILTER_DIRECTION_DOWNLINK = android.hardware.radio.V1_6.QosFilterDirection.DOWNLINK; @@ -83,7 +83,7 @@ public final class QosFilter implements Parcelable { public static final int QOS_FILTER_DIRECTION_BIDIRECTIONAL = android.hardware.radio.V1_6.QosFilterDirection.BIDIRECTIONAL; - @QosFilterDirection + @QosBearerFilterDirection private int filterDirection; /** @@ -92,7 +92,7 @@ public final class QosFilter implements Parcelable { */ private int precedence; - QosFilter() { + QosBearerFilter() { localAddresses = new ArrayList<>(); remoteAddresses = new ArrayList<>(); localPort = new PortRange(); @@ -101,7 +101,7 @@ public final class QosFilter implements Parcelable { filterDirection = QOS_FILTER_DIRECTION_BIDIRECTIONAL; } - public QosFilter(List<LinkAddress> localAddresses, List<LinkAddress> remoteAddresses, + public QosBearerFilter(List<LinkAddress> localAddresses, List<LinkAddress> remoteAddresses, PortRange localPort, PortRange remotePort, int protocol, int tos, long flowLabel, long spi, int direction, int precedence) { this.localAddresses = localAddresses; @@ -116,10 +116,30 @@ public final class QosFilter implements Parcelable { this.precedence = precedence; } + public List<LinkAddress> getLocalAddresses() { + return localAddresses; + } + + public List<LinkAddress> getRemoteAddresses() { + return remoteAddresses; + } + + public PortRange getLocalPortRange() { + return localPort; + } + + public PortRange getRemotePortRange() { + return remotePort; + } + + public int getPrecedence() { + return precedence; + } + /** @hide */ - public static @NonNull QosFilter create( + public static @NonNull QosBearerFilter create( @NonNull android.hardware.radio.V1_6.QosFilter qosFilter) { - QosFilter ret = new QosFilter(); + QosBearerFilter ret = new QosBearerFilter(); String[] localAddresses = qosFilter.localAddresses.stream().toArray(String[]::new); if (localAddresses != null) { @@ -202,6 +222,14 @@ public final class QosFilter implements Parcelable { this.end = end; } + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(start); @@ -254,7 +282,7 @@ public final class QosFilter implements Parcelable { @Override public String toString() { - return "QosFilter {" + return "QosBearerFilter {" + " localAddresses=" + localAddresses + " remoteAddresses=" + remoteAddresses + " localPort=" + localPort @@ -278,11 +306,11 @@ public final class QosFilter implements Parcelable { public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof QosFilter)) { + if (o == null || !(o instanceof QosBearerFilter)) { return false; } - QosFilter other = (QosFilter) o; + QosBearerFilter other = (QosBearerFilter) o; return localAddresses.size() == other.localAddresses.size() && localAddresses.containsAll(other.localAddresses) @@ -324,7 +352,7 @@ public final class QosFilter implements Parcelable { LinkAddress.LIFETIME_UNKNOWN, LinkAddress.LIFETIME_UNKNOWN); } - private QosFilter(Parcel source) { + private QosBearerFilter(Parcel source) { localAddresses = new ArrayList<>(); source.readList(localAddresses, LinkAddress.class.getClassLoader()); remoteAddresses = new ArrayList<>(); @@ -358,16 +386,16 @@ public final class QosFilter implements Parcelable { return 0; } - public static final @NonNull Parcelable.Creator<QosFilter> CREATOR = - new Parcelable.Creator<QosFilter>() { + public static final @NonNull Parcelable.Creator<QosBearerFilter> CREATOR = + new Parcelable.Creator<QosBearerFilter>() { @Override - public QosFilter createFromParcel(Parcel source) { - return new QosFilter(source); + public QosBearerFilter createFromParcel(Parcel source) { + return new QosBearerFilter(source); } @Override - public QosFilter[] newArray(int size) { - return new QosFilter[size]; + public QosBearerFilter[] newArray(int size) { + return new QosBearerFilter[size]; } }; } diff --git a/telephony/java/android/telephony/data/QosBearerSession.java b/telephony/java/android/telephony/data/QosBearerSession.java new file mode 100644 index 000000000000..30effc9273d7 --- /dev/null +++ b/telephony/java/android/telephony/data/QosBearerSession.java @@ -0,0 +1,137 @@ +/** + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.data; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + + +/** + * Class that stores information specific to QOS session. + * + * @hide + */ +public final class QosBearerSession implements Parcelable{ + + final int qosBearerSessionId; + final Qos qos; + final List<QosBearerFilter> qosBearerFilterList; + + public QosBearerSession(int qosBearerSessionId, @NonNull Qos qos, @NonNull List<QosBearerFilter> qosBearerFilterList) { + this.qosBearerSessionId = qosBearerSessionId; + this.qos = qos; + this.qosBearerFilterList = qosBearerFilterList; + } + + private QosBearerSession(Parcel source) { + qosBearerSessionId = source.readInt(); + qos = source.readParcelable(Qos.class.getClassLoader()); + qosBearerFilterList = new ArrayList<>(); + source.readList(qosBearerFilterList, QosBearerFilter.class.getClassLoader()); + } + + public int getQosBearerSessionId() { + return qosBearerSessionId; + } + + public Qos getQos() { + return qos; + } + + public List<QosBearerFilter> getQosBearerFilterList() { + return qosBearerFilterList; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(qosBearerSessionId); + if (qos.getType() == Qos.QOS_TYPE_EPS) { + dest.writeParcelable((EpsQos)qos, flags); + } else { + dest.writeParcelable((NrQos)qos, flags); + } + dest.writeList(qosBearerFilterList); + } + + public static @NonNull QosBearerSession create( + @NonNull android.hardware.radio.V1_6.QosSession qosSession) { + List<QosBearerFilter> qosBearerFilters = new ArrayList<>(); + + if (qosSession.qosFilters != null) { + for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) { + qosBearerFilters.add(QosBearerFilter.create(filter)); + } + } + + return new QosBearerSession( + qosSession.qosSessionId, + Qos.create(qosSession.qos), + qosBearerFilters); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "QosBearerSession {" + + " qosBearerSessionId=" + qosBearerSessionId + + " qos=" + qos + + " qosBearerFilterList=" + qosBearerFilterList + "}"; + } + + @Override + public int hashCode() { + return Objects.hash(qosBearerSessionId, qos, qosBearerFilterList); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || !(o instanceof QosBearerSession)) { + return false; + } + + QosBearerSession other = (QosBearerSession) o; + return this.qosBearerSessionId == other.qosBearerSessionId + && this.qos.equals(other.qos) + && this.qosBearerFilterList.size() == other.qosBearerFilterList.size() + && this.qosBearerFilterList.containsAll(other.qosBearerFilterList); + } + + + public static final @NonNull Parcelable.Creator<QosBearerSession> CREATOR = + new Parcelable.Creator<QosBearerSession>() { + @Override + public QosBearerSession createFromParcel(Parcel source) { + return new QosBearerSession(source); + } + + @Override + public QosBearerSession[] newArray(int size) { + return new QosBearerSession[size]; + } + }; +} diff --git a/telephony/java/android/telephony/data/QosSession.java b/telephony/java/android/telephony/data/QosSession.java deleted file mode 100644 index f07b6a9f6725..000000000000 --- a/telephony/java/android/telephony/data/QosSession.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony.data; - -import android.annotation.NonNull; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -/** - * Class that stores information specific to QOS session. - * - * @hide - */ -public final class QosSession implements Parcelable{ - - final int qosSessionId; - final Qos qos; - final List<QosFilter> qosFilterList; - - public QosSession(int qosSessionId, @NonNull Qos qos, @NonNull List<QosFilter> qosFilterList) { - this.qosSessionId = qosSessionId; - this.qos = qos; - this.qosFilterList = qosFilterList; - } - - private QosSession(Parcel source) { - qosSessionId = source.readInt(); - qos = source.readParcelable(Qos.class.getClassLoader()); - qosFilterList = new ArrayList<>(); - source.readList(qosFilterList, QosFilter.class.getClassLoader()); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(qosSessionId); - if (qos.getType() == Qos.QOS_TYPE_EPS) { - dest.writeParcelable((EpsQos)qos, flags); - } else { - dest.writeParcelable((NrQos)qos, flags); - } - dest.writeList(qosFilterList); - } - - public static @NonNull QosSession create( - @NonNull android.hardware.radio.V1_6.QosSession qosSession) { - List<QosFilter> qosFilters = new ArrayList<>(); - - if (qosSession.qosFilters != null) { - for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) { - qosFilters.add(QosFilter.create(filter)); - } - } - - return new QosSession( - qosSession.qosSessionId, - Qos.create(qosSession.qos), - qosFilters); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public String toString() { - return "QosSession {" - + " qosSessionId=" + qosSessionId - + " qos=" + qos - + " qosFilterList=" + qosFilterList + "}"; - } - - @Override - public int hashCode() { - return Objects.hash(qosSessionId, qos, qosFilterList); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o == null || !(o instanceof QosSession)) { - return false; - } - - QosSession other = (QosSession) o; - return this.qosSessionId == other.qosSessionId - && this.qos.equals(other.qos) - && this.qosFilterList.size() == other.qosFilterList.size() - && this.qosFilterList.containsAll(other.qosFilterList); - } - - - public static final @NonNull Parcelable.Creator<QosSession> CREATOR = - new Parcelable.Creator<QosSession>() { - @Override - public QosSession createFromParcel(Parcel source) { - return new QosSession(source); - } - - @Override - public QosSession[] newArray(int size) { - return new QosSession[size]; - } - }; -} diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index cc050becfb25..34984e05e181 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.util.RemoteCallbackListExt; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.HashMap; /** @@ -368,7 +369,13 @@ public class ImsConfigImplBase { } private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) { - mRcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config; + // cache uncompressed config + config = isCompressed ? RcsConfig.decompressGzip(config) : config; + if (Arrays.equals(mRcsConfigData, config)) { + return; + } + mRcsConfigData = config; + // can be null in testing if (mRcsCallbacks != null) { mRcsCallbacks.broadcastAction(c -> { diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index e270b8dc3fe4..9fe06dc32c28 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2352,6 +2352,16 @@ interface ITelephony { void triggerRcsReconfiguration(int subId); /** + * Enables or disables the test mode for RCS VoLTE single registration. + */ + void setRcsSingleRegistrationTestModeEnabled(boolean enabled); + + /** + * Gets the test mode for RCS VoLTE single registration. + */ + boolean getRcsSingleRegistrationTestModeEnabled(); + + /** * Overrides the config of RCS VoLTE single registration enabled for the device. */ void setDeviceSingleRegistrationEnabledOverride(String enabled); diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index d41a6c889afb..8751e82bc085 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -321,4 +321,107 @@ public class TelephonyIntents { */ public static final String ACTION_USER_ACTIVITY_NOTIFICATION = "android.intent.action.USER_ACTIVITY_NOTIFICATION"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_REDIRECTED + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = + "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = + "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_PCO_VALUE + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = + "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = + "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_RESET + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_RESET = + "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_REDIRECTION_URL + */ + @Deprecated + public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_DATA_FAIL_CAUSE + */ + @Deprecated + public static final String EXTRA_ERROR_CODE = "errorCode"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_TYPE + */ + @Deprecated + public static final String EXTRA_APN_TYPE = "apnType"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_TYPE + */ + @Deprecated + public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_PROTOCOL + */ + @Deprecated + public static final String EXTRA_APN_PROTOCOL = "apnProto"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_PROTOCOL + */ + @Deprecated + public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_PCO_ID + */ + @Deprecated + public static final String EXTRA_PCO_ID = "pcoId"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_PCO_VALUE + */ + @Deprecated + public static final String EXTRA_PCO_VALUE = "pcoValue"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_DEFAULT_NETWORK_AVAILABLE + */ + @Deprecated + public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; } diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt index 56b56efd501b..0ca4d9551f39 100644 --- a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt +++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt @@ -63,10 +63,10 @@ class NetworkStateSnapshotTest { @Test fun testParcelUnparcel() { - val emptySnapshot = NetworkStateSnapshot(LinkProperties(), NetworkCapabilities(), - Network(TEST_NETID), null, TYPE_NONE) + val emptySnapshot = NetworkStateSnapshot(Network(TEST_NETID), NetworkCapabilities(), + LinkProperties(), null, TYPE_NONE) val snapshot = NetworkStateSnapshot( - TEST_LINK_PROPERTIES, TEST_CAPABILITIES, Network(TEST_NETID), TEST_IMSI, TYPE_WIFI) + Network(TEST_NETID), TEST_CAPABILITIES, TEST_LINK_PROPERTIES, TEST_IMSI, TYPE_WIFI) assertParcelSane(emptySnapshot, 5) assertParcelSane(snapshot, 5) } diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java index 2e1c29a2e405..3a8d6004f66f 100644 --- a/tests/net/java/android/net/IpSecAlgorithmTest.java +++ b/tests/net/java/android/net/IpSecAlgorithmTest.java @@ -129,6 +129,7 @@ public class IpSecAlgorithmTest { checkCryptKeyLenValidation(IpSecAlgorithm.CRYPT_AES_CTR, len); } checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_XCBC, 128, 96); + checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_CMAC, 128, 96); checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 288, 128); } diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt index 27224c216db3..64b774cc4340 100644 --- a/tests/net/java/android/net/NetworkTemplateTest.kt +++ b/tests/net/java/android/net/NetworkTemplateTest.kt @@ -20,14 +20,13 @@ import android.content.Context import android.net.ConnectivityManager.TYPE_MOBILE import android.net.ConnectivityManager.TYPE_WIFI import android.net.NetworkIdentity.SUBTYPE_COMBINED -import android.net.NetworkIdentity.OEM_NONE; -import android.net.NetworkIdentity.OEM_PAID; -import android.net.NetworkIdentity.OEM_PRIVATE; +import android.net.NetworkIdentity.OEM_NONE +import android.net.NetworkIdentity.OEM_PAID +import android.net.NetworkIdentity.OEM_PRIVATE import android.net.NetworkIdentity.buildNetworkIdentity import android.net.NetworkStats.DEFAULT_NETWORK_ALL import android.net.NetworkStats.METERED_ALL import android.net.NetworkStats.ROAMING_ALL -import android.net.NetworkTemplate.MATCH_ETHERNET import android.net.NetworkTemplate.MATCH_MOBILE import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD import android.net.NetworkTemplate.MATCH_WIFI @@ -50,7 +49,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotEquals import kotlin.test.assertTrue -import kotlin.test.fail private const val TEST_IMSI1 = "imsi1" private const val TEST_IMSI2 = "imsi2" @@ -60,17 +58,17 @@ private const val TEST_SSID1 = "ssid1" class NetworkTemplateTest { private val mockContext = mock(Context::class.java) - private fun buildMobileNetworkState(subscriberId: String): NetworkState = + private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot = buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId) - private fun buildWifiNetworkState(ssid: String): NetworkState = + private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot = buildNetworkState(TYPE_WIFI, ssid = ssid) private fun buildNetworkState( type: Int, subscriberId: String? = null, ssid: String? = null, - oemManaged: Int = OEM_NONE, - ): NetworkState { + oemManaged: Int = OEM_NONE + ): NetworkStateSnapshot { val lp = LinkProperties() val caps = NetworkCapabilities().apply { setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) @@ -81,7 +79,7 @@ class NetworkTemplateTest { setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, (oemManaged and OEM_PRIVATE) == OEM_PRIVATE) } - return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId) + return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type) } private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) = @@ -179,7 +177,7 @@ class NetworkTemplateTest { OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) // Verify that "not OEM managed network" constants are equal. - assertEquals(OEM_MANAGED_NO, OEM_NONE); + assertEquals(OEM_MANAGED_NO, OEM_NONE) // Verify the constants don't conflict. assertEquals(constantValues.size, constantValues.distinct().count()) @@ -201,8 +199,13 @@ class NetworkTemplateTest { * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide * one of {@code TEST_SSID*}. */ - private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null, - templateSsid: String? = null, identSsid: String? = null) { + private fun matchOemManagedIdent( + networkType: Int, + matchType: Int, + subscriberId: String? = null, + templateSsid: String? = null, + identSsid: String? = null + ) { val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) // A null subscriberId needs a null matchSubscriberIds argument as well. val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId) diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index e7ac3b6b2b13..c7e8282c8e8b 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -90,6 +90,10 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; import static android.net.RouteInfo.RTN_UNREACHABLE; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.os.Process.INVALID_UID; import static android.system.OsConstants.IPPROTO_TCP; @@ -198,7 +202,7 @@ import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; -import android.net.NetworkState; +import android.net.NetworkStateSnapshot; import android.net.NetworkTestResultParcelable; import android.net.OemNetworkPreferences; import android.net.ProxyInfo; @@ -217,6 +221,8 @@ import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; import android.net.metrics.IpConnectivityLog; +import android.net.resolv.aidl.Nat64PrefixEventParcel; +import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.NetworkMonitorUtils; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; @@ -5484,7 +5490,7 @@ public class ConnectivityServiceTest { UnderlyingNetworkInfo[].class); verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(), - any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture()); + any(NetworkStateSnapshot[].class), eq(defaultIface), vpnInfosCaptor.capture()); assertSameElementsNoDuplicates(networksCaptor.getValue(), networks); @@ -5554,9 +5560,8 @@ public class ConnectivityServiceTest { // Temp metered change shouldn't update ifaces mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); waitForIdle(); - verify(mStatsService, never()) - .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), - eq(new UnderlyingNetworkInfo[0])); + verify(mStatsService, never()).forceUpdateIfaces(eq(onlyCell), any( + NetworkStateSnapshot[].class), eq(MOBILE_IFNAME), eq(new UnderlyingNetworkInfo[0])); reset(mStatsService); // Roaming change should update ifaces @@ -5638,7 +5643,7 @@ public class ConnectivityServiceTest { // Confirm that we never tell NetworkStatsService that cell is no longer the underlying // network for the VPN... verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class), - any(NetworkState[].class), any() /* anyString() doesn't match null */, + any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */, argThat(infos -> infos[0].underlyingIfaces.size() == 1 && WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0)))); verifyNoMoreInteractions(mStatsService); @@ -5652,7 +5657,7 @@ public class ConnectivityServiceTest { mEthernetNetworkAgent.connect(false); waitForIdle(); verify(mStatsService).forceUpdateIfaces(any(Network[].class), - any(NetworkState[].class), any() /* anyString() doesn't match null */, + any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */, argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1 && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0)))); mEthernetNetworkAgent.disconnect(); @@ -5920,6 +5925,16 @@ public class ConnectivityServiceTest { assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); } + private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( + final int netId, final String ipAddress, final String hostname, final int validation) { + final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); + event.netId = netId; + event.ipAddress = ipAddress; + event.hostname = hostname; + event.validation = validation; + return event; + } + @Test public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { // The default on Android is opportunistic mode ("Automatic"). @@ -5950,8 +5965,9 @@ public class ConnectivityServiceTest { // Send a validation event for a server that is not part of the current // resolver config. The validation event should be ignored. - mService.mNetdEventCallback.onPrivateDnsValidationEvent( - mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true); + mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( + makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", + "145.100.185.18", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Add a dns server to the LinkProperties. @@ -5968,20 +5984,23 @@ public class ConnectivityServiceTest { // Send a validation event containing a hostname that is not part of // the current resolver config. The validation event should be ignored. - mService.mNetdEventCallback.onPrivateDnsValidationEvent( - mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true); + mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( + makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, + "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Send a validation event where validation failed. - mService.mNetdEventCallback.onPrivateDnsValidationEvent( - mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false); + mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( + makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, + "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); cellNetworkCallback.assertNoCallback(); // Send a validation event where validation succeeded for a server in // the current resolver config. A LinkProperties callback with updated // private dns fields should be sent. - mService.mNetdEventCallback.onPrivateDnsValidationEvent( - mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true); + mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( + makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, + "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); cellNetworkCallback.assertNoCallback(); @@ -7825,6 +7844,16 @@ public class ConnectivityServiceTest { return stacked; } + private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, + final String prefixAddress, final int prefixLength) { + final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); + event.netId = netId; + event.prefixOperation = prefixOperation; + event.prefixAddress = prefixAddress; + event.prefixLength = prefixLength; + return event; + } + @Test public void testStackedLinkProperties() throws Exception { final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); @@ -7909,8 +7938,8 @@ public class ConnectivityServiceTest { // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); - mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, - kNat64PrefixString, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent( + makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); LinkProperties lpBeforeClat = networkCallback.expectCallback( CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); assertEquals(0, lpBeforeClat.getStackedLinks().size()); @@ -7950,8 +7979,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Change the NAT64 prefix without first removing it. // Expect clatd to be stopped and started with the new prefix. - mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, - kOtherNat64PrefixString, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( + cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0); verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); @@ -7999,8 +8028,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. - mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, - kOtherNat64PrefixString, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( + cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getNat64Prefix() == null); @@ -8012,8 +8041,8 @@ public class ConnectivityServiceTest { networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); - mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, - kNat64PrefixString, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( + cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); @@ -8025,8 +8054,8 @@ public class ConnectivityServiceTest { verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); // NAT64 prefix is removed. Expect that clat is stopped. - mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, - kNat64PrefixString, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( + cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); @@ -8114,8 +8143,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); - mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, - pref64FromDnsStr, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent( + makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); @@ -8148,8 +8177,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); // Stopping prefix discovery results in a prefix removed notification. - mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */, - pref64FromDnsStr, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent( + makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); @@ -8187,8 +8216,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockNetd).clatdStop(iface); inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); - mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, - pref64FromDnsStr, 96); + mService.mResolverUnsolEventCallback.onNat64PrefixEvent( + makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java index f5b85ca06f92..5760211d9a27 100644 --- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java @@ -22,6 +22,8 @@ import static android.net.NetworkCapabilities.MAX_TRANSPORT; import static android.net.NetworkCapabilities.MIN_TRANSPORT; import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; +import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; @@ -164,7 +166,8 @@ public class DnsManagerTest { mDnsManager.flushVmDnsCache(); mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE, - InetAddress.parseNumericAddress("4.4.4.4"), "", true)); + InetAddress.parseNumericAddress("4.4.4.4"), "", + VALIDATION_RESULT_SUCCESS)); LinkProperties fixedLp = new LinkProperties(lp); mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); assertFalse(fixedLp.isPrivateDnsActive()); @@ -204,7 +207,8 @@ public class DnsManagerTest { // Validate one. mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", true)); + InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", + VALIDATION_RESULT_SUCCESS)); fixedLp = new LinkProperties(lp); mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")), @@ -212,7 +216,8 @@ public class DnsManagerTest { // Validate the 2nd one. mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", true)); + InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", + VALIDATION_RESULT_SUCCESS)); fixedLp = new LinkProperties(lp); mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); assertEquals(Arrays.asList( @@ -232,7 +237,8 @@ public class DnsManagerTest { mDnsManager.flushVmDnsCache(); mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + InetAddress.parseNumericAddress("3.3.3.3"), "", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -245,7 +251,8 @@ public class DnsManagerTest { mDnsManager.flushVmDnsCache(); mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED, - InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + InetAddress.parseNumericAddress("3.3.3.3"), "", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -253,7 +260,8 @@ public class DnsManagerTest { // Validation event has untracked ipAddress mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("4.4.4.4"), "", true)); + InetAddress.parseNumericAddress("4.4.4.4"), "", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -261,8 +269,8 @@ public class DnsManagerTest { // Validation event has untracked hostname mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "hostname", - true)); + InetAddress.parseNumericAddress("3.3.3.3"), "hostname", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -270,7 +278,8 @@ public class DnsManagerTest { // Validation event failed mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", false)); + InetAddress.parseNumericAddress("3.3.3.3"), "", + VALIDATION_RESULT_FAILURE)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -279,7 +288,7 @@ public class DnsManagerTest { mDnsManager.removeNetwork(new Network(TEST_NETID)); mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + InetAddress.parseNumericAddress("3.3.3.3"), "", VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -293,7 +302,8 @@ public class DnsManagerTest { mDnsManager.flushVmDnsCache(); mDnsManager.updatePrivateDnsValidation( new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + InetAddress.parseNumericAddress("3.3.3.3"), "", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); assertFalse(lp.isPrivateDnsActive()); assertNull(lp.getPrivateDnsServerName()); @@ -398,7 +408,8 @@ public class DnsManagerTest { mDnsManager.updatePrivateDns(network, mDnsManager.getPrivateDnsConfig()); mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "", true)); + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "", + VALIDATION_RESULT_SUCCESS)); mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); privateDnsCfg = mDnsManager.getPrivateDnsConfig(network); assertTrue(privateDnsCfg.useTls); diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 54d6fb9f2c12..9334e2c4ad77 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -19,9 +19,7 @@ package com.android.server.net; import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkIdentity.OEM_PAID; import static android.net.NetworkIdentity.OEM_PRIVATE; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; @@ -86,7 +84,7 @@ import android.net.INetworkStatsSession; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkState; +import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; @@ -286,7 +284,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -329,7 +327,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -403,7 +401,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -444,7 +442,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testUidStatsAcrossNetworks() throws Exception { // pretend first mobile network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -475,7 +473,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // disappearing, to verify we don't count backwards. incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); - states = new NetworkState[] {buildMobile3gState(IMSI_2)}; + states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_2)}; expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) @@ -519,7 +517,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testUidRemovedIsMoved() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -583,7 +581,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE); final NetworkTemplate template5g = buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR); - final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)}; + final NetworkStateSnapshot[] states = + new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; // 3G network comes online. expectNetworkStatsSummary(buildEmptyStats()); @@ -673,7 +672,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO); // OEM_PAID network comes online. - NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ + buildOemManagedMobileState(IMSI_1, false, new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -688,7 +688,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { forcePollAndWaitForIdle(); // OEM_PRIVATE network comes online. - states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -703,7 +703,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { forcePollAndWaitForIdle(); // OEM_PAID + OEM_PRIVATE network comes online. - states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; expectNetworkStatsSummary(buildEmptyStats()); @@ -719,7 +719,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { forcePollAndWaitForIdle(); // OEM_NONE network comes online. - states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})}; + states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), @@ -771,7 +771,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testSummaryForAllUid() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -830,7 +830,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testDetailedUidStats() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -871,9 +871,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { final String stackedIface = "stacked-test0"; final LinkProperties stackedProp = new LinkProperties(); stackedProp.setInterfaceName(stackedIface); - final NetworkState wifiState = buildWifiState(); + final NetworkStateSnapshot wifiState = buildWifiState(); wifiState.linkProperties.addStackedLink(stackedProp); - NetworkState[] states = new NetworkState[] {wifiState}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -929,7 +929,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testForegroundBackground() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -986,8 +986,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testMetered() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = - new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)}; + NetworkStateSnapshot[] states = + new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1026,8 +1026,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testRoaming() throws Exception { // pretend that network comes online expectDefaultSettings(); - NetworkState[] states = - new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)}; + NetworkStateSnapshot[] states = + new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1, true /* isRoaming */)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1065,7 +1065,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testTethering() throws Exception { // pretend first mobile network comes online expectDefaultSettings(); - final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)}; + final NetworkStateSnapshot[] states = + new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1122,7 +1123,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. expectDefaultSettings(); - NetworkState[] states = new NetworkState[] {buildWifiState()}; + NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1220,8 +1221,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testStatsProviderUpdateStats() throws Exception { // Pretend that network comes online. expectDefaultSettings(); - final NetworkState[] states = - new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; + final NetworkStateSnapshot[] states = + new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1282,8 +1283,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testStatsProviderSetAlert() throws Exception { // Pretend that network comes online. expectDefaultSettings(); - NetworkState[] states = - new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; + NetworkStateSnapshot[] states = + new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new UnderlyingNetworkInfo[0]); @@ -1326,7 +1327,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN); final NetworkTemplate templateAll = buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL); - final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)}; + final NetworkStateSnapshot[] states = + new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); @@ -1401,7 +1403,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public void testOperationCount_nonDefault_traffic() throws Exception { // Pretend mobile network comes online, but wifi is the default network. expectDefaultSettings(); - NetworkState[] states = new NetworkState[]{ + NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)}; expectNetworkStatsUidDetail(buildEmptyStats()); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), @@ -1489,7 +1491,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(buildEmptyStats()); } - private String getActiveIface(NetworkState... states) throws Exception { + private String getActiveIface(NetworkStateSnapshot... states) throws Exception { if (states == null || states.length == 0 || states[0].linkProperties == null) { return null; } @@ -1565,11 +1567,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertEquals("unexpected operations", operations, entry.operations); } - private static NetworkState buildWifiState() { + private static NetworkStateSnapshot buildWifiState() { return buildWifiState(false, TEST_IFACE); } - private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) { + private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) { final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(iface); final NetworkCapabilities capabilities = new NetworkCapabilities(); @@ -1577,35 +1579,30 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); capabilities.setSSID(TEST_SSID); - return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null); + return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI); } - private static NetworkState buildMobile3gState(String subscriberId) { + private static NetworkStateSnapshot buildMobile3gState(String subscriberId) { return buildMobile3gState(subscriberId, false /* isRoaming */); } - private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) { + private static NetworkStateSnapshot buildMobile3gState(String subscriberId, boolean isRoaming) { final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(TEST_IFACE); final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId); + return new NetworkStateSnapshot( + MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE); } private NetworkStats buildEmptyStats() { return new NetworkStats(getElapsedRealtime(), 0); } - private static NetworkState buildVpnState() { - final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(TUN_IFACE); - return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null); - } - - private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming, - int[] oemNetCapabilities) { + private static NetworkStateSnapshot buildOemManagedMobileState( + String subscriberId, boolean isRoaming, int[] oemNetCapabilities) { final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(TEST_IFACE); final NetworkCapabilities capabilities = new NetworkCapabilities(); @@ -1615,7 +1612,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { capabilities.setCapability(nc, true); } capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId); + return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId, + TYPE_MOBILE); } private long getElapsedRealtime() { |