diff options
84 files changed, 1727 insertions, 682 deletions
diff --git a/ApiDocs.bp b/ApiDocs.bp index ca921ff97c35..d6302097081a 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -65,7 +65,7 @@ stubs_defaults { "test-base/src/**/*.java", ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":art-module-public-api-stubs-source", + ":art.module.public.api{.public.stubs.source}", ":conscrypt.module.public.api{.public.stubs.source}", ":android_icu4j_public_api_files", "test-mock/src/**/*.java", @@ -131,7 +131,7 @@ doc_defaults { ], knowntags: [ "docs/knowntags.txt", - ":known-oj-tags", + ":art.module.public.api{.doctags}", ], custom_template: "droiddoc-templates-sdk", resourcesdir: "docs/html/reference/images/", diff --git a/StubLibraries.bp b/StubLibraries.bp index 79e2a87cf31d..c55fbd2d0728 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -47,7 +47,7 @@ stubs_defaults { "core/java/**/*.logtags", ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":art-module-public-api-stubs-source", + ":art.module.public.api{.public.stubs.source}", ":android_icu4j_public_api_files", "**/package.html", ], diff --git a/apex/media/OWNERS b/apex/media/OWNERS index 9b853c5dd7d8..ced2fb5e2dcd 100644 --- a/apex/media/OWNERS +++ b/apex/media/OWNERS @@ -1,4 +1,10 @@ andrewlewis@google.com aquilescanta@google.com +chz@google.com +hdmoon@google.com +hkuang@google.com +jinpark@google.com +klhyun@google.com +lnilsson@google.com marcone@google.com sungsoo@google.com diff --git a/api/current.txt b/api/current.txt index 68a22f2360cf..e16876e45c87 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8771,6 +8771,7 @@ package android.bluetooth { method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int); method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int); method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int); + method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt); method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int); } @@ -36463,7 +36464,7 @@ package android.os { method public int dataCapacity(); method public int dataPosition(); method public int dataSize(); - method public void enforceInterface(String); + method public void enforceInterface(@NonNull String); method public boolean hasFileDescriptors(); method public byte[] marshall(); method @NonNull public static android.os.Parcel obtain(); @@ -36534,7 +36535,7 @@ package android.os { method public void writeFloatArray(@Nullable float[]); method public void writeInt(int); method public void writeIntArray(@Nullable int[]); - method public void writeInterfaceToken(String); + method public void writeInterfaceToken(@NonNull String); method public void writeList(@Nullable java.util.List); method public void writeLong(long); method public void writeLongArray(@Nullable long[]); @@ -46944,7 +46945,7 @@ package android.telephony { method public long getNci(); method @IntRange(from=0, to=3279165) public int getNrarfcn(); method @IntRange(from=0, to=1007) public int getPci(); - method @IntRange(from=0, to=65535) public int getTac(); + method @IntRange(from=0, to=16777215) public int getTac(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR; } @@ -47038,9 +47039,9 @@ package android.telephony { field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR; } - public abstract class CellLocation { - ctor public CellLocation(); - method public static android.telephony.CellLocation getEmpty(); + @Deprecated public abstract class CellLocation { + ctor @Deprecated public CellLocation(); + method @Deprecated public static android.telephony.CellLocation getEmpty(); method @Deprecated public static void requestLocationUpdate(); } @@ -47830,6 +47831,7 @@ package android.telephony { method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method public int getState(); + method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR; } @@ -48547,19 +48549,19 @@ package android.telephony { package android.telephony.cdma { - public class CdmaCellLocation extends android.telephony.CellLocation { - ctor public CdmaCellLocation(); - ctor public CdmaCellLocation(android.os.Bundle); - method public static double convertQuartSecToDecDegrees(int); - method public void fillInNotifierBundle(android.os.Bundle); - method public int getBaseStationId(); - method public int getBaseStationLatitude(); - method public int getBaseStationLongitude(); - method public int getNetworkId(); - method public int getSystemId(); - method public void setCellLocationData(int, int, int); - method public void setCellLocationData(int, int, int, int, int); - method public void setStateInvalid(); + @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation { + ctor @Deprecated public CdmaCellLocation(); + ctor @Deprecated public CdmaCellLocation(android.os.Bundle); + method @Deprecated public static double convertQuartSecToDecDegrees(int); + method @Deprecated public void fillInNotifierBundle(android.os.Bundle); + method @Deprecated public int getBaseStationId(); + method @Deprecated public int getBaseStationLatitude(); + method @Deprecated public int getBaseStationLongitude(); + method @Deprecated public int getNetworkId(); + method @Deprecated public int getSystemId(); + method @Deprecated public void setCellLocationData(int, int, int); + method @Deprecated public void setCellLocationData(int, int, int, int, int); + method @Deprecated public void setStateInvalid(); } } @@ -48759,15 +48761,15 @@ package android.telephony.euicc { package android.telephony.gsm { - public class GsmCellLocation extends android.telephony.CellLocation { - ctor public GsmCellLocation(); - ctor public GsmCellLocation(android.os.Bundle); - method public void fillInNotifierBundle(android.os.Bundle); - method public int getCid(); - method public int getLac(); - method public int getPsc(); - method public void setLacAndCid(int, int); - method public void setStateInvalid(); + @Deprecated public class GsmCellLocation extends android.telephony.CellLocation { + ctor @Deprecated public GsmCellLocation(); + ctor @Deprecated public GsmCellLocation(android.os.Bundle); + method @Deprecated public void fillInNotifierBundle(android.os.Bundle); + method @Deprecated public int getCid(); + method @Deprecated public int getLac(); + method @Deprecated public int getPsc(); + method @Deprecated public void setLacAndCid(int, int); + method @Deprecated public void setStateInvalid(); } @Deprecated public final class SmsManager { diff --git a/api/system-current.txt b/api/system-current.txt index 7276b37ba20b..ddf9c4d97e6f 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10838,6 +10838,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { @@ -11187,6 +11188,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -11400,6 +11402,7 @@ package android.telephony.data { method public int getCause(); method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses(); method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses(); + method public int getHandoverFailureMode(); method public int getId(); method @NonNull public String getInterfaceName(); method public int getLinkStatus(); @@ -11411,6 +11414,11 @@ package android.telephony.data { method public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; + field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 2; // 0x2 + field public static final int HANDOVER_FAILURE_MODE_LEGACY = 1; // 0x1 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 3; // 0x3 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 4; // 0x4 + field public static final int HANDOVER_FAILURE_MODE_UNKNOWN = 0; // 0x0 field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 field public static final int LINK_STATUS_DORMANT = 1; // 0x1 field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 @@ -11424,6 +11432,7 @@ package android.telephony.data { method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setHandoverFailureMode(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt index 9c40b6cf63ce..86169614e3c4 100644 --- a/api/system-lint-baseline.txt +++ b/api/system-lint-baseline.txt @@ -1,43 +1,46 @@ // Baseline format: 1.0 AcronymName: android.net.NetworkCapabilities#setSSID(String): - Acronyms should not be capitalized in method names: was `setSSID`, should this be `setSsid`? + ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION: -ActionValue: android.net.wifi.WifiManager#ACTION_LINK_CONFIGURATION_CHANGED: - - -// Tethering broadcast action / extras cannot change name for backwards compatibility ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED: - Inconsistent action value; expected `android.net.action.TETHER_STATE_CHANGED`, was `android.net.conn.TETHER_STATE_CHANGED` + ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER: - Inconsistent extra value; expected `android.net.extra.ACTIVE_TETHER`, was `tetherArray` + ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER: - Inconsistent extra value; expected `android.net.extra.AVAILABLE_TETHER`, was `availableArray` + ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER: - Inconsistent extra value; expected `android.net.extra.ERRORED_TETHER`, was `erroredArray` + +ActionValue: android.net.wifi.WifiManager#ACTION_LINK_CONFIGURATION_CHANGED: + + ArrayReturn: android.bluetooth.BluetoothCodecStatus#BluetoothCodecStatus(android.bluetooth.BluetoothCodecConfig, android.bluetooth.BluetoothCodecConfig[], android.bluetooth.BluetoothCodecConfig[]) parameter #1: - Method parameter should be Collection<BluetoothCodecConfig> (or subclass) instead of raw array; was `android.bluetooth.BluetoothCodecConfig[]` + ArrayReturn: android.bluetooth.BluetoothCodecStatus#BluetoothCodecStatus(android.bluetooth.BluetoothCodecConfig, android.bluetooth.BluetoothCodecConfig[], android.bluetooth.BluetoothCodecConfig[]) parameter #2: - Method parameter should be Collection<BluetoothCodecConfig> (or subclass) instead of raw array; was `android.bluetooth.BluetoothCodecConfig[]` + ArrayReturn: android.bluetooth.BluetoothCodecStatus#getCodecsLocalCapabilities(): - Method should return Collection<BluetoothCodecConfig> (or subclass) instead of raw array; was `android.bluetooth.BluetoothCodecConfig[]` + ArrayReturn: android.bluetooth.BluetoothCodecStatus#getCodecsSelectableCapabilities(): - Method should return Collection<BluetoothCodecConfig> (or subclass) instead of raw array; was `android.bluetooth.BluetoothCodecConfig[]` + ArrayReturn: android.bluetooth.BluetoothUuid#containsAnyUuid(android.os.ParcelUuid[], android.os.ParcelUuid[]) parameter #0: - Method parameter should be Collection<ParcelUuid> (or subclass) instead of raw array; was `android.os.ParcelUuid[]` + ArrayReturn: android.bluetooth.BluetoothUuid#containsAnyUuid(android.os.ParcelUuid[], android.os.ParcelUuid[]) parameter #1: - Method parameter should be Collection<ParcelUuid> (or subclass) instead of raw array; was `android.os.ParcelUuid[]` + ArrayReturn: android.media.tv.tuner.Tuner.FilterCallback#onFilterEvent(android.media.tv.tuner.Tuner.Filter, android.media.tv.tuner.filter.FilterEvent[]) parameter #1: - Method parameter should be Collection<FilterEvent> (or subclass) instead of raw array; was `android.media.tv.tuner.filter.FilterEvent[]` + ArrayReturn: android.net.NetworkScoreManager#requestScores(android.net.NetworkKey[]) parameter #0: - Method parameter should be Collection<NetworkKey> (or subclass) instead of raw array; was `android.net.NetworkKey[]` + ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): +BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex) + + ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#deletePersistentGroup(android.net.wifi.p2p.WifiP2pManager.Channel, int, android.net.wifi.p2p.WifiP2pManager.ActionListener): ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener): @@ -65,7 +68,7 @@ GenericException: android.service.autofill.augmented.FillWindow#finalize(): IntentBuilderName: android.content.Context#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler): - Methods creating an Intent should be named `create<Foo>Intent()`, was `registerReceiverForAllUsers` + KotlinKeyword: android.app.Notification#when: @@ -73,7 +76,19 @@ KotlinKeyword: android.app.Notification#when: KotlinOperator: android.telephony.CbGeoUtils.Geometry#contains(android.telephony.CbGeoUtils.LatLng): - Method can be invoked as a "in" operator from Kotlin: `contains` (this is usually desirable; just make sure it makes sense for this type of object) + + + +MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig): + android.net.wifi.rtt.RangingRequest does not declare a `getResponders()` method matching method android.net.wifi.rtt.RangingRequest.Builder.addResponder(android.net.wifi.rtt.ResponderConfig) +MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int): + android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int) +MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation): + android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation) +MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean): + android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean) +MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String): + android.telephony.mbms.DownloadRequest does not declare a `getServiceId()` method matching method android.telephony.mbms.DownloadRequest.Builder.setServiceId(String) MissingNullability: android.hardware.soundtrigger.SoundTrigger.ModuleProperties#toString(): @@ -217,28 +232,27 @@ MutableBareField: android.net.wifi.WifiScanner.ScanSettings#type: NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0: - + NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED: - New setting keys are not allowed. (Field: TETHER_OFFLOAD_DISABLED) + NoSettingsProvider: android.provider.Settings.Global#TETHER_SUPPORTED: - New setting keys are not allowed. (Field: TETHER_SUPPORTED) NotCloseable: android.bluetooth.BluetoothA2dpSink: - Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.bluetooth.BluetoothA2dpSink + NotCloseable: android.bluetooth.BluetoothMap: - Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.bluetooth.BluetoothMap + NotCloseable: android.bluetooth.BluetoothPan: - Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.bluetooth.BluetoothPan + NotCloseable: android.bluetooth.BluetoothPbap: - Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.bluetooth.BluetoothPbap + OnNameExpected: android.content.ContentProvider#checkUriPermission(android.net.Uri, int, int): - If implemented by developer, should follow the on<Something> style; otherwise consider marking final + PairedRegistration: android.net.wifi.nl80211.WifiNl80211Manager#registerApCallback(String, java.util.concurrent.Executor, android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback): @@ -300,7 +314,7 @@ SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, and SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String): SamShouldBeLast: android.app.WallpaperManager#addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler): - SAM-compatible parameters (such as parameter 1, "listener", in android.app.WallpaperManager.addOnColorsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback): SamShouldBeLast: android.content.Context#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection): @@ -334,19 +348,19 @@ SamShouldBeLast: android.location.LocationManager#registerGnssNavigationMessageC SamShouldBeLast: android.location.LocationManager#registerGnssStatusCallback(java.util.concurrent.Executor, android.location.GnssStatus.Callback): SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper): - SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener): SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener): SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper): - SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener): SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, android.location.LocationListener, android.os.Looper): - SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper): - SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.media.AudioFocusRequest.Builder#setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler): SamShouldBeLast: android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int): @@ -359,6 +373,8 @@ SamShouldBeLast: android.media.AudioRecordingMonitor#registerAudioRecordingCallb SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): +SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): + SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback): @@ -510,8 +526,8 @@ ServiceName: android.provider.DeviceConfig#NAMESPACE_PACKAGE_MANAGER_SERVICE: UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociated(String, android.net.MacAddress, android.os.UserHandle): - When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added + UserHandleName: android.telephony.CellBroadcastIntents#sendOrderedBroadcastForBackgroundReceivers(android.content.Context, android.os.UserHandle, android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle): - Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `sendOrderedBroadcastForBackgroundReceivers` + diff --git a/api/system-removed.txt b/api/system-removed.txt index 09544c11f8b7..3acc22528438 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -180,11 +180,6 @@ package android.telecom { package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt index 6562c7e35c73..0287a286e69c 100644 --- a/api/test-lint-baseline.txt +++ b/api/test-lint-baseline.txt @@ -7,16 +7,14 @@ AcronymName: android.app.NotificationChannel#setImportanceLockedByOEM(boolean): ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION: -// Tethering broadcast action / extras cannot change name for backwards compatibility ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED: - Inconsistent action value; expected `android.net.action.TETHER_STATE_CHANGED`, was `android.net.conn.TETHER_STATE_CHANGED` + ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER: - Inconsistent extra value; expected `android.net.extra.ACTIVE_TETHER`, was `tetherArray` + ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER: - Inconsistent extra value; expected `android.net.extra.AVAILABLE_TETHER`, was `availableArray` + ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER: - Inconsistent extra value; expected `android.net.extra.ERRORED_TETHER`, was `erroredArray` - + ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_ADDITIONAL_CALL_INFO: ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CALL_RAT_TYPE: @@ -75,6 +73,12 @@ ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_LIST: ArrayReturn: android.app.UiAutomation#executeShellCommandRw(String): +ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[]) parameter #3: + Method parameter should be Collection<Keyphrase> (or subclass) instead of raw array; was `android.hardware.soundtrigger.SoundTrigger.Keyphrase[]` +ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int) parameter #3: + Method parameter should be Collection<Keyphrase> (or subclass) instead of raw array; was `android.hardware.soundtrigger.SoundTrigger.Keyphrase[]` +ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#getKeyphrases(): + Method should return Collection<Keyphrase> (or subclass) instead of raw array; was `android.hardware.soundtrigger.SoundTrigger.Keyphrase[]` ArrayReturn: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1: ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10: @@ -117,6 +121,8 @@ ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQue ArrayReturn: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0: +ArrayReturn: android.view.Display#getSupportedWideColorGamut(): + Method should return Collection<ColorSpace> (or subclass) instead of raw array; was `android.graphics.ColorSpace[]` ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0: ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): @@ -211,6 +217,36 @@ BannedThrow: android.os.Process#getThreadScheduler(int): +BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#allowPrivilegedPlaybackCapture(boolean): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.media.audiopolicy.AudioMixingRule.Builder.allowPrivilegedPlaybackCapture(boolean) +BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.media.audiopolicy.AudioMixingRule.Builder.excludeMixRule(int,Object) +BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.media.audiopolicy.AudioMixingRule.Builder.excludeRule(android.media.AudioAttributes,int) +BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeCapability(int): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.NetworkCapabilities.Builder.removeCapability(int) +BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeTransportType(int): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.NetworkCapabilities.Builder.removeTransportType(int) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateDnsslLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updateDnsslLifetime(long) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixPreferredLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updatePrefixPreferredLifetime(long) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixValidLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updatePrefixValidLifetime(long) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRdnssLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updateRdnssLifetime(long) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouteInfoLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updateRouteInfoLifetime(long) +BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouterLifetime(long): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.metrics.RaEvent.Builder.updateRouterLifetime(long) +BuilderSetStyle: android.os.StrictMode.ThreadPolicy.Builder#detectExplicitGc(): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.ThreadPolicy.Builder.detectExplicitGc() +BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#detectIncorrectContextUse(): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.VmPolicy.Builder.detectIncorrectContextUse() +BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#permitIncorrectContextUse(): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.VmPolicy.Builder.permitIncorrectContextUse() + + CallbackInterface: android.app.prediction.AppPredictor.Callback: CallbackInterface: android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback: @@ -345,8 +381,12 @@ ExecutorRegistration: android.os.IncidentManager#requestAuthorization(int, Strin ExecutorRegistration: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener, android.os.Handler): +ExecutorRegistration: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler): + Registration methods should have overload that accepts delivery Executor: `countPermissionApps` ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler): +ExecutorRegistration: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback): + Registration methods should have overload that accepts delivery Executor: `setCallback` ExecutorRegistration: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener): ExecutorRegistration: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener): @@ -365,6 +405,8 @@ ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#ini ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback): +ExecutorRegistration: android.window.WindowOrganizer#applySyncTransaction(android.window.WindowContainerTransaction, android.window.WindowContainerTransactionCallback): + Registration methods should have overload that accepts delivery Executor: `applySyncTransaction` ForbiddenSuperClass: android.app.AppDetailsActivity: @@ -385,6 +427,12 @@ GenericException: android.service.autofill.augmented.FillWindow#finalize(): +GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByCategory(): + Getter should be on the built object, not the builder: method android.hardware.display.BrightnessConfiguration.Builder.getMaxCorrectionsByCategory() +GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByPackageName(): + Getter should be on the built object, not the builder: method android.hardware.display.BrightnessConfiguration.Builder.getMaxCorrectionsByPackageName() + + GetterSetterNames: android.app.NotificationChannel#isBlockableSystem(): GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByCriticalDeviceFunction(): @@ -406,13 +454,13 @@ GetterSetterNames: android.location.GnssClock#setElapsedRealtimeUncertaintyNanos GetterSetterNames: android.location.GnssClock#setFullBiasNanos(long): GetterSetterNames: android.location.GnssClock#setLeapSecond(int): - -GetterSetterNames: android.location.GnssClock#setReferenceConstellationTypeForIsb(int): - + GetterSetterNames: android.location.GnssClock#setReferenceCarrierFrequencyHzForIsb(double): - + GetterSetterNames: android.location.GnssClock#setReferenceCodeTypeForIsb(String): - + +GetterSetterNames: android.location.GnssClock#setReferenceConstellationTypeForIsb(int): + GetterSetterNames: android.location.GnssClock#setTimeUncertaintyNanos(double): GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double): @@ -420,15 +468,15 @@ GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double): GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float): GetterSetterNames: android.location.GnssMeasurement#setCodeType(String): - + GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double): - + GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasUncertaintyNanos(double): - + GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasNanos(double): - + GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasUncertaintyNanos(double): - + GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double): GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored(): @@ -461,6 +509,8 @@ IntentBuilderName: android.app.backup.BackupManager#getConfigurationIntent(Strin IntentBuilderName: android.app.backup.BackupManager#getDataManagementIntent(String): +IntentBuilderName: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale): + Methods creating an Intent should be named `create<Foo>Intent()`, was `getManageKeyphraseIntent` IntentName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE: @@ -509,6 +559,8 @@ ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(a ListenerLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper) parameter #2: +ListenerLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler) parameter #3: + Listeners should always be at end of argument list (method `countPermissionApps`) ListenerLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler) parameter #2: ListenerLast: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) parameter #1: @@ -541,6 +593,142 @@ MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE +MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setAttributionTag(String): + android.app.AppOpsManager.HistoricalOpsRequest does not declare a `getAttributionTag()` method matching method android.app.AppOpsManager.HistoricalOpsRequest.Builder.setAttributionTag(String) +MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setFlags(int): + android.app.AppOpsManager.HistoricalOpsRequest does not declare a `getFlags()` method matching method android.app.AppOpsManager.HistoricalOpsRequest.Builder.setFlags(int) +MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setOpNames(java.util.List<java.lang.String>): + android.app.AppOpsManager.HistoricalOpsRequest does not declare a `getOpNames()` method matching method android.app.AppOpsManager.HistoricalOpsRequest.Builder.setOpNames(java.util.List<java.lang.String>) +MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setPackageName(String): + android.app.AppOpsManager.HistoricalOpsRequest does not declare a `getPackageName()` method matching method android.app.AppOpsManager.HistoricalOpsRequest.Builder.setPackageName(String) +MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setUid(int): + android.app.AppOpsManager.HistoricalOpsRequest does not declare a `getUid()` method matching method android.app.AppOpsManager.HistoricalOpsRequest.Builder.setUid(int) +MissingGetterMatchingBuilder: android.content.integrity.RuleSet.Builder#addRules(java.util.List<android.content.integrity.Rule>): + android.content.integrity.RuleSet does not declare a `getRuless()` method matching method android.content.integrity.RuleSet.Builder.addRules(java.util.List<android.content.integrity.Rule>) +MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByCategory(int, android.hardware.display.BrightnessCorrection): + android.hardware.display.BrightnessConfiguration does not declare a `getCorrectionByCategorys()` method matching method android.hardware.display.BrightnessConfiguration.Builder.addCorrectionByCategory(int,android.hardware.display.BrightnessCorrection) +MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByPackageName(String, android.hardware.display.BrightnessCorrection): + android.hardware.display.BrightnessConfiguration does not declare a `getCorrectionByPackageNames()` method matching method android.hardware.display.BrightnessConfiguration.Builder.addCorrectionByPackageName(String,android.hardware.display.BrightnessCorrection) +MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#setDescription(String): + android.hardware.display.BrightnessConfiguration does not declare a `getDescription()` method matching method android.hardware.display.BrightnessConfiguration.Builder.setDescription(String) +MissingGetterMatchingBuilder: android.hardware.lights.LightsRequest.Builder#setLight(android.hardware.lights.Light, android.hardware.lights.LightState): + android.hardware.lights.LightsRequest does not declare a `getLight()` method matching method android.hardware.lights.LightsRequest.Builder.setLight(android.hardware.lights.Light,android.hardware.lights.LightState) +MissingGetterMatchingBuilder: android.media.VolumeShaper.Configuration.Builder#setOptionFlags(int): + android.media.VolumeShaper.Configuration does not declare a `getOptionFlags()` method matching method android.media.VolumeShaper.Configuration.Builder.setOptionFlags(int) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo): + android.media.audiopolicy.AudioMix does not declare a `getDevice()` method matching method android.media.audiopolicy.AudioMix.Builder.setDevice(android.media.AudioDeviceInfo) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat): + android.media.audiopolicy.AudioMix does not declare a `getFormat()` method matching method android.media.audiopolicy.AudioMix.Builder.setFormat(android.media.AudioFormat) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int): + android.media.audiopolicy.AudioMix does not declare a `getRouteFlags()` method matching method android.media.audiopolicy.AudioMix.Builder.setRouteFlags(int) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object): + android.media.audiopolicy.AudioMixingRule does not declare a `getMixRules()` method matching method android.media.audiopolicy.AudioMixingRule.Builder.addMixRule(int,Object) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int): + android.media.audiopolicy.AudioMixingRule does not declare a `getRules()` method matching method android.media.audiopolicy.AudioMixingRule.Builder.addRule(android.media.AudioAttributes,int) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix): + android.media.audiopolicy.AudioPolicy does not declare a `getMixs()` method matching method android.media.audiopolicy.AudioPolicy.Builder.addMix(android.media.audiopolicy.AudioMix) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener): + android.media.audiopolicy.AudioPolicy does not declare a `getAudioPolicyFocusListener()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener): + android.media.audiopolicy.AudioPolicy does not declare a `getAudioPolicyStatusListener()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback): + android.media.audiopolicy.AudioPolicy does not declare a `getAudioPolicyVolumeCallback()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsAudioFocusPolicy(boolean): + android.media.audiopolicy.AudioPolicy does not declare a `isIsAudioFocusPolicy()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setIsAudioFocusPolicy(boolean) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsTestFocusPolicy(boolean): + android.media.audiopolicy.AudioPolicy does not declare a `isIsTestFocusPolicy()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setIsTestFocusPolicy(boolean) +MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper): + android.media.audiopolicy.AudioPolicy does not declare a `getLooper()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setLooper(android.os.Looper) +MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setBytesRemaining(long): + android.net.CaptivePortalData does not declare a `getBytesRemaining()` method matching method android.net.CaptivePortalData.Builder.setBytesRemaining(long) +MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setExpiryTime(long): + android.net.CaptivePortalData does not declare a `getExpiryTime()` method matching method android.net.CaptivePortalData.Builder.setExpiryTime(long) +MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setRefreshTime(long): + android.net.CaptivePortalData does not declare a `getRefreshTime()` method matching method android.net.CaptivePortalData.Builder.setRefreshTime(long) +MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#addCapability(int): + android.net.NetworkCapabilities does not declare a `getCapabilitys()` method matching method android.net.NetworkCapabilities.Builder.addCapability(int) +MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorPackageName(String): + android.net.NetworkCapabilities does not declare a `getRequestorPackageName()` method matching method android.net.NetworkCapabilities.Builder.setRequestorPackageName(String) +MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorUid(int): + android.net.NetworkCapabilities does not declare a `getRequestorUid()` method matching method android.net.NetworkCapabilities.Builder.setRequestorUid(int) +MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setShouldShowEntitlementUi(boolean): + android.net.TetheringManager.TetheringRequest does not declare a `shouldShowEntitlementUi()` method matching method android.net.TetheringManager.TetheringRequest.Builder.setShouldShowEntitlementUi(boolean) +MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setStaticIpv4Addresses(android.net.LinkAddress, android.net.LinkAddress): + android.net.TetheringManager.TetheringRequest does not declare a `getStaticIpv4Addresses()` method matching method android.net.TetheringManager.TetheringRequest.Builder.setStaticIpv4Addresses(android.net.LinkAddress,android.net.LinkAddress) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setActualLifetime(long): + android.net.metrics.ApfProgramEvent does not declare a `getActualLifetime()` method matching method android.net.metrics.ApfProgramEvent.Builder.setActualLifetime(long) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setCurrentRas(int): + android.net.metrics.ApfProgramEvent does not declare a `getCurrentRas()` method matching method android.net.metrics.ApfProgramEvent.Builder.setCurrentRas(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFilteredRas(int): + android.net.metrics.ApfProgramEvent does not declare a `getFilteredRas()` method matching method android.net.metrics.ApfProgramEvent.Builder.setFilteredRas(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFlags(boolean, boolean): + android.net.metrics.ApfProgramEvent does not declare a `isFlags()` method matching method android.net.metrics.ApfProgramEvent.Builder.setFlags(boolean,boolean) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setLifetime(long): + android.net.metrics.ApfProgramEvent does not declare a `getLifetime()` method matching method android.net.metrics.ApfProgramEvent.Builder.setLifetime(long) +MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setProgramLength(int): + android.net.metrics.ApfProgramEvent does not declare a `getProgramLength()` method matching method android.net.metrics.ApfProgramEvent.Builder.setProgramLength(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDroppedRas(int): + android.net.metrics.ApfStats does not declare a `getDroppedRas()` method matching method android.net.metrics.ApfStats.Builder.setDroppedRas(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDurationMs(long): + android.net.metrics.ApfStats does not declare a `getDurationMs()` method matching method android.net.metrics.ApfStats.Builder.setDurationMs(long) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMatchingRas(int): + android.net.metrics.ApfStats does not declare a `getMatchingRas()` method matching method android.net.metrics.ApfStats.Builder.setMatchingRas(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMaxProgramSize(int): + android.net.metrics.ApfStats does not declare a `getMaxProgramSize()` method matching method android.net.metrics.ApfStats.Builder.setMaxProgramSize(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setParseErrors(int): + android.net.metrics.ApfStats does not declare a `getParseErrors()` method matching method android.net.metrics.ApfStats.Builder.setParseErrors(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdates(int): + android.net.metrics.ApfStats does not declare a `getProgramUpdates()` method matching method android.net.metrics.ApfStats.Builder.setProgramUpdates(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAll(int): + android.net.metrics.ApfStats does not declare a `getProgramUpdatesAll()` method matching method android.net.metrics.ApfStats.Builder.setProgramUpdatesAll(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAllowingMulticast(int): + android.net.metrics.ApfStats does not declare a `getProgramUpdatesAllowingMulticast()` method matching method android.net.metrics.ApfStats.Builder.setProgramUpdatesAllowingMulticast(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setReceivedRas(int): + android.net.metrics.ApfStats does not declare a `getReceivedRas()` method matching method android.net.metrics.ApfStats.Builder.setReceivedRas(int) +MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setZeroLifetimeRas(int): + android.net.metrics.ApfStats does not declare a `getZeroLifetimeRas()` method matching method android.net.metrics.ApfStats.Builder.setZeroLifetimeRas(int) +MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setDurationMs(int): + android.net.metrics.DhcpClientEvent does not declare a `getDurationMs()` method matching method android.net.metrics.DhcpClientEvent.Builder.setDurationMs(int) +MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setMsg(String): + android.net.metrics.DhcpClientEvent does not declare a `getMsg()` method matching method android.net.metrics.DhcpClientEvent.Builder.setMsg(String) +MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setDurationMs(long): + android.net.metrics.ValidationProbeEvent does not declare a `getDurationMs()` method matching method android.net.metrics.ValidationProbeEvent.Builder.setDurationMs(long) +MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setProbeType(int, boolean): + android.net.metrics.ValidationProbeEvent does not declare a `getProbeType()` method matching method android.net.metrics.ValidationProbeEvent.Builder.setProbeType(int,boolean) +MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setReturnCode(int): + android.net.metrics.ValidationProbeEvent does not declare a `getReturnCode()` method matching method android.net.metrics.ValidationProbeEvent.Builder.setReturnCode(int) +MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUniqueIdIncluded(boolean): + android.security.keystore.KeyGenParameterSpec does not declare a `isUniqueIdIncluded()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUniqueIdIncluded(boolean) +MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation): + android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation) +MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setClientState(android.os.Bundle): + android.service.autofill.augmented.FillResponse does not declare a `getClientState()` method matching method android.service.autofill.augmented.FillResponse.Builder.setClientState(android.os.Bundle) +MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setFillWindow(android.service.autofill.augmented.FillWindow): + android.service.autofill.augmented.FillResponse does not declare a `getFillWindow()` method matching method android.service.autofill.augmented.FillResponse.Builder.setFillWindow(android.service.autofill.augmented.FillWindow) +MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setInlineSuggestions(java.util.List<android.service.autofill.Dataset>): + android.service.autofill.augmented.FillResponse does not declare a `getInlineSuggestions()` method matching method android.service.autofill.augmented.FillResponse.Builder.setInlineSuggestions(java.util.List<android.service.autofill.Dataset>) +MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean): + android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean) +MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setIsAdhocConferenceCall(boolean): + android.telecom.ConnectionRequest does not declare a `isIsAdhocConferenceCall()` method matching method android.telecom.ConnectionRequest.Builder.setIsAdhocConferenceCall(boolean) +MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeFromInCall(android.os.ParcelFileDescriptor): + android.telecom.ConnectionRequest does not declare a `getRttPipeFromInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeFromInCall(android.os.ParcelFileDescriptor) +MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeToInCall(android.os.ParcelFileDescriptor): + android.telecom.ConnectionRequest does not declare a `getRttPipeToInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeToInCall(android.os.ParcelFileDescriptor) +MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setShouldShowIncomingCallUi(boolean): + android.telecom.ConnectionRequest does not declare a `shouldShowIncomingCallUi()` method matching method android.telecom.ConnectionRequest.Builder.setShouldShowIncomingCallUi(boolean) +MissingGetterMatchingBuilder: android.telecom.PhoneAccount.Builder#setGroupId(String): + android.telecom.PhoneAccount does not declare a `getGroupId()` method matching method android.telecom.PhoneAccount.Builder.setGroupId(String) +MissingGetterMatchingBuilder: android.telephony.NetworkRegistrationInfo.Builder#setEmergencyOnly(boolean): + android.telephony.NetworkRegistrationInfo does not declare a `isEmergencyOnly()` method matching method android.telephony.NetworkRegistrationInfo.Builder.setEmergencyOnly(boolean) +MissingGetterMatchingBuilder: android.telephony.ims.ImsSsData.Builder#setCallForwardingInfo(java.util.List<android.telephony.ims.ImsCallForwardInfo>): + android.telephony.ims.ImsSsData does not declare a `getCallForwardingInfo()` method matching method android.telephony.ims.ImsSsData.Builder.setCallForwardingInfo(java.util.List<android.telephony.ims.ImsCallForwardInfo>) +MissingGetterMatchingBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int): + android.telephony.ims.stub.ImsFeatureConfiguration does not declare a `getFeatures()` method matching method android.telephony.ims.stub.ImsFeatureConfiguration.Builder.addFeature(int,int) +MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String): + android.telephony.mbms.DownloadRequest does not declare a `getServiceId()` method matching method android.telephony.mbms.DownloadRequest.Builder.setServiceId(String) + + MissingNullability: android.app.Activity#onMovedToDisplay(int, android.content.res.Configuration) parameter #1: MissingNullability: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int) parameter #0: @@ -2294,11 +2482,11 @@ NoClone: android.service.autofill.augmented.AugmentedAutofillService#dump(java.i NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0: NoClone: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0: - + NoSettingsProvider: android.provider.Settings.Global#APP_OPS_CONSTANTS: - New setting keys are not allowed (Field: APP_OPS_CONSTANTS); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Global#AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES: NoSettingsProvider: android.provider.Settings.Global#AUTOMATIC_POWER_SAVE_MODE: @@ -2312,7 +2500,7 @@ NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABL NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS: NoSettingsProvider: android.provider.Settings.Global#HIDE_ERROR_DIALOGS: - New setting keys are not allowed (Field: HIDE_ERROR_DIALOGS); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Global#LOCATION_GLOBAL_KILL_SWITCH: NoSettingsProvider: android.provider.Settings.Global#LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST: @@ -2356,21 +2544,21 @@ NoSettingsProvider: android.provider.Settings.Secure#DOZE_ALWAYS_ON: NoSettingsProvider: android.provider.Settings.Secure#ENABLED_VR_LISTENERS: NoSettingsProvider: android.provider.Settings.Secure#IMMERSIVE_MODE_CONFIRMATIONS: - New setting keys are not allowed (Field: IMMERSIVE_MODE_CONFIRMATIONS); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_DELAY_MILLIS: NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_INTERVAL_MILLIS: NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS: - New setting keys are not allowed (Field: LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_SHOW_NOTIFICATIONS: - New setting keys are not allowed (Field: LOCK_SCREEN_SHOW_NOTIFICATIONS); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT: - New setting keys are not allowed (Field: NFC_PAYMENT_DEFAULT_COMPONENT); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Secure#NOTIFICATION_BADGING: NoSettingsProvider: android.provider.Settings.Secure#POWER_MENU_LOCKED_SHOW_CONTENT: - New setting keys are not allowed (Field: POWER_MENU_LOCKED_SHOW_CONTENT); use getters/setters in relevant manager class + NoSettingsProvider: android.provider.Settings.Secure#SYNC_PARENT_SOUNDS: NoSettingsProvider: android.provider.Settings.Secure#USER_SETUP_COMPLETE: @@ -2383,6 +2571,8 @@ NotCloseable: android.app.ActivityView: NotCloseable: android.app.prediction.AppPredictor: +NotCloseable: android.net.EthernetManager.TetheredInterfaceRequest: + Classes that release resources (release()) should implement AutoClosable and CloseGuard: class android.net.EthernetManager.TetheredInterfaceRequest NotCloseable: android.os.HwParcel: NotCloseable: android.telephony.ims.stub.ImsUtImplBase: @@ -2399,6 +2589,8 @@ OnNameExpected: android.service.notification.NotificationAssistantService#attach OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported(): +OnNameExpected: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback): + If implemented by developer, should follow the on<Something> style; otherwise consider marking final OnNameExpected: android.telephony.ims.ImsService#createMmTelFeature(int): OnNameExpected: android.telephony.ims.ImsService#createRcsFeature(int): @@ -2427,6 +2619,14 @@ OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#updateGro +OptionalBuilderConstructorArgument: android.app.prediction.AppTargetEvent.Builder#Builder(android.app.prediction.AppTarget, int) parameter #0: + Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter target in android.app.prediction.AppTargetEvent.Builder(android.app.prediction.AppTarget target, int actionType) +OptionalBuilderConstructorArgument: android.net.CaptivePortalData.Builder#Builder(android.net.CaptivePortalData) parameter #0: + Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter data in android.net.CaptivePortalData.Builder(android.net.CaptivePortalData data) +OptionalBuilderConstructorArgument: android.os.VibrationAttributes.Builder#Builder(android.media.AudioAttributes, android.os.VibrationEffect) parameter #1: + Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter effect in android.os.VibrationAttributes.Builder(android.media.AudioAttributes audio, android.os.VibrationEffect effect) + + PackageLayering: android.util.FeatureFlagUtils: @@ -2614,7 +2814,7 @@ SamShouldBeLast: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, SamShouldBeLast: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]): SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper): - SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener): SamShouldBeLast: android.os.BugreportManager#startBugreport(android.os.ParcelFileDescriptor, android.os.ParcelFileDescriptor, android.os.BugreportParams, java.util.concurrent.Executor, android.os.BugreportManager.BugreportCallback): @@ -2623,6 +2823,8 @@ SamShouldBeLast: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathReci SamShouldBeLast: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String): +SamShouldBeLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler): + SAM-compatible parameters (such as parameter 3, "callback", in android.permission.PermissionControllerManager.countPermissionApps) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions SamShouldBeLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler): SamShouldBeLast: android.permission.PermissionControllerManager#revokeRuntimePermissions(java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, java.util.concurrent.Executor, android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback): @@ -2667,6 +2869,24 @@ SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyS +StaticFinalBuilder: android.content.integrity.RuleSet.Builder: + Builder must be final: android.content.integrity.RuleSet.Builder +StaticFinalBuilder: android.hardware.display.BrightnessConfiguration.Builder: + Builder must be final: android.hardware.display.BrightnessConfiguration.Builder +StaticFinalBuilder: android.media.audiopolicy.AudioMix.Builder: + Builder must be final: android.media.audiopolicy.AudioMix.Builder +StaticFinalBuilder: android.media.audiopolicy.AudioMixingRule.Builder: + Builder must be final: android.media.audiopolicy.AudioMixingRule.Builder +StaticFinalBuilder: android.media.audiopolicy.AudioPolicy.Builder: + Builder must be final: android.media.audiopolicy.AudioPolicy.Builder +StaticFinalBuilder: android.net.CaptivePortalData.Builder: + Builder must be final: android.net.CaptivePortalData.Builder +StaticFinalBuilder: android.net.TetheringManager.TetheringRequest.Builder: + Builder must be final: android.net.TetheringManager.TetheringRequest.Builder +StaticFinalBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder: + Builder must be final: android.telephony.ims.stub.ImsFeatureConfiguration.Builder + + StaticUtils: android.os.health.HealthKeys: StaticUtils: android.service.autofill.InternalTransformation: @@ -2691,12 +2911,24 @@ StreamFiles: android.provider.MediaStore#scanVolume(android.content.Context, jav +UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, java.util.Locale) parameter #1: + Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale` +UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale) parameter #2: + Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale` +UseIcu: android.hardware.soundtrigger.KeyphraseMetadata#supportsLocale(java.util.Locale) parameter #0: + Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale` +UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#Keyphrase(int, int, java.util.Locale, String, int[]) parameter #2: + Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale` +UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#getLocale(): + Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale` + + UseParcelFileDescriptor: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0: UserHandle: android.app.ActivityManager#switchUser(android.os.UserHandle): - When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added + UserHandle: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle): UserHandle: android.app.role.RoleManager#addOnRoleHoldersChangedListenerAsUser(java.util.concurrent.Executor, android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle): @@ -2712,11 +2944,13 @@ UserHandle: android.app.role.RoleManager#removeOnRoleHoldersChangedListenerAsUse UserHandle: android.app.role.RoleManager#removeRoleHolderAsUser(String, String, int, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>): UserHandle: android.app.usage.StorageStatsManager#queryCratesForPackage(java.util.UUID, String, android.os.UserHandle): - When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added + UserHandle: android.app.usage.StorageStatsManager#queryCratesForUser(java.util.UUID, android.os.UserHandle): - When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added + UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociated(String, android.net.MacAddress, android.os.UserHandle): +UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociatedForWifiConnection(String, android.net.MacAddress, android.os.UserHandle): + When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added UserHandle: android.content.pm.PackageManager#getInstallReason(String, android.os.UserHandle): UserHandle: android.content.pm.PackageManager#getPermissionFlags(String, String, android.os.UserHandle): @@ -2725,6 +2959,8 @@ UserHandle: android.content.pm.PackageManager#grantRuntimePermission(String, Str UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle): +UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle, String): + When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added UserHandle: android.content.pm.PackageManager#updatePermissionFlags(String, String, int, int, android.os.UserHandle): UserHandle: android.location.LocationManager#setLocationEnabledForUser(boolean, android.os.UserHandle): @@ -2735,6 +2971,8 @@ UserHandle: android.permission.PermissionControllerManager#getRuntimePermissionB UserHandle: android.permission.PermissionControllerManager#stageAndApplyRuntimePermissionsBackup(byte[], android.os.UserHandle): +UserHandle: android.telecom.TelecomManager#getDefaultDialerPackage(android.os.UserHandle): + When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added UserHandleName: android.app.ActivityView#startActivity(android.content.Intent, android.os.UserHandle): diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 30826e036c40..09aaf5bc3d97 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -18839,7 +18839,6 @@ HSPLandroid/telephony/PreciseDataConnectionState;-><init>(Landroid/os/Parcel;)V HSPLandroid/telephony/PreciseDataConnectionState;-><init>(Landroid/os/Parcel;Landroid/telephony/PreciseDataConnectionState$1;)V HPLandroid/telephony/PreciseDataConnectionState;->equals(Ljava/lang/Object;)Z HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionApn()Ljava/lang/String; -HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionLinkProperties()Landroid/net/LinkProperties; HPLandroid/telephony/PreciseDataConnectionState;->getNetworkType()I HPLandroid/telephony/PreciseDataConnectionState;->getState()I HSPLandroid/telephony/PreciseDataConnectionState;->toString()Ljava/lang/String; diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index c58b5d218e74..6d22eb93fd02 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -688,6 +688,31 @@ public final class BluetoothGatt implements BluetoothProfile { } }); } + + /** + * Callback invoked when service changed event is received + * @hide + */ + @Override + public void onServiceChanged(String address) { + if (DBG) { + Log.d(TAG, "onServiceChanged() - Device=" + address); + } + + if (!address.equals(mDevice.getAddress())) { + return; + } + + runOrQueueCallback(new Runnable() { + @Override + public void run() { + final BluetoothGattCallback callback = mCallback; + if (callback != null) { + callback.onServiceChanged(BluetoothGatt.this); + } + } + }); + } }; /*package*/ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device, diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java index f718c0b57c1b..1c40cff076f6 100644 --- a/core/java/android/bluetooth/BluetoothGattCallback.java +++ b/core/java/android/bluetooth/BluetoothGattCallback.java @@ -16,6 +16,8 @@ package android.bluetooth; +import android.annotation.NonNull; + /** * This abstract class is used to implement {@link BluetoothGatt} callbacks. */ @@ -194,4 +196,16 @@ public abstract class BluetoothGattCallback { public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout, int status) { } + + /** + * Callback indicating service changed event is received + * + * <p>Receiving this event means that the GATT database is out of sync with + * the remote device. {@link BluetoothGatt#discoverServices} should be + * called to re-discover the services. + * + * @param gatt GATT client involved + */ + public void onServiceChanged(@NonNull BluetoothGatt gatt) { + } } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index f257326904fd..2138f53e9f54 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -785,4 +785,6 @@ interface IPackageManager { List<String> getMimeGroup(String packageName, String group); boolean isAutoRevokeWhitelisted(String packageName); + + void grantImplicitAccess(int queryingUid, String visibleAuthority); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 46af6303d04d..0789cfb2af56 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -8018,6 +8018,20 @@ public abstract class PackageManager { "getMimeGroup not implemented in subclass"); } + /** + * Grants implicit visibility of the package that provides an authority to a querying UID. + * + * @throws SecurityException when called by a package other than the contacts provider + * @hide + */ + public void grantImplicitAccess(int queryingUid, String visibleAuthority) { + try { + ActivityThread.getPackageManager().grantImplicitAccess(queryingUid, visibleAuthority); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + // Some of the flags don't affect the query result, but let's be conservative and cache // each combination of flags separately. diff --git a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java index 27f8a61b8999..7b6a457411f3 100644 --- a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java +++ b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java @@ -37,12 +37,16 @@ public class FrameNumberTracker { /** the completed frame number for each type of capture results */ private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT]; - /** the skipped frame numbers that don't belong to each type of capture results */ - private final LinkedList<Long>[] mSkippedOtherFrameNumbers = + /** the frame numbers that don't belong to each type of capture results and are yet to be seen + * through an updateTracker() call. Each list holds a list of frame numbers that should appear + * with request types other than that, to which the list corresponds. + */ + private final LinkedList<Long>[] mPendingFrameNumbersWithOtherType = new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT]; - /** the skipped frame numbers that belong to each type of capture results */ - private final LinkedList<Long>[] mSkippedFrameNumbers = + /** the frame numbers that belong to each type of capture results which should appear, but + * haven't yet.*/ + private final LinkedList<Long>[] mPendingFrameNumbers = new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT]; /** frame number -> request type */ @@ -53,8 +57,8 @@ public class FrameNumberTracker { public FrameNumberTracker() { for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) { mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED; - mSkippedOtherFrameNumbers[i] = new LinkedList<Long>(); - mSkippedFrameNumbers[i] = new LinkedList<Long>(); + mPendingFrameNumbersWithOtherType[i] = new LinkedList<Long>(); + mPendingFrameNumbers[i] = new LinkedList<Long>(); } } @@ -66,29 +70,29 @@ public class FrameNumberTracker { int requestType = (int) pair.getValue(); Boolean removeError = false; if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) { - mCompletedFrameNumber[requestType] = errorFrameNumber; removeError = true; + } + // The error frame number could have also either been in the pending list or one of the + // 'other' pending lists. + if (!mPendingFrameNumbers[requestType].isEmpty()) { + if (errorFrameNumber == mPendingFrameNumbers[requestType].element()) { + mPendingFrameNumbers[requestType].remove(); + removeError = true; + } } else { - if (!mSkippedFrameNumbers[requestType].isEmpty()) { - if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) { - mCompletedFrameNumber[requestType] = errorFrameNumber; - mSkippedFrameNumbers[requestType].remove(); + for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) { + int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT; + if (!mPendingFrameNumbersWithOtherType[otherType].isEmpty() && errorFrameNumber + == mPendingFrameNumbersWithOtherType[otherType].element()) { + mPendingFrameNumbersWithOtherType[otherType].remove(); removeError = true; - } - } else { - for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) { - int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT; - if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber - == mSkippedOtherFrameNumbers[otherType].element()) { - mCompletedFrameNumber[requestType] = errorFrameNumber; - mSkippedOtherFrameNumbers[otherType].remove(); - removeError = true; - break; - } + break; } } } if (removeError) { + mCompletedFrameNumber[requestType] = errorFrameNumber; + mPartialResults.remove(errorFrameNumber); iter.remove(); } } @@ -182,7 +186,7 @@ public class FrameNumberTracker { * It validates that all previous frames of the same category have arrived. * * If there is a gap since previous frame number of the same category, assume the frames in - * the gap are other categories and store them in the skipped frame number queue to check + * the gap are other categories and store them in the pending frame number queue to check * against when frames of those categories arrive. */ private void updateCompletedFrameNumber(long frameNumber, @@ -199,25 +203,29 @@ public class FrameNumberTracker { if (frameNumber < maxOtherFrameNumberSeen) { // if frame number is smaller than completed frame numbers of other categories, // it must be: - // - the head of mSkippedFrameNumbers for this category, or - // - in one of other mSkippedOtherFrameNumbers - if (!mSkippedFrameNumbers[requestType].isEmpty()) { - // frame number must be head of current type of mSkippedFrameNumbers if - // mSkippedFrameNumbers isn't empty. - if (frameNumber < mSkippedFrameNumbers[requestType].element()) { + // - the head of mPendingFrameNumbers for this category, or + // - in one of other mPendingFrameNumbersWithOtherType + if (!mPendingFrameNumbers[requestType].isEmpty()) { + // frame number must be head of current type of mPendingFrameNumbers if + // mPendingFrameNumbers isn't empty. + Long pendingFrameNumberSameType = mPendingFrameNumbers[requestType].element(); + if (frameNumber == pendingFrameNumberSameType) { + // frame number matches the head of the pending frame number queue. + // Do this before the inequality checks since this is likely to be the common + // case. + mPendingFrameNumbers[requestType].remove(); + } else if (frameNumber < pendingFrameNumberSameType) { throw new IllegalArgumentException("frame number " + frameNumber + " is a repeat"); - } else if (frameNumber > mSkippedFrameNumbers[requestType].element()) { + } else { throw new IllegalArgumentException("frame number " + frameNumber + " comes out of order. Expecting " - + mSkippedFrameNumbers[requestType].element()); + + pendingFrameNumberSameType); } - // frame number matches the head of the skipped frame number queue. - mSkippedFrameNumbers[requestType].remove(); } else { - // frame number must be in one of the other mSkippedOtherFrameNumbers. - int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber); - int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber); + // frame number must be in one of the other mPendingFrameNumbersWithOtherType. + int index1 = mPendingFrameNumbersWithOtherType[otherType1].indexOf(frameNumber); + int index2 = mPendingFrameNumbersWithOtherType[otherType2].indexOf(frameNumber); boolean inSkippedOther1 = index1 != -1; boolean inSkippedOther2 = index2 != -1; if (!(inSkippedOther1 ^ inSkippedOther2)) { @@ -225,33 +233,39 @@ public class FrameNumberTracker { + " is a repeat or invalid"); } - // We know the category of frame numbers in skippedOtherFrameNumbers leading up - // to the current frame number. Move them into the correct skippedFrameNumbers. + // We know the category of frame numbers in pendingFrameNumbersWithOtherType leading + // up to the current frame number. The destination is the type which isn't the + // requestType* and isn't the src. Move them into the correct pendingFrameNumbers. + // * : This is since frameNumber is the first frame of requestType that we've + // received in the 'others' list, since for each request type frames come in order. + // All the frames before frameNumber are of the same type. They're not of + // 'requestType', neither of the type of the 'others' list they were found in. The + // remaining option is the 3rd type. LinkedList<Long> srcList, dstList; int index; if (inSkippedOther1) { - srcList = mSkippedOtherFrameNumbers[otherType1]; - dstList = mSkippedFrameNumbers[otherType2]; + srcList = mPendingFrameNumbersWithOtherType[otherType1]; + dstList = mPendingFrameNumbers[otherType2]; index = index1; } else { - srcList = mSkippedOtherFrameNumbers[otherType2]; - dstList = mSkippedFrameNumbers[otherType1]; + srcList = mPendingFrameNumbersWithOtherType[otherType2]; + dstList = mPendingFrameNumbers[otherType1]; index = index2; } for (int i = 0; i < index; i++) { dstList.add(srcList.removeFirst()); } - // Remove current frame number from skippedOtherFrameNumbers + // Remove current frame number from pendingFrameNumbersWithOtherType srcList.remove(); } } else { // there is a gap of unseen frame numbers which should belong to the other - // 2 categories. Put all the skipped frame numbers in the queue. + // 2 categories. Put all the pending frame numbers in the queue. for (long i = Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1; i < frameNumber; i++) { - mSkippedOtherFrameNumbers[requestType].add(i); + mPendingFrameNumbersWithOtherType[requestType].add(i); } } diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index e2486aff9d7c..81213294361b 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -141,8 +141,8 @@ public class Build { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java index 21fd819f3d94..ab5637cbb878 100644 --- a/core/java/android/os/FileBridge.java +++ b/core/java/android/os/FileBridge.java @@ -16,7 +16,6 @@ package android.os; -import static android.system.OsConstants.AF_UNIX; import static android.system.OsConstants.SOCK_STREAM; import android.system.ErrnoException; @@ -58,17 +57,19 @@ public class FileBridge extends Thread { /** CMD_CLOSE */ private static final int CMD_CLOSE = 3; - private FileDescriptor mTarget; + private ParcelFileDescriptor mTarget; - private final FileDescriptor mServer = new FileDescriptor(); - private final FileDescriptor mClient = new FileDescriptor(); + private ParcelFileDescriptor mServer; + private ParcelFileDescriptor mClient; private volatile boolean mClosed; public FileBridge() { try { - Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mServer, mClient); - } catch (ErrnoException e) { + ParcelFileDescriptor[] fds = ParcelFileDescriptor.createSocketPair(SOCK_STREAM); + mServer = fds[0]; + mClient = fds[1]; + } catch (IOException e) { throw new RuntimeException("Failed to create bridge"); } } @@ -80,15 +81,14 @@ public class FileBridge extends Thread { public void forceClose() { IoUtils.closeQuietly(mTarget); IoUtils.closeQuietly(mServer); - IoUtils.closeQuietly(mClient); mClosed = true; } - public void setTargetFile(FileDescriptor target) { + public void setTargetFile(ParcelFileDescriptor target) { mTarget = target; } - public FileDescriptor getClientSocket() { + public ParcelFileDescriptor getClientSocket() { return mClient; } @@ -96,32 +96,33 @@ public class FileBridge extends Thread { public void run() { final byte[] temp = new byte[8192]; try { - while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) { + while (IoBridge.read(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH) == MSG_LENGTH) { final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN); if (cmd == CMD_WRITE) { // Shuttle data into local file int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN); while (len > 0) { - int n = IoBridge.read(mServer, temp, 0, Math.min(temp.length, len)); + int n = IoBridge.read(mServer.getFileDescriptor(), temp, 0, + Math.min(temp.length, len)); if (n == -1) { throw new IOException( "Unexpected EOF; still expected " + len + " bytes"); } - IoBridge.write(mTarget, temp, 0, n); + IoBridge.write(mTarget.getFileDescriptor(), temp, 0, n); len -= n; } } else if (cmd == CMD_FSYNC) { // Sync and echo back to confirm - Os.fsync(mTarget); - IoBridge.write(mServer, temp, 0, MSG_LENGTH); + Os.fsync(mTarget.getFileDescriptor()); + IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH); } else if (cmd == CMD_CLOSE) { // Close and echo back to confirm - Os.fsync(mTarget); - Os.close(mTarget); + Os.fsync(mTarget.getFileDescriptor()); + mTarget.close(); mClosed = true; - IoBridge.write(mServer, temp, 0, MSG_LENGTH); + IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH); break; } } @@ -143,17 +144,11 @@ public class FileBridge extends Thread { mClient = clientPfd.getFileDescriptor(); } - public FileBridgeOutputStream(FileDescriptor client) { - mClientPfd = null; - mClient = client; - } - @Override public void close() throws IOException { try { writeCommandAndBlock(CMD_CLOSE, "close()"); } finally { - IoBridge.closeAndSignalBlockedThreads(mClient); IoUtils.closeQuietly(mClientPfd); } } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 7b82b1a2e0d4..fe70a8803eb4 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -642,11 +642,11 @@ public final class Parcel { * {@link #dataPosition}. This is used to validate that the marshalled * transaction is intended for the target interface. */ - public final void writeInterfaceToken(String interfaceName) { + public final void writeInterfaceToken(@NonNull String interfaceName) { nativeWriteInterfaceToken(mNativePtr, interfaceName); } - public final void enforceInterface(String interfaceName) { + public final void enforceInterface(@NonNull String interfaceName) { nativeEnforceInterface(mNativePtr, interfaceName); } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 52dd86554e91..2aa5c13e6e9f 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -851,12 +851,11 @@ public class Process { /** * Set the priority of a thread, based on Linux priorities. - * - * @param tid The identifier of the thread/process to change. It should be - * the native thread id but not the managed id of {@link java.lang.Thread}. + * + * @param tid The identifier of the thread/process to change. * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java index b654707a683b..35e7bad83736 100644 --- a/core/java/android/os/ServiceManager.java +++ b/core/java/android/os/ServiceManager.java @@ -235,6 +235,21 @@ public final class ServiceManager { } /** + * Returns the list of declared instances for an interface. + * + * @return true if the service is declared somewhere (eg. VINTF manifest) and + * waitForService should always be able to return the service. + */ + public static String[] getDeclaredInstances(@NonNull String iface) { + try { + return getIServiceManager().getDeclaredInstances(iface); + } catch (RemoteException e) { + Log.e(TAG, "error in getDeclaredInstances", e); + return null; + } + } + + /** * Returns the specified service from the service manager. * * If the service is not running, servicemanager will attempt to start it, and this function diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java index 91b56fbbc38e..b70b6b5d209e 100644 --- a/core/java/android/os/ServiceManagerNative.java +++ b/core/java/android/os/ServiceManagerNative.java @@ -90,6 +90,10 @@ class ServiceManagerProxy implements IServiceManager { return mServiceManager.isDeclared(name); } + public String[] getDeclaredInstances(String iface) throws RemoteException { + return mServiceManager.getDeclaredInstances(iface); + } + public void registerClientCallback(String name, IBinder service, IClientCallback cb) throws RemoteException { throw new RemoteException(); diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 2dbce7b0fc7b..3673ae7f7a37 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -26,10 +26,8 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; -import android.telephony.Annotation.ApnType; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.PreciseCallStates; @@ -37,7 +35,6 @@ import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; -import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.util.Log; @@ -413,17 +410,16 @@ public class TelephonyRegistryManager { * @param subId for which data connection state changed. * @param slotIndex for which data connections state changed. Can be derived from subId except * when subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState the PreciseDataConnectionState * - * @see android.telephony.PreciseDataConnection + * @see PreciseDataConnectionState * @see TelephonyManager#DATA_DISCONNECTED */ public void notifyDataConnectionForSubscriber(int slotIndex, int subId, - @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState) { + @NonNull PreciseDataConnectionState preciseState) { try { sRegistry.notifyDataConnectionForSubscriber( - slotIndex, subId, apnType, preciseState); + slotIndex, subId, preciseState); } catch (RemoteException ex) { // system process is dead } @@ -623,25 +619,6 @@ public class TelephonyRegistryManager { } /** - * Notify precise data connection failed cause on certain subscription. - * - * @param subId for which data connection failed. - * @param slotIndex for which data conenction failed. Can be derived from subId except when - * subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. - * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. - * @param failCause data fail cause. - */ - public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType, - @Nullable String apn, @DataFailureCause int failCause) { - try { - sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call * on certain subscription. * diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl index 6ece045ffcf7..6ece045ffcf7 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 095882ebe669..60f1b4438f54 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -36,7 +36,6 @@ import com.android.internal.logging.AndroidConfig; import com.android.server.NetworkManagementSocketTagger; import dalvik.system.RuntimeHooks; -import dalvik.system.ThreadPrioritySetter; import dalvik.system.VMRuntime; import libcore.content.type.MimeMap; @@ -208,7 +207,6 @@ public class RuntimeInit { */ public static void preForkInit() { if (DEBUG) Slog.d(TAG, "Entered preForkInit."); - RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter()); RuntimeInit.enableDdms(); // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e. // MimeMap.setDefault(DefaultMimeMapFactory.create()); @@ -221,35 +219,6 @@ public class RuntimeInit { MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create); } - private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter { - // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc - private static final int[] NICE_VALUES = { - Process.THREAD_PRIORITY_LOWEST, // 1 (MIN_PRIORITY) - Process.THREAD_PRIORITY_BACKGROUND + 6, - Process.THREAD_PRIORITY_BACKGROUND + 3, - Process.THREAD_PRIORITY_BACKGROUND, - Process.THREAD_PRIORITY_DEFAULT, // 5 (NORM_PRIORITY) - Process.THREAD_PRIORITY_DEFAULT - 2, - Process.THREAD_PRIORITY_DEFAULT - 4, - Process.THREAD_PRIORITY_URGENT_DISPLAY + 3, - Process.THREAD_PRIORITY_URGENT_DISPLAY + 2, - Process.THREAD_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY) - }; - - @Override - public void setPriority(int nativeTid, int priority) { - // Check NICE_VALUES[] length first. - if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) { - throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length); - } - // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10). - if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { - throw new IllegalArgumentException("Priority out of range: " + priority); - } - Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]); - } - } - @UnsupportedAppUsage protected static final void commonInit() { if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5a04992a35b4..ea09fc8cd34a 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -65,9 +65,7 @@ interface ITelephonyRegistry { void notifyDataActivity(int state); void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnectionForSubscriber( - int phoneId, int subId, int apnType, in PreciseDataConnectionState preciseState); - @UnsupportedAppUsage - void notifyDataConnectionFailed(String apnType); + int phoneId, int subId, in PreciseDataConnectionState preciseState); // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. void notifyCellLocation(in CellIdentity cellLocation); void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @@ -77,8 +75,6 @@ interface ITelephonyRegistry { int foregroundCallState, int backgroundCallState); void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(int phoneId, int subId, int apnType, String apn, - int failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); void notifySrvccStateChanged(in int subId, in int lteState); void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, diff --git a/core/jni/Android.bp b/core/jni/Android.bp index f0f1b74c37b3..1968146099ae 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -315,4 +315,9 @@ cc_library_shared { cflags: ["-DANDROID_EXPERIMENTAL_MTE"], }, }, + + // Workaround Clang LTO crash. + lto: { + never: true, + }, } diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index eeda275b811c..ad8aeb20ab3e 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -90,6 +90,12 @@ static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className, return res; } +static inline jobject jniGetReferent(JNIEnv* env, jobject ref) { + jclass cls = FindClassOrDie(env, "java/lang/ref/Reference"); + jmethodID get = GetMethodIDOrDie(env, cls, "get", "()Ljava/lang/Object;"); + return env->CallObjectMethod(ref, get); +} + /** * Read the specified field from jobject, and convert to std::string. * If the field cannot be obtained, return defaultValue. diff --git a/core/proto/OWNERS b/core/proto/OWNERS index 4892faaceafe..542d26fa233e 100644 --- a/core/proto/OWNERS +++ b/core/proto/OWNERS @@ -14,8 +14,12 @@ per-file settings_enums.proto=tmfang@google.com # Frameworks ogunwale@google.com jjaggi@google.com +roosa@google.com per-file usagestatsservice.proto, usagestatsservice_v2.proto = mwachens@google.com +# Biometrics +kchyn@google.com + # Launcher hyunyoungs@google.com diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 8656820c4ea2..80f73f043068 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2682,6 +2682,14 @@ <permission android:name="android.permission.SUGGEST_MANUAL_TIME_AND_ZONE" android:protectionLevel="signature" /> + <!-- Allows applications like settings to manage configuration associated with automatic time + and time zone detection. + <p>Not for use by third-party applications. + @hide + --> + <permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" + android:protectionLevel="signature|privileged" /> + <!-- ==================================================== --> <!-- Permissions related to changing status bar --> <!-- ==================================================== --> diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java index d4f6b1fcec4e..708bfa6ece2e 100644 --- a/core/tests/coretests/src/android/os/FileBridgeTest.java +++ b/core/tests/coretests/src/android/os/FileBridgeTest.java @@ -16,6 +16,9 @@ package android.os; +import static android.os.ParcelFileDescriptor.MODE_CREATE; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; + import android.os.FileBridge.FileBridgeOutputStream; import android.test.AndroidTestCase; import android.test.MoreAsserts; @@ -25,7 +28,6 @@ import libcore.io.Streams; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Random; @@ -33,7 +35,7 @@ import java.util.Random; public class FileBridgeTest extends AndroidTestCase { private File file; - private FileOutputStream fileOs; + private ParcelFileDescriptor outputFile; private FileBridge bridge; private FileBridgeOutputStream client; @@ -44,17 +46,17 @@ public class FileBridgeTest extends AndroidTestCase { file = getContext().getFileStreamPath("meow.dat"); file.delete(); - fileOs = new FileOutputStream(file); + outputFile = ParcelFileDescriptor.open(file, MODE_CREATE | MODE_READ_WRITE); bridge = new FileBridge(); - bridge.setTargetFile(fileOs.getFD()); + bridge.setTargetFile(outputFile); bridge.start(); client = new FileBridgeOutputStream(bridge.getClientSocket()); } @Override protected void tearDown() throws Exception { - fileOs.close(); + outputFile.close(); file.delete(); } diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 672b428d1623..0a9e50eb92dd 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -427,6 +427,8 @@ applications that come with the platform <permission name="android.permission.CAPTURE_AUDIO_OUTPUT" /> <!-- Permissions required for CTS test - AdbManagerTest --> <permission name="android.permission.MANAGE_DEBUGGING" /> + <!-- Permissions required for CTS test - TimeManagerTest --> + <permission name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index a362bd220936..667a7517a24c 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -139,7 +139,7 @@ void CanvasContext::destroy() { mAnimationContext->destroy(); } -static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) { +static void setBufferCount(ANativeWindow* window) { int query_value; int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value); if (err != 0 || query_value < 0) { @@ -148,7 +148,9 @@ static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) { } auto min_undequeued_buffers = static_cast<uint32_t>(query_value); - int bufferCount = min_undequeued_buffers + 2 + extraBuffers; + // We only need to set min_undequeued + 2 because the renderahead amount was already factored into the + // query for min_undequeued + int bufferCount = min_undequeued_buffers + 2; native_window_set_buffer_count(window, bufferCount); } @@ -179,7 +181,8 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior); if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) { - setBufferCount(mNativeSurface->getNativeWindow(), mRenderAheadCapacity); + setBufferCount(mNativeSurface->getNativeWindow()); + } mFrameNumber = -1; diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index d35bc4176cb3..d02b49697821 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -372,7 +372,7 @@ public class Ringtone { AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) { startLocalPlayer(); } - } else if (mAllowRemote && (mRemotePlayer != null)) { + } else if (mAllowRemote && (mRemotePlayer != null) && (mUri != null)) { final Uri canonicalUri = mUri.getCanonicalUri(); final boolean looping; final float volume; diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 8deb0c4451ea..9deeb8fbab16 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -34,6 +34,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.AssetFileDescriptor; import android.database.Cursor; +import android.database.StaleDataException; import android.net.Uri; import android.os.Environment; import android.os.FileUtils; @@ -492,7 +493,12 @@ public class RingtoneManager { public Uri getRingtoneUri(int position) { // use cursor directly instead of requerying it, which could easily // cause position to shuffle. - if (mCursor == null || !mCursor.moveToPosition(position)) { + try { + if (mCursor == null || !mCursor.moveToPosition(position)) { + return null; + } + } catch (StaleDataException | IllegalStateException e) { + Log.e(TAG, "Unexpected Exception has been catched.", e); return null; } @@ -1130,11 +1136,13 @@ public class RingtoneManager { // Try finding the scanned ringtone final String filename = getDefaultRingtoneFilename(type); + final String whichAudio = getQueryStringForType(type); + final String where = MediaColumns.DISPLAY_NAME + "=? AND " + whichAudio + "=?"; final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI; try (Cursor cursor = context.getContentResolver().query(baseUri, new String[] { MediaColumns._ID }, - MediaColumns.DISPLAY_NAME + "=?", - new String[] { filename }, null)) { + where, + new String[] { filename, "1" }, null)) { if (cursor.moveToFirst()) { final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse( ContentUris.withAppendedId(baseUri, cursor.getLong(0))); @@ -1162,4 +1170,13 @@ public class RingtoneManager { default: throw new IllegalArgumentException(); } } + + private static String getQueryStringForType(int type) { + switch (type) { + case TYPE_RINGTONE: return MediaStore.Audio.AudioColumns.IS_RINGTONE; + case TYPE_NOTIFICATION: return MediaStore.Audio.AudioColumns.IS_NOTIFICATION; + case TYPE_ALARM: return MediaStore.Audio.AudioColumns.IS_ALARM; + default: throw new IllegalArgumentException(); + } + } } diff --git a/media/jni/Android.bp b/media/jni/Android.bp index d2294b38d992..d3466702ebf2 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -96,6 +96,11 @@ cc_library_shared { "-Wunused", "-Wunreachable-code", ], + + // Workaround Clang LTO crash. + lto: { + never: true, + }, } cc_library_shared { diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp index 5ba5c0159275..40e4c54c2921 100644 --- a/media/jni/audioeffect/Android.bp +++ b/media/jni/audioeffect/Android.bp @@ -28,4 +28,9 @@ cc_library_shared { "-Wunused", "-Wunreachable-code", ], + + // Workaround Clang LTO crash. + lto: { + never: true, + }, } diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 0aa060546513..8a36837d10d5 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -8771,6 +8771,7 @@ package android.bluetooth { method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int); method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int); method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int); + method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt); method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int); } @@ -35030,7 +35031,7 @@ package android.os { method public int dataCapacity(); method public int dataPosition(); method public int dataSize(); - method public void enforceInterface(String); + method public void enforceInterface(@NonNull String); method public boolean hasFileDescriptors(); method public byte[] marshall(); method @NonNull public static android.os.Parcel obtain(); @@ -35101,7 +35102,7 @@ package android.os { method public void writeFloatArray(@Nullable float[]); method public void writeInt(int); method public void writeIntArray(@Nullable int[]); - method public void writeInterfaceToken(String); + method public void writeInterfaceToken(@NonNull String); method public void writeList(@Nullable java.util.List); method public void writeLong(long); method public void writeLongArray(@Nullable long[]); @@ -45112,7 +45113,7 @@ package android.telephony { method public long getNci(); method @IntRange(from=0, to=3279165) public int getNrarfcn(); method @IntRange(from=0, to=1007) public int getPci(); - method @IntRange(from=0, to=65535) public int getTac(); + method @IntRange(from=0, to=16777215) public int getTac(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR; } @@ -45206,9 +45207,9 @@ package android.telephony { field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR; } - public abstract class CellLocation { - ctor public CellLocation(); - method public static android.telephony.CellLocation getEmpty(); + @Deprecated public abstract class CellLocation { + ctor @Deprecated public CellLocation(); + method @Deprecated public static android.telephony.CellLocation getEmpty(); method @Deprecated public static void requestLocationUpdate(); } @@ -45998,6 +45999,7 @@ package android.telephony { method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method public int getState(); + method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR; } @@ -46715,19 +46717,19 @@ package android.telephony { package android.telephony.cdma { - public class CdmaCellLocation extends android.telephony.CellLocation { - ctor public CdmaCellLocation(); - ctor public CdmaCellLocation(android.os.Bundle); - method public static double convertQuartSecToDecDegrees(int); - method public void fillInNotifierBundle(android.os.Bundle); - method public int getBaseStationId(); - method public int getBaseStationLatitude(); - method public int getBaseStationLongitude(); - method public int getNetworkId(); - method public int getSystemId(); - method public void setCellLocationData(int, int, int); - method public void setCellLocationData(int, int, int, int, int); - method public void setStateInvalid(); + @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation { + ctor @Deprecated public CdmaCellLocation(); + ctor @Deprecated public CdmaCellLocation(android.os.Bundle); + method @Deprecated public static double convertQuartSecToDecDegrees(int); + method @Deprecated public void fillInNotifierBundle(android.os.Bundle); + method @Deprecated public int getBaseStationId(); + method @Deprecated public int getBaseStationLatitude(); + method @Deprecated public int getBaseStationLongitude(); + method @Deprecated public int getNetworkId(); + method @Deprecated public int getSystemId(); + method @Deprecated public void setCellLocationData(int, int, int); + method @Deprecated public void setCellLocationData(int, int, int, int, int); + method @Deprecated public void setStateInvalid(); } } @@ -46927,15 +46929,15 @@ package android.telephony.euicc { package android.telephony.gsm { - public class GsmCellLocation extends android.telephony.CellLocation { - ctor public GsmCellLocation(); - ctor public GsmCellLocation(android.os.Bundle); - method public void fillInNotifierBundle(android.os.Bundle); - method public int getCid(); - method public int getLac(); - method public int getPsc(); - method public void setLacAndCid(int, int); - method public void setStateInvalid(); + @Deprecated public class GsmCellLocation extends android.telephony.CellLocation { + ctor @Deprecated public GsmCellLocation(); + ctor @Deprecated public GsmCellLocation(android.os.Bundle); + method @Deprecated public void fillInNotifierBundle(android.os.Bundle); + method @Deprecated public int getCid(); + method @Deprecated public int getLac(); + method @Deprecated public int getPsc(); + method @Deprecated public void setLacAndCid(int, int); + method @Deprecated public void setStateInvalid(); } @Deprecated public final class SmsManager { diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 6a6914a65a73..b67c22c27cb8 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -9720,6 +9720,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { @@ -10069,6 +10070,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -10282,6 +10284,7 @@ package android.telephony.data { method public int getCause(); method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses(); method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses(); + method public int getHandoverFailureMode(); method public int getId(); method @NonNull public String getInterfaceName(); method public int getLinkStatus(); @@ -10293,6 +10296,11 @@ package android.telephony.data { method public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; + field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 2; // 0x2 + field public static final int HANDOVER_FAILURE_MODE_LEGACY = 1; // 0x1 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 3; // 0x3 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 4; // 0x4 + field public static final int HANDOVER_FAILURE_MODE_UNKNOWN = 0; // 0x0 field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 field public static final int LINK_STATUS_DORMANT = 1; // 0x1 field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 @@ -10306,6 +10314,7 @@ package android.telephony.data { method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setHandoverFailureMode(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); diff --git a/non-updatable-api/system-removed.txt b/non-updatable-api/system-removed.txt index ab4c6d1a71a0..0c02c43b1084 100644 --- a/non-updatable-api/system-removed.txt +++ b/non-updatable-api/system-removed.txt @@ -165,11 +165,6 @@ package android.telecom { package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index f5f58efb72e6..a9279971ce1e 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -326,6 +326,9 @@ <!-- Permission needed for CTS test - DisplayTest --> <uses-permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS" /> + <!-- Permission needed for CTS test - TimeManagerTest --> + <uses-permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" /> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index f6c2ee264cb5..02815a571db8 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -503,14 +503,14 @@ public class BugreportProgressService extends Service { } if (msg.what != MSG_SERVICE_COMMAND) { - // Sanity check. + // Confidence check. Log.e(TAG, "Invalid message type: " + msg.what); return; } // At this point it's handling onStartCommand(), with the intent passed as an Extra. if (!(msg.obj instanceof Intent)) { - // Sanity check. + // Confidence check. Log.wtf(TAG, "handleMessage(): invalid msg.obj type: " + msg.obj); return; } diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java index b95092a9384c..b8cfa1e80043 100644 --- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java @@ -561,7 +561,7 @@ public class BugreportReceiverTest { // Clear properties mContext.getSharedPreferences(PREFS_BUGREPORT, Context.MODE_PRIVATE) .edit().clear().commit(); - // Sanity check... + // Confidence check... assertEquals("Did not reset properties", STATE_UNKNOWN, getWarningState(mContext, STATE_UNKNOWN)); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 18a7adda3f7d..cf83603997c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -284,6 +284,9 @@ public class MobileSignalController extends SignalController< mNetworkToIconLookup.put(toDisplayIconKey( TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE), TelephonyIcons.NR_5G_PLUS); + mNetworkToIconLookup.put(toIconKey( + TelephonyManager.NETWORK_TYPE_NR), + TelephonyIcons.NR_5G); } private String getIconKey() { @@ -306,9 +309,9 @@ public class MobileSignalController extends SignalController< case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO: return toIconKey(TelephonyManager.NETWORK_TYPE_LTE) + "_CA_Plus"; case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA: - return "5G"; + return toIconKey(TelephonyManager.NETWORK_TYPE_NR); case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE: - return "5G_Plus"; + return toIconKey(TelephonyManager.NETWORK_TYPE_NR) + "_Plus"; default: return "unsupported"; } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java index 33b9d00e70dc..da5f25b2a596 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java @@ -28,6 +28,7 @@ import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate; import android.hardware.tetheroffload.control.V1_0.NetworkProtocol; import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent; import android.net.netlink.NetlinkSocket; +import android.net.netlink.StructNfGenMsg; import android.net.netlink.StructNlMsgHdr; import android.net.util.SharedLog; import android.net.util.SocketUtils; @@ -41,11 +42,12 @@ import android.system.OsConstants; import com.android.internal.annotations.VisibleForTesting; import java.io.FileDescriptor; -import java.io.InterruptedIOException; import java.io.IOException; +import java.io.InterruptedIOException; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; import java.util.NoSuchElementException; @@ -66,11 +68,12 @@ public class OffloadHardwareInterface { private static final String NO_IPV4_ADDRESS = ""; private static final String NO_IPV4_GATEWAY = ""; // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h - private static final int NF_NETLINK_CONNTRACK_NEW = 1; - private static final int NF_NETLINK_CONNTRACK_UPDATE = 2; - private static final int NF_NETLINK_CONNTRACK_DESTROY = 4; + public static final int NF_NETLINK_CONNTRACK_NEW = 1; + public static final int NF_NETLINK_CONNTRACK_UPDATE = 2; + public static final int NF_NETLINK_CONNTRACK_DESTROY = 4; // Reference libnetfilter_conntrack/linux_nfnetlink_conntrack.h public static final short NFNL_SUBSYS_CTNETLINK = 1; + public static final short IPCTNL_MSG_CT_NEW = 0; public static final short IPCTNL_MSG_CT_GET = 1; private final long NETLINK_MESSAGE_TIMEOUT_MS = 500; @@ -237,7 +240,7 @@ public class OffloadHardwareInterface { NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY); if (h1 == null) return false; - sendNetlinkMessage(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET), + sendIpv4NfGenMsg(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET), (short) (NLM_F_REQUEST | NLM_F_DUMP)); final NativeHandle h2 = mDeps.createConntrackSocket( @@ -267,16 +270,23 @@ public class OffloadHardwareInterface { } @VisibleForTesting - public void sendNetlinkMessage(@NonNull NativeHandle handle, short type, short flags) { - final int length = StructNlMsgHdr.STRUCT_SIZE; + public void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) { + final int length = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE; final byte[] msg = new byte[length]; - final StructNlMsgHdr nlh = new StructNlMsgHdr(); final ByteBuffer byteBuffer = ByteBuffer.wrap(msg); + byteBuffer.order(ByteOrder.nativeOrder()); + + final StructNlMsgHdr nlh = new StructNlMsgHdr(); nlh.nlmsg_len = length; nlh.nlmsg_type = type; nlh.nlmsg_flags = flags; - nlh.nlmsg_seq = 1; + nlh.nlmsg_seq = 0; nlh.pack(byteBuffer); + + // Header needs to be added to buffer since a generic netlink request is being sent. + final StructNfGenMsg nfh = new StructNfGenMsg((byte) OsConstants.AF_INET); + nfh.pack(byteBuffer); + try { NetlinkSocket.sendMessage(handle.getFileDescriptor(), msg, 0 /* offset */, length, NETLINK_MESSAGE_TIMEOUT_MS); diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index fd9e36080c80..b285849f9edf 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -15,6 +15,7 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.TetheringManager.TETHERING_WIFI_P2P; import static java.util.Arrays.asList; @@ -23,7 +24,6 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.Network; import android.net.ip.IpServer; import android.net.util.PrefixUtils; @@ -90,16 +90,24 @@ public class PrivateAddressCoordinator { /** * Record a new upstream IpPrefix which may conflict with tethering downstreams. - * The downstreams will be notified if a conflict is found. + * The downstreams will be notified if a conflict is found. When updateUpstreamPrefix is called, + * UpstreamNetworkState must have an already populated LinkProperties. */ - public void updateUpstreamPrefix(final Network network, final LinkProperties lp) { - final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes(lp.getAllLinkAddresses()); + public void updateUpstreamPrefix(final UpstreamNetworkState ns) { + // Do not support VPN as upstream + if (ns.networkCapabilities != null && ns.networkCapabilities.hasTransport(TRANSPORT_VPN)) { + removeUpstreamPrefix(ns.network); + return; + } + + final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes( + ns.linkProperties.getAllLinkAddresses()); if (ipv4Prefixes.isEmpty()) { - removeUpstreamPrefix(network); + removeUpstreamPrefix(ns.network); return; } - mUpstreamPrefixMap.put(network, ipv4Prefixes); + mUpstreamPrefixMap.put(ns.network, ipv4Prefixes); handleMaybePrefixConflict(ipv4Prefixes); } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 7dd5290ee83b..474f4e8b603a 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1678,14 +1678,6 @@ public class Tethering { } } - private void addUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties); - } - - private void removeUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); - } - @VisibleForTesting void handleUpstreamNetworkMonitorCallback(int arg1, Object o) { if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) { @@ -1696,10 +1688,10 @@ public class Tethering { final UpstreamNetworkState ns = (UpstreamNetworkState) o; switch (arg1) { case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: - addUpstreamPrefixes(ns); + mPrivateAddressCoordinator.updateUpstreamPrefix(ns); break; case UpstreamNetworkMonitor.EVENT_ON_LOST: - removeUpstreamPrefixes(ns); + mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); break; } @@ -2104,7 +2096,7 @@ public class Tethering { } private boolean hasCallingPermission(@NonNull String permission) { - return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED; + return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; } /** Unregister tethering event callback */ diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java index 64be2d9a5599..d206ea0b4d45 100644 --- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java +++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java @@ -553,7 +553,6 @@ public class EthernetTetheringTest { TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class); TestNetworkInterface iface = tnm.createTapInterface(); Log.d(TAG, "Created test interface " + iface.getInterfaceName()); - assertNotNull(NetworkInterface.getByName(iface.getInterfaceName())); return iface; } diff --git a/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java new file mode 100644 index 000000000000..57c28fc67cc3 --- /dev/null +++ b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 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 com.android.networkstack.tethering; + +import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE; +import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; +import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; + +import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_GET; +import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_NEW; +import static com.android.networkstack.tethering.OffloadHardwareInterface.NFNL_SUBSYS_CTNETLINK; +import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_DESTROY; +import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_NEW; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.net.netlink.StructNlMsgHdr; +import android.net.util.SharedLog; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.NativeHandle; +import android.system.Os; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ConntrackSocketTest { + private static final long TIMEOUT = 500; + + private HandlerThread mHandlerThread; + private Handler mHandler; + private final SharedLog mLog = new SharedLog("privileged-test"); + + private OffloadHardwareInterface mOffloadHw; + private OffloadHardwareInterface.Dependencies mDeps; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mHandlerThread = new HandlerThread(getClass().getSimpleName()); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + + // Looper must be prepared here since AndroidJUnitRunner runs tests on separate threads. + if (Looper.myLooper() == null) Looper.prepare(); + + mDeps = new OffloadHardwareInterface.Dependencies(mLog); + mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps); + } + + @Test + public void testIpv4ConntrackSocket() throws Exception { + // Set up server and connect. + final InetSocketAddress anyAddress = new InetSocketAddress( + InetAddress.getByName("127.0.0.1"), 0); + final ServerSocket serverSocket = new ServerSocket(); + serverSocket.bind(anyAddress); + final SocketAddress theAddress = serverSocket.getLocalSocketAddress(); + + // Make a connection to the server. + final Socket socket = new Socket(); + socket.connect(theAddress); + final Socket acceptedSocket = serverSocket.accept(); + + final NativeHandle handle = mDeps.createConntrackSocket( + NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY); + mOffloadHw.sendIpv4NfGenMsg(handle, + (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET), + (short) (NLM_F_REQUEST | NLM_F_DUMP)); + + boolean foundConntrackEntry = false; + ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_RECV_BUFSIZE); + buffer.order(ByteOrder.nativeOrder()); + + try { + while (Os.read(handle.getFileDescriptor(), buffer) > 0) { + buffer.flip(); + + // TODO: ConntrackMessage should get a parse API like StructNlMsgHdr + // so we can confirm that the conntrack added is for the TCP connection above. + final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(buffer); + assertNotNull(nlmsghdr); + + // As long as 1 conntrack entry is found test case will pass, even if it's not + // the from the TCP connection above. + if (nlmsghdr.nlmsg_type == ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW)) { + foundConntrackEntry = true; + break; + } + } + } finally { + socket.close(); + serverSocket.close(); + } + assertTrue("Did not receive any NFNL_SUBSYS_CTNETLINK/IPCTNL_MSG_CT_NEW message", + foundConntrackEntry); + } +} diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java index c543fad62dba..38b19dd3da5c 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java @@ -17,8 +17,9 @@ package com.android.networkstack.tethering; import static android.net.util.TetheringUtils.uint16; -import static android.system.OsConstants.SOCK_STREAM; +import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_UNIX; +import static android.system.OsConstants.SOCK_STREAM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -35,14 +36,15 @@ import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback; import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate; import android.hardware.tetheroffload.control.V1_0.NetworkProtocol; import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent; +import android.net.netlink.StructNfGenMsg; import android.net.netlink.StructNlMsgHdr; import android.net.util.SharedLog; import android.os.Handler; import android.os.NativeHandle; import android.os.test.TestLooper; import android.system.ErrnoException; -import android.system.OsConstants; import android.system.Os; +import android.system.OsConstants; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -55,8 +57,8 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.io.FileDescriptor; -import java.io.OutputStream; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; @RunWith(AndroidJUnit4.class) @@ -218,7 +220,7 @@ public final class OffloadHardwareInterfaceTest { } @Test - public void testNetlinkMessage() throws Exception { + public void testSendIpv4NfGenMsg() throws Exception { FileDescriptor writeSocket = new FileDescriptor(); FileDescriptor readSocket = new FileDescriptor(); try { @@ -229,17 +231,25 @@ public final class OffloadHardwareInterfaceTest { } when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket); - mOffloadHw.sendNetlinkMessage(mNativeHandle, TEST_TYPE, TEST_FLAGS); + mOffloadHw.sendIpv4NfGenMsg(mNativeHandle, TEST_TYPE, TEST_FLAGS); + + ByteBuffer buffer = ByteBuffer.allocate(9823); // Arbitrary value > expectedLen. + buffer.order(ByteOrder.nativeOrder()); - ByteBuffer buffer = ByteBuffer.allocate(StructNlMsgHdr.STRUCT_SIZE); int read = Os.read(readSocket, buffer); + final int expectedLen = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE; + assertEquals(expectedLen, read); buffer.flip(); - assertEquals(StructNlMsgHdr.STRUCT_SIZE, buffer.getInt()); + assertEquals(expectedLen, buffer.getInt()); assertEquals(TEST_TYPE, buffer.getShort()); assertEquals(TEST_FLAGS, buffer.getShort()); - assertEquals(1 /* seq */, buffer.getInt()); + assertEquals(0 /* seq */, buffer.getInt()); assertEquals(0 /* pid */, buffer.getInt()); + assertEquals(AF_INET, buffer.get()); // nfgen_family + assertEquals(0 /* error */, buffer.get()); // version + assertEquals(0 /* error */, buffer.getShort()); // res_id + assertEquals(expectedLen, buffer.position()); } private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) { diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 8e93c2e447b3..7b6632c36f24 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -15,6 +15,10 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.TetheringManager.TETHERING_ETHERNET; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; @@ -30,13 +34,12 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; -import android.net.InetAddresses; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.ip.IpServer; -import android.net.util.NetworkConstants; import android.net.util.PrefixUtils; import androidx.test.filters.SmallTest; @@ -48,13 +51,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.List; - @RunWith(AndroidJUnit4.class) @SmallTest public final class PrivateAddressCoordinatorTest { - private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; - private static final String TEST_WIFI_IFNAME = "test_wlan0"; + private static final String TEST_IFNAME = "test0"; @Mock private IpServer mHotspotIpServer; @Mock private IpServer mUsbIpServer; @@ -69,7 +69,8 @@ public final class PrivateAddressCoordinatorTest { private final LinkAddress mLegacyWifiP2pAddress = new LinkAddress("192.168.49.1/24"); private final Network mWifiNetwork = new Network(1); private final Network mMobileNetwork = new Network(2); - private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork}; + private final Network mVpnNetwork = new Network(3); + private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork, mVpnNetwork}; private void setUpIpServers() throws Exception { when(mUsbIpServer.interfaceType()).thenReturn(TETHERING_USB); @@ -184,33 +185,25 @@ public final class PrivateAddressCoordinatorTest { assertEquals("Fail to reselect available prefix: ", predefinedPrefix, allowUseFreePrefix); } - private LinkProperties buildUpstreamLinkProperties(boolean withIPv4, boolean withIPv6, - boolean isMobile) { - final String testIface; - final String testIpv4Address; - if (isMobile) { - testIface = TEST_MOBILE_IFNAME; - testIpv4Address = "10.0.0.1"; - } else { - testIface = TEST_WIFI_IFNAME; - testIpv4Address = "192.168.43.5"; - } - + private UpstreamNetworkState buildUpstreamNetworkState(final Network network, + final LinkAddress v4Addr, final LinkAddress v6Addr, final NetworkCapabilities cap) { final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(testIface); + prop.setInterfaceName(TEST_IFNAME); + if (v4Addr != null) prop.addLinkAddress(v4Addr); - if (withIPv4) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress(testIpv4Address), - NetworkConstants.IPV4_ADDR_BITS)); - } + if (v6Addr != null) prop.addLinkAddress(v6Addr); + + return new UpstreamNetworkState(prop, cap, network); + } - if (withIPv6) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), - NetworkConstants.RFC7421_PREFIX_LENGTH)); + private NetworkCapabilities makeNetworkCapabilities(final int transportType) { + final NetworkCapabilities cap = new NetworkCapabilities(); + cap.addTransportType(transportType); + if (transportType == TRANSPORT_VPN) { + cap.removeCapability(NET_CAPABILITY_NOT_VPN); } - return prop; + + return cap; } @Test @@ -220,53 +213,76 @@ public final class PrivateAddressCoordinatorTest { final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); // Force always get subAddress "43.5" for conflict testing. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); - // 1. Enable hotspot with prefix 192.168.43.0/24 + // - Enable hotspot with prefix 192.168.43.0/24 final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(hotspotAddr); assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr); - // 2. Update v6 only mobile network, hotspot prefix should not be removed. - List<String> testConflicts; - final LinkProperties v6OnlyMobileProp = buildUpstreamLinkProperties(false, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v6OnlyMobileProp); + // - test mobile network with null NetworkCapabilities. Ideally this should not happen, + // just make sure no crash in this case. + final UpstreamNetworkState noCapUpstream = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, null); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - test mobile upstream with no address. + final UpstreamNetworkState noAddress = buildUpstreamNetworkState(mMobileNetwork, + null, null, makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v6 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + null, new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mMobileNetwork); - // 3. Update v4 only mobile network, hotspot prefix should not be removed. - final LinkProperties v4OnlyMobileProp = buildUpstreamLinkProperties(true, false, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4OnlyMobileProp); + // - Update v4 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 4. Update v4v6 mobile network, hotspot prefix should not be removed. - final LinkProperties v4v6MobileProp = buildUpstreamLinkProperties(true, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4v6MobileProp); + // - Update v4v6 mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4v6Mobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4v6Mobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 5. Update v6 only wifi network, hotspot prefix should not be removed. - final LinkProperties v6OnlyWifiProp = buildUpstreamLinkProperties(false, true, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v6OnlyWifiProp); + // - Update v6 only wifi network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + null, new LinkAddress("2001:db8::/64"), makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); - // 6. Update v4 only wifi network, it conflict with hotspot prefix. - final LinkProperties v4OnlyWifiProp = buildUpstreamLinkProperties(true, false, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + // - Update vpn network, it conflict with hotspot prefix but VPN networks are ignored. + final UpstreamNetworkState v4OnlyVpn = buildUpstreamNetworkState(mVpnNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_VPN)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyVpn); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v4 only wifi network, it conflict with hotspot prefix. + final UpstreamNetworkState v4OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); reset(mHotspotIpServer); - // 7. Restart hotspot again and its prefix is different previous. + // - Restart hotspot again and its prefix is different previous. mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); final LinkAddress hotspotAddr2 = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix2 = PrefixUtils.asIpPrefix(hotspotAddr2); assertNotEquals(hotspotPrefix, hotspotPrefix2); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr2); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 7. Usb tethering can be enabled and its prefix is different with conflict one. + // - Usb tethering can be enabled and its prefix is different with conflict one. final LinkAddress usbAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer); final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(usbAddr); assertNotEquals(predefinedPrefix, usbPrefix); assertNotEquals(hotspotPrefix2, usbPrefix); when(mUsbIpServer.getAddress()).thenReturn(usbAddr); - // 8. Disable wifi upstream, then wifi's prefix can be selected again. + // - Disable wifi upstream, then wifi's prefix can be selected again. mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); final LinkAddress ethAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mEthernetIpServer); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index fd5a621f1a25..df23da650a6f 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -34,7 +34,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.net.LinkProperties; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -46,8 +45,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.DeviceConfig; import android.telephony.Annotation; -import android.telephony.Annotation.ApnType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.BarringInfo; @@ -63,7 +60,6 @@ import android.telephony.CellSignalStrengthLte; import android.telephony.CellSignalStrengthNr; import android.telephony.CellSignalStrengthTdscdma; import android.telephony.CellSignalStrengthWcdma; -import android.telephony.DataFailCause; import android.telephony.DisconnectCause; import android.telephony.LocationAccessPolicy; import android.telephony.PhoneCapability; @@ -81,7 +77,9 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.util.ArrayMap; import android.util.LocalLog; +import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; @@ -304,13 +302,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { @RadioPowerState private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; - private final LocalLog mLocalLog = new LocalLog(100); + private final LocalLog mLocalLog = new LocalLog(200); - private final LocalLog mListenLog = new LocalLog(100); + private final LocalLog mListenLog = new LocalLog(00); - // Per-phoneMap of APN Type to DataConnectionState - private List<Map<Integer, PreciseDataConnectionState>> mPreciseDataConnectionStates = - new ArrayList<Map<Integer, PreciseDataConnectionState>>(); + /** + * Per-phone map of precise data connection state. The key of the map is the pair of transport + * type and APN setting. This is the cache to prevent redundant callbacks to the listeners. + * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes + * its entry from the map. + */ + private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>> + mPreciseDataConnectionStates; static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = PhoneStateListener.LISTEN_REGISTRATION_FAILURE @@ -523,7 +526,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap<Integer, PreciseDataConnectionState>()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -612,7 +615,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap<Integer, PreciseDataConnectionState>()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -1689,38 +1692,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { * * @param phoneId the phoneId carrying the data connection * @param subId the subscriptionId for the data connection - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState a PreciseDataConnectionState that has info about the data connection */ @Override - public void notifyDataConnectionForSubscriber( - int phoneId, int subId, @ApnType int apnType, PreciseDataConnectionState preciseState) { + public void notifyDataConnectionForSubscriber(int phoneId, int subId, + @NonNull PreciseDataConnectionState preciseState) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } - String apn = ""; - int state = TelephonyManager.DATA_UNKNOWN; - int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - LinkProperties linkProps = null; + ApnSetting apnSetting = preciseState.getApnSetting(); - if (preciseState != null) { - apn = preciseState.getDataConnectionApn(); - state = preciseState.getState(); - networkType = preciseState.getNetworkType(); - linkProps = preciseState.getDataConnectionLinkProperties(); - } - if (VDBG) { - log("notifyDataConnectionForSubscriber: subId=" + subId - + " state=" + state + "' apn='" + apn - + "' apnType=" + apnType + " networkType=" + networkType - + "' preciseState=" + preciseState); - } + int apnTypes = apnSetting.getApnTypeBitmask(); + int state = preciseState.getState(); + int networkType = preciseState.getNetworkType(); synchronized (mRecords) { if (validatePhoneId(phoneId)) { // We only call the callback when the change is for default APN type. - if ((ApnSetting.TYPE_DEFAULT & apnType) != 0 + if ((ApnSetting.TYPE_DEFAULT & apnTypes) != 0 && (mDataConnectionState[phoneId] != state || mDataConnectionNetworkType[phoneId] != networkType)) { String str = "onDataConnectionStateChanged(" @@ -1749,19 +1739,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType[phoneId] = networkType; } - boolean needsNotify = false; - // State has been cleared for this APN Type - if (preciseState == null) { - // We try clear the state and check if the state was previously not cleared - needsNotify = mPreciseDataConnectionStates.get(phoneId).remove(apnType) != null; - } else { - // We need to check to see if the state actually changed - PreciseDataConnectionState oldPreciseState = - mPreciseDataConnectionStates.get(phoneId).put(apnType, preciseState); - needsNotify = !preciseState.equals(oldPreciseState); - } - - if (needsNotify) { + Pair<Integer, ApnSetting> key = Pair.create(preciseState.getTransportType(), + preciseState.getApnSetting()); + PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId) + .remove(key); + log("Jack: oldState=" + oldState); + log("Jack: newState=" + preciseState); + if (!Objects.equals(oldState, preciseState)) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) @@ -1773,54 +1757,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } - } - } - handleRemoveListLocked(); - } + handleRemoveListLocked(); - broadcastDataConnectionStateChanged(state, apn, apnType, subId); - } + broadcastDataConnectionStateChanged(phoneId, subId, preciseState); - /** - * Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function. - * @see #notifyDataConnectionFailedForSubscriber - */ - public void notifyDataConnectionFailed(String apnType) { - loge("This function should not be invoked"); - } + String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId=" + + subId + " " + preciseState; + log(str); + mLocalLog.log(str); + } - private void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, int apnType) { - if (!checkNotifyPermission("notifyDataConnectionFailed()")) { - return; - } - if (VDBG) { - log("notifyDataConnectionFailedForSubscriber: subId=" + subId - + " apnType=" + apnType); - } - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState( - TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, null, null, - DataFailCause.NONE, null)); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } + // If the state is disconnected, it would be the end of life cycle of a data + // connection, so remove it from the cache. + if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) { + mPreciseDataConnectionStates.get(phoneId).put(key, preciseState); } } - - handleRemoveListLocked(); } } @@ -1970,42 +1922,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void notifyPreciseDataConnectionFailed(int phoneId, int subId, @ApnType int apnType, - String apn, @DataFailureCause int failCause) { - if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { - return; - } - - // precise notify invokes imprecise notify - notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType); - - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState( - TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, null, null, - failCause, null)); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } - } - } - handleRemoveListLocked(); - } - } - - @Override public void notifySrvccStateChanged(int subId, @SrvccState int state) { if (!checkNotifyPermission("notifySrvccStateChanged()")) { return; @@ -2575,16 +2491,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private void broadcastDataConnectionStateChanged(int state, String apn, - int apnType, int subId) { + private void broadcastDataConnectionStateChanged(int slotIndex, int subId, + @NonNull PreciseDataConnectionState pdcs) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); - intent.putExtra(PHONE_CONSTANTS_STATE_KEY, TelephonyUtils.dataStateToString(state)); - intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn); + intent.putExtra(PHONE_CONSTANTS_STATE_KEY, + TelephonyUtils.dataStateToString(pdcs.getState())); + intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName()); intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, - ApnSetting.getApnTypesStringFromBitmask(apnType)); + ApnSetting.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); } @@ -2941,7 +2859,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { /** * Returns a string representation of the radio technology (network type) * currently in use on the device. - * @param subId for which network type is returned + * @param type for which network type is returned * @return the name of the radio technology * */ diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index ff8c628e785b..7cdd3b3a42fe 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -284,10 +284,12 @@ public abstract class BiometricServiceBase extends SystemService @Override public int handleFailedAttempt() { final int lockoutMode = getLockoutMode(); - if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { - mPerformanceStats.permanentLockout++; - } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { - mPerformanceStats.lockout++; + if (mPerformanceStats != null) { + if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { + mPerformanceStats.permanentLockout++; + } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { + mPerformanceStats.lockout++; + } } // Failing multiple times will continue to push out the lockout time @@ -730,10 +732,12 @@ public abstract class BiometricServiceBase extends SystemService if (client != null && client.onAuthenticated(identifier, authenticated, token)) { removeClient(client); } - if (authenticated) { - mPerformanceStats.accept++; - } else { - mPerformanceStats.reject++; + if (mPerformanceStats != null) { + if (authenticated) { + mPerformanceStats.accept++; + } else { + mPerformanceStats.reject++; + } } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 9817abfec4bd..8e1fccd07f7a 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -77,6 +77,7 @@ import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.os.Binder; import android.os.Build.VERSION_CODES; import android.os.Bundle; @@ -142,6 +143,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; /** @@ -2301,7 +2303,7 @@ public class Vpn { void onChildTransformCreated( @NonNull Network network, @NonNull IpSecTransform transform, int direction); - void onSessionLost(@NonNull Network network); + void onSessionLost(@NonNull Network network, @Nullable Exception exception); } /** @@ -2458,7 +2460,7 @@ public class Vpn { networkAgent.sendLinkProperties(lp); } catch (Exception e) { Log.d(TAG, "Error in ChildOpened for network " + network, e); - onSessionLost(network); + onSessionLost(network, e); } } @@ -2488,7 +2490,7 @@ public class Vpn { mIpSecManager.applyTunnelModeTransform(mTunnelIface, direction, transform); } catch (IOException e) { Log.d(TAG, "Transform application failed for network " + network, e); - onSessionLost(network); + onSessionLost(network, e); } } @@ -2546,11 +2548,20 @@ public class Vpn { Log.d(TAG, "Ike Session started for network " + network); } catch (Exception e) { Log.i(TAG, "Setup failed for network " + network + ". Aborting", e); - onSessionLost(network); + onSessionLost(network, e); } }); } + /** Marks the state as FAILED, and disconnects. */ + private void markFailedAndDisconnect(Exception exception) { + synchronized (Vpn.this) { + updateState(DetailedState.FAILED, exception.getMessage()); + } + + disconnectVpnRunner(); + } + /** * Handles loss of a session * @@ -2560,7 +2571,7 @@ public class Vpn { * <p>This method MUST always be called on the mExecutor thread in order to ensure * consistency of the Ikev2VpnRunner fields. */ - public void onSessionLost(@NonNull Network network) { + public void onSessionLost(@NonNull Network network, @Nullable Exception exception) { if (!isActiveNetwork(network)) { Log.d(TAG, "onSessionLost() called for obsolete network " + network); @@ -2572,6 +2583,27 @@ public class Vpn { return; } + if (exception instanceof IkeProtocolException) { + final IkeProtocolException ikeException = (IkeProtocolException) exception; + + switch (ikeException.getErrorType()) { + case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough + case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough + case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE: + // All the above failures are configuration errors, and are terminal + markFailedAndDisconnect(exception); + return; + // All other cases possibly recoverable. + } + } else if (exception instanceof IllegalArgumentException) { + // Failed to build IKE/ChildSessionParams; fatal profile configuration error + markFailedAndDisconnect(exception); + return; + } + mActiveNetwork = null; // Close all obsolete state, but keep VPN alive incase a usable network comes up. @@ -2621,12 +2653,18 @@ public class Vpn { } /** - * Cleans up all Ikev2VpnRunner internal state + * Disconnects and shuts down this VPN. + * + * <p>This method resets all internal Ikev2VpnRunner state, but unless called via + * VpnRunner#exit(), this Ikev2VpnRunner will still be listed as the active VPN of record + * until the next VPN is started, or the Ikev2VpnRunner is explicitly exited. This is + * necessary to ensure that the detailed state is shown in the Settings VPN menus; if the + * active VPN is cleared, Settings VPNs will not show the resultant state or errors. * * <p>This method MUST always be called on the mExecutor thread in order to ensure * consistency of the Ikev2VpnRunner fields. */ - private void shutdownVpnRunner() { + private void disconnectVpnRunner() { mActiveNetwork = null; mIsRunning = false; @@ -2640,9 +2678,13 @@ public class Vpn { @Override public void exitVpnRunner() { - mExecutor.execute(() -> { - shutdownVpnRunner(); - }); + try { + mExecutor.execute(() -> { + disconnectVpnRunner(); + }); + } catch (RejectedExecutionException ignored) { + // The Ikev2VpnRunner has already shut down. + } } } diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java index 103f659cc258..626303001ba0 100644 --- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java @@ -270,13 +270,13 @@ public class VpnIkev2Utils { @Override public void onClosed() { Log.d(mTag, "IkeClosed for network " + mNetwork); - mCallback.onSessionLost(mNetwork); // Server requested session closure. Retry? + mCallback.onSessionLost(mNetwork, null); // Server requested session closure. Retry? } @Override public void onClosedExceptionally(@NonNull IkeException exception) { Log.d(mTag, "IkeClosedExceptionally for network " + mNetwork, exception); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, exception); } @Override @@ -306,13 +306,13 @@ public class VpnIkev2Utils { @Override public void onClosed() { Log.d(mTag, "ChildClosed for network " + mNetwork); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, null); } @Override public void onClosedExceptionally(@NonNull IkeException exception) { Log.d(mTag, "ChildClosedExceptionally for network " + mNetwork, exception); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, exception); } @Override @@ -349,7 +349,7 @@ public class VpnIkev2Utils { @Override public void onLost(@NonNull Network network) { Log.d(mTag, "Tearing down; lost network: " + network); - mCallback.onSessionLost(network); + mCallback.onSessionLost(network, null); } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 66652ca26e54..535284083d11 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.hardware.hdmi.HdmiPortInfo; import android.hardware.tv.cec.V1_0.CecMessage; import android.hardware.tv.cec.V1_0.HotplugEvent; @@ -725,6 +727,7 @@ final class HdmiCecController { private IHdmiCec mHdmiCec; private final Object mLock = new Object(); private int mPhysicalAddress = INVALID_PHYSICAL_ADDRESS; + @Nullable private HdmiCecCallback mCallback; @Override public String nativeInit() { @@ -733,7 +736,7 @@ final class HdmiCecController { boolean connectToHal() { try { - mHdmiCec = IHdmiCec.getService(); + mHdmiCec = IHdmiCec.getService(true); try { mHdmiCec.linkToDeath(this, HDMI_CEC_HAL_DEATH_COOKIE); } catch (RemoteException e) { @@ -747,7 +750,8 @@ final class HdmiCecController { } @Override - public void setCallback(HdmiCecCallback callback) { + public void setCallback(@NonNull HdmiCecCallback callback) { + mCallback = callback; try { mHdmiCec.setCallback(callback); } catch (RemoteException e) { @@ -887,6 +891,10 @@ final class HdmiCecController { if (cookie == HDMI_CEC_HAL_DEATH_COOKIE) { HdmiLogger.error(TAG, "Service died cokkie : " + cookie + "; reconnecting"); connectToHal(); + // Reconnect the callback + if (mCallback != null) { + setCallback(mCallback); + } } } diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS index 25ef9facb216..c09ade9e075f 100644 --- a/services/core/java/com/android/server/inputmethod/OWNERS +++ b/services/core/java/com/android/server/inputmethod/OWNERS @@ -4,3 +4,4 @@ ogunwale@google.com yukawa@google.com tarandeep@google.com lumark@google.com +roosa@google.com diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index e12cb8f533a7..f116a24a76e1 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -352,6 +352,11 @@ public abstract class ApexManager { public abstract boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds); /** + * Inform apexd that the boot has completed. + */ + public abstract void markBootCompleted(); + + /** * Dumps various state information to the provided {@link PrintWriter} object. * * @param pw the {@link PrintWriter} object to send information to. @@ -883,6 +888,15 @@ public abstract class ApexManager { } } + @Override + public void markBootCompleted() { + try { + waitForApexService().markBootCompleted(); + } catch (RemoteException re) { + Slog.e(TAG, "Unable to contact apexservice", re); + } + } + /** * Dump information about the packages contained in a particular cache * @param packagesCache the cache to print information about. @@ -1130,6 +1144,11 @@ public abstract class ApexManager { } @Override + public void markBootCompleted() { + // No-op + } + + @Override void dump(PrintWriter pw, String packageName) { // No-op } diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index c3c2e5e65103..069a00f03a1d 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -547,9 +547,9 @@ public class AppsFilter { final boolean newIsForceQueryable = mForceQueryable.contains(newPkgSetting.appId) /* shared user that is already force queryable */ - || newPkg.isForceQueryable() - || newPkgSetting.forceQueryableOverride + || newPkgSetting.forceQueryableOverride /* adb override */ || (newPkgSetting.isSystem() && (mSystemAppsQueryable + || newPkg.isForceQueryable() || ArrayUtils.contains(mForceQueryableByDevicePackageNames, newPkg.getPackageName()))); if (newIsForceQueryable diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 994cec2b1e59..90d9834d891a 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -943,6 +943,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + private ParcelFileDescriptor openTargetInternal(String path, int flags, int mode) + throws IOException, ErrnoException { + // TODO: this should delegate to DCS so the system process avoids + // holding open FDs into containers. + final FileDescriptor fd = Os.open(path, flags, mode); + return new ParcelFileDescriptor(fd); + } + + private ParcelFileDescriptor createRevocableFdInternal(RevocableFileDescriptor fd, + ParcelFileDescriptor pfd) throws IOException { + int releasedFdInt = pfd.detachFd(); + FileDescriptor releasedFd = new FileDescriptor(); + releasedFd.setInt$(releasedFdInt); + fd.init(mContext, releasedFd); + return fd.getRevocableFileDescriptor(); + } + private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes, ParcelFileDescriptor incomingFd) throws IOException { // Quick sanity check of state, and allocate a pipe for ourselves. We @@ -975,21 +992,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { Binder.restoreCallingIdentity(identity); } - // TODO: this should delegate to DCS so the system process avoids - // holding open FDs into containers. - final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), + ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(), O_CREAT | O_WRONLY, 0644); Os.chmod(target.getAbsolutePath(), 0644); // If caller specified a total length, allocate it for them. Free up // cache space to grow, if needed. if (stageDir != null && lengthBytes > 0) { - mContext.getSystemService(StorageManager.class).allocateBytes(targetFd, lengthBytes, + mContext.getSystemService(StorageManager.class).allocateBytes( + targetPfd.getFileDescriptor(), lengthBytes, PackageHelper.translateAllocateFlags(params.installFlags)); } if (offsetBytes > 0) { - Os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET); + Os.lseek(targetPfd.getFileDescriptor(), offsetBytes, OsConstants.SEEK_SET); } if (incomingFd != null) { @@ -999,8 +1015,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // inserted above to hold the session active. try { final Int64Ref last = new Int64Ref(0); - FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, lengthBytes, null, - Runnable::run, (long progress) -> { + FileUtils.copy(incomingFd.getFileDescriptor(), targetPfd.getFileDescriptor(), + lengthBytes, null, Runnable::run, + (long progress) -> { if (params.sizeBytes > 0) { final long delta = progress - last.value; last.value = progress; @@ -1011,7 +1028,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } }); } finally { - IoUtils.closeQuietly(targetFd); + IoUtils.closeQuietly(targetPfd); IoUtils.closeQuietly(incomingFd); // We're done here, so remove the "bridge" that was holding @@ -1027,12 +1044,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } return null; } else if (PackageInstaller.ENABLE_REVOCABLE_FD) { - fd.init(mContext, targetFd); - return fd.getRevocableFileDescriptor(); + return createRevocableFdInternal(fd, targetPfd); } else { - bridge.setTargetFile(targetFd); + bridge.setTargetFile(targetPfd); bridge.start(); - return new ParcelFileDescriptor(bridge.getClientSocket()); + return bridge.getClientSocket(); } } catch (ErrnoException e) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 81748b23e6ee..4f0c707a1dae 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -280,6 +280,7 @@ import android.os.storage.StorageManagerInternal; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; import android.permission.IPermissionManager; +import android.provider.ContactsContract; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.provider.Settings.Secure; @@ -25400,6 +25401,32 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Override + public void grantImplicitAccess(int recipientUid, String visibleAuthority) { + // This API is exposed temporarily to only the contacts provider. (b/158688602) + final int callingUid = Binder.getCallingUid(); + ProviderInfo contactsProvider = resolveContentProviderInternal( + ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid)); + if (contactsProvider == null || contactsProvider.applicationInfo == null + || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) { + throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess"); + } + final int userId = UserHandle.getUserId(recipientUid); + final long token = Binder.clearCallingIdentity(); + final ProviderInfo providerInfo; + try { + providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId); + } finally { + Binder.restoreCallingIdentity(token); + } + if (providerInfo == null) { + return; + } + int visibleUid = providerInfo.applicationInfo.uid; + mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid), + visibleUid, false); + } + boolean canHaveOatDir(String packageName) { synchronized (mLock) { AndroidPackage p = mPackages.get(packageName); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 09682c664eab..39b320318302 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -1377,7 +1377,7 @@ class PackageManagerShellCommand extends ShellCommand { long timeoutMs = -1; while ((opt = getNextOption()) != null) { switch (opt) { - case "--wait": + case "--wait-for-staged-ready": waitForStagedSessionReady = true; // If there is only one remaining argument, then it represents the sessionId, we // shouldn't try to parse it as timeoutMs. @@ -2865,7 +2865,7 @@ class PackageManagerShellCommand extends ShellCommand { } sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK; break; - case "--wait": + case "--wait-for-staged-ready": params.mWaitForStagedSessionReady = true; try { params.timeoutMs = Long.parseLong(peekNextArg()); @@ -3597,7 +3597,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" [--preload] [--instant] [--full] [--dont-kill]"); pw.println(" [--enable-rollback]"); pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]"); - pw.println(" [--apex] [--wait TIMEOUT]"); + pw.println(" [--apex] [--wait-for-staged-ready TIMEOUT]"); pw.println(" [PATH [SPLIT...]|-]"); pw.println(" Install an application. Must provide the apk data to install, either as"); pw.println(" file path(s) or '-' to read from stdin. Options are:"); @@ -3625,8 +3625,8 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" 3=device setup, 4=user request"); pw.println(" --force-uuid: force install on to disk volume with given UUID"); pw.println(" --apex: install an .apex file, not an .apk"); - pw.println(" --wait: when performing staged install, wait TIMEOUT milliseconds"); - pw.println(" for pre-reboot verification to complete. If TIMEOUT is not"); + pw.println(" --wait-for-staged-ready: when performing staged install, wait TIMEOUT"); + pw.println(" ms for pre-reboot verification to complete. If TIMEOUT is not"); pw.println(" specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds."); pw.println(""); pw.println(" install-existing [--user USER_ID|all|current]"); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index e2bd1f1119ca..0c96f592c0db 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -164,6 +164,7 @@ public class StagingManager { public void onBootPhase(int phase) { if (phase == SystemService.PHASE_BOOT_COMPLETED && sStagingManager != null) { sStagingManager.markStagedSessionsAsSuccessful(); + sStagingManager.markBootCompleted(); } } } @@ -179,6 +180,10 @@ public class StagingManager { } } + private void markBootCompleted() { + mApexManager.markBootCompleted(); + } + /** * Validates the signature used to sign the container of the new apex package * diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index 26230949cda6..37aedac8f28e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -365,14 +365,15 @@ public class AppsFilterTest { } @Test - public void testForceQueryable_DoesntFilter() throws Exception { + public void testForceQueryable_SystemDoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); PackageSetting target = simulateAddPackage(appsFilter, - pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID); + pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID, + setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)); PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID); @@ -380,6 +381,23 @@ public class AppsFilterTest { SYSTEM_USER)); } + + @Test + public void testForceQueryable_NonSystemFilters() throws Exception { + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + simulateAddBasicAndroid(appsFilter); + appsFilter.onSystemReady(); + + PackageSetting target = simulateAddPackage(appsFilter, + pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID); + PackageSetting calling = simulateAddPackage(appsFilter, + pkg("com.some.other.package"), DUMMY_CALLING_APPID); + + assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target, + SYSTEM_USER)); + } + @Test public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { final AppsFilter appsFilter = diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt index 8228d30d0a4f..ddc608413db8 100644 --- a/telephony/api/system-current.txt +++ b/telephony/api/system-current.txt @@ -316,6 +316,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { @@ -659,6 +660,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -872,6 +874,7 @@ package android.telephony.data { method public int getCause(); method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses(); method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses(); + method public int getHandoverFailureMode(); method public int getId(); method @NonNull public String getInterfaceName(); method public int getLinkStatus(); @@ -883,6 +886,11 @@ package android.telephony.data { method public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; + field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 2; // 0x2 + field public static final int HANDOVER_FAILURE_MODE_LEGACY = 1; // 0x1 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 3; // 0x3 + field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 4; // 0x4 + field public static final int HANDOVER_FAILURE_MODE_UNKNOWN = 0; // 0x0 field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 field public static final int LINK_STATUS_DORMANT = 1; // 0x1 field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 @@ -896,6 +904,7 @@ package android.telephony.data { method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setHandoverFailureMode(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); diff --git a/telephony/api/system-removed.txt b/telephony/api/system-removed.txt index c7fd30438dff..ae46075c4829 100644 --- a/telephony/api/system-removed.txt +++ b/telephony/api/system-removed.txt @@ -1,11 +1,6 @@ // Signature format: 2.0 package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index f2dae237b627..235b09474537 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3923,6 +3923,16 @@ public class CarrierConfigManager { public static final String KEY_DEFAULT_PREFERRED_APN_NAME_STRING = "default_preferred_apn_name_string"; + /** + * For Android 11, provide a temporary solution for OEMs to use the lower of the two MTU values + * for IPv4 and IPv6 if both are sent. + * TODO: remove in later release + * + * @hide + */ + public static final String KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED = + "use_lower_mtu_value_if_both_received"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -4463,6 +4473,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false); sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, ""); + sDefaults.putBoolean(KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED, false); } /** diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index 067b98a16779..3923c756033f 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -37,7 +37,7 @@ public final class CellIdentityNr extends CellIdentity { private static final String TAG = "CellIdentityNr"; private static final int MAX_PCI = 1007; - private static final int MAX_TAC = 65535; + private static final int MAX_TAC = 16777215; // 0xffffff private static final int MAX_NRARFCN = 3279165; private static final long MAX_NCI = 68719476735L; @@ -65,7 +65,7 @@ public final class CellIdentityNr extends CellIdentity { /** * * @param pci Physical Cell Id in range [0, 1007]. - * @param tac 16-bit Tracking Area Code. + * @param tac 24-bit Tracking Area Code. * @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165]. * @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2. * @param mccStr 3-digit Mobile Country Code in string format. @@ -138,7 +138,11 @@ public final class CellIdentityNr extends CellIdentity { @NonNull @Override public CellLocation asCellLocation() { - return new GsmCellLocation(); + GsmCellLocation cl = new GsmCellLocation(); + int tac = mTac != CellInfo.UNAVAILABLE ? mTac : -1; + cl.setLacAndCid(tac, -1); + cl.setPsc(0); + return cl; } @Override @@ -211,9 +215,9 @@ public final class CellIdentityNr extends CellIdentity { /** * Get the tracking area code. - * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown. + * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown. */ - @IntRange(from = 0, to = 65535) + @IntRange(from = 0, to = 16777215) public int getTac() { return mTac; } diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index cdf735195d61..8f5ec365e65c 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -29,7 +29,10 @@ import com.android.internal.telephony.PhoneConstants; /** * Abstract class that represents the location of the device. {@more} + * + * @deprecated use {@link android.telephony.CellIdentity CellIdentity}. */ +@Deprecated public abstract class CellLocation { /** diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index b682bdd7aee3..fd9f46011c7e 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -28,11 +28,15 @@ import android.net.LinkProperties; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DataState; import android.telephony.Annotation.NetworkType; import android.telephony.data.ApnSetting; +import android.telephony.data.DataCallResponse; + +import com.android.internal.telephony.util.TelephonyUtils; import java.util.Objects; @@ -53,14 +57,13 @@ import java.util.Objects; * */ public final class PreciseDataConnectionState implements Parcelable { - - private @DataState int mState = TelephonyManager.DATA_UNKNOWN; - private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - private @DataFailureCause int mFailCause = DataFailCause.NONE; - private @ApnType int mApnTypes = ApnSetting.TYPE_NONE; - private String mApn = ""; - private LinkProperties mLinkProperties = null; - private ApnSetting mApnSetting = null; + private final @TransportType int mTransportType; + private final int mId; + private final @DataState int mState; + private final @NetworkType int mNetworkType; + private final @DataFailureCause int mFailCause; + private final LinkProperties mLinkProperties; + private final ApnSetting mApnSetting; /** * Constructor @@ -77,60 +80,54 @@ public final class PreciseDataConnectionState implements Parcelable { @ApnType int apnTypes, @NonNull String apn, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause) { - this(state, networkType, apnTypes, apn, linkProperties, failCause, null); + this(AccessNetworkConstants.TRANSPORT_TYPE_INVALID, -1, state, networkType, + linkProperties, failCause, new ApnSetting.Builder() + .setApnTypeBitmask(apnTypes) + .setApnName(apn) + .setEntryName(apn) + .build()); } /** * Constructor of PreciseDataConnectionState * - * @param state the state of the data connection - * @param networkType the access network that is/would carry this data connection - * @param apnTypes the APN types that this data connection carries - * @param apn the APN of this data connection - * @param linkProperties if the data connection is connected, the properties of the connection - * @param failCause in case a procedure related to this data connection fails, a non-zero error + * @param transportType The transport of the data connection + * @param id The id of the data connection + * @param state The state of the data connection + * @param networkType The access network that is/would carry this data connection + * @param linkProperties If the data connection is connected, the properties of the connection + * @param failCause In case a procedure related to this data connection fails, a non-zero error * code indicating the cause of the failure. - * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings; + * @param apnSetting If there is a valid APN for this Data Connection, then the APN Settings; * if there is no valid APN setting for the specific type, then this will be null - * @hide */ - public PreciseDataConnectionState(@DataState int state, - @NetworkType int networkType, - @ApnType int apnTypes, @NonNull String apn, - @Nullable LinkProperties linkProperties, - @DataFailureCause int failCause, - @Nullable ApnSetting apnSetting) { + private PreciseDataConnectionState(@TransportType int transportType, int id, + @DataState int state, @NetworkType int networkType, + @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, + @Nullable ApnSetting apnSetting) { + mTransportType = transportType; + mId = id; mState = state; mNetworkType = networkType; - mApnTypes = apnTypes; - mApn = apn; mLinkProperties = linkProperties; mFailCause = failCause; mApnSetting = apnSetting; } /** - * Empty Constructor - * - * @hide - */ - public PreciseDataConnectionState() { - } - - /** * Construct a PreciseDataConnectionState object from the given parcel. * * @hide */ private PreciseDataConnectionState(Parcel in) { + mTransportType = in.readInt(); + mId = in.readInt(); mState = in.readInt(); mNetworkType = in.readInt(); - mApnTypes = in.readInt(); - mApn = in.readString(); - mLinkProperties = (LinkProperties) in.readParcelable(null); + mLinkProperties = in.readParcelable(LinkProperties.class.getClassLoader()); mFailCause = in.readInt(); - mApnSetting = (ApnSetting) in.readParcelable(null); + mApnSetting = in.readParcelable(ApnSetting.class.getClassLoader()); } /** @@ -160,29 +157,38 @@ public final class PreciseDataConnectionState implements Parcelable { } /** - * Returns the high-level state of this data connection. + * @return The transport type of this data connection. */ - public @DataState int getState() { - return mState; + public @TransportType int getTransportType() { + return mTransportType; } /** - * Returns the network type associated with this data connection. + * @return The unique id of the data connection + * + * Note this is the id assigned in {@link DataCallResponse}. + * The id remains the same for data connection handover between + * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} and + * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} * - * @deprecated use {@link getNetworkType()} * @hide - * @removed Removed from the R preview SDK but was never part of the stable API surface. */ - @Deprecated @SystemApi - public @NetworkType int getDataConnectionNetworkType() { - return mNetworkType; + public int getId() { + return mId; } /** - * Returns the network type associated with this data connection. + * @return The high-level state of this data connection. + */ + public @DataState int getState() { + return mState; + } + + /** + * Get the network type associated with this data connection. * - * Return the current/latest (radio) bearer technology that carries this data connection. + * @return The current/latest (radio) bearer technology that carries this data connection. * For a variety of reasons, the network type can change during the life of the data * connection, and this information is not reliable unless the physical link is currently * active; (there is currently no mechanism to know whether the physical link is active at @@ -202,7 +208,7 @@ public final class PreciseDataConnectionState implements Parcelable { @Deprecated @SystemApi public @ApnType int getDataConnectionApnTypeBitMask() { - return mApnTypes; + return (mApnSetting != null) ? mApnSetting.getApnTypeBitmask() : ApnSetting.TYPE_NONE; } /** @@ -215,21 +221,7 @@ public final class PreciseDataConnectionState implements Parcelable { @SystemApi @Deprecated public String getDataConnectionApn() { - return mApn; - } - - /** - * Get the properties of the network link {@link LinkProperties}. - * - * @deprecated use {@link #getLinkProperties()} - * @hide - * @removed Removed from the R preview SDK but was never part of the stable API surface. - */ - @Deprecated - @SystemApi - @Nullable - public LinkProperties getDataConnectionLinkProperties() { - return mLinkProperties; + return (mApnSetting != null) ? mApnSetting.getApnName() : ""; } /** @@ -265,7 +257,9 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Return the APN Settings for this data connection. * - * @return the ApnSetting that was used to configure this data connection. + * @return the ApnSetting that was used to configure this data connection. Note that a data + * connection cannot be established without a valid {@link ApnSetting}. The return value would + * never be {@code null} even though it has {@link Nullable} annotation. */ public @Nullable ApnSetting getApnSetting() { return mApnSetting; @@ -278,10 +272,10 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mTransportType); + out.writeInt(mId); out.writeInt(mState); out.writeInt(mNetworkType); - out.writeInt(mApnTypes); - out.writeString(mApn); out.writeParcelable(mLinkProperties, flags); out.writeInt(mFailCause); out.writeParcelable(mApnSetting, flags); @@ -301,24 +295,23 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { - return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties, - mFailCause, mApnSetting); + return Objects.hash(mTransportType, mId, mState, mNetworkType, mFailCause, + mLinkProperties, mApnSetting); } - @Override - public boolean equals(@Nullable Object obj) { - - if (!(obj instanceof PreciseDataConnectionState)) { - return false; - } - PreciseDataConnectionState other = (PreciseDataConnectionState) obj; - return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes - && mFailCause == other.mFailCause - && Objects.equals(mLinkProperties, other.mLinkProperties) - && mNetworkType == other.mNetworkType - && mState == other.mState - && Objects.equals(mApnSetting, other.mApnSetting); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PreciseDataConnectionState that = (PreciseDataConnectionState) o; + return mTransportType == that.mTransportType + && mId == that.mId + && mState == that.mState + && mNetworkType == that.mNetworkType + && mFailCause == that.mFailCause + && Objects.equals(mLinkProperties, that.mLinkProperties) + && Objects.equals(mApnSetting, that.mApnSetting); } @NonNull @@ -326,14 +319,137 @@ public final class PreciseDataConnectionState implements Parcelable { public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("Data Connection state: " + mState); - sb.append(", Network type: " + mNetworkType); - sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes)); - sb.append(", APN: " + mApn); - sb.append(", Link properties: " + mLinkProperties); - sb.append(", Fail cause: " + DataFailCause.toString(mFailCause)); - sb.append(", Apn Setting: " + mApnSetting); + sb.append(" state: " + TelephonyUtils.dataStateToString(mState)); + sb.append(", transport: " + + AccessNetworkConstants.transportTypeToString(mTransportType)); + sb.append(", id: " + mId); + sb.append(", network type: " + TelephonyManager.getNetworkTypeName(mNetworkType)); + sb.append(", APN Setting: " + mApnSetting); + sb.append(", link properties: " + mLinkProperties); + sb.append(", fail cause: " + DataFailCause.toString(mFailCause)); return sb.toString(); } + + /** + * {@link PreciseDataConnectionState} builder + * + * @hide + */ + public static final class Builder { + /** The transport type of the data connection */ + private @TransportType int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; + + /** + * The unique ID of the data connection. This is the id assigned in + * {@link DataCallResponse)}. + */ + private int mId = -1; + + /** The state of the data connection */ + private @DataState int mState = TelephonyManager.DATA_UNKNOWN; + + /** The network type associated with this data connection */ + private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + + /** If the data connection is connected, the properties of the connection */ + private @Nullable LinkProperties mLinkProperties = null; + + /** + * In case a procedure related to this data connection fails, a non-zero error code + * indicating the cause of the failure. + */ + private @DataFailureCause int mFailCause = DataFailCause.NONE; + + /** The APN Setting for this data connection */ + private @Nullable ApnSetting mApnSetting = null; + + /** + * Set the transport type of the data connection. + * + * @param transportType The transport type of the data connection + * @return The builder + */ + public @NonNull Builder setTransportType(@TransportType int transportType) { + mTransportType = transportType; + return this; + } + + /** + * Set the id of the data connection. + * + * @param id The id of the data connection + * @return The builder + */ + public @NonNull Builder setId(int id) { + mId = id; + return this; + } + + /** + * Set the state of the data connection. + * + * @param state The state of the data connection + * @return The builder + */ + public @NonNull Builder setState(@DataState int state) { + mState = state; + return this; + } + + /** + * Set the network type associated with this data connection. + * + * @param networkType The network type + * @return The builder + */ + public @NonNull Builder setNetworkType(@NetworkType int networkType) { + mNetworkType = networkType; + return this; + } + + /** + * Set the link properties of the connection. + * + * @param linkProperties Link properties + * @return The builder + */ + public @NonNull Builder setLinkProperties(LinkProperties linkProperties) { + mLinkProperties = linkProperties; + return this; + } + + /** + * Set the fail cause of the data connection. + * + * @param failCause In case a procedure related to this data connection fails, a non-zero + * error code indicating the cause of the failure. + * @return The builder + */ + public @NonNull Builder setFailCause(@DataFailureCause int failCause) { + mFailCause = failCause; + return this; + } + + /** + * Set the APN Setting for this data connection. + * + * @param apnSetting APN setting + * @return This builder + */ + public @NonNull Builder setApnSetting(@NonNull ApnSetting apnSetting) { + mApnSetting = apnSetting; + return this; + } + + /** + * Build the {@link PreciseDataConnectionState} instance. + * + * @return The {@link PreciseDataConnectionState} instance + */ + public PreciseDataConnectionState build() { + return new PreciseDataConnectionState(mTransportType, mId, mState, mNetworkType, + mLinkProperties, mFailCause, mApnSetting); + } + } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index c7aaee1797c2..66eadb5f71e0 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1884,8 +1884,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -1937,8 +1937,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -2006,8 +2006,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -2084,8 +2084,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -2122,8 +2122,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -2206,8 +2206,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -2243,8 +2243,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -3719,8 +3719,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -3757,8 +3757,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -4011,8 +4011,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -4050,8 +4050,8 @@ public class TelephonyManager { * * <p>Starting with API level 29, persistent device identifiers are guarded behind additional * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of - * the following requirements is met: + * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This + * method can be invoked if one of the following requirements is met: * <ul> * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this * is a privileged permission that can only be granted to apps preloaded on the device. @@ -13388,4 +13388,38 @@ public class TelephonyManager { return true; } } + + /** + * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app. + * + * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or + * does not exist on the SIM card. + * + * @throws IllegalStateException if the Telephony process is not currently available. + * @throws SecurityException if the caller doesn't have the permission. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public @NonNull List<String> getEquivalentHomePlmns() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getEquivalentHomePlmns(getSubId(), mContext.getOpPackageName(), + getAttributionTag()); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } + } + + return Collections.emptyList(); + } } diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java index 9bc39a0c6ced..d808cabaaa92 100644 --- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java +++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java @@ -23,7 +23,10 @@ import android.telephony.CellLocation; /** * Represents the cell location on a CDMA phone. + * + * @deprecated use {@link android.telephony.CellIdentity CellIdentity}. */ +@Deprecated public class CdmaCellLocation extends CellLocation { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mBaseStationId = -1; diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index e60ae896f9f8..ff9329ef9742 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -1214,12 +1214,16 @@ public class ApnSetting implements Parcelable { return false; } - // TODO - if we have this function we should also have hashCode. - // Also should handle changes in type order and perhaps case-insensitivity. + @Override + public int hashCode() { + return Objects.hash(mApnName, mProxyAddress, mProxyPort, mMmsc, mMmsProxyAddress, + mMmsProxyPort, mUser, mPassword, mAuthType, mApnTypeBitmask, mId, mOperatorNumeric, + mProtocol, mRoamingProtocol, mMtu, mCarrierEnabled, mNetworkTypeBitmask, mProfileId, + mPersistent, mMaxConns, mWaitTime, mMaxConnsTime, mMvnoType, mMvnoMatchData, + mApnSetId, mCarrierId, mSkip464Xlat); + } - /** - * @hide - */ + @Override public boolean equals(Object o) { if (o instanceof ApnSetting == false) { return false; diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 242c2e979571..5ead8decdb63 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -67,6 +67,47 @@ public final class DataCallResponse implements Parcelable { /** Indicates the data connection is active with physical link up. */ public static final int LINK_STATUS_ACTIVE = 2; + /** {@hide} */ + @IntDef(prefix = "HANDOVER_FAILURE_MODE_", value = { + HANDOVER_FAILURE_MODE_LEGACY, + HANDOVER_FAILURE_MODE_DO_FALLBACK, + HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER, + HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface HandoverFailureMode {} + + /** + * Data handover failure mode is unknown. + */ + public static final int HANDOVER_FAILURE_MODE_UNKNOWN = 0; + + /** + * Perform fallback to the source data transport on data handover failure using + * the legacy logic, which is fallback if the fail cause is + * {@link DataFailCause#HANDOFF_PREFERENCE_CHANGED}. + */ + public static final int HANDOVER_FAILURE_MODE_LEGACY = 1; + + /** + * Perform fallback to the source data transport on data handover failure. + */ + public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 2; + + /** + * Do not perform fallback to the source data transport on data handover failure. + * Frameworks should keep retrying handover by sending + * {@link DataService#REQUEST_REASON_HANDOVER} request to the underlying {@link DataService}. + */ + public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 3; + + /** + * Do not perform fallback to the source transport on data handover failure. + * Frameworks should retry setup a new data connection by sending + * {@link DataService#REQUEST_REASON_NORMAL} request to the underlying {@link DataService}. + */ + public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 4; + private final @DataFailureCause int mCause; private final int mSuggestedRetryTime; private final int mId; @@ -80,6 +121,7 @@ public final class DataCallResponse implements Parcelable { private final int mMtu; private final int mMtuV4; private final int mMtuV6; + private final @HandoverFailureMode int mHandoverFailureMode; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. @@ -126,14 +168,15 @@ public final class DataCallResponse implements Parcelable { mPcscfAddresses = (pcscfAddresses == null) ? new ArrayList<>() : new ArrayList<>(pcscfAddresses); mMtu = mMtuV4 = mMtuV6 = mtu; + mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY; } - /** @hide */ private DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, - @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6) { + @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, + @HandoverFailureMode int handoverFailureMode) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; @@ -151,6 +194,7 @@ public final class DataCallResponse implements Parcelable { mMtu = mtu; mMtuV4 = mtuV4; mMtuV6 = mtuV6; + mHandoverFailureMode = handoverFailureMode; } /** @hide */ @@ -173,6 +217,7 @@ public final class DataCallResponse implements Parcelable { mMtu = source.readInt(); mMtuV4 = source.readInt(); mMtuV6 = source.readInt(); + mHandoverFailureMode = source.readInt(); } /** @@ -262,6 +307,13 @@ public final class DataCallResponse implements Parcelable { return mMtuV6; } + /** + * @return The data handover failure mode. + */ + public @HandoverFailureMode int getHandoverFailureMode() { + return mHandoverFailureMode; + } + @NonNull @Override public String toString() { @@ -339,6 +391,7 @@ public final class DataCallResponse implements Parcelable { dest.writeInt(mMtu); dest.writeInt(mMtuV4); dest.writeInt(mMtuV6); + dest.writeInt(mHandoverFailureMode); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -395,6 +448,8 @@ public final class DataCallResponse implements Parcelable { private int mMtuV6; + private @HandoverFailureMode int mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY; + /** * Default constructor for Builder. */ @@ -553,6 +608,17 @@ public final class DataCallResponse implements Parcelable { } /** + * Set data handover failure mode for the data call response. + * + * @param failureMode Handover failure mode. + * @return The same instance of the builder. + */ + public @NonNull Builder setHandoverFailureMode(@HandoverFailureMode int failureMode) { + mHandoverFailureMode = failureMode; + return this; + } + + /** * Build the DataCallResponse. * * @return the DataCallResponse object. @@ -560,7 +626,7 @@ public final class DataCallResponse implements Parcelable { public @NonNull DataCallResponse build() { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, - mPcscfAddresses, mMtu, mMtuV4, mMtuV6); + mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode); } } } diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java index 30cea0e6dd59..2eee4ce371a0 100644 --- a/telephony/java/android/telephony/gsm/GsmCellLocation.java +++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java @@ -23,7 +23,10 @@ import android.telephony.CellLocation; /** * Represents the cell location on a GSM phone. + * + * @deprecated use {@link android.telephony.CellIdentity CellIdentity}. */ +@Deprecated public class GsmCellLocation extends CellLocation { private int mLac; private int mCid; @@ -55,7 +58,7 @@ public class GsmCellLocation extends CellLocation { } /** - * @return gsm cell id, -1 if unknown, 0xffff max legal value + * @return gsm cell id, -1 if unknown or invalid, 0xffff max legal value */ public int getCid() { return mCid; diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index ae1b5c1b50bd..659d9cd38faf 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2297,4 +2297,12 @@ interface ITelephony { * Whether device can connect to 5G network when two SIMs are active. */ boolean canConnectTo5GInDsdsMode(); + + /** + * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app. + * + * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or + * does not exist on the SIM card. + */ + List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId); } diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt index 0f62c4fa66a3..e9227e94da98 100644 --- a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt +++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt @@ -107,7 +107,10 @@ class PlatformCompatCommandNotInstalledTest { fun ParcelFileDescriptor.text() = FileReader(fileDescriptor).readText() @After - fun resetIdentity() = uiAutomation.dropShellPermissionIdentity() + fun resetChangeIdAndIdentity() { + command("am compat reset $TEST_CHANGE_ID $TEST_PKG") + uiAutomation.dropShellPermissionIdentity() + } @Test fun execute() { diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java index 61d7c763e8d7..fb4a2b209347 100644 --- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java +++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java @@ -26,6 +26,7 @@ import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,6 +58,9 @@ public class NetworkStagedRollbackTest extends BaseHostJUnit4Test { private WatchdogEventLogger mLogger = new WatchdogEventLogger(); + @Rule + public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); + @Before public void setUp() throws Exception { runPhase("cleanUp"); diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java index 9169ef517bf7..be74e338d7ac 100644 --- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java +++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java @@ -34,6 +34,7 @@ import com.android.tradefed.util.CommandStatus; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -87,6 +88,9 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { private WatchdogEventLogger mLogger = new WatchdogEventLogger(); + @Rule + public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); + @Before public void setUp() throws Exception { deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex", diff --git a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java new file mode 100644 index 000000000000..b08621314ee0 --- /dev/null +++ b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 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 com.android.tests.rollback.host; + +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; + +import org.junit.rules.ExternalResource; + +public class AbandonSessionsRule extends ExternalResource { + private final BaseHostJUnit4Test mHost; + + public AbandonSessionsRule(BaseHostJUnit4Test host) { + mHost = host; + } + + @Override + protected void before() throws Throwable { + abandonSessions(mHost.getDevice()); + } + + @Override + protected void after() { + try { + abandonSessions(mHost.getDevice()); + } catch (Exception ignore) { + } + } + + /** + * Abandons all sessions to prevent interference in our tests. + */ + private static void abandonSessions(ITestDevice device) throws Exception { + // No point in abandoning applied or failed sessions. We care about ready sessions only. + String cmdListReadySessions = + "pm list staged-sessions --only-sessionid --only-parent --only-ready"; + String output = device.executeShellCommand(cmdListReadySessions); + if (output.trim().isEmpty()) { + // No sessions to abandon + return; + } + // Ensure we have sufficient privilege to abandon sessions from other apps + device.enableAdbRoot(); + device.executeShellCommand("for i in $(" + cmdListReadySessions + + "); do pm install-abandon $i; done"); + device.disableAdbRoot(); + } +} diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp index c3fdd695c2b7..1e286bb15c49 100644 --- a/tests/StagedInstallTest/Android.bp +++ b/tests/StagedInstallTest/Android.bp @@ -24,7 +24,15 @@ java_test_host { name: "StagedInstallInternalTest", srcs: ["src/**/*.java"], libs: ["tradefed"], - static_libs: ["testng", "compatibility-tradefed"], + static_libs: [ + "testng", + "compatibility-tradefed", + "module_test_util", + ], + data: [ + ":com.android.apex.cts.shim.v2_prebuilt", + ":TestAppAv1", + ], test_suites: ["general-tests"], test_config: "StagedInstallInternalTest.xml", } diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java index 9b432f7d0ca5..86d5fd80c108 100644 --- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java @@ -19,8 +19,10 @@ package com.android.tests.stagedinstallinternal.host; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import com.android.ddmlib.Log; +import com.android.tests.util.ModuleTestUtils; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.util.ProcessInfo; @@ -30,6 +32,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.io.File; + @RunWith(DeviceJUnit4ClassRunner.class) public class StagedInstallInternalTest extends BaseHostJUnit4Test { @@ -37,6 +41,11 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { private static final long SYSTEM_SERVER_TIMEOUT_MS = 60 * 1000; private boolean mWasRoot = false; + private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex"; + private static final String APK_A = "TestAppAv1.apk"; + + private final ModuleTestUtils mTestUtils = new ModuleTestUtils(this); + /** * Runs the given phase of a test by calling into the device. * Throws an exception if the test phase fails. @@ -87,6 +96,58 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify"); } + @Test + public void testAdbStagedInstallWaitForReadyFlagWorks() throws Exception { + assumeTrue("Device does not support updating APEX", + mTestUtils.isApexUpdateSupported()); + + File apexFile = mTestUtils.getTestFile(SHIM_V2); + String output = getDevice().executeAdbCommand("install", "--staged", + "--wait-for-staged-ready", "60000", apexFile.getAbsolutePath()); + assertThat(output).contains("Reboot device to apply staged session"); + String sessionId = getDevice().executeShellCommand( + "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim(); + assertThat(sessionId).isNotEmpty(); + } + + @Test + public void testAdbStagedInstallNoWaitFlagWorks() throws Exception { + assumeTrue("Device does not support updating APEX", + mTestUtils.isApexUpdateSupported()); + + File apexFile = mTestUtils.getTestFile(SHIM_V2); + String output = getDevice().executeAdbCommand("install", "--staged", + "--no-wait", apexFile.getAbsolutePath()); + assertThat(output).doesNotContain("Reboot device to apply staged session"); + assertThat(output).contains("Success"); + String sessionId = getDevice().executeShellCommand( + "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim(); + assertThat(sessionId).isEmpty(); + } + + @Test + public void testAdbInstallMultiPackageCommandWorks() throws Exception { + assumeTrue("Device does not support updating APEX", + mTestUtils.isApexUpdateSupported()); + + File apexFile = mTestUtils.getTestFile(SHIM_V2); + File apkFile = mTestUtils.getTestFile(APK_A); + String output = getDevice().executeAdbCommand("install-multi-package", + apexFile.getAbsolutePath(), apkFile.getAbsolutePath()); + assertThat(output).contains("Created parent session"); + assertThat(output).contains("Created child session"); + assertThat(output).contains("Success. Reboot device to apply staged session"); + + // Ensure there is only one parent session + String[] sessionIds = getDevice().executeShellCommand( + "pm get-stagedsessions --only-ready --only-parent --only-sessionid").split("\n"); + assertThat(sessionIds.length).isEqualTo(1); + // Ensure there are two children session + sessionIds = getDevice().executeShellCommand( + "pm get-stagedsessions --only-ready --only-sessionid").split("\n"); + assertThat(sessionIds.length).isEqualTo(3); + } + private void restartSystemServer() throws Exception { // Restart the system server long oldStartTime = getDevice().getProcessByName("system_server").getStartTime(); diff --git a/tests/net/Android.bp b/tests/net/Android.bp index 124b6609f687..0fe84abcbc7b 100644 --- a/tests/net/Android.bp +++ b/tests/net/Android.bp @@ -63,6 +63,7 @@ android_test { "services.net", ], libs: [ + "android.net.ipsec.ike.stubs.module_lib", "android.test.runner", "android.test.base", "android.test.mock", diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index e8c4ee9c628d..f2b7c1ea2ba7 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -20,6 +20,7 @@ import static android.content.pm.UserInfo.FLAG_ADMIN; import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_RESTRICTED; +import static android.net.ConnectivityManager.NetworkCallback; import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; @@ -45,7 +46,9 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -66,6 +69,7 @@ import android.net.Ikev2VpnProfile; import android.net.InetAddresses; import android.net.IpPrefix; import android.net.IpSecManager; +import android.net.IpSecTunnelInterfaceResponse; import android.net.LinkProperties; import android.net.LocalSocket; import android.net.Network; @@ -75,6 +79,8 @@ import android.net.RouteInfo; import android.net.UidRange; import android.net.VpnManager; import android.net.VpnService; +import android.net.ipsec.ike.IkeSessionCallback; +import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.ConditionVariable; @@ -101,6 +107,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -150,6 +157,11 @@ public class VpnTest { private static final String TEST_VPN_IDENTITY = "identity"; private static final byte[] TEST_VPN_PSK = "psk".getBytes(); + private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE); + private static final String TEST_IFACE_NAME = "TEST_IFACE"; + private static final int TEST_TUNNEL_RESOURCE_ID = 0x2345; + private static final long TEST_TIMEOUT_MS = 500L; + /** * Names and UIDs for some fake packages. Important points: * - UID is ordered increasing. @@ -227,6 +239,13 @@ public class VpnTest { // Deny all appops by default. when(mAppOps.noteOpNoThrow(anyInt(), anyInt(), anyString())) .thenReturn(AppOpsManager.MODE_IGNORED); + + // Setup IpSecService + final IpSecTunnelInterfaceResponse tunnelResp = + new IpSecTunnelInterfaceResponse( + IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME); + when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any())) + .thenReturn(tunnelResp); } @Test @@ -988,6 +1007,52 @@ public class VpnTest { eq(AppOpsManager.MODE_IGNORED)); } + private NetworkCallback triggerOnAvailableAndGetCallback() { + final ArgumentCaptor<NetworkCallback> networkCallbackCaptor = + ArgumentCaptor.forClass(NetworkCallback.class); + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) + .requestNetwork(any(), networkCallbackCaptor.capture()); + + final NetworkCallback cb = networkCallbackCaptor.getValue(); + cb.onAvailable(TEST_NETWORK); + return cb; + } + + @Test + public void testStartPlatformVpnAuthenticationFailed() throws Exception { + final ArgumentCaptor<IkeSessionCallback> captor = + ArgumentCaptor.forClass(IkeSessionCallback.class); + final IkeProtocolException exception = mock(IkeProtocolException.class); + when(exception.getErrorType()) + .thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED); + + final Vpn vpn = startLegacyVpn(mVpnProfile); + final NetworkCallback cb = triggerOnAvailableAndGetCallback(); + + // Wait for createIkeSession() to be called before proceeding in order to ensure consistent + // state + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) + .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); + final IkeSessionCallback ikeCb = captor.getValue(); + ikeCb.onClosedExceptionally(exception); + + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); + assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState()); + } + + @Test + public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception { + when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) + .thenThrow(new IllegalArgumentException()); + final Vpn vpn = startLegacyVpn(mVpnProfile); + final NetworkCallback cb = triggerOnAvailableAndGetCallback(); + + // Wait for createIkeSession() to be called before proceeding in order to ensure consistent + // state + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); + assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState()); + } + private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) { assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null, mKeyStore)); diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl index cf2cb4ae5eb4..57055f78d03d 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceInfo; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl index d5a1e8f505a9..e4d28bb2d39f 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceRequest; |