summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--Android.mk21
-rwxr-xr-xapi/current.txt5
-rw-r--r--api/removed.txt8
-rw-r--r--api/system-current.txt11
-rw-r--r--api/test-current.txt12
-rw-r--r--cmds/statsd/src/atoms.proto75
-rw-r--r--cmds/statsd/src/guardrail/MemoryLeakTrackUtil.cpp99
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--core/java/android/app/SystemServiceRegistry.java2
-rw-r--r--core/java/android/app/backup/OWNERS6
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java313
-rwxr-xr-xcore/java/android/bluetooth/BluetoothA2dpSink.java128
-rw-r--r--core/java/android/bluetooth/BluetoothAvrcpController.java129
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java3
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java40
-rw-r--r--core/java/android/bluetooth/BluetoothHeadsetClient.java195
-rw-r--r--core/java/android/bluetooth/BluetoothHearingAid.java273
-rw-r--r--core/java/android/bluetooth/BluetoothHidDevice.java138
-rw-r--r--core/java/android/bluetooth/BluetoothHidHost.java144
-rw-r--r--core/java/android/bluetooth/BluetoothMap.java128
-rw-r--r--core/java/android/bluetooth/BluetoothMapClient.java137
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java134
-rw-r--r--core/java/android/bluetooth/BluetoothPbap.java86
-rw-r--r--core/java/android/bluetooth/BluetoothPbapClient.java135
-rw-r--r--core/java/android/bluetooth/BluetoothProfileConnector.java166
-rw-r--r--core/java/android/bluetooth/BluetoothSap.java128
-rw-r--r--core/java/android/bluetooth/BluetoothServerSocket.java35
-rw-r--r--core/java/android/bluetooth/le/ScanFilter.java9
-rw-r--r--core/java/android/content/pm/PackageParser.java5
-rw-r--r--core/java/android/net/DhcpResults.java8
-rw-r--r--core/java/android/net/IIpSecService.aidl4
-rw-r--r--core/java/android/net/ITestNetworkManager.aidl4
-rw-r--r--core/java/android/net/IpSecManager.java3
-rw-r--r--core/java/android/net/TestNetworkManager.java22
-rw-r--r--core/java/android/net/UrlQuerySanitizer.java17
-rw-r--r--core/java/android/net/metrics/ApfProgramEvent.java14
-rw-r--r--core/java/android/net/metrics/ApfStats.java16
-rw-r--r--core/java/android/net/metrics/DhcpClientEvent.java9
-rw-r--r--core/java/android/net/metrics/IpManagerEvent.java8
-rw-r--r--core/java/android/net/metrics/IpReachabilityEvent.java7
-rw-r--r--core/java/android/net/metrics/NetworkEvent.java8
-rw-r--r--core/java/android/net/metrics/RaEvent.java12
-rw-r--r--core/java/android/net/metrics/ValidationProbeEvent.java9
-rw-r--r--core/java/android/os/BugreportManager.java35
-rwxr-xr-xcore/java/android/os/Build.java1
-rw-r--r--core/java/android/os/GraphicsEnvironment.java156
-rw-r--r--core/java/android/os/INetworkManagementService.aidl15
-rw-r--r--core/java/android/provider/CallLog.java17
-rw-r--r--core/java/android/provider/Settings.java69
-rw-r--r--core/java/android/webkit/MimeTypeMap.java12
-rw-r--r--core/jni/android_ddm_DdmHandleNativeHeap.cpp25
-rw-r--r--core/jni/android_net_NetUtils.cpp4
-rw-r--r--core/jni/android_os_Debug.cpp12
-rw-r--r--core/jni/android_os_GraphicsEnvironment.cpp9
-rw-r--r--core/jni/android_os_HwBinder.cpp2
-rw-r--r--core/jni/android_util_jar_StrictJarFile.cpp2
-rw-r--r--core/proto/android/providers/settings/global.proto25
-rw-r--r--core/proto/android/stats/dnsresolver/Android.bp25
-rw-r--r--core/proto/android/stats/dnsresolver/dns_resolver.proto214
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/res/res/xml/sms_short_codes.xml2
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java9
-rw-r--r--data/etc/privapp-permissions-platform.xml7
-rw-r--r--graphics/proto/Android.bp11
-rw-r--r--graphics/proto/game_driver.proto (renamed from cmds/statsd/src/guardrail/MemoryLeakTrackUtil.h)32
-rw-r--r--graphics/proto/jarjar-rules.txt1
-rw-r--r--libs/androidfw/ApkAssets.cpp6
-rw-r--r--libs/androidfw/ZipFileRO.cpp2
-rw-r--r--libs/androidfw/tests/TestHelpers.cpp3
-rw-r--r--libs/usb/tests/AccessoryChat/Android.bp24
-rw-r--r--libs/usb/tests/AccessoryChat/Android.mk28
-rw-r--r--nfc-extras/tests/Android.bp33
-rw-r--r--nfc-extras/tests/Android.mk35
-rw-r--r--packages/CaptivePortalLogin/AndroidManifest.xml1
-rw-r--r--packages/NetworkStack/Android.bp35
-rw-r--r--packages/NetworkStack/jni/network_stack_utils_jni.cpp6
-rw-r--r--packages/NetworkStack/res/values/config.xml4
-rw-r--r--packages/NetworkStack/src/android/net/apf/ApfFilter.java17
-rw-r--r--packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java36
-rw-r--r--packages/NetworkStack/src/android/net/dhcp/DhcpServer.java5
-rw-r--r--packages/NetworkStack/src/android/net/ip/IpClient.java39
-rw-r--r--packages/NetworkStack/src/android/net/util/NetworkStackUtils.java43
-rw-r--r--packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java (renamed from packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java)2
-rw-r--r--packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java (renamed from packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java)11
-rw-r--r--packages/NetworkStack/src/com/android/server/NetworkStackService.java10
-rw-r--r--packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java105
-rw-r--r--packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java23
-rw-r--r--packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java5
-rw-r--r--packages/NetworkStack/tests/Android.bp2
-rw-r--r--packages/NetworkStack/tests/src/android/net/apf/ApfTest.java8
-rw-r--r--packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java49
-rw-r--r--packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java5
-rw-r--r--packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java123
-rw-r--r--packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java47
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml20
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java23
-rw-r--r--packages/Shell/Android.bp14
-rw-r--r--packages/Shell/Android.mk27
-rw-r--r--packages/Shell/tests/Android.bp19
-rw-r--r--packages/Shell/tests/Android.mk24
-rw-r--r--packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml31
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java15
-rw-r--r--proto/src/metrics_constants.proto5
-rw-r--r--services/backup/OWNERS6
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java16
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java112
-rw-r--r--services/core/java/com/android/server/IpSecService.java164
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java54
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java24
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java15
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java9
-rw-r--r--services/core/java/com/android/server/connectivity/DnsManager.java6
-rw-r--r--services/core/java/com/android/server/connectivity/KeepaliveTracker.java117
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java6
-rw-r--r--services/core/java/com/android/server/gpu/GpuService.java274
-rw-r--r--services/core/java/com/android/server/pm/OWNERS8
-rw-r--r--services/core/java/com/android/server/wm/OWNERS5
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/net/Android.bp25
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl9
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl8
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl6
-rw-r--r--services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl9
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl4
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl8
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl6
-rw-r--r--services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl4
-rw-r--r--services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl8
-rw-r--r--services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl17
-rw-r--r--services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl8
-rw-r--r--services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl7
-rw-r--r--services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl4
-rw-r--r--services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl7
-rw-r--r--services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl5
-rw-r--r--services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl15
-rw-r--r--services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl13
-rw-r--r--services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl11
-rw-r--r--services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl10
-rw-r--r--services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl4
-rw-r--r--services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl14
-rw-r--r--services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl16
-rw-r--r--services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl9
-rw-r--r--services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl24
-rw-r--r--services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl8
-rw-r--r--services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl7
-rw-r--r--services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl4
-rw-r--r--services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl7
-rw-r--r--services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl7
-rw-r--r--services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl5
-rw-r--r--services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl15
-rw-r--r--services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl13
-rw-r--r--services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl11
-rw-r--r--services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl10
-rw-r--r--services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl4
-rw-r--r--services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl15
-rw-r--r--services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl16
-rw-r--r--services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl9
-rw-r--r--services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl24
-rw-r--r--services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl8
-rw-r--r--services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl7
-rw-r--r--services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl4
-rw-r--r--services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl7
-rw-r--r--services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl7
-rw-r--r--services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl5
-rw-r--r--services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl15
-rw-r--r--services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl13
-rw-r--r--services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl11
-rw-r--r--services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl10
-rw-r--r--services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl4
-rw-r--r--services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl16
-rw-r--r--services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl16
-rw-r--r--services/net/java/android/net/DhcpResultsParcelable.aidl3
-rw-r--r--services/net/java/android/net/IIpMemoryStore.aidl8
-rw-r--r--services/net/java/android/net/INetworkMonitor.aidl14
-rw-r--r--services/net/java/android/net/IpMemoryStore.java5
-rw-r--r--services/net/java/android/net/IpMemoryStoreClient.java59
-rw-r--r--services/net/java/android/net/NattKeepalivePacketData.java (renamed from core/java/android/net/NattKeepalivePacketData.java)19
-rw-r--r--services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl25
-rw-r--r--services/net/java/android/net/ip/IIpClient.aidl2
-rw-r--r--services/net/java/android/net/ip/IpClientUtil.java5
-rw-r--r--services/net/java/android/net/ip/IpServer.java5
-rw-r--r--services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl (renamed from services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl)2
-rw-r--r--services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl (renamed from services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl)4
-rw-r--r--services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java50
-rw-r--r--services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java50
-rw-r--r--services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java54
-rw-r--r--services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java53
-rw-r--r--services/net/java/android/net/ipmemorystore/OnStatusListener.java49
-rw-r--r--services/net/java/android/net/shared/IpConfigurationParcelableUtil.java2
-rw-r--r--services/tests/uiservicestests/Android.bp2
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java8
-rw-r--r--startop/iorap/DISABLED_TEST_MAPPING (renamed from startop/iorap/TEST_MAPPING)0
-rw-r--r--telecomm/java/android/telecom/PhoneAccountHandle.java18
-rw-r--r--telephony/java/android/provider/Telephony.java16
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java106
-rw-r--r--telephony/java/android/telephony/CellIdentity.java18
-rw-r--r--telephony/java/android/telephony/DataSpecificRegistrationInfo.java15
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java33
-rw-r--r--telephony/java/android/telephony/ServiceState.java123
-rw-r--r--telephony/java/android/telephony/SmsManager.java41
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java42
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java69
-rw-r--r--telephony/java/android/telephony/UiccCardInfo.java4
-rw-r--r--telephony/java/android/telephony/UiccSlotInfo.java8
-rw-r--r--telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java13
-rw-r--r--telephony/java/android/telephony/emergency/EmergencyNumber.java39
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java12
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java5
-rw-r--r--telephony/java/android/telephony/ims/Rcs1To1Thread.java18
-rw-r--r--telephony/java/android/telephony/ims/RcsControllerCall.java30
-rw-r--r--telephony/java/android/telephony/ims/RcsEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsEventDescriptor.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsEventQueryResultDescriptor.java4
-rw-r--r--telephony/java/android/telephony/ims/RcsFileTransferPart.java82
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThread.java55
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadEvent.java16
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java13
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEventDescriptor.java7
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java8
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEventDescriptor.java6
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java22
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEventDescriptor.java9
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java10
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEventDescriptor.java8
-rw-r--r--telephony/java/android/telephony/ims/RcsIncomingMessage.java25
-rw-r--r--telephony/java/android/telephony/ims/RcsManager.java9
-rw-r--r--telephony/java/android/telephony/ims/RcsMessage.java87
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageQueryResult.java76
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.aidl (renamed from telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl)2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.java74
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageStore.java86
-rw-r--r--telephony/java/android/telephony/ims/RcsOutgoingMessage.java11
-rw-r--r--telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java39
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipant.java23
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java6
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantAliasChangedEventDescriptor.java4
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantQueryResult.java5
-rw-r--r--telephony/java/android/telephony/ims/RcsThread.java37
-rw-r--r--telephony/java/android/telephony/ims/RcsThreadQueryResult.java9
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcs.aidl184
-rw-r--r--telephony/java/com/android/internal/telephony/DctConstants.java1
-rwxr-xr-xtelephony/java/com/android/internal/telephony/ISub.aidl2
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl6
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java4
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java2
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java2
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java2
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java2
-rw-r--r--tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java2
-rw-r--r--tests/net/Android.bp3
-rw-r--r--tests/net/common/Android.bp4
-rw-r--r--tests/net/common/java/android/net/CaptivePortalTest.java90
-rw-r--r--tests/net/common/java/android/net/LinkAddressTest.java (renamed from tests/net/java/android/net/LinkAddressTest.java)0
-rw-r--r--tests/net/common/java/android/net/LinkPropertiesTest.java (renamed from tests/net/java/android/net/LinkPropertiesTest.java)4
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java (renamed from tests/net/java/android/net/NetworkCapabilitiesTest.java)18
-rw-r--r--tests/net/common/java/android/net/NetworkTest.java (renamed from tests/net/java/android/net/NetworkTest.java)8
-rw-r--r--tests/net/common/java/android/net/RouteInfoTest.java (renamed from tests/net/java/android/net/RouteInfoTest.java)0
-rw-r--r--tests/net/common/java/android/net/StaticIpConfigurationTest.java (renamed from tests/net/java/android/net/StaticIpConfigurationTest.java)58
-rw-r--r--tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java (renamed from tests/net/java/android/net/apf/ApfCapabilitiesTest.java)5
-rw-r--r--tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt79
-rw-r--r--tests/net/common/java/android/net/metrics/ApfStatsTest.kt64
-rw-r--r--tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt50
-rw-r--r--tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt65
-rw-r--r--tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java161
-rw-r--r--tests/net/common/java/android/net/metrics/IpManagerEventTest.kt46
-rw-r--r--tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt45
-rw-r--r--tests/net/common/java/android/net/metrics/NetworkEventTest.kt50
-rw-r--r--tests/net/common/java/android/net/metrics/RaEventTest.kt79
-rw-r--r--tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt79
-rw-r--r--tests/net/java/android/net/TcpKeepalivePacketDataTest.java2
-rw-r--r--tests/net/java/android/net/shared/InitialConfigurationTest.java3
-rw-r--r--tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java12
-rw-r--r--tests/net/java/android/net/shared/ProvisioningConfigurationTest.java3
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java84
-rw-r--r--tests/net/java/com/android/server/IpSecServiceTest.java96
-rw-r--r--tests/net/java/com/android/server/LegacyTypeTrackerTest.kt114
-rw-r--r--tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java83
-rw-r--r--tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java2
-rw-r--r--tests/net/util/Android.bp30
-rw-r--r--tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java (renamed from tests/net/java/android/net/shared/ParcelableTestUtil.java)2
-rw-r--r--tests/net/util/java/com/android/internal/util/TestUtils.java (renamed from tests/net/java/com/android/internal/util/TestUtils.java)30
-rw-r--r--tools/aapt2/ResourceUtils.cpp6
-rw-r--r--tools/aapt2/SdkConstants.cpp14
-rw-r--r--tools/aapt2/SdkConstants.h2
-rw-r--r--tools/aapt2/configuration/ConfigurationParser_test.cpp31
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists.py2
-rw-r--r--tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java6
-rw-r--r--tools/stats_log_api_gen/Collation.cpp8
-rw-r--r--tools/stats_log_api_gen/Collation.h3
-rw-r--r--tools/stats_log_api_gen/main.cpp517
-rwxr-xr-xwifi/tests/runtests.sh3
310 files changed, 6565 insertions, 3121 deletions
diff --git a/Android.bp b/Android.bp
index ec8636d40f8d..57f651319562 100644
--- a/Android.bp
+++ b/Android.bp
@@ -687,6 +687,7 @@ java_defaults {
static_libs: [
"apex_aidl_interface-java",
"framework-protos",
+ "game-driver-protos",
"android.hidl.base-V1.0-java",
"android.hardware.cas-V1.0-java",
"android.hardware.contexthub-V1.0-java",
diff --git a/Android.mk b/Android.mk
index c58f7af1d7d5..9bda2dc6d69a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,27 +32,6 @@ ifneq ($(ANDROID_BUILD_EMBEDDED),true)
# ============================================================
include $(CLEAR_VARS)
-aidl_parcelables :=
-define stubs-to-aidl-parcelables
- gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/$1.aidl
- aidl_parcelables += $$(gen)
- $$(gen): $(call java-lib-header-files,$1) $(HOST_OUT_EXECUTABLES)/sdkparcelables
- @echo Extract SDK parcelables: $$@
- rm -f $$@
- $(HOST_OUT_EXECUTABLES)/sdkparcelables $$< $$@
-endef
-
-$(foreach stubs,android_stubs_current android_test_stubs_current android_system_stubs_current,\
- $(eval $(call stubs-to-aidl-parcelables,$(stubs))))
-
-gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
-.KATI_RESTAT: $(gen)
-$(gen): $(aidl_parcelables)
- @echo Combining SDK parcelables: $@
- rm -f $@.tmp
- cat $^ | sort -u > $@.tmp
- $(call commit-change-for-toc,$@)
-
# This is used by ide.mk as the list of source files that are
# always included.
INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document))
diff --git a/api/current.txt b/api/current.txt
index d44829ecb7a0..4c015b6b855f 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -8734,8 +8734,8 @@ package android.bluetooth.le {
method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
- method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid);
- method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+ method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid);
+ method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid, @Nullable android.os.ParcelUuid);
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
}
@@ -20931,7 +20931,6 @@ package android.icu.util {
ctor public JapaneseCalendar(int, int, int, int);
ctor public JapaneseCalendar(int, int, int);
ctor public JapaneseCalendar(int, int, int, int, int, int);
- field @Deprecated public static final int CURRENT_ERA;
field public static final int HEISEI;
field public static final int MEIJI;
field public static final int SHOWA;
diff --git a/api/removed.txt b/api/removed.txt
index 72202ad9712a..f40b14614323 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -275,6 +275,14 @@ package android.hardware {
}
+package android.icu.util {
+
+ public class JapaneseCalendar extends android.icu.util.GregorianCalendar {
+ field public static final int CURRENT_ERA;
+ }
+
+}
+
package android.location {
public class Location implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 3b4a8680bf44..ce379f549c39 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4609,17 +4609,6 @@ package android.provider {
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static boolean putString(@NonNull android.content.ContentResolver, @NonNull String, @Nullable String, @Nullable String, boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void resetToDefaults(@NonNull android.content.ContentResolver, @Nullable String);
field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
- field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
- field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
- field public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
- field public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
- field public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
- field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
- field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
- field public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS = "captive_portal_other_fallback_urls";
- field public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
- field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
field public static final String CARRIER_APP_NAMES = "carrier_app_names";
field public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
field public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
diff --git a/api/test-current.txt b/api/test-current.txt
index dc5ff8f229c2..21d761fbac2f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -923,6 +923,7 @@ package android.net.util {
package android.os {
public static class Build.VERSION {
+ field public static final String[] ACTIVE_CODENAMES;
field public static final int FIRST_SDK_INT;
field public static final int RESOURCES_SDK_INT;
}
@@ -1200,17 +1201,6 @@ package android.provider {
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
- field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
- field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
- field public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
- field public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
- field public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
- field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
- field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
- field public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS = "captive_portal_other_fallback_urls";
- field public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
- field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
field public static final String LOCATION_GLOBAL_KILL_SWITCH = "location_global_kill_switch";
field public static final String LOW_POWER_MODE = "low_power";
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 564e9186b868..f04f017d8911 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -33,6 +33,7 @@ import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
import "frameworks/base/core/proto/android/server/enums.proto";
import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
+import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto";
import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
import "frameworks/base/core/proto/android/telecomm/enums.proto";
import "frameworks/base/core/proto/android/telephony/enums.proto";
@@ -133,8 +134,8 @@ message Atom {
PhoneStateChanged phone_state_changed = 95;
LowMemReported low_mem_reported = 81;
ThermalThrottlingStateChanged thermal_throttling = 86;
- NetworkDnsEventReported network_dns_event_reported = 116;
- DataStallEvent data_stall_event = 121;
+ NetworkDnsEventReported network_dns_event_reported = 116 [(log_from_module) = "resolv"];
+ DataStallEvent data_stall_event = 121 [(log_from_module) = "network_stack"];
BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = 125;
BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = 126;
BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = 127;
@@ -165,7 +166,7 @@ message Atom {
BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
ProcessStartTime process_start_time = 169;
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
- NetworkStackReported network_stack_reported = 182;
+ NetworkStackReported network_stack_reported = 182 [(log_from_module) = "network_stack"];
}
// Pulled events will start at field 10000.
@@ -2794,51 +2795,37 @@ message Temperature {
}
/**
- * Logs the latency period(in microseconds) and the return code of
- * the DNS(Domain Name System) lookups.
- * These 4 methods(GETADDRINFO,GETHOSTBYNAME,GETHOSTBYADDR,RES_NSEND)
- * to get info(address or hostname) from DNS server(or DNS cache).
- * Logged from:
- * /system/netd/server/DnsProxyListener.cpp
+ * Logs a DNS lookup operation initiated by the system resolver on behalf of an application
+ * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
+ *
+ * The NetworkDnsEventReported message represents the entire lookup operation, which may
+ * result one or more queries to the recursive DNS resolvers. Those are individually logged
+ * in DnsQueryEvents to enable computing error rates and network latency and timeouts
+ * broken up by query type, transport, network interface, etc.
*/
message NetworkDnsEventReported {
- // The types of the DNS lookups, as defined in
- //system/netd/server/binder/android/net/metrics/INetdEventListener.aidl
- enum EventType {
- EVENT_UNKNOWN = 0;
- EVENT_GETADDRINFO = 1;
- EVENT_GETHOSTBYNAME = 2;
- EVENT_GETHOSTBYADDR = 3;
- EVENT_RES_NSEND = 4;
- }
- optional EventType event_type = 1;
-
- // The return value of the DNS resolver for each DNS lookups.
- //bionic/libc/include/netdb.h
- //system/netd/resolv/include/netd_resolv/resolv.h
- enum ReturnCode {
- EAI_NO_ERROR = 0;
- EAI_ADDRFAMILY = 1;
- EAI_AGAIN = 2;
- EAI_BADFLAGS = 3;
- EAI_FAIL = 4;
- EAI_FAMILY = 5;
- EAI_MEMORY = 6;
- EAI_NODATA = 7;
- EAI_NONAME = 8;
- EAI_SERVICE = 9;
- EAI_SOCKTYPE = 10;
- EAI_SYSTEM = 11;
- EAI_BADHINTS = 12;
- EAI_PROTOCOL = 13;
- EAI_OVERFLOW = 14;
- RESOLV_TIMEOUT = 255;
- EAI_MAX = 256;
- }
- optional ReturnCode return_code = 2;
+ optional android.stats.dnsresolver.EventType event_type = 1;
+
+ optional android.stats.dnsresolver.ReturnCode return_code = 2;
- // The latency period(in microseconds) it took for this DNS lookup to complete.
+ // The latency in microseconds of the entire DNS lookup operation.
optional int32 latency_micros = 3;
+
+ // Only valid for event_type = EVENT_GETADDRINFO.
+ optional int32 hints_ai_flags = 4;
+
+ // Flags passed to android_res_nsend() defined in multinetwork.h
+ // Only valid for event_type = EVENT_RESNSEND.
+ optional int32 res_nsend_flags = 5;
+
+ optional android.stats.dnsresolver.Transport network_type = 6;
+
+ // The DNS over TLS mode on a specific netId.
+ optional android.stats.dnsresolver.PrivateDnsModes private_dns_modes = 7;
+
+ // Additional pass-through fields opaque to statsd.
+ // The DNS resolver Mainline module can add new fields here without requiring an OS update.
+ optional android.stats.dnsresolver.DnsQueryEvents dns_query_events = 8 [(log_mode) = MODE_BYTES];
}
/**
diff --git a/cmds/statsd/src/guardrail/MemoryLeakTrackUtil.cpp b/cmds/statsd/src/guardrail/MemoryLeakTrackUtil.cpp
deleted file mode 100644
index 01c75873fdf9..000000000000
--- a/cmds/statsd/src/guardrail/MemoryLeakTrackUtil.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include <sstream>
-#include "MemoryLeakTrackUtil.h"
-
-/*
- * The code here originally resided in MediaPlayerService.cpp
- */
-
-// Figure out the abi based on defined macros.
-#if defined(__arm__)
-#define ABI_STRING "arm"
-#elif defined(__aarch64__)
-#define ABI_STRING "arm64"
-#elif defined(__mips__) && !defined(__LP64__)
-#define ABI_STRING "mips"
-#elif defined(__mips__) && defined(__LP64__)
-#define ABI_STRING "mips64"
-#elif defined(__i386__)
-#define ABI_STRING "x86"
-#elif defined(__x86_64__)
-#define ABI_STRING "x86_64"
-#else
-#error "Unsupported ABI"
-#endif
-
-extern std::string backtrace_string(const uintptr_t* frames, size_t frame_count);
-
-namespace android {
-namespace os {
-namespace statsd {
-
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, size_t* infoSize,
- size_t* totalMemory, size_t* backtraceSize);
-
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
-std::string dumpMemInfo(size_t limit) {
- uint8_t* info;
- size_t overallSize;
- size_t infoSize;
- size_t totalMemory;
- size_t backtraceSize;
- get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
-
- size_t count;
- if (info == nullptr || overallSize == 0 || infoSize == 0 ||
- (count = overallSize / infoSize) == 0) {
- VLOG("no malloc info, libc.debug.malloc.program property should be set");
- return std::string();
- }
-
- std::ostringstream oss;
- oss << totalMemory << " bytes in " << count << " allocations\n";
- oss << " ABI: '" ABI_STRING "'"
- << "\n\n";
- if (count > limit) count = limit;
-
- // The memory is sorted based on total size which is useful for finding
- // worst memory offenders. For diffs, sometimes it is preferable to sort
- // based on the backtrace.
- for (size_t i = 0; i < count; i++) {
- struct AllocEntry {
- size_t size; // bit 31 is set if this is zygote allocated memory
- size_t allocations;
- uintptr_t backtrace[];
- };
-
- const AllocEntry* const e = (AllocEntry*)(info + i * infoSize);
-
- oss << (e->size * e->allocations) << " bytes ( " << e->size << " bytes * " << e->allocations
- << " allocations )\n";
- oss << backtrace_string(e->backtrace, backtraceSize) << "\n";
- }
- oss << "\n";
- free_malloc_leak_info(info);
- return oss.str();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f453289b4bc5..d9c82ea31537 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1003,9 +1003,8 @@ public final class ActivityThread extends ClientTransactionHandler {
}
public void updateHttpProxy() {
- final ConnectivityManager cm = ConnectivityManager.from(
+ ActivityThread.updateHttpProxy(
getApplication() != null ? getApplication() : getSystemContext());
- Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
}
public void processInBackground() {
@@ -6690,6 +6689,11 @@ public final class ActivityThread extends ClientTransactionHandler {
return thread;
}
+ public static void updateHttpProxy(@NonNull Context context) {
+ final ConnectivityManager cm = ConnectivityManager.from(context);
+ Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
+ }
+
@UnsupportedAppUsage
public final void installSystemProviders(List<ProviderInfo> providers) {
if (providers != null) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 70fa5fa56d58..f6b7eefc7864 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -555,7 +555,7 @@ final class SystemServiceRegistry {
new CachedServiceFetcher<RcsManager>() {
@Override
public RcsManager createService(ContextImpl ctx) {
- return new RcsManager();
+ return new RcsManager(ctx.getOuterContext());
}
});
diff --git a/core/java/android/app/backup/OWNERS b/core/java/android/app/backup/OWNERS
index 1c9a43acfa65..9c21e8fe5e45 100644
--- a/core/java/android/app/backup/OWNERS
+++ b/core/java/android/app/backup/OWNERS
@@ -1,7 +1,9 @@
-artikz@google.com
+alsutton@google.com
+anniemeng@google.com
brufino@google.com
bryanmawhinney@google.com
ctate@google.com
jorlow@google.com
-mkarpinski@google.com
+nathch@google.com
+rthakohov@google.com
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 9faa1d675d8d..e7f2d18ad6a2 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -22,23 +22,16 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
-
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
@@ -209,101 +202,32 @@ public final class BluetoothA2dp implements BluetoothProfile {
@UnsupportedAppUsage
public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
- private Context mContext;
- private ServiceListener mServiceListener;
- private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
- @GuardedBy("mServiceLock")
- private IBluetoothA2dp mService;
private BluetoothAdapter mAdapter;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- try {
- mServiceLock.writeLock().lock();
- if (mService != null) {
- mService = null;
- mContext.unbindService(mConnection);
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.writeLock().unlock();
- }
- } else {
- try {
- mServiceLock.readLock().lock();
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.readLock().unlock();
- }
- }
+ private final BluetoothProfileConnector<IBluetoothA2dp> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.A2DP, "BluetoothA2dp",
+ IBluetoothA2dp.class.getName()) {
+ @Override
+ public IBluetoothA2dp getServiceInterface(IBinder service) {
+ return IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothA2dp proxy object for interacting with the local
* Bluetooth A2DP service.
*/
- /*package*/ BluetoothA2dp(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothA2dp(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothA2dp.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- UserHandle.CURRENT_OR_SELF)) {
- Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
@UnsupportedAppUsage
/*package*/ void close() {
- mServiceListener = null;
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- try {
- mServiceLock.writeLock().lock();
- if (mService != null) {
- mService = null;
- mContext.unbindService(mConnection);
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.writeLock().unlock();
- }
+ private IBluetoothA2dp getService() {
+ return mProfileConnector.getService();
}
@Override
@@ -333,17 +257,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.connect(device);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.connect(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -376,17 +298,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.disconnect(device);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.disconnect(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -397,17 +317,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getConnectedDevices();
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ return service.getConnectedDevices();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -418,17 +336,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getDevicesMatchingConnectionStates(states);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ return service.getDevicesMatchingConnectionStates(states);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -439,18 +355,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -480,18 +394,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) log("setActiveDevice(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& ((device == null) || isValidDevice(device))) {
- return mService.setActiveDevice(device);
+ return service.setActiveDevice(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -511,17 +423,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public BluetoothDevice getActiveDevice() {
if (VDBG) log("getActiveDevice()");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getActiveDevice();
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ return service.getActiveDevice();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return null;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -543,22 +453,20 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -578,18 +486,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getPriority(device);
+ return service.getPriority(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.PRIORITY_OFF;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.PRIORITY_OFF;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -602,17 +508,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean isAvrcpAbsoluteVolumeSupported() {
if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.isAvrcpAbsoluteVolumeSupported();
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ return service.isAvrcpAbsoluteVolumeSupported();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e);
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -625,15 +529,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
public void setAvrcpAbsoluteVolume(int volume) {
if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- mService.setAvrcpAbsoluteVolume(volume);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ service.setAvrcpAbsoluteVolume(volume);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e);
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -646,18 +548,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
public boolean isA2dpPlaying(BluetoothDevice device) {
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.isA2dpPlaying(device);
+ return service.isA2dpPlaying(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -694,19 +594,17 @@ public final class BluetoothA2dp implements BluetoothProfile {
public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getCodecStatus(device);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ return service.getCodecStatus(device);
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return null;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in getCodecStatus()", e);
return null;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -723,17 +621,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
BluetoothCodecConfig codecConfig) {
if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- mService.setCodecConfigPreference(device, codecConfig);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
+ service.setCodecConfigPreference(device, codecConfig);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e);
return;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -772,21 +668,19 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()) {
if (enable) {
- mService.enableOptionalCodecs(device);
+ service.enableOptionalCodecs(device);
} else {
- mService.disableOptionalCodecs(device);
+ service.disableOptionalCodecs(device);
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e);
return;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -801,17 +695,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
@UnsupportedAppUsage
public int supportsOptionalCodecs(BluetoothDevice device) {
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.supportsOptionalCodecs(device);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.supportsOptionalCodecs(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -826,17 +718,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
@UnsupportedAppUsage
public int getOptionalCodecsEnabled(BluetoothDevice device) {
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.getOptionalCodecsEnabled(device);
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.getOptionalCodecsEnabled(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return OPTIONAL_CODECS_PREF_UNKNOWN;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
return OPTIONAL_CODECS_PREF_UNKNOWN;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -858,18 +748,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
return;
}
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ final IBluetoothA2dp service = getService();
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- mService.setOptionalCodecsEnabled(device, value);
+ service.setOptionalCodecsEnabled(device, value);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -900,35 +788,6 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- try {
- mServiceLock.writeLock().lock();
- mService = IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
- } finally {
- mServiceLock.writeLock().unlock();
- }
-
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- try {
- mServiceLock.writeLock().lock();
- mService = null;
- } finally {
- mServiceLock.writeLock().unlock();
- }
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
- }
- }
- };
-
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index fda2f8927535..5a8055a29cfc 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -17,10 +17,7 @@
package android.bluetooth;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -124,93 +121,31 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
public static final String EXTRA_AUDIO_CONFIG =
"android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
- private Context mContext;
- private ServiceListener mServiceListener;
- private volatile IBluetoothA2dpSink mService;
private BluetoothAdapter mAdapter;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private final BluetoothProfileConnector<IBluetoothA2dpSink> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.A2DP_SINK,
+ "BluetoothA2dpSink", IBluetoothA2dpSink.class.getName()) {
+ @Override
+ public IBluetoothA2dpSink getServiceInterface(IBinder service) {
+ return IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothA2dp proxy object for interacting with the local
* Bluetooth A2DP service.
*/
- /*package*/ BluetoothA2dpSink(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothA2dpSink(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothA2dpSink.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
/*package*/ void close() {
- mServiceListener = null;
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private IBluetoothA2dpSink getService() {
+ return mProfileConnector.getService();
}
@Override
@@ -241,7 +176,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.connect(device);
@@ -282,7 +217,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
@UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -301,7 +236,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -320,7 +255,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -339,7 +274,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -365,7 +300,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*/
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
if (VDBG) log("getAudioConfig(" + device + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getAudioConfig(device);
@@ -395,7 +330,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -427,7 +362,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -448,7 +383,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @param device BluetoothDevice device
*/
public boolean isA2dpPlaying(BluetoothDevice device) {
- final IBluetoothA2dpSink service = mService;
+ final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.isA2dpPlaying(device);
@@ -487,25 +422,6 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
}
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK,
- BluetoothA2dpSink.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP_SINK);
- }
- }
- };
-
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index e7c8944788fd..4e7e4415c54d 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -16,10 +16,7 @@
package android.bluetooth;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -79,93 +76,32 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
public static final String EXTRA_PLAYER_SETTING =
"android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";
- private Context mContext;
- private ServiceListener mServiceListener;
- private volatile IBluetoothAvrcpController mService;
private BluetoothAdapter mAdapter;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private final BluetoothProfileConnector<IBluetoothAvrcpController> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.AVRCP_CONTROLLER,
+ "BluetoothAvrcpController", IBluetoothAvrcpController.class.getName()) {
+ @Override
+ public IBluetoothAvrcpController getServiceInterface(IBinder service) {
+ return IBluetoothAvrcpController.Stub.asInterface(
+ Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothAvrcpController proxy object for interacting with the local
* Bluetooth AVRCP service.
*/
- /*package*/ BluetoothAvrcpController(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothAvrcpController(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothAvrcpController.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth AVRCP Controller Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
/*package*/ void close() {
- mServiceListener = null;
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private IBluetoothAvrcpController getService() {
+ return mProfileConnector.getService();
}
@Override
@@ -179,7 +115,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -198,7 +135,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -217,7 +155,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -238,7 +177,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getPlayerSettings");
BluetoothAvrcpPlayerSettings settings = null;
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled()) {
try {
settings = service.getPlayerSettings(device);
@@ -256,7 +196,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
*/
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.setPlayerApplicationSetting(plAppSetting);
@@ -276,7 +217,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+ keyState);
- final IBluetoothAvrcpController service = mService;
+ final IBluetoothAvrcpController service =
+ getService();
if (service != null && isEnabled()) {
try {
service.sendGroupNavigationCmd(device, keyCode, keyState);
@@ -289,25 +231,6 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
if (service == null) Log.w(TAG, "Proxy not attached to service");
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothAvrcpController.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.AVRCP_CONTROLLER,
- BluetoothAvrcpController.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.AVRCP_CONTROLLER);
- }
- }
- };
-
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1e1280105964..34c7372202ee 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -56,7 +56,8 @@ import java.util.UUID;
* returned by {@link BluetoothAdapter#getBondedDevices()
* BluetoothAdapter.getBondedDevices()}. You can then open a
* {@link BluetoothSocket} for communication with the remote device, using
- * {@link #createRfcommSocketToServiceRecord(UUID)}.
+ * {@link #createRfcommSocketToServiceRecord(UUID)} over Bluetooth BR/EDR or using
+ * {@link #createL2capChannel(int)} over Bluetooth LE.
*
* <p class="note"><strong>Note:</strong>
* Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8d9d340ee68b..9862a63ef238 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -337,19 +337,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
doUnbind();
} else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
+ doBind();
}
}
};
@@ -374,24 +364,32 @@ public final class BluetoothHeadset implements BluetoothProfile {
doBind();
}
- boolean doBind() {
- try {
- return mAdapter.getBluetoothManager().bindBluetoothProfileService(
- BluetoothProfile.HEADSET, mConnection);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to bind HeadsetService", e);
+ private boolean doBind() {
+ synchronized (mConnection) {
+ if (mService == null) {
+ if (VDBG) Log.d(TAG, "Binding service...");
+ try {
+ return mAdapter.getBluetoothManager().bindBluetoothProfileService(
+ BluetoothProfile.HEADSET, mConnection);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to bind HeadsetService", e);
+ }
+ }
}
return false;
}
- void doUnbind() {
+ private void doUnbind() {
synchronized (mConnection) {
if (mService != null) {
+ if (VDBG) Log.d(TAG, "Unbinding service...");
try {
mAdapter.getBluetoothManager().unbindBluetoothProfileService(
BluetoothProfile.HEADSET, mConnection);
} catch (RemoteException e) {
Log.e(TAG, "Unable to unbind HeadsetService", e);
+ } finally {
+ mService = null;
}
}
}
@@ -411,8 +409,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (mgr != null) {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
+ } catch (RemoteException re) {
+ Log.e(TAG, "", re);
}
}
mServiceListener = null;
@@ -1169,7 +1167,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
@Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
+ doUnbind();
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_HEADSET_SERVICE_DISCONNECTED));
}
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index ec18d42698c1..05833b5f571d 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -17,10 +17,7 @@
package android.bluetooth;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -366,73 +363,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
public static final int CALL_ACCEPT_HOLD = 1;
public static final int CALL_ACCEPT_TERMINATE = 2;
- private Context mContext;
- private ServiceListener mServiceListener;
- private volatile IBluetoothHeadsetClient mService;
private BluetoothAdapter mAdapter;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
+ private final BluetoothProfileConnector<IBluetoothHeadsetClient> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.HEADSET_CLIENT,
+ "BluetoothHeadsetClient", IBluetoothHeadsetClient.class.getName()) {
@Override
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- Intent intent = new Intent(
- IBluetoothHeadsetClient.class.getName());
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ public IBluetoothHeadsetClient getServiceInterface(IBinder service) {
+ return IBluetoothHeadsetClient.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothHeadsetClient proxy object.
*/
- /*package*/ BluetoothHeadsetClient(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothHeadsetClient(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
-
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothHeadsetClient.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
/**
@@ -443,27 +389,11 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
/*package*/ void close() {
if (VDBG) log("close()");
+ mProfileConnector.disconnect();
+ }
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
-
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothHeadsetClient getService() {
+ return mProfileConnector.getService();
}
/**
@@ -480,7 +410,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@UnsupportedAppUsage
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.connect(device);
@@ -503,7 +434,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -524,7 +456,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -547,7 +480,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -569,7 +503,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -589,7 +524,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -611,7 +547,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -637,7 +574,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.startVoiceRecognition(device);
@@ -662,7 +600,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.stopVoiceRecognition(device);
@@ -682,7 +621,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getCurrentCalls(device);
@@ -702,7 +642,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public Bundle getCurrentAgEvents(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getCurrentAgEvents(device);
@@ -726,7 +667,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@UnsupportedAppUsage
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.acceptCall(device, flag);
@@ -747,7 +689,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean holdCall(BluetoothDevice device) {
if (DBG) log("holdCall()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.holdCall(device);
@@ -773,7 +716,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@UnsupportedAppUsage
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.rejectCall(device);
@@ -803,7 +747,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
if (DBG) log("terminateCall()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.terminateCall(device, call);
@@ -831,7 +776,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean enterPrivateMode(BluetoothDevice device, int index) {
if (DBG) log("enterPrivateMode()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.enterPrivateMode(device, index);
@@ -858,7 +804,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean explicitCallTransfer(BluetoothDevice device) {
if (DBG) log("explicitCallTransfer()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.explicitCallTransfer(device);
@@ -881,7 +828,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
if (DBG) log("dial()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.dial(device, number);
@@ -905,7 +853,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean sendDTMF(BluetoothDevice device, byte code) {
if (DBG) log("sendDTMF()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.sendDTMF(device, code);
@@ -931,7 +880,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
if (DBG) log("getLastVoiceTagNumber()");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getLastVoiceTagNumber(device);
@@ -951,7 +901,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@UnsupportedAppUsage
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getAudioState(device);
@@ -974,7 +925,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
service.setAudioRouteAllowed(device, allowed);
@@ -996,7 +948,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
*/
public boolean getAudioRouteAllowed(BluetoothDevice device) {
if (VDBG) log("getAudioRouteAllowed");
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getAudioRouteAllowed(device);
@@ -1020,7 +973,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
public boolean connectAudio(BluetoothDevice device) {
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.connectAudio(device);
@@ -1044,7 +998,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
public boolean disconnectAudio(BluetoothDevice device) {
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.disconnectAudio(device);
@@ -1065,7 +1020,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @return bundle of AG features; null if no service or AG not connected
*/
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
- final IBluetoothHeadsetClient service = mService;
+ final IBluetoothHeadsetClient service =
+ getService();
if (service != null && isEnabled()) {
try {
return service.getCurrentAgFeatures(device);
@@ -1079,29 +1035,6 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
return null;
}
-
- private final ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothHeadsetClient.Stub.asInterface(Binder.allowBlocking(service));
-
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT,
- BluetoothHeadsetClient.this);
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET_CLIENT);
- }
- }
- };
-
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 58ff2e14fd50..60fb6fb122e3 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -22,20 +22,14 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
-
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* This class provides the public APIs to control the Hearing Aid profile.
@@ -128,97 +122,31 @@ public final class BluetoothHearingAid implements BluetoothProfile {
*/
public static final long HI_SYNC_ID_INVALID = IBluetoothHearingAid.HI_SYNC_ID_INVALID;
- private Context mContext;
- private ServiceListener mServiceListener;
- private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
- @GuardedBy("mServiceLock")
- private IBluetoothHearingAid mService;
private BluetoothAdapter mAdapter;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- try {
- mServiceLock.writeLock().lock();
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.writeLock().unlock();
- }
- } else {
- try {
- mServiceLock.readLock().lock();
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.readLock().unlock();
- }
- }
+ private final BluetoothProfileConnector<IBluetoothHearingAid> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.HEARING_AID,
+ "BluetoothHearingAid", IBluetoothHearingAid.class.getName()) {
+ @Override
+ public IBluetoothHearingAid getServiceInterface(IBinder service) {
+ return IBluetoothHearingAid.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothHearingAid proxy object for interacting with the local
* Bluetooth Hearing Aid service.
*/
- /*package*/ BluetoothHearingAid(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothHearingAid(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- void doBind() {
- Intent intent = new Intent(IBluetoothHearingAid.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- android.os.Process.myUserHandle())) {
- Log.e(TAG, "Could not bind to Bluetooth Hearing Aid Service with " + intent);
- return;
- }
+ mProfileConnector.connect(context, listener);
}
/*package*/ void close() {
- mServiceListener = null;
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- try {
- mServiceLock.writeLock().lock();
- if (mService != null) {
- mService = null;
- mContext.unbindService(mConnection);
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- } finally {
- mServiceLock.writeLock().unlock();
- }
+ private IBluetoothHearingAid getService() {
+ return mProfileConnector.getService();
}
/**
@@ -240,18 +168,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.connect(device);
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.connect(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -282,18 +208,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled() && isValidDevice(device)) {
- return mService.disconnect(device);
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ return service.disconnect(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -303,18 +227,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
@Override
public @NonNull List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getConnectedDevices();
+ if (service != null && isEnabled()) {
+ return service.getConnectedDevices();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -325,18 +247,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
@NonNull int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getDevicesMatchingConnectionStates(states);
+ if (service != null && isEnabled()) {
+ return service.getDevicesMatchingConnectionStates(states);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -347,19 +267,17 @@ public final class BluetoothHearingAid implements BluetoothProfile {
public @BluetoothProfile.BtProfileState int getConnectionState(
@NonNull BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -387,20 +305,18 @@ public final class BluetoothHearingAid implements BluetoothProfile {
*/
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) log("setActiveDevice(" + device + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& ((device == null) || isValidDevice(device))) {
- mService.setActiveDevice(device);
+ service.setActiveDevice(device);
return true;
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -418,18 +334,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
@RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getActiveDevices() {
if (VDBG) log("getActiveDevices()");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getActiveDevices();
+ if (service != null && isEnabled()) {
+ return service.getActiveDevices();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<>();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<>();
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -450,23 +364,21 @@ public final class BluetoothHearingAid implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -484,19 +396,17 @@ public final class BluetoothHearingAid implements BluetoothProfile {
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getPriority(device);
+ return service.getPriority(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.PRIORITY_OFF;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.PRIORITY_OFF;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -535,18 +445,16 @@ public final class BluetoothHearingAid implements BluetoothProfile {
if (VDBG) {
log("getVolume()");
}
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()) {
- return mService.getVolume();
+ if (service != null && isEnabled()) {
+ return service.getVolume();
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return 0;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return 0;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -566,21 +474,18 @@ public final class BluetoothHearingAid implements BluetoothProfile {
public void adjustVolume(int direction) {
if (DBG) log("adjustVolume(" + direction + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
-
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
return;
}
if (!isEnabled()) return;
- mService.adjustVolume(direction);
+ service.adjustVolume(direction);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -593,20 +498,18 @@ public final class BluetoothHearingAid implements BluetoothProfile {
public void setVolume(int volume) {
if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
return;
}
if (!isEnabled()) return;
- mService.setVolume(volume);
+ service.setVolume(volume);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -622,21 +525,19 @@ public final class BluetoothHearingAid implements BluetoothProfile {
if (VDBG) {
log("getCustomerId(" + device + ")");
}
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
return HI_SYNC_ID_INVALID;
}
if (!isEnabled() || !isValidDevice(device)) return HI_SYNC_ID_INVALID;
- return mService.getHiSyncId(device);
+ return service.getHiSyncId(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return HI_SYNC_ID_INVALID;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -652,19 +553,17 @@ public final class BluetoothHearingAid implements BluetoothProfile {
if (VDBG) {
log("getDeviceSide(" + device + ")");
}
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getDeviceSide(device);
+ return service.getDeviceSide(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return SIDE_LEFT;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return SIDE_LEFT;
- } finally {
- mServiceLock.readLock().unlock();
}
}
@@ -680,52 +579,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
if (VDBG) {
log("getDeviceMode(" + device + ")");
}
+ final IBluetoothHearingAid service = getService();
try {
- mServiceLock.readLock().lock();
- if (mService != null && isEnabled()
+ if (service != null && isEnabled()
&& isValidDevice(device)) {
- return mService.getDeviceMode(device);
+ return service.getDeviceMode(device);
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return MODE_MONAURAL;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return MODE_MONAURAL;
- } finally {
- mServiceLock.readLock().unlock();
}
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- try {
- mServiceLock.writeLock().lock();
- mService = IBluetoothHearingAid.Stub.asInterface(Binder.allowBlocking(service));
- } finally {
- mServiceLock.writeLock().unlock();
- }
-
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.HEARING_AID,
- BluetoothHearingAid.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- try {
- mServiceLock.writeLock().lock();
- mService = null;
- } finally {
- mServiceLock.writeLock().unlock();
- }
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HEARING_AID);
- }
- }
- };
-
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index 3bc8544ebf87..e9b0be2c4cd6 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -18,10 +18,8 @@ package android.bluetooth;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -327,11 +325,6 @@ public final class BluetoothHidDevice implements BluetoothProfile {
}
}
- private Context mContext;
- private ServiceListener mServiceListener;
- private volatile IBluetoothHidDevice mService;
- private BluetoothAdapter mAdapter;
-
private static class CallbackWrapper extends IBluetoothHidDeviceCallback.Stub {
private final Executor mExecutor;
@@ -385,114 +378,33 @@ public final class BluetoothHidDevice implements BluetoothProfile {
}
}
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
-
- public void onBluetoothStateChange(boolean up) {
- Log.d(TAG, "onBluetoothStateChange: up=" + up);
- synchronized (mConnection) {
- if (up) {
- try {
- if (mService == null) {
- Log.d(TAG, "Binding HID Device service...");
- doBind();
- }
- } catch (IllegalStateException e) {
- Log.e(TAG, "onBluetoothStateChange: could not bind to HID Dev "
- + "service: ", e);
- } catch (SecurityException e) {
- Log.e(TAG, "onBluetoothStateChange: could not bind to HID Dev "
- + "service: ", e);
- }
- } else {
- Log.d(TAG, "Unbinding service...");
- doUnbind();
- }
- }
- }
- };
-
- private final ServiceConnection mConnection =
- new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "onServiceConnected()");
- mService = IBluetoothHidDevice.Stub.asInterface(service);
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(
- BluetoothProfile.HID_DEVICE, BluetoothHidDevice.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "onServiceDisconnected()");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HID_DEVICE);
- }
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothHidDevice> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.HID_DEVICE,
+ "BluetoothHidDevice", IBluetoothHidDevice.class.getName()) {
+ @Override
+ public IBluetoothHidDevice getServiceInterface(IBinder service) {
+ return IBluetoothHidDevice.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
BluetoothHidDevice(Context context, ServiceListener listener) {
- mContext = context;
- mServiceListener = listener;
mAdapter = BluetoothAdapter.getDefaultAdapter();
-
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothHidDevice.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent);
- return false;
- }
- Log.d(TAG, "Bound to HID Device Service");
- return true;
- }
-
- void doUnbind() {
- if (mService != null) {
- mService = null;
- try {
- mContext.unbindService(mConnection);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Unable to unbind HidDevService", e);
- }
- }
+ mProfileConnector.connect(context, listener);
}
void close() {
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- doUnbind();
- }
- mServiceListener = null;
+ private IBluetoothHidDevice getService() {
+ return mProfileConnector.getService();
}
/** {@inheritDoc} */
@Override
public List<BluetoothDevice> getConnectedDevices() {
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
return service.getConnectedDevices();
@@ -509,7 +421,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
/** {@inheritDoc} */
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -526,7 +438,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
/** {@inheritDoc} */
@Override
public int getConnectionState(BluetoothDevice device) {
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
return service.getConnectionState(device);
@@ -583,7 +495,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
throw new IllegalArgumentException("callback parameter cannot be null");
}
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
CallbackWrapper cbw = new CallbackWrapper(executor, callback);
@@ -611,7 +523,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean unregisterApp() {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.unregisterApp();
@@ -636,7 +548,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.sendReport(device, id, data);
@@ -662,7 +574,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.replyReport(device, type, id, data);
@@ -686,7 +598,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean reportError(BluetoothDevice device, byte error) {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.reportError(device, error);
@@ -707,7 +619,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
* {@hide}
*/
public String getUserAppName() {
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
@@ -733,7 +645,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean connect(BluetoothDevice device) {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.connect(device);
@@ -757,7 +669,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
public boolean disconnect(BluetoothDevice device) {
boolean result = false;
- final IBluetoothHidDevice service = mService;
+ final IBluetoothHidDevice service = getService();
if (service != null) {
try {
result = service.disconnect(device);
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index 289e769a99ef..4afb382c0660 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -18,10 +18,7 @@ package android.bluetooth;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -219,97 +216,32 @@ public final class BluetoothHidHost implements BluetoothProfile {
public static final String EXTRA_IDLE_TIME =
"android.bluetooth.BluetoothHidHost.extra.IDLE_TIME";
- private Context mContext;
- private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
- private volatile IBluetoothHidHost mService;
-
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- if (mService != null) {
- mService = null;
- mContext.unbindService(mConnection);
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private final BluetoothProfileConnector<IBluetoothHidHost> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.HID_HOST,
+ "BluetoothHidHost", IBluetoothHidHost.class.getName()) {
+ @Override
+ public IBluetoothHidHost getServiceInterface(IBinder service) {
+ return IBluetoothHidHost.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothHidHost proxy object for interacting with the local
* Bluetooth Service which handles the InputDevice profile
*/
- /*package*/ BluetoothHidHost(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothHidHost(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
-
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
-
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothHidHost.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
/*package*/ void close() {
if (VDBG) log("close()");
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothHidHost getService() {
+ return mProfileConnector.getService();
}
/**
@@ -333,7 +265,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.connect(device);
@@ -373,7 +305,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -392,7 +324,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -411,7 +343,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -430,7 +362,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -460,7 +392,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -492,7 +424,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -505,26 +437,6 @@ public final class BluetoothHidHost implements BluetoothProfile {
return BluetoothProfile.PRIORITY_OFF;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothHidHost.Stub.asInterface(Binder.allowBlocking(service));
-
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.HID_HOST,
- BluetoothHidHost.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HID_HOST);
- }
- }
- };
-
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
@@ -544,7 +456,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean virtualUnplug(BluetoothDevice device) {
if (DBG) log("virtualUnplug(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.virtualUnplug(device);
@@ -570,7 +482,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean getProtocolMode(BluetoothDevice device) {
if (VDBG) log("getProtocolMode(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getProtocolMode(device);
@@ -594,7 +506,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
if (DBG) log("setProtocolMode(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.setProtocolMode(device, protocolMode);
@@ -625,7 +537,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
+ "bufferSize=" + bufferSize);
}
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getReport(device, reportType, reportId, bufferSize);
@@ -651,7 +563,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.setReport(device, reportType, report);
@@ -676,7 +588,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean sendData(BluetoothDevice device, String report) {
if (DBG) log("sendData(" + device + "), report=" + report);
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.sendData(device, report);
@@ -700,7 +612,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean getIdleTime(BluetoothDevice device) {
if (DBG) log("getIdletime(" + device + ")");
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getIdleTime(device);
@@ -725,7 +637,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
*/
public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
- final IBluetoothHidHost service = mService;
+ final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.setIdleTime(device, idleTime);
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 98c23c600f14..dd2f150ad4eb 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -17,10 +17,7 @@
package android.bluetooth;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -44,11 +41,6 @@ public final class BluetoothMap implements BluetoothProfile {
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
- private volatile IBluetoothMap mService;
- private final Context mContext;
- private ServiceListener mServiceListener;
- private BluetoothAdapter mAdapter;
-
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
@@ -57,64 +49,23 @@ public final class BluetoothMap implements BluetoothProfile {
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothMap> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.MAP,
+ "BluetoothMap", IBluetoothMap.class.getName()) {
+ @Override
+ public IBluetoothMap getServiceInterface(IBinder service) {
+ return IBluetoothMap.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothMap proxy object.
*/
- /*package*/ BluetoothMap(Context context, ServiceListener l) {
+ /*package*/ BluetoothMap(Context context, ServiceListener listener) {
if (DBG) Log.d(TAG, "Create BluetoothMap proxy object");
- mContext = context;
- mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothMap.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
protected void finalize() throws Throwable {
@@ -132,26 +83,11 @@ public final class BluetoothMap implements BluetoothProfile {
* are ok.
*/
public synchronized void close() {
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothMap getService() {
+ return mProfileConnector.getService();
}
/**
@@ -162,7 +98,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public int getState() {
if (VDBG) log("getState()");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null) {
try {
return service.getState();
@@ -184,7 +120,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null) {
try {
return service.getClient();
@@ -205,7 +141,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null) {
try {
return service.isConnected(device);
@@ -237,7 +173,7 @@ public final class BluetoothMap implements BluetoothProfile {
@UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -278,7 +214,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -298,7 +234,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -318,7 +254,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -344,7 +280,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -373,7 +309,7 @@ public final class BluetoothMap implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- final IBluetoothMap service = mService;
+ final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -386,24 +322,6 @@ public final class BluetoothMap implements BluetoothProfile {
return PRIORITY_OFF;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) log("Proxy object connected");
- mService = IBluetoothMap.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) log("Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.MAP);
- }
- }
- };
-
private static void log(String msg) {
Log.d(TAG, msg);
}
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 559a59b68b4e..ec0180c5adde 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -18,11 +18,9 @@ package android.bluetooth;
import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.net.Uri;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -60,11 +58,6 @@ public final class BluetoothMapClient implements BluetoothProfile {
public static final String EXTRA_SENDER_CONTACT_NAME =
"android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
- private volatile IBluetoothMapClient mService;
- private final Context mContext;
- private ServiceListener mServiceListener;
- private BluetoothAdapter mAdapter;
-
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
@@ -75,64 +68,23 @@ public final class BluetoothMapClient implements BluetoothProfile {
private static final int UPLOADING_FEATURE_BITMASK = 0x08;
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothMapClient> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.MAP_CLIENT,
+ "BluetoothMapClient", IBluetoothMapClient.class.getName()) {
+ @Override
+ public IBluetoothMapClient getServiceInterface(IBinder service) {
+ return IBluetoothMapClient.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothMapClient proxy object.
*/
- /*package*/ BluetoothMapClient(Context context, ServiceListener l) {
+ /*package*/ BluetoothMapClient(Context context, ServiceListener listener) {
if (DBG) Log.d(TAG, "Create BluetoothMapClient proxy object");
- mContext = context;
- mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothMapClient.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth MAP MCE Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
protected void finalize() throws Throwable {
@@ -150,26 +102,11 @@ public final class BluetoothMapClient implements BluetoothProfile {
* are ok.
*/
public void close() {
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothMapClient getService() {
+ return mProfileConnector.getService();
}
/**
@@ -179,7 +116,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null) {
try {
return service.isConnected(device);
@@ -199,7 +136,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean connect(BluetoothDevice device) {
if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null) {
try {
return service.connect(device);
@@ -221,7 +158,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) Log.d(TAG, "disconnect(" + device + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -241,7 +178,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) Log.d(TAG, "getConnectedDevices()");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -262,7 +199,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -283,7 +220,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -307,7 +244,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -336,7 +273,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -365,7 +302,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
PendingIntent sentIntent, PendingIntent deliveredIntent) {
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
@@ -385,7 +322,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
*/
public boolean getUnreadMessages(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
- final IBluetoothMapClient service = mService;
+ final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getUnreadMessages(device);
@@ -405,34 +342,16 @@ public final class BluetoothMapClient implements BluetoothProfile {
* MapSupportedFeatures field is set. False is returned otherwise.
*/
public boolean isUploadingSupported(BluetoothDevice device) {
+ final IBluetoothMapClient service = getService();
try {
- return (mService != null && isEnabled() && isValidDevice(device))
- && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0);
+ return (service != null && isEnabled() && isValidDevice(device))
+ && ((service.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0);
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
}
return false;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothMapClient.Stub.asInterface(service);
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT,
- BluetoothMapClient.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.MAP_CLIENT);
- }
- }
- };
-
private boolean isEnabled() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true;
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 58be73296027..fb78789ba8ad 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -19,10 +19,7 @@ package android.bluetooth;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -121,108 +118,42 @@ public final class BluetoothPan implements BluetoothProfile {
*/
public static final int PAN_OPERATION_SUCCESS = 1004;
- private Context mContext;
- private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
- private volatile IBluetoothPan mPanService;
+ private final BluetoothProfileConnector<IBluetoothPan> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.PAN,
+ "BluetoothPan", IBluetoothPan.class.getName()) {
+ @Override
+ public IBluetoothPan getServiceInterface(IBinder service) {
+ return IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
+ }
+ };
+
/**
* Create a BluetoothPan proxy object for interacting with the local
* Bluetooth Service which handles the Pan profile
*/
@UnsupportedAppUsage
- /*package*/ BluetoothPan(Context context, ServiceListener l) {
- mContext = context;
- mServiceListener = l;
+ /*package*/ BluetoothPan(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
- try {
- mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback);
- } catch (RemoteException re) {
- Log.w(TAG, "Unable to register BluetoothStateChangeCallback", re);
- }
- if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
- doBind();
- }
-
- @UnsupportedAppUsage
- boolean doBind() {
- Intent intent = new Intent(IBluetoothPan.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
@UnsupportedAppUsage
/*package*/ void close() {
if (VDBG) log("close()");
+ mProfileConnector.disconnect();
+ }
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mStateChangeCallback);
- } catch (RemoteException re) {
- Log.w(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
- }
- }
-
- synchronized (mConnection) {
- if (mPanService != null) {
- try {
- mPanService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothPan getService() {
+ return mProfileConnector.getService();
}
+
protected void finalize() {
close();
}
- private final IBluetoothStateChangeCallback mStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
-
- @Override
- public void onBluetoothStateChange(boolean on) {
- // Handle enable request to bind again.
- Log.d(TAG, "onBluetoothStateChange on: " + on);
- if (on) {
- try {
- if (mPanService == null) {
- if (VDBG) Log.d(TAG, "onBluetoothStateChange calling doBind()");
- doBind();
- }
-
- } catch (IllegalStateException e) {
- Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
- e);
-
- } catch (SecurityException e) {
- Log.e(TAG, "onBluetoothStateChange: could not bind to PAN service: ",
- e);
- }
- } else {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mPanService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- }
- };
-
/**
* Initiate connection to a profile of the remote bluetooth device.
*
@@ -243,7 +174,7 @@ public final class BluetoothPan implements BluetoothProfile {
@UnsupportedAppUsage
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.connect(device);
@@ -284,7 +215,7 @@ public final class BluetoothPan implements BluetoothProfile {
@UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -303,7 +234,7 @@ public final class BluetoothPan implements BluetoothProfile {
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -322,7 +253,7 @@ public final class BluetoothPan implements BluetoothProfile {
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -341,7 +272,7 @@ public final class BluetoothPan implements BluetoothProfile {
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -357,7 +288,7 @@ public final class BluetoothPan implements BluetoothProfile {
@UnsupportedAppUsage
public void setBluetoothTethering(boolean value) {
if (DBG) log("setBluetoothTethering(" + value + ")");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
service.setBluetoothTethering(value);
@@ -370,7 +301,7 @@ public final class BluetoothPan implements BluetoothProfile {
@UnsupportedAppUsage
public boolean isTetheringOn() {
if (VDBG) log("isTetheringOn()");
- final IBluetoothPan service = mPanService;
+ final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
return service.isTetheringOn();
@@ -381,25 +312,6 @@ public final class BluetoothPan implements BluetoothProfile {
return false;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
- mPanService = IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.PAN,
- BluetoothPan.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) Log.d(TAG, "BluetoothPAN Proxy object disconnected");
- mPanService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.PAN);
- }
- }
- };
-
@UnsupportedAppUsage
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index b303c34ee0ae..d94c65742e6c 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.util.ArrayList;
@@ -117,28 +118,9 @@ public class BluetoothPbap implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
log("onBluetoothStateChange: up=" + up);
if (!up) {
- log("Unbinding service...");
- synchronized (mConnection) {
- try {
- if (mService != null) {
- mService = null;
- mContext.unbindService(mConnection);
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
+ doUnbind();
} else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- log("Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
+ doBind();
}
}
};
@@ -154,25 +136,51 @@ public class BluetoothPbap implements BluetoothProfile {
if (mgr != null) {
try {
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
+ } catch (RemoteException re) {
+ Log.e(TAG, "", re);
}
}
doBind();
}
boolean doBind() {
- Intent intent = new Intent(IBluetoothPbap.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
- return false;
+ synchronized (mConnection) {
+ try {
+ if (mService == null) {
+ log("Binding service...");
+ Intent intent = new Intent(IBluetoothPbap.class.getName());
+ ComponentName comp = intent.resolveSystemService(
+ mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+ UserHandle.CURRENT_OR_SELF)) {
+ Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
+ return false;
+ }
+ }
+ } catch (SecurityException se) {
+ Log.e(TAG, "", se);
+ return false;
+ }
}
return true;
}
+ private void doUnbind() {
+ synchronized (mConnection) {
+ if (mService != null) {
+ log("Unbinding service...");
+ try {
+ mContext.unbindService(mConnection);
+ } catch (IllegalArgumentException ie) {
+ Log.e(TAG, "", ie);
+ } finally {
+ mService = null;
+ }
+ }
+ }
+ }
+
protected void finalize() throws Throwable {
try {
close();
@@ -192,21 +200,11 @@ public class BluetoothPbap implements BluetoothProfile {
if (mgr != null) {
try {
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
-
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
+ } catch (RemoteException re) {
+ Log.e(TAG, "", re);
}
}
+ doUnbind();
mServiceListener = null;
}
@@ -312,7 +310,7 @@ public class BluetoothPbap implements BluetoothProfile {
public void onServiceDisconnected(ComponentName className) {
log("Proxy object disconnected");
- mService = null;
+ doUnbind();
if (mServiceListener != null) {
mServiceListener.onServiceDisconnected();
}
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 1446adc8b9c3..d70e1e7f3f5f 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -16,10 +16,7 @@
package android.bluetooth;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -42,11 +39,6 @@ public final class BluetoothPbapClient implements BluetoothProfile {
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED";
- private volatile IBluetoothPbapClient mService;
- private final Context mContext;
- private ServiceListener mServiceListener;
- private BluetoothAdapter mAdapter;
-
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
@@ -55,72 +47,25 @@ public final class BluetoothPbapClient implements BluetoothProfile {
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) {
- Log.d(TAG, "onBluetoothStateChange: PBAP CLIENT up=" + up);
- }
- if (!up) {
- if (VDBG) {
- Log.d(TAG, "Unbinding service...");
- }
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) {
- Log.d(TAG, "Binding service...");
- }
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothPbapClient> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.PBAP_CLIENT,
+ "BluetoothPbapClient", IBluetoothPbapClient.class.getName()) {
+ @Override
+ public IBluetoothPbapClient getServiceInterface(IBinder service) {
+ return IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothPbapClient proxy object.
*/
- BluetoothPbapClient(Context context, ServiceListener l) {
+ BluetoothPbapClient(Context context, ServiceListener listener) {
if (DBG) {
Log.d(TAG, "Create BluetoothPbapClient proxy object");
}
- mContext = context;
- mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- doBind();
- }
-
- private boolean doBind() {
- Intent intent = new Intent(IBluetoothPbapClient.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth PBAP Client Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
protected void finalize() throws Throwable {
@@ -138,26 +83,11 @@ public final class BluetoothPbapClient implements BluetoothProfile {
* are ok.
*/
public synchronized void close() {
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothPbapClient getService() {
+ return mProfileConnector.getService();
}
/**
@@ -173,7 +103,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("connect(" + device + ") for PBAP Client.");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.connect(device);
@@ -198,7 +128,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("disconnect(" + device + ")" + new Exception());
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
service.disconnect(device);
@@ -225,7 +155,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("getConnectedDevices()");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -250,7 +180,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("getDevicesMatchingStates()");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -275,7 +205,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("getConnectionState(" + device + ")");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -290,29 +220,6 @@ public final class BluetoothPbapClient implements BluetoothProfile {
return BluetoothProfile.STATE_DISCONNECTED;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) {
- log("Proxy object connected");
- }
- mService = IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT,
- BluetoothPbapClient.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) {
- log("Proxy object disconnected");
- }
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.PBAP_CLIENT);
- }
- }
- };
-
private static void log(String msg) {
Log.d(TAG, msg);
}
@@ -345,7 +252,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("setPriority(" + device + ", " + priority + ")");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -378,7 +285,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (VDBG) {
log("getPriority(" + device + ")");
}
- final IBluetoothPbapClient service = mService;
+ final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
diff --git a/core/java/android/bluetooth/BluetoothProfileConnector.java b/core/java/android/bluetooth/BluetoothProfileConnector.java
new file mode 100644
index 000000000000..d9987249a6e2
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothProfileConnector.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+/**
+ * Connector for Bluetooth profile proxies to bind manager service and
+ * profile services
+ * @param <T> The Bluetooth profile interface for this connection.
+ * @hide
+ */
+public abstract class BluetoothProfileConnector<T> {
+ private int mProfileId;
+ private BluetoothProfile.ServiceListener mServiceListener;
+ private BluetoothProfile mProfileProxy;
+ private Context mContext;
+ private String mProfileName;
+ private String mServiceName;
+ private volatile T mService;
+
+ private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+ new IBluetoothStateChangeCallback.Stub() {
+ public void onBluetoothStateChange(boolean up) {
+ if (up) {
+ doBind();
+ } else {
+ doUnbind();
+ }
+ }
+ };
+
+ private final ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ logDebug("Proxy object connected");
+ mService = getServiceInterface(service);
+
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(mProfileId, mProfileProxy);
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ logDebug("Proxy object disconnected");
+ doUnbind();
+ if (mServiceListener != null) {
+ mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
+ }
+ }
+ };
+
+ BluetoothProfileConnector(BluetoothProfile profile, int profileId, String profileName,
+ String serviceName) {
+ mProfileId = profileId;
+ mProfileProxy = profile;
+ mProfileName = profileName;
+ mServiceName = serviceName;
+ }
+
+ private boolean doBind() {
+ synchronized (mConnection) {
+ if (mService == null) {
+ logDebug("Binding service...");
+ try {
+ Intent intent = new Intent(mServiceName);
+ ComponentName comp = intent.resolveSystemService(
+ mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+ UserHandle.CURRENT_OR_SELF)) {
+ logError("Could not bind to Bluetooth Service with " + intent);
+ return false;
+ }
+ } catch (SecurityException se) {
+ logError("Failed to bind service. " + se);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private void doUnbind() {
+ synchronized (mConnection) {
+ if (mService != null) {
+ logDebug("Unbinding service...");
+ try {
+ mContext.unbindService(mConnection);
+ } catch (IllegalArgumentException ie) {
+ logError("Unable to unbind service: " + ie);
+ } finally {
+ mService = null;
+ }
+ }
+ }
+ }
+
+ void connect(Context context, BluetoothProfile.ServiceListener listener) {
+ mContext = context;
+ mServiceListener = listener;
+ IBluetoothManager mgr = BluetoothAdapter.getDefaultAdapter().getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException re) {
+ logError("Failed to register state change callback. " + re);
+ }
+ }
+ doBind();
+ }
+
+ void disconnect() {
+ mServiceListener = null;
+ IBluetoothManager mgr = BluetoothAdapter.getDefaultAdapter().getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException re) {
+ logError("Failed to unregister state change callback" + re);
+ }
+ }
+ doUnbind();
+ }
+
+ T getService() {
+ return mService;
+ }
+
+ /**
+ * This abstract function is used to implement method to get the
+ * connected Bluetooth service interface.
+ * @param service the connected binder service.
+ * @return T the binder interface of {@code service}.
+ * @hide
+ */
+ public abstract T getServiceInterface(IBinder service);
+
+ private void logDebug(String log) {
+ Log.d(mProfileName, log);
+ }
+
+ private void logError(String log) {
+ Log.e(mProfileName, log);
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 1b732062f614..e0610c890559 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -17,10 +17,7 @@
package android.bluetooth;
import android.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -69,11 +66,6 @@ public final class BluetoothSap implements BluetoothProfile {
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
- private volatile IBluetoothSap mService;
- private final Context mContext;
- private ServiceListener mServiceListener;
- private BluetoothAdapter mAdapter;
-
/**
* There was an error trying to obtain the state.
*
@@ -95,64 +87,23 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public static final int RESULT_CANCELED = 2;
- private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
- new IBluetoothStateChangeCallback.Stub() {
- public void onBluetoothStateChange(boolean up) {
- if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
- if (!up) {
- if (VDBG) Log.d(TAG, "Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- } else {
- synchronized (mConnection) {
- try {
- if (mService == null) {
- if (VDBG) Log.d(TAG, "Binding service...");
- doBind();
- }
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothSap> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.SAP,
+ "BluetoothSap", IBluetoothSap.class.getName()) {
+ @Override
+ public IBluetoothSap getServiceInterface(IBinder service) {
+ return IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
}
- };
+ };
/**
* Create a BluetoothSap proxy object.
*/
- /*package*/ BluetoothSap(Context context, ServiceListener l) {
+ /*package*/ BluetoothSap(Context context, ServiceListener listener) {
if (DBG) Log.d(TAG, "Create BluetoothSap proxy object");
- mContext = context;
- mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- doBind();
- }
-
- boolean doBind() {
- Intent intent = new Intent(IBluetoothSap.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- mContext.getUser())) {
- Log.e(TAG, "Could not bind to Bluetooth SAP Service with " + intent);
- return false;
- }
- return true;
+ mProfileConnector.connect(context, listener);
}
protected void finalize() throws Throwable {
@@ -172,26 +123,11 @@ public final class BluetoothSap implements BluetoothProfile {
* @hide
*/
public synchronized void close() {
- IBluetoothManager mgr = mAdapter.getBluetoothManager();
- if (mgr != null) {
- try {
- mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
+ mProfileConnector.disconnect();
+ }
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG, "", re);
- }
- }
- }
- mServiceListener = null;
+ private IBluetoothSap getService() {
+ return mProfileConnector.getService();
}
/**
@@ -203,7 +139,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public int getState() {
if (VDBG) log("getState()");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null) {
try {
return service.getState();
@@ -226,7 +162,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null) {
try {
return service.getClient();
@@ -249,7 +185,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null) {
try {
return service.isConnected(device);
@@ -284,7 +220,7 @@ public final class BluetoothSap implements BluetoothProfile {
@UnsupportedAppUsage
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.disconnect(device);
@@ -305,7 +241,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled()) {
try {
return service.getConnectedDevices();
@@ -326,7 +262,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled()) {
try {
return service.getDevicesMatchingConnectionStates(states);
@@ -347,7 +283,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getConnectionState(device);
@@ -372,7 +308,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
if (priority != BluetoothProfile.PRIORITY_OFF
&& priority != BluetoothProfile.PRIORITY_ON) {
@@ -398,7 +334,7 @@ public final class BluetoothSap implements BluetoothProfile {
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- final IBluetoothSap service = mService;
+ final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getPriority(device);
@@ -411,24 +347,6 @@ public final class BluetoothSap implements BluetoothProfile {
return PRIORITY_OFF;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) log("Proxy object connected");
- mService = IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.SAP, BluetoothSap.this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) log("Proxy object disconnected");
- mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.SAP);
- }
- }
- };
-
private static void log(String msg) {
Log.d(TAG, msg);
}
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 4e886250b4fa..c06b837a9ee3 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -35,21 +35,28 @@ import java.io.IOException;
* On the client side, use a single {@link BluetoothSocket} to both initiate
* an outgoing connection and to manage the connection.
*
- * <p>The most common type of Bluetooth socket is RFCOMM, which is the type
- * supported by the Android APIs. RFCOMM is a connection-oriented, streaming
- * transport over Bluetooth. It is also known as the Serial Port Profile (SPP).
+ * <p>For Bluetooth BR/EDR, the most common type of socket is RFCOMM, which is the type supported by
+ * the Android APIs. RFCOMM is a connection-oriented, streaming transport over Bluetooth BR/EDR. It
+ * is also known as the Serial Port Profile (SPP). To create a listening
+ * {@link BluetoothServerSocket} that's ready for incoming Bluetooth BR/EDR connections, use {@link
+ * BluetoothAdapter#listenUsingRfcommWithServiceRecord
+ * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}.
*
- * <p>To create a listening {@link BluetoothServerSocket} that's ready for
- * incoming connections, use
- * {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord
- * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}. Then call
- * {@link #accept()} to listen for incoming connection requests. This call
- * will block until a connection is established, at which point, it will return
- * a {@link BluetoothSocket} to manage the connection. Once the {@link
- * BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on
- * the {@link BluetoothServerSocket} when it's no longer needed for accepting
- * connections. Closing the {@link BluetoothServerSocket} will <em>not</em>
- * close the returned {@link BluetoothSocket}.
+ * <p>For Bluetooth LE, the socket uses LE Connection-oriented Channel (CoC). LE CoC is a
+ * connection-oriented, streaming transport over Bluetooth LE and has a credit-based flow control.
+ * Correspondingly, use {@link BluetoothAdapter#listenUsingL2capChannel
+ * BluetoothAdapter.listenUsingL2capChannel()} to create a listening {@link BluetoothServerSocket}
+ * that's ready for incoming Bluetooth LE CoC connections. For LE CoC, you can use {@link #getPsm()}
+ * to get the protocol/service multiplexer (PSM) value that the peer needs to use to connect to your
+ * socket.
+ *
+ * <p> After the listening {@link BluetoothServerSocket} is created, call {@link #accept()} to
+ * listen for incoming connection requests. This call will block until a connection is established,
+ * at which point, it will return a {@link BluetoothSocket} to manage the connection. Once the
+ * {@link BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on the {@link
+ * BluetoothServerSocket} when it's no longer needed for accepting
+ * connections. Closing the {@link BluetoothServerSocket} will <em>not</em> close the returned
+ * {@link BluetoothSocket}.
*
* <p>{@link BluetoothServerSocket} is thread
* safe. In particular, {@link #close} will always immediately abort ongoing
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index c5d435b76139..66d1da8909cd 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -586,7 +587,8 @@ public final class ScanFilter implements Parcelable {
/**
* Set filter on service solicitation uuid.
*/
- public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid) {
+ public @NonNull Builder setServiceSolicitationUuid(
+ @Nullable ParcelUuid serviceSolicitationUuid) {
mServiceSolicitationUuid = serviceSolicitationUuid;
return this;
}
@@ -601,8 +603,9 @@ public final class ScanFilter implements Parcelable {
* @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
* {@code serviceSolicitationUuidMask} is not {@code null}.
*/
- public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid,
- ParcelUuid solicitationUuidMask) {
+ public @NonNull Builder setServiceSolicitationUuid(
+ @Nullable ParcelUuid serviceSolicitationUuid,
+ @Nullable ParcelUuid solicitationUuidMask) {
if (mServiceSolicitationUuidMask != null && mServiceSolicitationUuid == null) {
throw new IllegalArgumentException(
"SolicitationUuid is null while SolicitationUuidMask is not null!");
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index d710d57d8f0b..ca43d40bbcaa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -80,7 +80,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Base64;
-import android.util.ByteStringUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.PackageUtils;
@@ -99,6 +98,7 @@ import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
+import libcore.util.HexEncoding;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -5999,7 +5999,8 @@ public class PackageParser {
}
// first see if the hash represents a single-signer in our signing history
- byte[] sha256Bytes = ByteStringUtils.fromHexToByteArray(sha256String);
+ byte[] sha256Bytes = sha256String == null
+ ? null : HexEncoding.decode(sha256String, false /* allowSingleChar */);
if (hasSha256Certificate(sha256Bytes, flags)) {
return true;
}
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index a33f3fcfb263..65bc75b8c00f 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -64,6 +64,8 @@ public final class DhcpResults implements Parcelable {
@UnsupportedAppUsage
public int mtu;
+ public String serverHostName;
+
public DhcpResults() {
super();
}
@@ -97,6 +99,7 @@ public final class DhcpResults implements Parcelable {
vendorInfo = source.vendorInfo;
leaseDuration = source.leaseDuration;
mtu = source.mtu;
+ serverHostName = source.serverHostName;
}
}
@@ -129,6 +132,7 @@ public final class DhcpResults implements Parcelable {
vendorInfo = null;
leaseDuration = 0;
mtu = 0;
+ serverHostName = null;
}
@Override
@@ -139,6 +143,7 @@ public final class DhcpResults implements Parcelable {
str.append(" Vendor info ").append(vendorInfo);
str.append(" lease ").append(leaseDuration).append(" seconds");
if (mtu != 0) str.append(" MTU ").append(mtu);
+ str.append(" Servername ").append(serverHostName);
return str.toString();
}
@@ -154,6 +159,7 @@ public final class DhcpResults implements Parcelable {
return toStaticIpConfiguration().equals(target.toStaticIpConfiguration())
&& Objects.equals(serverAddress, target.serverAddress)
&& Objects.equals(vendorInfo, target.vendorInfo)
+ && Objects.equals(serverHostName, target.serverHostName)
&& leaseDuration == target.leaseDuration
&& mtu == target.mtu;
}
@@ -179,6 +185,7 @@ public final class DhcpResults implements Parcelable {
dest.writeInt(mtu);
InetAddressUtils.parcelInetAddress(dest, serverAddress, flags);
dest.writeString(vendorInfo);
+ dest.writeString(serverHostName);
}
@Override
@@ -193,6 +200,7 @@ public final class DhcpResults implements Parcelable {
dhcpResults.mtu = in.readInt();
dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in);
dhcpResults.vendorInfo = in.readString();
+ dhcpResults.serverHostName = in.readString();
return dhcpResults;
}
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
index d6774d47b49e..b5a2a16c7ff5 100644
--- a/core/java/android/net/IIpSecService.aidl
+++ b/core/java/android/net/IIpSecService.aidl
@@ -72,4 +72,8 @@ interface IIpSecService
int tunnelResourceId, int direction, int transformResourceId, in String callingPackage);
void removeTransportModeTransforms(in ParcelFileDescriptor socket);
+
+ int lockEncapSocketForNattKeepalive(int encapSocketResourceId, int requesterUid);
+
+ void releaseNattKeepalive(int nattKeepaliveResourceId, int ownerUid);
}
diff --git a/core/java/android/net/ITestNetworkManager.aidl b/core/java/android/net/ITestNetworkManager.aidl
index bab6ae8e7409..d586038ebb89 100644
--- a/core/java/android/net/ITestNetworkManager.aidl
+++ b/core/java/android/net/ITestNetworkManager.aidl
@@ -17,6 +17,7 @@
package android.net;
import android.net.LinkAddress;
+import android.net.LinkProperties;
import android.net.TestNetworkInterface;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -31,7 +32,8 @@ interface ITestNetworkManager
TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs);
TestNetworkInterface createTapInterface();
- void setupTestNetwork(in String iface, in IBinder binder);
+ void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered,
+ in IBinder binder);
void teardownTestNetwork(int netId);
}
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index d4c3edca4367..889e9bc7875e 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -941,7 +941,8 @@ public final class IpSecManager {
throw new IllegalArgumentException(sse);
} else if (sse.errorCode == OsConstants.EAGAIN) {
throw new IllegalStateException(sse);
- } else if (sse.errorCode == OsConstants.EOPNOTSUPP) {
+ } else if (sse.errorCode == OsConstants.EOPNOTSUPP
+ || sse.errorCode == OsConstants.EPROTONOSUPPORT) {
throw new UnsupportedOperationException(sse);
}
}
diff --git a/core/java/android/net/TestNetworkManager.java b/core/java/android/net/TestNetworkManager.java
index e274005eb9d1..4ac4a69e4b1b 100644
--- a/core/java/android/net/TestNetworkManager.java
+++ b/core/java/android/net/TestNetworkManager.java
@@ -56,6 +56,26 @@ public class TestNetworkManager {
/**
* Sets up a capability-limited, testing-only network for a given interface
*
+ * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note
+ * that the interface name and link addresses will be overwritten, and the passed-in values
+ * discarded.
+ * @param isMetered Whether or not the network should be considered metered.
+ * @param binder A binder object guarding the lifecycle of this test network.
+ * @hide
+ */
+ public void setupTestNetwork(
+ @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
+ Preconditions.checkNotNull(lp, "Invalid LinkProperties");
+ try {
+ mService.setupTestNetwork(lp.getInterfaceName(), lp, isMetered, binder);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Sets up a capability-limited, testing-only network for a given interface
+ *
* @param iface the name of the interface to be used for the Network LinkProperties.
* @param binder A binder object guarding the lifecycle of this test network.
* @hide
@@ -63,7 +83,7 @@ public class TestNetworkManager {
@TestApi
public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
try {
- mService.setupTestNetwork(iface, binder);
+ mService.setupTestNetwork(iface, null, true, binder);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
index 5b674067192e..cf08b653d0f4 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -22,6 +22,8 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
*
@@ -837,15 +839,11 @@ public class UrlQuerySanitizer {
* @param string the escaped string
* @return the unescaped string.
*/
+ private static final Pattern plusOrPercent = Pattern.compile("[+%]");
public String unescape(String string) {
- // Early exit if no escaped characters.
- int firstEscape = string.indexOf('%');
- if ( firstEscape < 0) {
- firstEscape = string.indexOf('+');
- if (firstEscape < 0) {
- return string;
- }
- }
+ final Matcher matcher = plusOrPercent.matcher(string);
+ if (!matcher.find()) return string;
+ final int firstEscape = matcher.start();
int length = string.length();
@@ -855,8 +853,7 @@ public class UrlQuerySanitizer {
char c = string.charAt(i);
if (c == '+') {
c = ' ';
- }
- else if ( c == '%' && i + 2 < length) {
+ } else if (c == '%' && i + 2 < length) {
char c1 = string.charAt(i + 1);
char c2 = string.charAt(i + 2);
if (isHexDigit(c1) && isHexDigit(c2)) {
diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java
index 30d3b84c978c..cd8ce8d87778 100644
--- a/core/java/android/net/metrics/ApfProgramEvent.java
+++ b/core/java/android/net/metrics/ApfProgramEvent.java
@@ -176,7 +176,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event {
out.writeInt(filteredRas);
out.writeInt(currentRas);
out.writeInt(programLength);
- out.writeInt(flags);
+ out.writeInt(this.flags);
}
/** @hide */
@@ -192,6 +192,18 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event {
programLength, actualLifetime, lifetimeString, namesOf(flags));
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(ApfProgramEvent.class))) return false;
+ final ApfProgramEvent other = (ApfProgramEvent) obj;
+ return lifetime == other.lifetime
+ && actualLifetime == other.actualLifetime
+ && filteredRas == other.filteredRas
+ && currentRas == other.currentRas
+ && programLength == other.programLength
+ && flags == other.flags;
+ }
+
/** @hide */
public static final Parcelable.Creator<ApfProgramEvent> CREATOR
= new Parcelable.Creator<ApfProgramEvent>() {
diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java
index ddc788dba649..2e78469afd0d 100644
--- a/core/java/android/net/metrics/ApfStats.java
+++ b/core/java/android/net/metrics/ApfStats.java
@@ -275,6 +275,22 @@ public final class ApfStats implements IpConnectivityLog.Event {
.toString();
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(ApfStats.class))) return false;
+ final ApfStats other = (ApfStats) obj;
+ return durationMs == other.durationMs
+ && receivedRas == other.receivedRas
+ && matchingRas == other.matchingRas
+ && droppedRas == other.droppedRas
+ && zeroLifetimeRas == other.zeroLifetimeRas
+ && parseErrors == other.parseErrors
+ && programUpdates == other.programUpdates
+ && programUpdatesAll == other.programUpdatesAll
+ && programUpdatesAllowingMulticast == other.programUpdatesAllowingMulticast
+ && maxProgramSize == other.maxProgramSize;
+ }
+
/** @hide */
public static final Parcelable.Creator<ApfStats> CREATOR = new Parcelable.Creator<ApfStats>() {
public ApfStats createFromParcel(Parcel in) {
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 93063cbe09a4..fa6bff32b822 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -22,6 +22,7 @@ import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
/**
* An event recorded when a DhcpClient state machine transitions to a new state.
@@ -101,6 +102,14 @@ public final class DhcpClientEvent implements IpConnectivityLog.Event {
return String.format("DhcpClientEvent(%s, %dms)", msg, durationMs);
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(DhcpClientEvent.class))) return false;
+ final DhcpClientEvent other = (DhcpClientEvent) obj;
+ return TextUtils.equals(msg, other.msg)
+ && durationMs == other.durationMs;
+ }
+
/** @hide */
public static final Parcelable.Creator<DhcpClientEvent> CREATOR
= new Parcelable.Creator<DhcpClientEvent>() {
diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index 013e3530a941..77908e6593ad 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -101,6 +101,14 @@ public final class IpManagerEvent implements IpConnectivityLog.Event {
Decoder.constants.get(eventType), durationMs);
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(IpManagerEvent.class))) return false;
+ final IpManagerEvent other = (IpManagerEvent) obj;
+ return eventType == other.eventType
+ && durationMs == other.durationMs;
+ }
+
final static class Decoder {
static final SparseArray<String> constants = MessageUtils.findMessageNames(
new Class[]{IpManagerEvent.class},
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index c7362979af61..f9ee39bf9fbd 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -93,6 +93,13 @@ public final class IpReachabilityEvent implements IpConnectivityLog.Event {
return String.format("IpReachabilityEvent(%s:%02x)", eventName, lo);
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(IpReachabilityEvent.class))) return false;
+ final IpReachabilityEvent other = (IpReachabilityEvent) obj;
+ return eventType == other.eventType;
+ }
+
final static class Decoder {
static final SparseArray<String> constants =
MessageUtils.findMessageNames(new Class[]{IpReachabilityEvent.class},
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index 512811580021..ec0f82a3aa66 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -121,6 +121,14 @@ public final class NetworkEvent implements IpConnectivityLog.Event {
Decoder.constants.get(eventType), durationMs);
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(NetworkEvent.class))) return false;
+ final NetworkEvent other = (NetworkEvent) obj;
+ return eventType == other.eventType
+ && durationMs == other.durationMs;
+ }
+
final static class Decoder {
static final SparseArray<String> constants = MessageUtils.findMessageNames(
new Class[]{NetworkEvent.class}, new String[]{"NETWORK_"});
diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java
index d16a10432373..6ccca7dba5b9 100644
--- a/core/java/android/net/metrics/RaEvent.java
+++ b/core/java/android/net/metrics/RaEvent.java
@@ -97,6 +97,18 @@ public final class RaEvent implements IpConnectivityLog.Event {
.toString();
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(RaEvent.class))) return false;
+ final RaEvent other = (RaEvent) obj;
+ return routerLifetime == other.routerLifetime
+ && prefixValidLifetime == other.prefixValidLifetime
+ && prefixPreferredLifetime == other.prefixPreferredLifetime
+ && routeInfoLifetime == other.routeInfoLifetime
+ && rdnssLifetime == other.rdnssLifetime
+ && dnsslLifetime == other.dnsslLifetime;
+ }
+
/** @hide */
public static final Parcelable.Creator<RaEvent> CREATOR = new Parcelable.Creator<RaEvent>() {
public RaEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index ebca7e6d5607..67844202de5d 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -170,6 +170,15 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event {
getProbeName(probeType), returnCode, getValidationStage(probeType), durationMs);
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().equals(ValidationProbeEvent.class))) return false;
+ final ValidationProbeEvent other = (ValidationProbeEvent) obj;
+ return durationMs == other.durationMs
+ && probeType == other.probeType
+ && returnCode == other.returnCode;
+ }
+
final static class Decoder {
static final SparseArray<String> constants = MessageUtils.findMessageNames(
new Class[]{ValidationProbeEvent.class},
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index e366fe05723e..32735aa24cd5 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -32,7 +32,7 @@ import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
import java.io.File;
-import java.io.IOException;
+import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
@@ -146,7 +146,6 @@ public final class BugreportManager {
@NonNull BugreportParams params,
@NonNull @CallbackExecutor Executor executor,
@NonNull BugreportCallback callback) {
- File tmpScreenshotFile = null;
try {
Preconditions.checkNotNull(bugreportFd);
Preconditions.checkNotNull(params);
@@ -155,13 +154,10 @@ public final class BugreportManager {
if (screenshotFd == null) {
// Binder needs a valid File Descriptor to be passed
- tmpScreenshotFile = File.createTempFile("tmp", ".png");
- screenshotFd = ParcelFileDescriptor.open(tmpScreenshotFile,
+ screenshotFd = ParcelFileDescriptor.open(new File("/dev/null"),
ParcelFileDescriptor.MODE_READ_ONLY);
}
- DumpstateListener dsListener = new DumpstateListener(executor,
- callback, tmpScreenshotFile);
-
+ DumpstateListener dsListener = new DumpstateListener(executor, callback);
// Note: mBinder can get callingUid from the binder transaction.
mBinder.startBugreport(-1 /* callingUid */,
mContext.getOpPackageName(),
@@ -169,13 +165,9 @@ public final class BugreportManager {
screenshotFd.getFileDescriptor(),
params.getMode(), dsListener);
} catch (RemoteException e) {
- deleteFile(tmpScreenshotFile);
throw e.rethrowFromSystemServer();
- } catch (IOException e) {
- // Need to delete the file if it was created but failed while trying to get fd
- deleteFile(tmpScreenshotFile);
- Log.e(TAG, "Not able to create/open temporary screenshot file ", e);
- callback.onError(BugreportCallback.BUGREPORT_ERROR_RUNTIME);
+ } catch (FileNotFoundException e) {
+ Log.wtf(TAG, "Not able to find /dev/null file: ", e);
} finally {
// We can close the file descriptors here because binder would have duped them.
IoUtils.closeQuietly(bugreportFd);
@@ -197,26 +189,13 @@ public final class BugreportManager {
}
}
- private void deleteFile(@Nullable File tmpScreenshotFile) {
- try {
- if (tmpScreenshotFile != null && tmpScreenshotFile.exists()) {
- tmpScreenshotFile.delete();
- }
- } catch (SecurityException e) {
- Log.e(TAG, "Not able to delete temporary screenshot file ", e);
- }
- }
-
private final class DumpstateListener extends IDumpstateListener.Stub {
private final Executor mExecutor;
private final BugreportCallback mCallback;
- private final File mTmpScreenshotFile;
- DumpstateListener(Executor executor, BugreportCallback callback,
- @Nullable File tmpScreenshotFile) {
+ DumpstateListener(Executor executor, BugreportCallback callback) {
mExecutor = executor;
mCallback = callback;
- mTmpScreenshotFile = tmpScreenshotFile;
}
@Override
@@ -240,7 +219,6 @@ public final class BugreportManager {
});
} finally {
Binder.restoreCallingIdentity(identity);
- deleteFile(mTmpScreenshotFile);
}
}
@@ -253,7 +231,6 @@ public final class BugreportManager {
});
} finally {
Binder.restoreCallingIdentity(identity);
- deleteFile(mTmpScreenshotFile);
}
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1c319fb4ea36..d3bed02a4b47 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -287,6 +287,7 @@ public class Build {
/**
* @hide
*/
+ @TestApi
@UnsupportedAppUsage
public static final String[] ACTIVE_CODENAMES = "REL".equals(ALL_CODENAMES[0])
? new String[0] : ALL_CODENAMES;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 606c8f398563..1aaee18914a2 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -28,11 +28,11 @@ import android.util.Log;
import dalvik.system.VMRuntime;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/** @hide */
public class GraphicsEnvironment {
@@ -49,7 +49,7 @@ public class GraphicsEnvironment {
private static final boolean DEBUG = false;
private static final String TAG = "GraphicsEnvironment";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
- private static final String GUP_WHITELIST_FILENAME = "whitelist.txt";
+ private static final String GAME_DRIVER_WHITELIST_ALL = "*";
private ClassLoader mClassLoader;
private String mLayerPath;
@@ -98,15 +98,15 @@ public class GraphicsEnvironment {
if (isDebuggable(context)) {
- int enable = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
+ final int enable = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
if (enable != 0) {
- String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
- Settings.Global.GPU_DEBUG_APP);
+ final String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.GPU_DEBUG_APP);
- String packageName = context.getPackageName();
+ final String packageName = context.getPackageName();
if ((gpuDebugApp != null && packageName != null)
&& (!gpuDebugApp.isEmpty() && !packageName.isEmpty())
@@ -136,37 +136,29 @@ public class GraphicsEnvironment {
setLayerPaths(mClassLoader, layerPaths);
}
+ private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
+ List<String> valueList = null;
+ final String settingsValue = bundle.getString(globalSetting);
+
+ if (settingsValue != null) {
+ valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
+ } else {
+ valueList = new ArrayList<>();
+ }
+
+ return valueList;
+ }
+
/**
* Choose whether the current process should use the builtin or an updated driver.
*/
private static void chooseDriver(Context context, Bundle coreSettings) {
- String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
}
- // To minimize risk of driver updates crippling the device beyond user repair, never use an
- // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
- // were tested thoroughly with the pre-installed driver.
- ApplicationInfo ai = context.getApplicationInfo();
- if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
- if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
- return;
- }
-
- String applicationPackageName = context.getPackageName();
- String devOptInApplicationName = coreSettings.getString(
- Settings.Global.GUP_DEV_OPT_IN_APPS);
- boolean devOptIn = applicationPackageName.equals(devOptInApplicationName);
- boolean whitelisted = onWhitelist(context, driverPackageName, ai.packageName);
- if (!devOptIn && !whitelisted) {
- if (DEBUG) {
- Log.w(TAG, applicationPackageName + " is not on the whitelist.");
- }
- return;
- }
-
- ApplicationInfo driverInfo;
+ final ApplicationInfo driverInfo;
try {
driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -184,7 +176,59 @@ public class GraphicsEnvironment {
return;
}
- String abi = chooseAbi(driverInfo);
+ // To minimize risk of driver updates crippling the device beyond user repair, never use an
+ // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
+ // were tested thoroughly with the pre-installed driver.
+ final ApplicationInfo ai = context.getApplicationInfo();
+ if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
+ if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
+ return;
+ }
+
+ // GAME_DRIVER_ALL_APPS
+ // 0: Default (Invalid values fallback to default as well)
+ // 1: All apps use Game Driver
+ // 2: All apps use system graphics driver
+ final int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
+ if (gameDriverAllApps == 2) {
+ if (DEBUG) {
+ Log.w(TAG, "Game Driver is turned off on this device");
+ }
+ return;
+ }
+
+ if (gameDriverAllApps != 1) {
+ // GAME_DRIVER_OPT_OUT_APPS has higher priority than GAME_DRIVER_OPT_IN_APPS
+ if (getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
+ .contains(ai.packageName)) {
+ if (DEBUG) {
+ Log.w(TAG, ai.packageName + " opts out from Game Driver.");
+ }
+ return;
+ }
+ final boolean isOptIn =
+ getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
+ .contains(ai.packageName);
+ final List<String> whitelist = getGlobalSettingsString(coreSettings,
+ Settings.Global.GAME_DRIVER_WHITELIST);
+ if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
+ && !whitelist.contains(ai.packageName)) {
+ if (DEBUG) {
+ Log.w(TAG, ai.packageName + " is not on the whitelist.");
+ }
+ return;
+ }
+
+ // If the application is not opted-in and check whether it's on the blacklist,
+ // terminate early if it's on the blacklist and fallback to system driver.
+ if (!isOptIn
+ && getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_BLACKLIST)
+ .contains(ai.packageName)) {
+ return;
+ }
+ }
+
+ final String abi = chooseAbi(driverInfo);
if (abi == null) {
if (DEBUG) {
// This is the normal case for the pre-installed empty driver package, don't spam
@@ -195,16 +239,23 @@ public class GraphicsEnvironment {
return;
}
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(driverInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(driverInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
- if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths);
- setDriverPath(paths);
+ final String sphalLibraries =
+ coreSettings.getString(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES);
+
+ if (DEBUG) {
+ Log.v(TAG,
+ "gfx driver package search path: " + paths
+ + ", required sphal libraries: " + sphalLibraries);
+ }
+ setDriverPathAndSphalLibraries(paths, sphalLibraries);
}
/**
@@ -218,7 +269,7 @@ public class GraphicsEnvironment {
* Should only be called after chooseDriver().
*/
public static void earlyInitEGL() {
- Thread eglInitThread = new Thread(
+ final Thread eglInitThread = new Thread(
() -> {
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
},
@@ -227,7 +278,7 @@ public class GraphicsEnvironment {
}
private static String chooseAbi(ApplicationInfo ai) {
- String isa = VMRuntime.getCurrentInstructionSet();
+ final String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null &&
isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) {
return ai.primaryCpuAbi;
@@ -239,32 +290,7 @@ public class GraphicsEnvironment {
return null;
}
- private static boolean onWhitelist(Context context, String driverPackageName,
- String applicationPackageName) {
- try {
- Context driverContext = context.createPackageContext(driverPackageName,
- Context.CONTEXT_RESTRICTED);
- AssetManager assets = driverContext.getAssets();
- InputStream stream = assets.open(GUP_WHITELIST_FILENAME);
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- for (String packageName; (packageName = reader.readLine()) != null; ) {
- if (packageName.equals(applicationPackageName)) {
- return true;
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- if (DEBUG) {
- Log.w(TAG, "driver package '" + driverPackageName + "' not installed");
- }
- } catch (IOException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to load whitelist driver package, abort.");
- }
- }
- return false;
- }
-
private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
private static native void setDebugLayers(String layers);
- private static native void setDriverPath(String path);
+ private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 03e8c154e3fc..7f60b9cec284 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -363,18 +363,6 @@ interface INetworkManagementService
boolean isNetworkActive();
/**
- * Setup a new physical network.
- * @param permission PERMISSION_NONE if no permissions required to access this network.
- * PERMISSION_NETWORK or PERMISSION_SYSTEM to set respective permission.
- */
- void createPhysicalNetwork(int netId, int permission);
-
- /**
- * Setup a new VPN.
- */
- void createVirtualNetwork(int netId, boolean secure);
-
- /**
* Add an interface to a network.
*/
void addInterfaceToNetwork(String iface, int netId);
@@ -396,9 +384,6 @@ interface INetworkManagementService
*/
void setNetworkPermission(int netId, int permission);
- void setPermission(String permission, in int[] uids);
- void clearPermission(in int[] uids);
-
/**
* Allow UID to call protect().
*/
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index ef28f07e817f..0827fd6e725e 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -967,6 +967,23 @@ public class CallLog {
// spam the call log with its own entries, causing entries from Telephony to be
// removed.
final Uri result = resolver.insert(uri, values);
+ if (result != null) {
+ String lastPathSegment = result.getLastPathSegment();
+ // When inserting into the call log, if ContentProvider#insert detect an appops
+ // denial a non-null "silent rejection" URI is returned which ends in 0.
+ // Example: content://call_log/calls/0
+ // The 0 in the last part of the path indicates a fake call id of 0.
+ // A denial when logging calls from the platform is bad; there is no other
+ // logging to indicate that this has happened so we will check for that scenario
+ // here and log a warning so we have a hint as to what is going on.
+ if (lastPathSegment != null && lastPathSegment.equals("0")) {
+ Log.w(LOG_TAG, "Failed to insert into call log due to appops denial;"
+ + " resultUri=" + result);
+ }
+ } else {
+ Log.w(LOG_TAG, "Failed to insert into call log; null result uri.");
+ }
+
if (values.containsKey(PHONE_ACCOUNT_ID)
&& !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_ID))
&& values.containsKey(PHONE_ACCOUNT_COMPONENT_NAME)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bf33e0619304..e94d3a71831b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10336,8 +10336,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
/**
@@ -10346,8 +10344,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
/**
@@ -10356,8 +10352,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
/**
@@ -10367,8 +10361,6 @@ public final class Settings {
* The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
/**
@@ -10397,8 +10389,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
/**
@@ -10407,8 +10397,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
/**
@@ -10417,8 +10405,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
/**
@@ -10427,8 +10413,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
"captive_portal_other_fallback_urls";
@@ -10438,8 +10422,6 @@ public final class Settings {
* by "@@,@@".
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
"captive_portal_fallback_probe_specs";
@@ -10450,8 +10432,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
/**
@@ -10460,8 +10440,6 @@ public final class Settings {
*
* @hide
*/
- @SystemApi
- @TestApi
public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
/**
@@ -11446,16 +11424,55 @@ public final class Settings {
public static final String GPU_DEBUG_APP = "gpu_debug_app";
/**
- * Apps that are selected to use Game Update Package.
+ * Game Driver global preference for all Apps.
+ * 0 = Default
+ * 1 = All Apps use Game Driver
+ * 2 = All Apps use system graphics driver
+ * @hide
+ */
+ public static final String GAME_DRIVER_ALL_APPS = "game_driver_all_apps";
+
+ /**
+ * List of Apps selected to use Game Driver.
+ * i.e. <pkg1>,<pkg2>,...,<pkgN>
+ * @hide
+ */
+ public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps";
+
+ /**
+ * List of Apps selected not to use Game Driver.
+ * i.e. <pkg1>,<pkg2>,...,<pkgN>
+ * @hide
+ */
+ public static final String GAME_DRIVER_OPT_OUT_APPS = "game_driver_opt_out_apps";
+
+ /**
+ * Apps on the blacklist that are forbidden to use Game Driver.
+ * @hide
+ */
+ public static final String GAME_DRIVER_BLACKLIST = "game_driver_blacklist";
+
+ /**
+ * List of blacklists, each blacklist is a blacklist for a specific version of Game Driver.
+ * @hide
+ */
+ public static final String GAME_DRIVER_BLACKLISTS = "game_driver_blacklists";
+
+ /**
+ * Apps on the whitelist that are allowed to use Game Driver.
+ * The string is a list of application package names, seperated by comma.
+ * i.e. <apk1>,<apk2>,...,<apkN>
* @hide
*/
- public static final String GUP_DEV_OPT_IN_APPS = "gup_dev_opt_in_apps";
+ public static final String GAME_DRIVER_WHITELIST = "game_driver_whitelist";
/**
- * Apps on the black list that are forbidden to useGame Update Package.
+ * List of libraries in sphal accessible by Game Driver
+ * The string is a list of library names, separated by colon.
+ * i.e. <lib1>:<lib2>:...:<libN>
* @hide
*/
- public static final String GUP_BLACK_LIST = "gup_black_list";
+ public static final String GAME_DRIVER_SPHAL_LIBRARIES = "game_driver_sphal_libraries";
/**
* Ordered GPU debug layer list
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index 386169528e89..fc23c54e834e 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -19,7 +19,7 @@ package android.webkit;
import android.annotation.Nullable;
import android.text.TextUtils;
-import libcore.net.MimeUtils;
+import libcore.net.MimeMap;
import java.util.regex.Pattern;
@@ -79,7 +79,7 @@ public class MimeTypeMap {
* @return {@code true} if there is a mimeType entry in the map.
*/
public boolean hasMimeType(String mimeType) {
- return MimeUtils.hasMimeType(mimeType);
+ return MimeMap.getDefault().hasMimeType(mimeType);
}
/**
@@ -89,12 +89,12 @@ public class MimeTypeMap {
*/
@Nullable
public String getMimeTypeFromExtension(String extension) {
- return MimeUtils.guessMimeTypeFromExtension(extension);
+ return MimeMap.getDefault().guessMimeTypeFromExtension(extension);
}
// Static method called by jni.
private static String mimeTypeFromExtension(String extension) {
- return MimeUtils.guessMimeTypeFromExtension(extension);
+ return MimeMap.getDefault().guessMimeTypeFromExtension(extension);
}
/**
@@ -103,7 +103,7 @@ public class MimeTypeMap {
* @return {@code true} if there is an extension entry in the map.
*/
public boolean hasExtension(String extension) {
- return MimeUtils.hasExtension(extension);
+ return MimeMap.getDefault().hasExtension(extension);
}
/**
@@ -115,7 +115,7 @@ public class MimeTypeMap {
*/
@Nullable
public String getExtensionFromMimeType(String mimeType) {
- return MimeUtils.guessExtensionFromMimeType(mimeType);
+ return MimeMap.getDefault().guessExtensionFromMimeType(mimeType);
}
/**
diff --git a/core/jni/android_ddm_DdmHandleNativeHeap.cpp b/core/jni/android_ddm_DdmHandleNativeHeap.cpp
index e22f581e14e2..076e99dd1fba 100644
--- a/core/jni/android_ddm_DdmHandleNativeHeap.cpp
+++ b/core/jni/android_ddm_DdmHandleNativeHeap.cpp
@@ -22,6 +22,9 @@
#include <jni.h>
#include "core_jni_helpers.h"
+#include <android-base/logging.h>
+#include <bionic_malloc.h>
+
#include <utils/Log.h>
#include <utils/String8.h>
@@ -30,11 +33,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
- size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
#define DDMS_HEADER_SIGNATURE 0x812345dd
#define DDMS_VERSION 2
@@ -78,9 +76,16 @@ static jbyteArray DdmHandleNativeHeap_getLeakInfo(JNIEnv* env, jobject) {
ReadFile("/proc/self/maps", maps);
header.mapSize = maps.size();
- uint8_t* allocBytes;
- get_malloc_leak_info(&allocBytes, &header.allocSize, &header.allocInfoSize,
- &header.totalMemory, &header.backtraceSize);
+ android_mallopt_leak_info_t leak_info;
+ if (!android_mallopt(M_GET_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info))) {
+ PLOG(ERROR) << "*** Failed to get malloc leak info";
+ return nullptr;
+ }
+
+ header.allocSize = leak_info.overall_size;
+ header.allocInfoSize = leak_info.info_size;
+ header.totalMemory = leak_info.total_memory;
+ header.backtraceSize = leak_info.backtrace_size;
ALOGD("*** mapSize: %zu allocSize: %zu allocInfoSize: %zu totalMemory: %zu",
header.mapSize, header.allocSize, header.allocInfoSize, header.totalMemory);
@@ -98,10 +103,10 @@ static jbyteArray DdmHandleNativeHeap_getLeakInfo(JNIEnv* env, jobject) {
env->SetByteArrayRegion(array, sizeof(header),
maps.size(), reinterpret_cast<const jbyte*>(maps.string()));
env->SetByteArrayRegion(array, sizeof(header) + maps.size(),
- header.allocSize, reinterpret_cast<jbyte*>(allocBytes));
+ header.allocSize, reinterpret_cast<jbyte*>(leak_info.buffer));
}
- free_malloc_leak_info(allocBytes);
+ android_mallopt(M_FREE_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info));
return array;
}
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 28c59db6b932..c5fc9b3628df 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -49,8 +49,8 @@ int ifc_disable(const char *ifname);
namespace android {
constexpr int MAXPACKETSIZE = 8 * 1024;
-// FrameworkListener limits the size of commands to 1024 bytes. TODO: fix this.
-constexpr int MAXCMDSIZE = 1024;
+// FrameworkListener limits the size of commands to 4096 bytes.
+constexpr int MAXCMDSIZE = 4096;
static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 8be617f08ac3..62c4d76ed455 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -33,8 +33,10 @@
#include <iomanip>
#include <string>
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
+#include <bionic_malloc.h>
#include <debuggerd/client.h>
#include <log/log.h>
#include <utils/misc.h>
@@ -960,9 +962,6 @@ static bool openFile(JNIEnv* env, jobject fileDescriptor, UniqueFile& fp)
return true;
}
-/* pulled out of bionic */
-extern "C" void write_malloc_leak_info(FILE* fp);
-
/*
* Dump the native heap, writing human-readable output to the specified
* file descriptor.
@@ -978,8 +977,11 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject,
ALOGD("Native heap dump starting...\n");
// Formatting of the native heap dump is handled by malloc debug itself.
// See https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md#backtrace-heap-dump-format
- write_malloc_leak_info(fp.get());
- ALOGD("Native heap dump complete.\n");
+ if (android_mallopt(M_WRITE_MALLOC_LEAK_INFO_TO_FILE, fp.get(), sizeof(FILE*))) {
+ ALOGD("Native heap dump complete.\n");
+ } else {
+ PLOG(ERROR) << "Failed to write native heap dump to file";
+ }
}
/*
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index dfa5de6b65c6..b95d500212d4 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -23,9 +23,12 @@
namespace {
-void setDriverPath(JNIEnv* env, jobject clazz, jstring path) {
+void setDriverPathAndSphalLibraries_native(JNIEnv* env, jobject clazz, jstring path,
+ jstring sphalLibraries) {
ScopedUtfChars pathChars(env, path);
- android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
+ ScopedUtfChars sphalLibrariesChars(env, sphalLibraries);
+ android::GraphicsEnv::getInstance().setDriverPathAndSphalLibraries(pathChars.c_str(),
+ sphalLibrariesChars.c_str());
}
void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
@@ -43,7 +46,7 @@ void setDebugLayers_native(JNIEnv* env, jobject clazz, jstring layers) {
}
const JNINativeMethod g_methods[] = {
- { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
+ { "setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPathAndSphalLibraries_native) },
{ "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
{ "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native) },
};
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 9c60e6bd8565..129b8af85ffe 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -188,7 +188,7 @@ status_t JHwBinder::onTransact(
if (env->IsInstanceOf(excep, gErrorClass)) {
/* It's an error */
LOG(ERROR) << "Forcefully exiting";
- exit(1);
+ _exit(1);
} else {
LOG(ERROR) << "Uncaught exception!";
}
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index 182a621c6978..a26707eedb28 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -146,7 +146,7 @@ jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
ZipEntry data;
const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- ZipString(entryNameChars.c_str()), &data);
+ entryNameChars.c_str(), &data);
if (error) {
return NULL;
}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 7c9176aa9eb7..a44ec9a911be 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -384,11 +384,26 @@ message GlobalSettingsProto {
// App allowed to load GPU debug layers.
optional SettingProto debug_app = 1;
optional SettingProto debug_layers = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Apps opt in to load graphics driver from Game Update Package
- // instead of native graphcis driver through developer options.
- optional SettingProto gup_dev_opt_in_apps = 8;
- // Apps on the black list that are forbidden to useGame Update Package.
- optional SettingProto gup_black_list = 9;
+ // Game Driver - global preference for all Apps
+ // 0 = Default
+ // 1 = All Apps use Game Driver
+ // 2 = All Apps use system graphics driver
+ optional SettingProto game_driver_all_apps = 8;
+ // Game Driver - List of Apps selected to use Game Driver
+ // i.e. <pkg1>,<pkg2>,...,<pkgN>
+ optional SettingProto game_driver_opt_in_apps = 9;
+ // Game Driver - List of Apps selected not to use Game Driver
+ // i.e. <pkg1>,<pkg2>,...,<pkgN>
+ optional SettingProto game_driver_opt_out_apps = 10;
+ // Game Driver - List of Apps that are forbidden to use Game Driver
+ optional SettingProto game_driver_blacklist = 11;
+ // Game Driver - List of Apps that are allowed to use Game Driver
+ optional SettingProto game_driver_whitelist = 12;
+ // Game Driver - List of blacklists, each blacklist is a blacklist for
+ // a specific Game Driver version
+ optional SettingProto game_driver_blacklists = 14;
+ // Game Driver - List of libraries in sphal accessible by Game Driver
+ optional SettingProto game_driver_sphal_libraries = 16;
}
optional Gpu gpu = 59;
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
new file mode 100644
index 000000000000..0b5aa8677a6e
--- /dev/null
+++ b/core/proto/android/stats/dnsresolver/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_library_static {
+ name: "dnsresolverprotosnano",
+ proto: {
+ type: "nano",
+ },
+ srcs: [
+ "dns_resolver.proto",
+ ],
+ sdk_version: "system_current",
+ no_framework_libs: true,
+}
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
new file mode 100644
index 000000000000..af6fea017bef
--- /dev/null
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+package android.stats.dnsresolver;
+
+enum EventType {
+ EVENT_UNKNOWN = 0;
+ EVENT_GETADDRINFO = 1;
+ EVENT_GETHOSTBYNAME = 2;
+ EVENT_GETHOSTBYADDR = 3;
+ EVENT_RES_NSEND = 4;
+}
+
+// The return value of the DNS resolver for each DNS lookups.
+// bionic/libc/include/netdb.h
+// system/netd/resolv/include/netd_resolv/resolv.h
+enum ReturnCode {
+ RC_EAI_NO_ERROR = 0;
+ RC_EAI_ADDRFAMILY = 1;
+ RC_EAI_AGAIN = 2;
+ RC_EAI_BADFLAGS = 3;
+ RC_EAI_FAIL = 4;
+ RC_EAI_FAMILY = 5;
+ RC_EAI_MEMORY = 6;
+ RC_EAI_NODATA = 7;
+ RC_EAI_NONAME = 8;
+ RC_EAI_SERVICE = 9;
+ RC_EAI_SOCKTYPE = 10;
+ RC_EAI_SYSTEM = 11;
+ RC_EAI_BADHINTS = 12;
+ RC_EAI_PROTOCOL = 13;
+ RC_EAI_OVERFLOW = 14;
+ RC_RESOLV_TIMEOUT = 255;
+ RC_EAI_MAX = 256;
+}
+
+enum NsRcode {
+ NS_R_NO_ERROR = 0; // No error occurred.
+ NS_R_FORMERR = 1; // Format error.
+ NS_R_SERVFAIL = 2; // Server failure.
+ NS_R_NXDOMAIN = 3; // Name error.
+ NS_R_NOTIMPL = 4; // Unimplemented.
+ NS_R_REFUSED = 5; // Operation refused.
+ // these are for BIND_UPDATE
+ NS_R_YXDOMAIN = 6; // Name exists
+ NS_R_YXRRSET = 7; // RRset exists
+ NS_R_NXRRSET = 8; // RRset does not exist
+ NS_R_NOTAUTH = 9; // Not authoritative for zone
+ NS_R_NOTZONE = 10; // Zone of record different from zone section
+ NS_R_MAX = 11;
+ // The following are EDNS extended rcodes
+ NS_R_BADVERS = 16;
+ // The following are TSIG errors
+ // NS_R_BADSIG = 16,
+ NS_R_BADKEY = 17;
+ NS_R_BADTIME = 18;
+}
+
+// Currently defined type values for resources and queries.
+enum NsType {
+ NS_T_INVALID = 0; // Cookie.
+ NS_T_A = 1; // Host address.
+ NS_T_NS = 2; // Authoritative server.
+ NS_T_MD = 3; // Mail destination.
+ NS_T_MF = 4; // Mail forwarder.
+ NS_T_CNAME = 5; // Canonical name.
+ NS_T_SOA = 6; // Start of authority zone.
+ NS_T_MB = 7; // Mailbox domain name.
+ NS_T_MG = 8; // Mail group member.
+ NS_T_MR = 9; // Mail rename name.
+ NS_T_NULL = 10; // Null resource record.
+ NS_T_WKS = 11; // Well known service.
+ NS_T_PTR = 12; // Domain name pointer.
+ NS_T_HINFO = 13; // Host information.
+ NS_T_MINFO = 14; // Mailbox information.
+ NS_T_MX = 15; // Mail routing information.
+ NS_T_TXT = 16; // Text strings.
+ NS_T_RP = 17; // Responsible person.
+ NS_T_AFSDB = 18; // AFS cell database.
+ NS_T_X25 = 19; // X_25 calling address.
+ NS_T_ISDN = 20; // ISDN calling address.
+ NS_T_RT = 21; // Router.
+ NS_T_NSAP = 22; // NSAP address.
+ NS_T_NSAP_PTR = 23; // Reverse NSAP lookup (deprecated).
+ NS_T_SIG = 24; // Security signature.
+ NS_T_KEY = 25; // Security key.
+ NS_T_PX = 26; // X.400 mail mapping.
+ NS_T_GPOS = 27; // Geographical position (withdrawn).
+ NS_T_AAAA = 28; // IPv6 Address.
+ NS_T_LOC = 29; // Location Information.
+ NS_T_NXT = 30; // Next domain (security).
+ NS_T_EID = 31; // Endpoint identifier.
+ NS_T_NIMLOC = 32; // Nimrod Locator.
+ NS_T_SRV = 33; // Server Selection.
+ NS_T_ATMA = 34; // ATM Address
+ NS_T_NAPTR = 35; // Naming Authority PoinTeR
+ NS_T_KX = 36; // Key Exchange
+ NS_T_CERT = 37; // Certification record
+ NS_T_A6 = 38; // IPv6 address (experimental)
+ NS_T_DNAME = 39; // Non-terminal DNAME
+ NS_T_SINK = 40; // Kitchen sink (experimentatl)
+ NS_T_OPT = 41; // EDNS0 option (meta-RR)
+ NS_T_APL = 42; // Address prefix list (RFC 3123)
+ NS_T_DS = 43; // Delegation Signer
+ NS_T_SSHFP = 44; // SSH Fingerprint
+ NS_T_IPSECKEY = 45; // IPSEC Key
+ NS_T_RRSIG = 46; // RRset Signature
+ NS_T_NSEC = 47; // Negative security
+ NS_T_DNSKEY = 48; // DNS Key
+ NS_T_DHCID = 49; // Dynamic host configuratin identifier
+ NS_T_NSEC3 = 50; // Negative security type 3
+ NS_T_NSEC3PARAM = 51; // Negative security type 3 parameters
+ NS_T_HIP = 55; // Host Identity Protocol
+ NS_T_SPF = 99; // Sender Policy Framework
+ NS_T_TKEY = 249; // Transaction key
+ NS_T_TSIG = 250; // Transaction signature.
+ NS_T_IXFR = 251; // Incremental zone transfer.
+ NS_T_AXFR = 252; // Transfer zone of authority.
+ NS_T_MAILB = 253; // Transfer mailbox records.
+ NS_T_MAILA = 254; // Transfer mail agent records.
+ NS_T_ANY = 255; // Wildcard match.
+ NS_T_ZXFR = 256; // BIND-specific, nonstandard.
+ NS_T_DLV = 32769; // DNSSEC look-aside validatation.
+ NS_T_MAX = 65536;
+}
+
+enum IpVersion {
+ IV_UNKNOWN = 0;
+ IV_IPV4 = 1;
+ IV_IPV6 = 2;
+}
+
+enum TransportType {
+ TT_UNKNOWN = 0;
+ TT_UDP = 1;
+ TT_TCP = 2;
+ TT_DOT = 3;
+}
+
+enum PrivateDnsModes {
+ PDM_UNKNOWN = 0;
+ PDM_OFF = 1;
+ PDM_OPPORTUNISTIC = 2;
+ PDM_STRICT = 3;
+}
+
+enum Transport {
+ // Indicates this network uses a Cellular transport.
+ TRANSPORT_DEFAULT = 0; // TRANSPORT_CELLULAR
+ // Indicates this network uses a Wi-Fi transport.
+ TRANSPORT_WIFI = 1;
+ // Indicates this network uses a Bluetooth transport.
+ TRANSPORT_BLUETOOTH = 2;
+ // Indicates this network uses an Ethernet transport.
+ TRANSPORT_ETHERNET = 3;
+ // Indicates this network uses a VPN transport.
+ TRANSPORT_VPN = 4;
+ // Indicates this network uses a Wi-Fi Aware transport.
+ TRANSPORT_WIFI_AWARE = 5;
+ // Indicates this network uses a LoWPAN transport.
+ TRANSPORT_LOWPAN = 6;
+}
+
+enum CacheStatus{
+ // the cache can't handle that kind of queries.
+ // or the answer buffer is too small.
+ CS_UNSUPPORTED = 0;
+ // the cache doesn't know about this query.
+ CS_NOTFOUND = 1;
+ // the cache found the answer.
+ CS_FOUND = 2;
+ // Don't do anything on cache.
+ CS_SKIP = 3;
+}
+
+message DnsQueryEvent {
+ optional android.stats.dnsresolver.NsRcode rcode = 1;
+
+ optional android.stats.dnsresolver.NsType type = 2;
+
+ optional android.stats.dnsresolver.CacheStatus cache_hit = 3;
+
+ optional android.stats.dnsresolver.IpVersion ip_version = 4;
+
+ optional android.stats.dnsresolver.TransportType transport = 5;
+
+ // Number of DNS query retry times
+ optional int32 retry_times = 6;
+
+ // Ordinal number of name server.
+ optional int32 dns_server_count = 7;
+
+ // Used only by TCP and DOT. True for new connections.
+ optional bool connected = 8;
+
+ optional int32 latency_micros = 9;
+}
+
+message DnsQueryEvents {
+ repeated DnsQueryEvent dns_query_event = 1;
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f1e9d659e0fd..be492505e230 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3395,7 +3395,7 @@
<item name="config_inCallNotificationVolume" format="float" type="dimen">.10</item>
<!-- URI for in call notification sound -->
- <string translatable="false" name="config_inCallNotificationSound">/system/media/audio/ui/InCallNotification.ogg</string>
+ <string translatable="false" name="config_inCallNotificationSound">/product/media/audio/ui/InCallNotification.ogg</string>
<!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
<integer name="config_cameraLiftTriggerSensorType">-1</integer>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 716376997f81..a92c50059a2a 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -70,7 +70,7 @@
<shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" />
<!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
- <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765" />
+ <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765|30075" />
<!-- Chile: 4-5 digits (not confirmed), known premium codes listed -->
<shortcode country="cl" pattern="\\d{4,5}" free="9963|9240" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 7b729284a063..76356ed572c7 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -444,8 +444,13 @@ public class SettingsBackupTest {
Settings.Global.ENABLE_GPU_DEBUG_LAYERS,
Settings.Global.GPU_DEBUG_APP,
Settings.Global.GPU_DEBUG_LAYERS,
- Settings.Global.GUP_DEV_OPT_IN_APPS,
- Settings.Global.GUP_BLACK_LIST,
+ Settings.Global.GAME_DRIVER_ALL_APPS,
+ Settings.Global.GAME_DRIVER_OPT_IN_APPS,
+ Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
+ Settings.Global.GAME_DRIVER_BLACKLISTS,
+ Settings.Global.GAME_DRIVER_BLACKLIST,
+ Settings.Global.GAME_DRIVER_WHITELIST,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 28099a16cda5..c17f076d2b71 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -33,12 +33,18 @@ applications that come with the platform
<permission name="android.permission.CRYPT_KEEPER"/>
</privapp-permissions>
+ <privapp-permissions package="com.android.captiveportallogin">
+ <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
+ <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
+ </privapp-permissions>
+
<privapp-permissions package="com.android.cellbroadcastreceiver">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
+ <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
</privapp-permissions>
<privapp-permissions package="com.android.defcontainer">
@@ -203,6 +209,7 @@ applications that come with the platform
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
<permission name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/>
<permission name="android.permission.MANAGE_USB"/>
+ <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
<permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/>
<permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
<permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
diff --git a/graphics/proto/Android.bp b/graphics/proto/Android.bp
new file mode 100644
index 000000000000..1d06348fb02f
--- /dev/null
+++ b/graphics/proto/Android.bp
@@ -0,0 +1,11 @@
+java_library_static {
+ name: "game-driver-protos",
+ host_supported: true,
+ proto: {
+ type: "lite",
+ },
+ srcs: ["game_driver.proto"],
+ no_framework_libs: true,
+ jarjar_rules: "jarjar-rules.txt",
+ sdk_version: "28",
+}
diff --git a/cmds/statsd/src/guardrail/MemoryLeakTrackUtil.h b/graphics/proto/game_driver.proto
index 444ed92cc9bb..fd7ffccac24c 100644
--- a/cmds/statsd/src/guardrail/MemoryLeakTrackUtil.h
+++ b/graphics/proto/game_driver.proto
@@ -1,11 +1,11 @@
/*
- * Copyright 2017, The Android Open Source Project
+ * Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -13,21 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#pragma once
-#include <iostream>
+syntax = "proto2";
-namespace android {
-namespace os {
-namespace statsd {
-/*
- * Dump the heap memory of the calling process, sorted by total size
- * (allocation size * number of allocations).
- *
- * limit is the number of unique allocations to return.
- */
-extern std::string dumpMemInfo(size_t limit);
+package android.gamedriver;
+
+option java_package = "android.gamedriver";
+option java_outer_classname = "GameDriverProto";
+
+message Blacklist {
+ optional int64 version_code = 1;
+ repeated string package_names = 2;
+}
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
+message Blacklists {
+ repeated Blacklist blacklists = 1;
+}
diff --git a/graphics/proto/jarjar-rules.txt b/graphics/proto/jarjar-rules.txt
new file mode 100644
index 000000000000..4e4063706352
--- /dev/null
+++ b/graphics/proto/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.** com.android.framework.protobuf.@1
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 66a547723b2f..47b7d646d79f 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -120,9 +120,8 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path));
// Find the resource table.
- ::ZipString entry_name(kResourcesArsc.c_str());
::ZipEntry entry;
- result = ::FindEntry(loaded_apk->zip_handle_.get(), entry_name, &entry);
+ result = ::FindEntry(loaded_apk->zip_handle_.get(), kResourcesArsc, &entry);
if (result != 0) {
// There is no resources.arsc, so create an empty LoadedArsc and return.
loaded_apk->loaded_arsc_ = LoadedArsc::CreateEmpty();
@@ -160,9 +159,8 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode mode) const {
CHECK(zip_handle_ != nullptr);
- ::ZipString name(path.c_str());
::ZipEntry entry;
- int32_t result = ::FindEntry(zip_handle_.get(), name, &entry);
+ int32_t result = ::FindEntry(zip_handle_.get(), path, &entry);
if (result != 0) {
return {};
}
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 6e2ca60cc3d3..44614c11fb14 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -98,7 +98,7 @@ ZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const
data->name = ZipString(entryName);
- const int32_t error = FindEntry(mHandle, data->name, &(data->entry));
+ const int32_t error = FindEntry(mHandle, entryName, &(data->entry));
if (error) {
delete data;
return NULL;
diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp
index 9e320a21b534..a81bb6ffab06 100644
--- a/libs/androidfw/tests/TestHelpers.cpp
+++ b/libs/androidfw/tests/TestHelpers.cpp
@@ -34,9 +34,8 @@ AssertionResult ReadFileFromZipToString(const std::string& zip_path, const std::
<< "': " << ::ErrorCodeString(result);
}
- ::ZipString name(file.c_str());
::ZipEntry entry;
- result = ::FindEntry(handle, name, &entry);
+ result = ::FindEntry(handle, file.c_str(), &entry);
if (result != 0) {
::CloseArchive(handle);
return AssertionFailure() << "Could not find file '" << file << "' in zip '" << zip_path
diff --git a/libs/usb/tests/AccessoryChat/Android.bp b/libs/usb/tests/AccessoryChat/Android.bp
index 4af6274b7ece..63a670c67bfc 100644
--- a/libs/usb/tests/AccessoryChat/Android.bp
+++ b/libs/usb/tests/AccessoryChat/Android.bp
@@ -1 +1,25 @@
subdirs = ["accessorychat"]
+//
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_test {
+ name: "AccessoryChat",
+
+ srcs: ["**/*.java"],
+
+ platform_apis: true,
+
+}
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
deleted file mode 100644
index cfe2da1eb471..000000000000
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := AccessoryChat
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
diff --git a/nfc-extras/tests/Android.bp b/nfc-extras/tests/Android.bp
new file mode 100644
index 000000000000..fc52006d14d2
--- /dev/null
+++ b/nfc-extras/tests/Android.bp
@@ -0,0 +1,33 @@
+// Copyright 2011, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "NfcExtrasTests",
+
+ // We only want this apk build for tests.
+
+ libs: [
+ "android.test.runner.stubs",
+ "com.android.nfc_extras.stubs",
+ "android.test.base.stubs",
+ ],
+
+ static_libs: ["junit"],
+
+ // Include all test java files.
+ srcs: ["src/**/*.java"],
+
+ sdk_version: "current",
+
+}
diff --git a/nfc-extras/tests/Android.mk b/nfc-extras/tests/Android.mk
deleted file mode 100644
index 8bba3ba99974..000000000000
--- a/nfc-extras/tests/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.runner.stubs \
- com.android.nfc_extras.stubs \
- android.test.base.stubs
-
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := NfcExtrasTests
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_PACKAGE)
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 44e0a659212a..ffd4d9d9acc6 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
<uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" />
<uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 5817118bc861..62de2ba45455 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -37,6 +37,7 @@ android_library {
"src/**/*.java",
":framework-networkstack-shared-srcs",
":services-networkstack-shared-srcs",
+ ":statslog-networkstack-java-gen",
],
static_libs: [
"androidx.annotation_annotation",
@@ -55,15 +56,24 @@ cc_library_shared {
srcs: [
"jni/network_stack_utils_jni.cpp"
],
-
+ sdk_version: "current",
shared_libs: [
"liblog",
- "libcutils",
- "libnativehelper",
- ],
- static_libs: [
- "libpcap",
+ "libnativehelper_compat_libc++",
],
+
+ // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
+ // java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
+ // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
+ // build because soong complains of:
+ // module NetworkStack missing dependencies: libc++_shared
+ //
+ // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
+ // we depend on do not dynamically link libc++. This is currently the case, because liblog is
+ // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
+ //
+ // TODO: find a better solution for this in R.
+ stl: "c++_static",
cflags: [
"-Wall",
"-Werror",
@@ -78,7 +88,10 @@ java_defaults {
static_libs: [
"NetworkStackBase",
],
- jni_libs: ["libnetworkstackutilsjni"],
+ jni_libs: [
+ "libnativehelper_compat_libc++",
+ "libnetworkstackutilsjni",
+ ],
// Resources already included in NetworkStackBase
resource_dirs: [],
jarjar_rules: "jarjar-rules-shared.txt",
@@ -104,3 +117,11 @@ android_app {
certificate: "networkstack",
manifest: "AndroidManifest.xml",
}
+
+genrule {
+ name: "statslog-networkstack-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module network_stack" +
+ " --javaPackage com.android.networkstack.metrics --javaClass NetworkStackStatsLog",
+ out: ["com/android/networkstack/metrics/NetworkStackStatsLog.java"],
+}
diff --git a/packages/NetworkStack/jni/network_stack_utils_jni.cpp b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
index 5544eaa809e7..f2ba5757ed80 100644
--- a/packages/NetworkStack/jni/network_stack_utils_jni.cpp
+++ b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
@@ -31,7 +31,7 @@
#include <string>
#include <nativehelper/JNIHelp.h>
-#include <utils/Log.h>
+#include <android/log.h>
namespace android {
constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils";
@@ -249,7 +249,7 @@ static const JNINativeMethod gNetworkStackUtilsMethods[] = {
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("ERROR: GetEnv failed");
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
return JNI_ERR;
}
@@ -261,4 +261,4 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
return JNI_VERSION_1_6;
}
-}; // namespace android \ No newline at end of file
+}; // namespace android
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
index 704788d7d7e2..478ed6b06596 100644
--- a/packages/NetworkStack/res/values/config.xml
+++ b/packages/NetworkStack/res/values/config.xml
@@ -7,6 +7,9 @@
values are meant to be the default when no other configuration is specified.
-->
+ <!-- DNS probe timeout for network validation. Enough for 3 DNS queries 5 seconds apart. -->
+ <integer name="default_captive_portal_dns_probe_timeout">12500</integer>
+
<!-- HTTP URL for network validation, to use for detecting captive portals. -->
<string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
@@ -27,6 +30,7 @@
<!-- Configuration hooks for the above settings.
Empty by default but may be overridden by RROs. -->
+ <integer name="config_captive_portal_dns_probe_timeout"></integer>
<!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
<string name="config_captive_portal_http_url" translatable="false"></string>
<!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 663e2f10ffe2..359c85983a94 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -39,6 +39,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.NattKeepalivePacketDataParcelable;
import android.net.TcpKeepalivePacketDataParcelable;
import android.net.apf.ApfGenerator.IllegalInstructionException;
import android.net.apf.ApfGenerator.Register;
@@ -1691,13 +1692,13 @@ public class ApfFilter {
}
/**
- * Add keepalive ack packet filter.
+ * Add TCP keepalive ack packet filter.
* This will add a filter to drop acks to the keepalive packet passed as an argument.
*
* @param slot The index used to access the filter.
* @param sentKeepalivePacket The attributes of the sent keepalive packet.
*/
- public synchronized void addKeepalivePacketFilter(final int slot,
+ public synchronized void addTcpKeepalivePacketFilter(final int slot,
final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
log("Adding keepalive ack(" + slot + ")");
if (null != mKeepaliveAcks.get(slot)) {
@@ -1711,6 +1712,18 @@ public class ApfFilter {
}
/**
+ * Add NATT keepalive packet filter.
+ * This will add a filter to drop NATT keepalive packet which is passed as an argument.
+ *
+ * @param slot The index used to access the filter.
+ * @param sentKeepalivePacket The attributes of the sent keepalive packet.
+ */
+ public synchronized void addNattKeepalivePacketFilter(final int slot,
+ final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
+ Log.e(TAG, "APF add NATT keepalive filter is not implemented");
+ }
+
+ /**
* Remove keepalive packet filter.
*
* @param slot The index used to access the filter.
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
index d7ff98b1f501..a15d42381ff0 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
@@ -195,6 +195,18 @@ public abstract class DhcpPacket {
public static final String VENDOR_INFO_ANDROID_METERED = "ANDROID_METERED";
/**
+ * DHCP Optional Type: Option overload option
+ */
+ protected static final byte DHCP_OPTION_OVERLOAD = 52;
+
+ /**
+ * Possible values of the option overload option.
+ */
+ private static final byte OPTION_OVERLOAD_FILE = 1;
+ private static final byte OPTION_OVERLOAD_SNAME = 2;
+ private static final byte OPTION_OVERLOAD_BOTH = 3;
+
+ /**
* DHCP Optional Type: DHCP Requested IP Address
*/
protected static final byte DHCP_REQUESTED_IP = 50;
@@ -309,6 +321,11 @@ public abstract class DhcpPacket {
protected final byte[] mClientMac;
/**
+ * The server host name from server.
+ */
+ protected String mServerHostName;
+
+ /**
* Asks the packet object to create a ByteBuffer serialization of
* the packet for transmission.
*/
@@ -848,6 +865,8 @@ public abstract class DhcpPacket {
Inet4Address ipDst = null;
Inet4Address bcAddr = null;
Inet4Address requestedIp = null;
+ String serverHostName;
+ byte optionOverload = 0;
// The following are all unsigned integers. Internally we store them as signed integers of
// the same length because that way we're guaranteed that they can't be out of the range of
@@ -989,9 +1008,9 @@ public abstract class DhcpPacket {
packet.get(clientMac);
// skip over address padding (16 octets allocated)
- packet.position(packet.position() + (16 - addrLen)
- + 64 // skip server host name (64 chars)
- + 128); // skip boot file name (128 chars)
+ packet.position(packet.position() + (16 - addrLen));
+ serverHostName = readAsciiString(packet, 64, false);
+ packet.position(packet.position() + 128);
// Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
if (packet.remaining() < 4) {
@@ -1102,6 +1121,11 @@ public abstract class DhcpPacket {
// Embedded nulls are safe as this does not get passed to netd.
vendorInfo = readAsciiString(packet, optionLen, true);
break;
+ case DHCP_OPTION_OVERLOAD:
+ expectedLen = 1;
+ optionOverload = packet.get();
+ optionOverload &= OPTION_OVERLOAD_BOTH;
+ break;
default:
// ignore any other parameters
for (int i = 0; i < optionLen; i++) {
@@ -1192,6 +1216,11 @@ public abstract class DhcpPacket {
newPacket.mT2 = T2;
newPacket.mVendorId = vendorId;
newPacket.mVendorInfo = vendorInfo;
+ if ((optionOverload & OPTION_OVERLOAD_SNAME) == 0) {
+ newPacket.mServerHostName = serverHostName;
+ } else {
+ newPacket.mServerHostName = "";
+ }
return newPacket;
}
@@ -1251,6 +1280,7 @@ public abstract class DhcpPacket {
results.vendorInfo = mVendorInfo;
results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
results.mtu = (mMtu != null && MIN_MTU <= mMtu && mMtu <= MAX_MTU) ? mMtu : 0;
+ results.serverHostName = mServerHostName;
return results;
}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
index d21b5f7853bb..b8ab94ce3830 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
@@ -647,4 +647,9 @@ public class DhcpServer extends IDhcpServer.Stub {
}
}
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 80d139cb6153..dc74c041c35a 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -29,6 +29,7 @@ import android.net.INetd;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.NattKeepalivePacketDataParcelable;
import android.net.NetworkStackIpMemoryStore;
import android.net.ProvisioningConfigurationParcelable;
import android.net.ProxyInfo;
@@ -371,6 +372,10 @@ public class IpClient extends StateMachine {
private boolean mMulticastFiltering;
private long mStartTimeMillis;
+ /* This must match the definition in KeepaliveTracker.KeepaliveInfo */
+ private static final int TYPE_NATT = 1;
+ private static final int TYPE_TCP = 2;
+
/**
* Reading the snapshot is an asynchronous operation initiated by invoking
* Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
@@ -553,10 +558,20 @@ public class IpClient extends StateMachine {
IpClient.this.addKeepalivePacketFilter(slot, pkt);
}
@Override
+ public void addNattKeepalivePacketFilter(int slot, NattKeepalivePacketDataParcelable pkt) {
+ checkNetworkStackCallingPermission();
+ IpClient.this.addNattKeepalivePacketFilter(slot, pkt);
+ }
+ @Override
public void removeKeepalivePacketFilter(int slot) {
checkNetworkStackCallingPermission();
IpClient.this.removeKeepalivePacketFilter(slot);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
public String getInterfaceName() {
@@ -686,11 +701,20 @@ public class IpClient extends StateMachine {
}
/**
- * Called by WifiStateMachine to add keepalive packet filter before setting up
+ * Called by WifiStateMachine to add TCP keepalive packet filter before setting up
* keepalive offload.
*/
public void addKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketDataParcelable pkt) {
- sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */, pkt);
+ sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, TYPE_TCP, pkt);
+ }
+
+ /**
+ * Called by WifiStateMachine to add NATT keepalive packet filter before setting up
+ * keepalive offload.
+ */
+ public void addNattKeepalivePacketFilter(int slot,
+ @NonNull NattKeepalivePacketDataParcelable pkt) {
+ sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, TYPE_NATT, pkt);
}
/**
@@ -1602,9 +1626,16 @@ public class IpClient extends StateMachine {
case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF: {
final int slot = msg.arg1;
+ final int type = msg.arg2;
+
if (mApfFilter != null) {
- mApfFilter.addKeepalivePacketFilter(slot,
- (TcpKeepalivePacketDataParcelable) msg.obj);
+ if (type == TYPE_NATT) {
+ mApfFilter.addNattKeepalivePacketFilter(slot,
+ (NattKeepalivePacketDataParcelable) msg.obj);
+ } else {
+ mApfFilter.addTcpKeepalivePacketFilter(slot,
+ (TcpKeepalivePacketDataParcelable) msg.obj);
+ }
}
break;
}
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
index fb03c544fd30..abfed3e1d84c 100644
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
@@ -62,6 +62,49 @@ public class NetworkStackUtils {
*/
public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
+ /**
+ * The URL used for HTTPS captive portal detection upon a new connection.
+ * A 204 response code from the server is used for validation.
+ */
+ public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
+
+ /**
+ * The URL used for HTTP captive portal detection upon a new connection.
+ * A 204 response code from the server is used for validation.
+ */
+ public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
+
+ /**
+ * The URL used for fallback HTTP captive portal detection when previous HTTP
+ * and HTTPS captive portal detection attemps did not return a conclusive answer.
+ */
+ public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
+
+ /**
+ * What to do when connecting a network that presents a captive portal.
+ * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
+ *
+ * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
+ */
+ public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
+
+ /**
+ * Don't attempt to detect captive portals.
+ */
+ public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
+
+ /**
+ * When detecting a captive portal, display a notification that
+ * prompts the user to sign in.
+ */
+ public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
+
+ /**
+ * When detecting a captive portal, immediately disconnect from the
+ * network and do not reconnect to that network in the future.
+ */
+ public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
+
static {
System.loadLibrary("networkstackutilsjni");
}
diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
index 225dc0f4bfdc..2523ecd4ea20 100644
--- a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java
+++ b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.metrics;
+package com.android.networkstack.metrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
index c96411e1e39f..93089017fd47 100644
--- a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
+++ b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.metrics;
+package com.android.networkstack.metrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -41,7 +41,6 @@ public class DataStallStatsUtils {
private static int probeResultToEnum(@Nullable final CaptivePortalProbeResult result) {
if (result == null) return DataStallEventProto.INVALID;
- // TODO: Add partial connectivity support.
if (result.isSuccessful()) {
return DataStallEventProto.VALID;
} else if (result.isPortal()) {
@@ -63,6 +62,12 @@ public class DataStallStatsUtils {
Log.d(TAG, "write: " + stats + " with result: " + validationResult
+ ", dns: " + HexDump.toHexString(stats.mDns));
}
- // TODO(b/124613085): Send to Statsd once the public StatsLog API is ready.
+ NetworkStackStatsLog.write(NetworkStackStatsLog.DATA_STALL_EVENT,
+ stats.mEvaluationType,
+ validationResult,
+ stats.mNetworkType,
+ stats.mWifiInfo,
+ stats.mCellularInfo,
+ stats.mDns);
}
}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index a0a90fde518f..a6d74842f631 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -251,6 +251,11 @@ public class NetworkStackService extends Service {
}
}
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private static class NetworkMonitorImpl extends INetworkMonitor.Stub {
@@ -325,5 +330,10 @@ public class NetworkStackService extends Service {
checkNetworkStackCallingPermission();
mNm.notifyNetworkCapabilitiesChanged(nc);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index d88e3dc84848..bacec78e5699 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -44,6 +44,12 @@ import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_MIN_EVALUATE_TI
import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS;
import static android.net.util.DataStallUtils.DEFAULT_DNS_LOG_SIZE;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE;
+import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
@@ -59,6 +65,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
import android.net.LinkProperties;
@@ -69,8 +76,6 @@ import android.net.TrafficStats;
import android.net.Uri;
import android.net.captiveportal.CaptivePortalProbeResult;
import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.metrics.DataStallDetectionStats;
-import android.net.metrics.DataStallStatsUtils;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.metrics.ValidationProbeEvent;
@@ -106,6 +111,8 @@ import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.TrafficStatsConstants;
import com.android.networkstack.R;
+import com.android.networkstack.metrics.DataStallDetectionStats;
+import com.android.networkstack.metrics.DataStallStatsUtils;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -122,6 +129,7 @@ import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
/**
@@ -136,8 +144,13 @@ public class NetworkMonitor extends StateMachine {
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/60.0.3112.32 Safari/537.36";
+ @VisibleForTesting
+ static final String CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT =
+ "captive_portal_dns_probe_timeout";
+
private static final int SOCKET_TIMEOUT_MS = 10000;
private static final int PROBE_TIMEOUT_MS = 3000;
+
enum EvaluationResult {
VALIDATED(true),
CAPTIVE_PORTAL(false);
@@ -1168,10 +1181,10 @@ public class NetworkMonitor extends StateMachine {
}
private boolean getIsCaptivePortalCheckEnabled() {
- String symbol = Settings.Global.CAPTIVE_PORTAL_MODE;
- int defaultValue = Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT;
+ String symbol = CAPTIVE_PORTAL_MODE;
+ int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT;
int mode = mDependencies.getSetting(mContext, symbol, defaultValue);
- return mode != Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE;
+ return mode != CAPTIVE_PORTAL_MODE_IGNORE;
}
private boolean getUseHttpsValidation() {
@@ -1181,8 +1194,34 @@ public class NetworkMonitor extends StateMachine {
private String getCaptivePortalServerHttpsUrl() {
return getSettingFromResource(mContext, R.string.config_captive_portal_https_url,
- R.string.default_captive_portal_https_url,
- Settings.Global.CAPTIVE_PORTAL_HTTPS_URL);
+ R.string.default_captive_portal_https_url, CAPTIVE_PORTAL_HTTPS_URL);
+ }
+
+ private int getDnsProbeTimeout() {
+ return getIntSetting(mContext, R.integer.config_captive_portal_dns_probe_timeout,
+ CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout);
+ }
+
+ /**
+ * Gets an integer setting from resources or device config
+ *
+ * configResource is used if set, followed by device config if set, followed by defaultResource.
+ * If none of these are set then an exception is thrown.
+ *
+ * TODO: move to a common location such as a ConfigUtils class.
+ * TODO(b/130324939): test that the resources can be overlayed by an RRO package.
+ */
+ @VisibleForTesting
+ int getIntSetting(@NonNull final Context context, @StringRes int configResource,
+ @NonNull String symbol, @StringRes int defaultResource) {
+ final Resources res = context.getResources();
+ try {
+ return res.getInteger(configResource);
+ } catch (Resources.NotFoundException e) {
+ return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
+ symbol, res.getInteger(defaultResource));
+ }
}
/**
@@ -1194,8 +1233,7 @@ public class NetworkMonitor extends StateMachine {
*/
public String getCaptivePortalServerHttpUrl() {
return getSettingFromResource(mContext, R.string.config_captive_portal_http_url,
- R.string.default_captive_portal_http_url,
- Settings.Global.CAPTIVE_PORTAL_HTTP_URL);
+ R.string.default_captive_portal_http_url, CAPTIVE_PORTAL_HTTP_URL);
}
private int getConsecutiveDnsTimeoutThreshold() {
@@ -1224,8 +1262,8 @@ public class NetworkMonitor extends StateMachine {
private URL[] makeCaptivePortalFallbackUrls() {
try {
- final String firstUrl = mDependencies.getSetting(mContext,
- Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL, null);
+ final String firstUrl = mDependencies.getSetting(mContext, CAPTIVE_PORTAL_FALLBACK_URL,
+ null);
final URL[] settingProviderUrls;
if (!TextUtils.isEmpty(firstUrl)) {
@@ -1446,6 +1484,45 @@ public class NetworkMonitor extends StateMachine {
return sendHttpProbe(url, probeType, null);
}
+ /** Do a DNS lookup for the given server, or throw UnknownHostException after timeoutMs */
+ @VisibleForTesting
+ protected InetAddress[] sendDnsProbeWithTimeout(String host, int timeoutMs)
+ throws UnknownHostException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AtomicReference<List<InetAddress>> resultRef = new AtomicReference<>();
+ final DnsResolver.Callback<List<InetAddress>> callback =
+ new DnsResolver.Callback<List<InetAddress>>() {
+ public void onAnswer(List<InetAddress> answer, int rcode) {
+ if (rcode == 0) {
+ resultRef.set(answer);
+ }
+ latch.countDown();
+ }
+ public void onError(@NonNull DnsResolver.DnsException e) {
+ validationLog("DNS error resolving " + host + ": " + e.getMessage());
+ latch.countDown();
+ }
+ };
+
+ final int oldTag = TrafficStats.getAndSetThreadStatsTag(
+ TrafficStatsConstants.TAG_SYSTEM_PROBE);
+ mDependencies.getDnsResolver().query(mNetwork, host, DnsResolver.FLAG_EMPTY,
+ r -> r.run() /* executor */, null /* cancellationSignal */, callback);
+ TrafficStats.setThreadStatsTag(oldTag);
+
+ try {
+ latch.await(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+
+ List<InetAddress> result = resultRef.get();
+ if (result == null || result.size() == 0) {
+ throw new UnknownHostException(host);
+ }
+
+ return result.toArray(new InetAddress[0]);
+ }
+
/** Do a DNS resolution of the given server. */
private void sendDnsProbe(String host) {
if (TextUtils.isEmpty(host)) {
@@ -1457,7 +1534,7 @@ public class NetworkMonitor extends StateMachine {
int result;
String connectInfo;
try {
- InetAddress[] addresses = mNetwork.getAllByName(host);
+ InetAddress[] addresses = sendDnsProbeWithTimeout(host, getDnsProbeTimeout());
StringBuffer buffer = new StringBuffer();
for (InetAddress address : addresses) {
buffer.append(',').append(address.getHostAddress());
@@ -1782,6 +1859,10 @@ public class NetworkMonitor extends StateMachine {
return new OneAddressPerFamilyNetwork(network);
}
+ public DnsResolver getDnsResolver() {
+ return DnsResolver.getInstance();
+ }
+
public Random getRandom() {
return new Random();
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
index 5650f2125737..6a6bf83bd3c8 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
@@ -33,8 +33,8 @@ import android.net.IIpMemoryStore;
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -297,16 +297,16 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
*/
@Override
public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
- @Nullable final IOnSameNetworkResponseListener listener) {
+ @Nullable final IOnSameL3NetworkResponseListener listener) {
if (null == listener) return;
mExecutor.execute(() -> {
try {
if (null == l2Key1 || null == l2Key2) {
- listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
return;
}
if (null == mDb) {
- listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
return;
}
try {
@@ -315,16 +315,16 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
final NetworkAttributes attr2 =
IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
if (null == attr1 || null == attr2) {
- listener.onSameNetworkResponse(makeStatus(SUCCESS),
+ listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
new SameL3NetworkResponse(l2Key1, l2Key2,
-1f /* never connected */).toParcelable());
return;
}
final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
- listener.onSameNetworkResponse(makeStatus(SUCCESS),
+ listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
} catch (Exception e) {
- listener.onSameNetworkResponse(makeStatus(ERROR_GENERIC), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
}
} catch (final RemoteException e) {
// Client at the other end died
@@ -343,7 +343,7 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
*/
@Override
public void retrieveNetworkAttributes(@Nullable final String l2Key,
- @Nullable final IOnNetworkAttributesRetrieved listener) {
+ @Nullable final IOnNetworkAttributesRetrievedListener listener) {
if (null == listener) return;
mExecutor.execute(() -> {
try {
@@ -494,4 +494,9 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED));
return true;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
index 2775fde4c8b9..bea7052d8af2 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
@@ -91,6 +91,11 @@ public final class RegularMaintenanceJobService extends JobService {
}
@Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+
+ @Override
public IBinder asBinder() {
return null;
}
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index fe3c1e8eb3e5..039f6bf791fb 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/Android.bp
@@ -56,6 +56,7 @@ android_test {
"liblog",
"liblzma",
"libnativehelper",
+ "libnativehelper_compat_libc++",
"libnetworkstacktestsjni",
"libnetworkstackutilsjni",
"libpackagelistparser",
@@ -99,5 +100,4 @@ cc_library_shared {
"libapf",
"libpcap",
],
-
}
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
index a0e508f130a5..93ab3be28fc7 100644
--- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
+++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
@@ -1553,7 +1553,7 @@ public class ApfTest {
parcel.seq = seqNum;
parcel.ack = ackNum;
- apfFilter.addKeepalivePacketFilter(slot1, parcel);
+ apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
program = cb.getApfProgram();
// Verify IPv4 keepalive ack packet is dropped
@@ -1592,7 +1592,7 @@ public class ApfTest {
ipv6Parcel.seq = seqNum;
ipv6Parcel.ack = ackNum;
- apfFilter.addKeepalivePacketFilter(slot1, ipv6Parcel);
+ apfFilter.addTcpKeepalivePacketFilter(slot1, ipv6Parcel);
program = cb.getApfProgram();
// Verify IPv6 keepalive ack packet is dropped
@@ -1614,8 +1614,8 @@ public class ApfTest {
apfFilter.removeKeepalivePacketFilter(slot1);
// Verify multiple filters
- apfFilter.addKeepalivePacketFilter(slot1, parcel);
- apfFilter.addKeepalivePacketFilter(slot2, ipv6Parcel);
+ apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
+ apfFilter.addTcpKeepalivePacketFilter(slot2, ipv6Parcel);
program = cb.getApfProgram();
// Verify IPv4 keepalive ack packet is dropped
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java
index 4d98403bfd4e..a30d3e492406 100644
--- a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java
@@ -302,8 +302,9 @@ public class DhcpPacketTest {
}
private void assertDhcpResults(String ipAddress, String gateway, String dnsServersString,
- String domains, String serverAddress, String vendorInfo, int leaseDuration,
- boolean hasMeteredHint, int mtu, DhcpResults dhcpResults) throws Exception {
+ String domains, String serverAddress, String serverHostName, String vendorInfo,
+ int leaseDuration, boolean hasMeteredHint, int mtu, DhcpResults dhcpResults)
+ throws Exception {
assertEquals(new LinkAddress(ipAddress), dhcpResults.ipAddress);
assertEquals(v4Address(gateway), dhcpResults.gateway);
@@ -316,6 +317,7 @@ public class DhcpPacketTest {
assertEquals(domains, dhcpResults.domains);
assertEquals(v4Address(serverAddress), dhcpResults.serverAddress);
+ assertEquals(serverHostName, dhcpResults.serverHostName);
assertEquals(vendorInfo, dhcpResults.vendorInfo);
assertEquals(leaseDuration, dhcpResults.leaseDuration);
assertEquals(hasMeteredHint, dhcpResults.hasMeteredHint());
@@ -327,6 +329,7 @@ public class DhcpPacketTest {
// TODO: Turn all of these into golden files. This will probably require using
// androidx.test.InstrumentationRegistry for obtaining a Context object
// to read such golden files, along with an appropriate Android.mk.
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// IP header.
"451001480000000080118849c0a89003c0a89ff7" +
@@ -347,16 +350,18 @@ public class DhcpPacketTest {
// Options
"638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
"3a0400000e103b040000189cff00000000000000000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
assertTrue(offerPacket instanceof DhcpOfferPacket); // Implicitly checks it's non-null.
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
- null, "192.168.144.3", null, 7200, false, 0, dhcpResults);
+ null, "192.168.144.3", "", null, 7200, false, 0, dhcpResults);
}
@Test
public void testOffer2() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// IP header.
"450001518d0600004011144dc0a82b01c0a82bf7" +
@@ -366,9 +371,9 @@ public class DhcpPacketTest {
"02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
// MAC address.
"30766ff2a90c00000000000000000000" +
- // Server name.
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Server name ("dhcp.android.com" plus invalid "AAAA" after null terminator).
+ "646863702e616e64726f69642e636f6d00000000000000000000000000000000" +
+ "0000000000004141414100000000000000000000000000000000000000000000" +
// File.
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
@@ -377,13 +382,15 @@ public class DhcpPacketTest {
// Options
"638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
"1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
+ // CHECKSTYLE:ON Generated code
assertEquals(337, packet.limit());
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
assertTrue(offerPacket instanceof DhcpOfferPacket); // Implicitly checks it's non-null.
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("192.168.43.247/24", "192.168.43.1", "192.168.43.1",
- null, "192.168.43.1", "ANDROID_METERED", 3600, true, 0, dhcpResults);
+ null, "192.168.43.1", "dhcp.android.com", "ANDROID_METERED", 3600, true, 0,
+ dhcpResults);
assertTrue(dhcpResults.hasMeteredHint());
}
@@ -588,11 +595,12 @@ public class DhcpPacketTest {
assertTrue(offerPacket instanceof DhcpOfferPacket); // Implicitly checks it's non-null.
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
- null, "192.168.144.3", null, 7200, false, expectedMtu, dhcpResults);
+ null, "192.168.144.3", "", null, 7200, false, expectedMtu, dhcpResults);
}
@Test
public void testMtu() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// IP header.
"451001480000000080118849c0a89003c0a89ff7" +
@@ -613,6 +621,7 @@ public class DhcpPacketTest {
// Options
"638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
"3a0400000e103b040000189cff00000000"));
+ // CHECKSTYLE:ON Generated code
checkMtu(packet, 0, null);
checkMtu(packet, 0, mtuBytes(1501));
@@ -629,6 +638,7 @@ public class DhcpPacketTest {
@Test
public void testBadHwaddrLength() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// IP header.
"450001518d0600004011144dc0a82b01c0a82bf7" +
@@ -649,6 +659,7 @@ public class DhcpPacketTest {
// Options
"638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
"1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
+ // CHECKSTYLE:ON Generated code
String expectedClientMac = "30766FF2A90C";
final int hwAddrLenOffset = 20 + 8 + 2;
@@ -705,6 +716,7 @@ public class DhcpPacketTest {
// store any information in the overloaded fields).
//
// For now, we just check that it parses correctly.
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// Ethernet header.
"b4cef6000000e80462236e300800" +
@@ -727,16 +739,18 @@ public class DhcpPacketTest {
// Options
"638253633501023604010101010104ffff000033040000a8c03401030304ac1101010604ac110101" +
"0000000000000000000000000000000000000000000000ff000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
assertTrue(offerPacket instanceof DhcpOfferPacket);
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1",
- null, "1.1.1.1", null, 43200, false, 0, dhcpResults);
+ null, "1.1.1.1", "", null, 43200, false, 0, dhcpResults);
}
@Test
public void testBug2111() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// IP header.
"4500014c00000000ff119beac3eaf3880a3f5d04" +
@@ -757,16 +771,18 @@ public class DhcpPacketTest {
// Options.
"638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" +
"0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
assertTrue(offerPacket instanceof DhcpOfferPacket);
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2",
- "domain123.co.uk", "192.0.2.254", null, 49094, false, 0, dhcpResults);
+ "domain123.co.uk", "192.0.2.254", "", null, 49094, false, 0, dhcpResults);
}
@Test
public void testBug2136() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// Ethernet header.
"bcf5ac000000d0c7890000000800" +
@@ -789,17 +805,19 @@ public class DhcpPacketTest {
// Options.
"6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" +
"0f0b6c616e63732e61632e756b000000000000000000ff00000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
assertTrue(offerPacket instanceof DhcpOfferPacket);
assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac()));
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
- "lancs.ac.uk", "10.32.255.128", null, 7200, false, 0, dhcpResults);
+ "lancs.ac.uk", "10.32.255.128", "", null, 7200, false, 0, dhcpResults);
}
@Test
public void testUdpServerAnySourcePort() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// Ethernet header.
"9cd917000000001c2e0000000800" +
@@ -823,6 +841,7 @@ public class DhcpPacketTest {
// Options.
"6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
"d18180060f0777766d2e6564751c040a0fffffff000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
assertTrue(offerPacket instanceof DhcpOfferPacket);
@@ -830,11 +849,12 @@ public class DhcpPacketTest {
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("10.15.122.242/16", "10.15.200.23",
"209.129.128.3,209.129.148.3,209.129.128.6",
- "wvm.edu", "10.1.105.252", null, 86400, false, 0, dhcpResults);
+ "wvm.edu", "10.1.105.252", "", null, 86400, false, 0, dhcpResults);
}
@Test
public void testUdpInvalidDstPort() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// Ethernet header.
"9cd917000000001c2e0000000800" +
@@ -858,6 +878,7 @@ public class DhcpPacketTest {
// Options.
"6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
"d18180060f0777766d2e6564751c040a0fffffff000000"));
+ // CHECKSTYLE:ON Generated code
try {
DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
@@ -867,6 +888,7 @@ public class DhcpPacketTest {
@Test
public void testMultipleRouters() throws Exception {
+ // CHECKSTYLE:OFF Generated code
final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
// Ethernet header.
"fc3d93000000" + "081735000000" + "0800" +
@@ -889,13 +911,14 @@ public class DhcpPacketTest {
// Options.
"638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
"0308c0a8bd01ffffff0006080808080808080404ff000000000000"));
+ // CHECKSTYLE:ON Generated code
DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
assertTrue(offerPacket instanceof DhcpOfferPacket);
assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
DhcpResults dhcpResults = offerPacket.toDhcpResults();
assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
- null, "192.171.189.2", null, 28800, false, 0, dhcpResults);
+ null, "192.171.189.2", "", null, 28800, false, 0, dhcpResults);
}
@Test
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
index 7d5e9e3ba174..f0e2f1b8d459 100644
--- a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
+++ b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
@@ -133,6 +133,11 @@ public class DhcpServerTest {
public void onStatusAvailable(int statusCode) {
assertEquals(STATUS_SUCCESS, statusCode);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
@Before
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index 7d9eb9b55d07..0dc1cbf8a984 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -33,6 +33,7 @@ import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -41,6 +42,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
@@ -55,6 +57,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkMonitorCallbacks;
import android.net.InetAddresses;
import android.net.LinkProperties;
@@ -62,8 +65,6 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.metrics.DataStallDetectionStats;
-import android.net.metrics.DataStallStatsUtils;
import android.net.metrics.IpConnectivityLog;
import android.net.util.SharedLog;
import android.net.wifi.WifiInfo;
@@ -71,6 +72,7 @@ import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
@@ -81,6 +83,10 @@ import android.util.ArrayMap;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.networkstack.R;
+import com.android.networkstack.metrics.DataStallDetectionStats;
+import com.android.networkstack.metrics.DataStallStatsUtils;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -95,8 +101,12 @@ import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Random;
+import java.util.concurrent.Executor;
import javax.net.ssl.SSLHandshakeException;
@@ -110,6 +120,7 @@ public class NetworkMonitorTest {
private @Mock IpConnectivityLog mLogger;
private @Mock SharedLog mValidationLogger;
private @Mock NetworkInfo mNetworkInfo;
+ private @Mock DnsResolver mDnsResolver;
private @Mock ConnectivityManager mCm;
private @Mock TelephonyManager mTelephony;
private @Mock WifiManager mWifi;
@@ -155,10 +166,36 @@ public class NetworkMonitorTest {
private static final NetworkCapabilities NO_INTERNET_CAPABILITIES = new NetworkCapabilities()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ private void setDnsAnswers(String[] answers) throws UnknownHostException {
+ if (answers == null) {
+ doThrow(new UnknownHostException()).when(mNetwork).getAllByName(any());
+ doNothing().when(mDnsResolver).query(any(), any(), anyInt(), any(), any(), any());
+ return;
+ }
+
+ List<InetAddress> answerList = new ArrayList<>();
+ for (String answer : answers) {
+ answerList.add(InetAddresses.parseNumericAddress(answer));
+ }
+ InetAddress[] answerArray = answerList.toArray(new InetAddress[0]);
+
+ doReturn(answerArray).when(mNetwork).getAllByName(any());
+
+ doAnswer((invocation) -> {
+ Executor executor = (Executor) invocation.getArgument(3);
+ DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(5);
+ new Handler(Looper.getMainLooper()).post(() -> {
+ executor.execute(() -> callback.onAnswer(answerList, 0));
+ });
+ return null;
+ }).when(mDnsResolver).query(eq(mNetwork), any(), anyInt(), any(), any(), any());
+ }
+
@Before
public void setUp() throws IOException {
MockitoAnnotations.initMocks(this);
when(mDependencies.getPrivateDnsBypassNetwork(any())).thenReturn(mNetwork);
+ when(mDependencies.getDnsResolver()).thenReturn(mDnsResolver);
when(mDependencies.getRandom()).thenReturn(mRandom);
when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt()))
.thenReturn(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
@@ -203,9 +240,8 @@ public class NetworkMonitorTest {
}).when(mNetwork).openConnection(any());
when(mHttpConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
when(mHttpsConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
- doReturn(new InetAddress[] {
- InetAddresses.parseNumericAddress("192.168.0.0")
- }).when(mNetwork).getAllByName(any());
+
+ setDnsAnswers(new String[]{"2001:db8::1", "192.0.2.2"});
when(mContext.registerReceiver(any(BroadcastReceiver.class), any())).then((invocation) -> {
mRegisteredReceivers.add(invocation.getArgument(0));
@@ -312,6 +348,44 @@ public class NetworkMonitorTest {
}
@Test
+ public void testGetIntSetting() throws Exception {
+ WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
+
+ // No config resource, no device config. Expect to get default resource.
+ doThrow(new Resources.NotFoundException())
+ .when(mResources).getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout));
+ doAnswer(invocation -> {
+ int defaultValue = invocation.getArgument(2);
+ return defaultValue;
+ }).when(mDependencies).getDeviceConfigPropertyInt(any(),
+ eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT),
+ anyInt());
+ when(mResources.getInteger(eq(R.integer.default_captive_portal_dns_probe_timeout)))
+ .thenReturn(42);
+ assertEquals(42, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+
+ // Set device config. Expect to get device config.
+ when(mDependencies.getDeviceConfigPropertyInt(any(),
+ eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT), anyInt()))
+ .thenReturn(1234);
+ assertEquals(1234, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+
+ // Set config resource. Expect to get config resource.
+ when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
+ .thenReturn(5678);
+ assertEquals(5678, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+ }
+
+ @Test
public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
setSslException(mHttpsConnection);
setPortal302(mHttpConnection);
@@ -641,6 +715,45 @@ public class NetworkMonitorTest {
runPartialConnectivityNetworkTest();
}
+ private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
+ String[] actualStrings = new String[actual.length];
+ for (int i = 0; i < actual.length; i++) {
+ actualStrings[i] = actual[i].getHostAddress();
+ }
+ assertArrayEquals("Array of IP addresses differs", expected, actualStrings);
+ }
+
+ @Test
+ public void testSendDnsProbeWithTimeout() throws Exception {
+ WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
+ final int shortTimeoutMs = 200;
+
+ String[] expected = new String[]{"2001:db8::"};
+ setDnsAnswers(expected);
+ InetAddress[] actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ assertIpAddressArrayEquals(expected, actual);
+
+ expected = new String[]{"2001:db8::", "192.0.2.1"};
+ setDnsAnswers(expected);
+ actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ assertIpAddressArrayEquals(expected, actual);
+
+ expected = new String[0];
+ setDnsAnswers(expected);
+ try {
+ wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ fail("No DNS results, expected UnknownHostException");
+ } catch (UnknownHostException e) {
+ }
+
+ setDnsAnswers(null);
+ try {
+ wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ fail("DNS query timed out, expected UnknownHostException");
+ } catch (UnknownHostException e) {
+ }
+ }
+
private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
for (int i = 0; i < count; i++) {
wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
index 94cc58919459..87346e5d6a28 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -31,8 +31,8 @@ import android.content.Context;
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -136,6 +136,11 @@ public class IpMemoryStoreServiceTest {
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -156,6 +161,11 @@ public class IpMemoryStoreServiceTest {
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -163,9 +173,9 @@ public class IpMemoryStoreServiceTest {
private interface OnNetworkAttributesRetrievedListener {
void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
}
- private IOnNetworkAttributesRetrieved onNetworkAttributesRetrieved(
+ private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
final OnNetworkAttributesRetrievedListener functor) {
- return new IOnNetworkAttributesRetrieved() {
+ return new IOnNetworkAttributesRetrievedListener() {
@Override
public void onNetworkAttributesRetrieved(final StatusParcelable status,
final String l2Key, final NetworkAttributesParcelable attributes)
@@ -178,21 +188,26 @@ public class IpMemoryStoreServiceTest {
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
/** Helper method to make an IOnSameNetworkResponseListener */
- private interface OnSameNetworkResponseListener {
- void onSameNetworkResponse(Status status, SameL3NetworkResponse answer);
+ private interface OnSameL3NetworkResponseListener {
+ void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
}
- private IOnSameNetworkResponseListener onSameResponse(
- final OnSameNetworkResponseListener functor) {
- return new IOnSameNetworkResponseListener() {
+ private IOnSameL3NetworkResponseListener onSameResponse(
+ final OnSameL3NetworkResponseListener functor) {
+ return new IOnSameL3NetworkResponseListener() {
@Override
- public void onSameNetworkResponse(final StatusParcelable status,
+ public void onSameL3NetworkResponse(final StatusParcelable status,
final SameL3NetworkResponseParcelable sameL3Network)
throws RemoteException {
- functor.onSameNetworkResponse(new Status(status),
+ functor.onSameL3NetworkResponse(new Status(status),
null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
}
@@ -200,6 +215,11 @@ public class IpMemoryStoreServiceTest {
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -219,6 +239,11 @@ public class IpMemoryStoreServiceTest {
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 2c4abaeb9949..d5b121768a66 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1131,7 +1131,4 @@
<!-- The notice header of Third-party licenses. not translatable -->
<string name="notice_header" translatable="false"></string>
-
- <!-- UI debug setting: opt in to use updated graphics driver? [CHAR LIMIT=100] -->
- <string name="gup_dev_opt_in_app_summary">Opt in app to use Game Update Package in developement</string>
</resources>
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index e1a602b53d9d..9536bae6bbe6 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -68,19 +68,19 @@
<!-- user interface sound effects -->
<integer name="def_power_sounds_enabled">1</integer>
- <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
+ <string name="def_low_battery_sound" translatable="false">/product/media/audio/ui/LowBattery.ogg</string>
<integer name="def_dock_sounds_enabled">0</integer>
<integer name="def_dock_sounds_enabled_when_accessibility">0</integer>
- <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
- <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
- <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
- <string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
+ <string name="def_desk_dock_sound" translatable="false">/product/media/audio/ui/Dock.ogg</string>
+ <string name="def_desk_undock_sound" translatable="false">/product/media/audio/ui/Undock.ogg</string>
+ <string name="def_car_dock_sound" translatable="false">/product/media/audio/ui/Dock.ogg</string>
+ <string name="def_car_undock_sound" translatable="false">/product/media/audio/ui/Undock.ogg</string>
<integer name="def_lockscreen_sounds_enabled">1</integer>
- <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
- <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
- <string name="def_trusted_sound" translatable="false">/system/media/audio/ui/Trusted.ogg</string>
- <string name="def_wireless_charging_started_sound" translatable="false">/system/media/audio/ui/WirelessChargingStarted.ogg</string>
- <string name="def_charging_started_sound" translatable="false">/system/media/audio/ui/ChargingStarted.ogg</string>
+ <string name="def_lock_sound" translatable="false">/product/media/audio/ui/Lock.ogg</string>
+ <string name="def_unlock_sound" translatable="false">/product/media/audio/ui/Unlock.ogg</string>
+ <string name="def_trusted_sound" translatable="false">/product/media/audio/ui/Trusted.ogg</string>
+ <string name="def_wireless_charging_started_sound" translatable="false">/product/media/audio/ui/WirelessChargingStarted.ogg</string>
+ <string name="def_charging_started_sound" translatable="false">/product/media/audio/ui/ChargingStarted.ogg</string>
<!-- sound trigger detection service default values -->
<integer name="def_max_sound_trigger_detection_service_ops_per_day" translatable="false">1000</integer>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 759b51c853da..c60e352e9960 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -648,11 +648,26 @@ class SettingsProtoDumpUtil {
Settings.Global.GPU_DEBUG_LAYERS,
GlobalSettingsProto.Gpu.DEBUG_LAYERS);
dumpSetting(s, p,
- Settings.Global.GUP_DEV_OPT_IN_APPS,
- GlobalSettingsProto.Gpu.GUP_DEV_OPT_IN_APPS);
+ Settings.Global.GAME_DRIVER_ALL_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_ALL_APPS);
dumpSetting(s, p,
- Settings.Global.GUP_BLACK_LIST,
- GlobalSettingsProto.Gpu.GUP_BLACK_LIST);
+ Settings.Global.GAME_DRIVER_OPT_IN_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_BLACKLIST,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_BLACKLIST);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_WHITELIST,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_WHITELIST);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_BLACKLISTS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_BLACKLISTS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_SPHAL_LIBRARIES);
p.end(gpuToken);
final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
diff --git a/packages/Shell/Android.bp b/packages/Shell/Android.bp
new file mode 100644
index 000000000000..aaaf0448fc31
--- /dev/null
+++ b/packages/Shell/Android.bp
@@ -0,0 +1,14 @@
+android_app {
+ name: "Shell",
+ srcs: ["src/**/*.java",":dumpstate_aidl"],
+ aidl: {
+ include_dirs: ["frameworks/native/cmds/dumpstate/binder"],
+ },
+ static_libs: ["androidx.legacy_legacy-support-v4"],
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+ jacoco: {
+ include_filter: ["com.android.shell.*"],
+ },
+}
diff --git a/packages/Shell/Android.mk b/packages/Shell/Android.mk
deleted file mode 100644
index b738d7771465..000000000000
--- a/packages/Shell/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_SRC_FILES += \
- ../../../native/cmds/dumpstate/binder/android/os/IDumpstate.aidl \
- ../../../native/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl \
- ../../../native/cmds/dumpstate/binder/android/os/IDumpstateToken.aidl
-
-LOCAL_AIDL_INCLUDES = frameworks/native/cmds/dumpstate/binder
-
-LOCAL_STATIC_ANDROID_LIBRARIES := androidx.legacy_legacy-support-v4
-LOCAL_USE_AAPT2 := true
-
-LOCAL_PACKAGE_NAME := Shell
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.shell.*
-
-include $(BUILD_PACKAGE)
-
-include $(LOCAL_PATH)/tests/Android.mk
diff --git a/packages/Shell/tests/Android.bp b/packages/Shell/tests/Android.bp
new file mode 100644
index 000000000000..8536c4fbb5a3
--- /dev/null
+++ b/packages/Shell/tests/Android.bp
@@ -0,0 +1,19 @@
+android_test {
+ name: "ShellTests",
+ srcs: ["src/**/*.java"],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+ static_libs: [
+ "androidx.test.rules",
+ "mockito-target-minus-junit4",
+ "ub-uiautomator",
+ "junit",
+ ],
+ platform_apis: true,
+ test_suites: ["device-tests"],
+ instrumentation_for: "Shell",
+ certificate: "platform",
+}
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
deleted file mode 100644
index 44ff3383d566..000000000000
--- a/packages/Shell/tests/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules \
- mockito-target-minus-junit4 \
- ub-uiautomator \
- junit \
-
-LOCAL_PACKAGE_NAME := ShellTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_INSTRUMENTATION_FOR := Shell
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
new file mode 100644
index 000000000000..fe1bb265880c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="22"
+ android:viewportHeight="17"
+ android:width="22dp"
+ android:height="17dp">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M1.22,8.49l0.43-4.96h4.33v1.17H2.67L2.44,7.41c0.41-0.29,0.85-0.43,1.33-0.43c0.77,0,1.38,0.3,1.83,0.9 s0.66,1.41,0.66,2.43c0,1.03-0.24,1.84-0.72,2.43s-1.14,0.88-1.98,0.88c-0.75,0-1.36-0.24-1.83-0.73s-0.74-1.16-0.81-2.02h1.13 c0.07,0.57,0.23,1,0.49,1.29c0.26,0.29,0.59,0.43,1.01,0.43c0.47,0,0.84-0.2,1.1-0.61c0.26-0.41,0.4-0.96,0.4-1.65 c0-0.65-0.14-1.18-0.43-1.59S3.96,8.11,3.47,8.11c-0.4,0-0.72,0.1-0.96,0.31L2.19,8.75L1.22,8.49z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M14.14,12.24l-0.22,0.27c-0.63,0.73-1.55,1.1-2.76,1.1c-1.08,0-1.92-0.36-2.53-1.07c-0.61-0.71-0.93-1.72-0.94-3.02V7.56 c0-1.39,0.28-2.44,0.84-3.13c0.56-0.7,1.39-1.04,2.51-1.04c0.95,0,1.69,0.26,2.23,0.79c0.54,0.53,0.83,1.28,0.89,2.26h-1.25 c-0.05-0.62-0.22-1.1-0.52-1.45c-0.29-0.35-0.74-0.52-1.34-0.52c-0.72,0-1.24,0.23-1.57,0.7C9.14,5.63,8.96,6.37,8.95,7.4v2.03 c0,1,0.19,1.77,0.57,2.31c0.38,0.54,0.93,0.8,1.65,0.8c0.67,0,1.19-0.16,1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M20.96,8.88h-3.52v3.53h4.1v1.07h-5.35V3.52h5.28V4.6h-4.03V7.8h3.52V8.88z" />
+
+</vector>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4437f49fd335..ccf345b0af36 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -390,6 +390,9 @@
<!-- Content description of the data connection type LTE+. [CHAR LIMIT=NONE] -->
<string name="data_connection_lte_plus">LTE+</string>
+ <!-- Content description of the data connection type 5Ge. [CHAR LIMIT=NONE] -->
+ <string name="data_connection_5ge" translate="false">5Ge</string>
+
<!-- Content description of the data connection type 5G. [CHAR LIMIT=NONE] -->
<string name="data_connection_5g" translate="false">5G</string>
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 2f7e3b18d3c1..b7c20aa197ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -46,6 +46,8 @@ import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionD
import java.io.PrintWriter;
import java.util.BitSet;
import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class MobileSignalController extends SignalController<
@@ -72,6 +74,8 @@ public class MobileSignalController extends SignalController<
private SignalStrength mSignalStrength;
private MobileIconGroup mDefaultIcons;
private Config mConfig;
+ // Some specific carriers have 5GE network which is special LTE CA network.
+ private static final int NETWORK_TYPE_LTE_CA_5GE = TelephonyManager.MAX_NETWORK_TYPE + 1;
// TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
// need listener lists anymore.
@@ -235,6 +239,8 @@ public class MobileSignalController extends SignalController<
TelephonyIcons.LTE_PLUS);
}
}
+ mNetworkToIconLookup.put(NETWORK_TYPE_LTE_CA_5GE,
+ TelephonyIcons.LTE_CA_5G_E);
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC);
}
@@ -400,6 +406,26 @@ public class MobileSignalController extends SignalController<
}
}
+ private boolean isCarrierSpecificDataIcon() {
+ if (mConfig.patternOfCarrierSpecificDataIcon == null
+ || mConfig.patternOfCarrierSpecificDataIcon.length() == 0) {
+ return false;
+ }
+
+ Pattern stringPattern = Pattern.compile(mConfig.patternOfCarrierSpecificDataIcon);
+ String[] operatorNames = new String[]{mServiceState.getOperatorAlphaLongRaw(),
+ mServiceState.getOperatorAlphaShortRaw()};
+ for (String opName : operatorNames) {
+ if (!TextUtils.isEmpty(opName)) {
+ Matcher matcher = stringPattern.matcher(opName);
+ if (matcher.find()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Updates the network's name based on incoming spn and plmn.
*/
@@ -566,12 +592,8 @@ public class MobileSignalController extends SignalController<
+ " dataState=" + state.getDataRegState());
}
mServiceState = state;
- if (state != null) {
- mDataNetType = state.getDataNetworkType();
- if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE && mServiceState != null &&
- mServiceState.isUsingCarrierAggregation()) {
- mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA;
- }
+ if (mServiceState != null) {
+ updateDataNetType(mServiceState.getDataNetworkType());
}
updateTelephony();
}
@@ -583,12 +605,19 @@ public class MobileSignalController extends SignalController<
+ " type=" + networkType);
}
mDataState = state;
+ updateDataNetType(networkType);
+ updateTelephony();
+ }
+
+ private void updateDataNetType(int networkType) {
mDataNetType = networkType;
- if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE && mServiceState != null &&
- mServiceState.isUsingCarrierAggregation()) {
- mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA;
+ if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE) {
+ if (isCarrierSpecificDataIcon()) {
+ mDataNetType = NETWORK_TYPE_LTE_CA_5GE;
+ } else if (mServiceState != null && mServiceState.isUsingCarrierAggregation()) {
+ mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA;
+ }
}
- updateTelephony();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index b4f0fec90fb0..5c6634c7aa1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -1084,6 +1084,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
boolean hspaDataDistinguishable;
boolean inflateSignalStrengths = false;
boolean alwaysShowDataRatIcon = false;
+ public String patternOfCarrierSpecificDataIcon = "";
/**
* Mapping from NR 5G status string to an integer. The NR 5G status string should match
@@ -1122,6 +1123,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
config.hideLtePlus = b.getBoolean(
CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL);
+ config.patternOfCarrierSpecificDataIcon = b.getString(
+ CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
String nr5GIconConfiguration =
b.getString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
if (!TextUtils.isEmpty(nr5GIconConfiguration)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 7347f66de8ce..2c4b1f97c739 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -35,6 +35,7 @@ class TelephonyIcons {
static final int ICON_3G = R.drawable.ic_3g_mobiledata;
static final int ICON_4G = R.drawable.ic_4g_mobiledata;
static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata;
+ static final int ICON_5G_E = R.drawable.ic_5g_e_mobiledata;
static final int ICON_1X = R.drawable.ic_1x_mobiledata;
static final int ICON_5G = R.drawable.ic_5g_mobiledata;
static final int ICON_5G_PLUS = R.drawable.ic_5g_plus_mobiledata;
@@ -204,6 +205,19 @@ class TelephonyIcons {
TelephonyIcons.ICON_LTE_PLUS,
true);
+ static final MobileIconGroup LTE_CA_5G_E = new MobileIconGroup(
+ "5Ge",
+ null,
+ null,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+ 0, 0,
+ 0,
+ 0,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+ R.string.data_connection_5ge,
+ TelephonyIcons.ICON_5G_E,
+ true);
+
static final MobileIconGroup NR_5G = new MobileIconGroup(
"5G",
null,
@@ -260,6 +274,7 @@ class TelephonyIcons {
ICON_NAME_TO_ICON.put("h+", H_PLUS);
ICON_NAME_TO_ICON.put("4g", FOUR_G);
ICON_NAME_TO_ICON.put("4g+", FOUR_G_PLUS);
+ ICON_NAME_TO_ICON.put("5ge", LTE_CA_5G_E);
ICON_NAME_TO_ICON.put("lte", LTE);
ICON_NAME_TO_ICON.put("lte+", LTE_PLUS);
ICON_NAME_TO_ICON.put("5g", NR_5G);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d79d833f2233..6902a706e91f 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6492,6 +6492,11 @@ message MetricsEvent {
// OS: Q
ACTION_EMERGENCY_DIALER_FROM_POWER_MENU = 1569;
+ // OPEN: Settings > Developer Options > Game Driver Preference
+ // CATEGORY: SETTINGS
+ // OS: Q
+ SETTINGS_GAME_DRIVER_DASHBOARD = 1613;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/backup/OWNERS b/services/backup/OWNERS
index 1c9a43acfa65..9c21e8fe5e45 100644
--- a/services/backup/OWNERS
+++ b/services/backup/OWNERS
@@ -1,7 +1,9 @@
-artikz@google.com
+alsutton@google.com
+anniemeng@google.com
brufino@google.com
bryanmawhinney@google.com
ctate@google.com
jorlow@google.com
-mkarpinski@google.com
+nathch@google.com
+rthakohov@google.com
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index b60dd0f52c73..223eb552f832 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1094,11 +1094,21 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
public void unbindBluetoothProfileService(int bluetoothProfile,
IBluetoothProfileServiceConnection proxy) {
synchronized (mProfileServices) {
- ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
+ Integer profile = new Integer(bluetoothProfile);
+ ProfileServiceConnections psc = mProfileServices.get(profile);
if (psc == null) {
return;
}
psc.removeProxy(proxy);
+ if (psc.isEmpty()) {
+ // All prxoies are disconnected, unbind with the service.
+ try {
+ mContext.unbindService(psc);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
+ }
+ mProfileServices.remove(profile);
+ }
}
}
@@ -1255,6 +1265,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mProxies.kill();
}
+ private boolean isEmpty() {
+ return mProxies.getRegisteredCallbackCount() == 0;
+ }
+
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// remove timeout message
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c1aff757d474..63fd2fda1ce6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -27,6 +27,7 @@ import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -634,7 +635,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
* the first network for a given type changes, or if the default network
* changes.
*/
- private class LegacyTypeTracker {
+ @VisibleForTesting
+ static class LegacyTypeTracker {
private static final boolean DBG = true;
private static final boolean VDBG = false;
@@ -660,10 +662,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
* - dump is thread-safe with respect to concurrent add and remove calls.
*/
private final ArrayList<NetworkAgentInfo> mTypeLists[];
+ @NonNull
+ private final ConnectivityService mService;
- public LegacyTypeTracker() {
- mTypeLists = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
+ LegacyTypeTracker(@NonNull ConnectivityService service) {
+ mService = service;
+ mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
}
public void addSupportedType(int type) {
@@ -712,10 +716,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
// Send a broadcast if this is the first network of its type or if it's the default.
- final boolean isDefaultNetwork = isDefaultNetwork(nai);
+ final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
if ((list.size() == 1) || isDefaultNetwork) {
maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
- sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
+ mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
}
}
@@ -733,19 +737,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- final DetailedState state = DetailedState.DISCONNECTED;
-
if (wasFirstNetwork || wasDefault) {
- maybeLogBroadcast(nai, state, type, wasDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
+ mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
}
if (!list.isEmpty() && wasFirstNetwork) {
if (DBG) log("Other network available for type " + type +
", sending connected broadcast");
final NetworkAgentInfo replacement = list.get(0);
- maybeLogBroadcast(replacement, state, type, isDefaultNetwork(replacement));
- sendLegacyNetworkBroadcast(replacement, state, type);
+ maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
+ mService.isDefaultNetwork(replacement));
+ mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
}
}
@@ -760,7 +763,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// send out another legacy broadcast - currently only used for suspend/unsuspend
// toggle
public void update(NetworkAgentInfo nai) {
- final boolean isDefault = isDefaultNetwork(nai);
+ final boolean isDefault = mService.isDefaultNetwork(nai);
final DetailedState state = nai.networkInfo.getDetailedState();
for (int type = 0; type < mTypeLists.length; type++) {
final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
@@ -768,7 +771,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean isFirst = contains && (nai == list.get(0));
if (isFirst || contains && isDefault) {
maybeLogBroadcast(nai, state, type, isDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ mService.sendLegacyNetworkBroadcast(nai, state, type);
}
}
}
@@ -804,7 +807,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.println();
}
}
- private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+ private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
/**
* Helper class which parses out priority arguments and dumps sections according to their
@@ -2815,6 +2818,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE,
mNai.network.netId));
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private boolean networkRequiresValidation(NetworkAgentInfo nai) {
@@ -2853,7 +2861,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
// With Private DNS bypass support, we can proceed to update the
@@ -3023,7 +3031,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
nai.networkMonitor().notifyNetworkDisconnected();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
mNetworkAgentInfos.remove(nai.messenger);
nai.clatd.update();
@@ -3062,11 +3070,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// fallback network the default or requested a new network from the
// NetworkFactories, so network traffic isn't interrupted for an unnecessarily
// long time.
- try {
- mNetd.networkDestroy(nai.network.netId);
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception destroying network: " + e);
- }
+ destroyNativeNetwork(nai);
mDnsManager.removeNetwork(nai.network);
}
synchronized (mNetworkForNetId) {
@@ -3074,6 +3078,35 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
+ try {
+ // This should never fail. Specifying an already in use NetID will cause failure.
+ if (networkAgent.isVPN()) {
+ mNetd.networkCreateVpn(networkAgent.network.netId,
+ (networkAgent.networkMisc == null
+ || !networkAgent.networkMisc.allowBypass));
+ } else {
+ mNetd.networkCreatePhysical(networkAgent.network.netId,
+ getNetworkPermission(networkAgent.networkCapabilities));
+ }
+ mDnsResolver.createNetworkCache(networkAgent.network.netId);
+ return true;
+ } catch (RemoteException | ServiceSpecificException e) {
+ loge("Error creating network " + networkAgent.network.netId + ": "
+ + e.getMessage());
+ return false;
+ }
+ }
+
+ private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
+ try {
+ mNetd.networkDestroy(networkAgent.network.netId);
+ mDnsResolver.destroyNetworkCache(networkAgent.network.netId);
+ } catch (RemoteException | ServiceSpecificException e) {
+ loge("Exception destroying network: " + e);
+ }
+ }
+
// If this method proves to be too slow then we can maintain a separate
// pendingIntent => NetworkRequestInfo map.
// This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
@@ -3412,7 +3445,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
nai.networkMonitor().setAcceptPartialConnectivity();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
}
}
@@ -3448,7 +3481,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
nai.networkMonitor().launchCaptivePortalApp();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
});
}
@@ -4076,7 +4109,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
nai.networkMonitor().forceReevaluation(uid);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
}
@@ -5371,7 +5404,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ @VisibleForTesting
+ protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
return nai == getDefaultNetwork();
}
@@ -5455,7 +5489,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
networkMonitor.start();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger);
NetworkInfo networkInfo = nai.networkInfo;
@@ -5512,7 +5546,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
if (networkAgent.everConnected) {
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
@@ -6473,21 +6507,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// A network that has just connected has zero requests and is thus a foreground network.
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
- try {
- // This should never fail. Specifying an already in use NetID will cause failure.
- if (networkAgent.isVPN()) {
- mNMS.createVirtualNetwork(networkAgent.network.netId,
- (networkAgent.networkMisc == null ||
- !networkAgent.networkMisc.allowBypass));
- } else {
- mNMS.createPhysicalNetwork(networkAgent.network.netId,
- getNetworkPermission(networkAgent.networkCapabilities));
- }
- } catch (Exception e) {
- loge("Error creating network " + networkAgent.network.netId + ": "
- + e.getMessage());
- return;
- }
+ if (!createNativeNetwork(networkAgent)) return;
networkAgent.created = true;
}
@@ -6518,7 +6538,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkAgent.networkMonitor().notifyNetworkConnected(
networkAgent.linkProperties, networkAgent.networkCapabilities);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ e.rethrowAsRuntimeException();
}
scheduleUnvalidatedPrompt(networkAgent);
@@ -6671,7 +6691,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
+ @VisibleForTesting
+ protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
// The NetworkInfo we actually send out has no bearing on the real
// state of affairs. For example, if the default connection is mobile,
// and a request for HIPRI has just gone away, we need to pretend that
@@ -6838,6 +6859,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceKeepalivePermission();
mKeepaliveTracker.startNattKeepalive(
getNetworkAgentInfoForNetwork(network), null /* fd */,
+ INVALID_RESOURCE_ID /* Unused */,
intervalSeconds, cb,
srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 2055b64483d9..c1f52552eaf7 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -28,8 +28,10 @@ import static android.system.OsConstants.SOCK_DGRAM;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.IIpSecService;
import android.net.INetd;
import android.net.IpSecAlgorithm;
@@ -42,6 +44,7 @@ import android.net.IpSecTunnelInterfaceResponse;
import android.net.IpSecUdpEncapResponse;
import android.net.LinkAddress;
import android.net.Network;
+import android.net.NetworkStack;
import android.net.NetworkUtils;
import android.net.TrafficStats;
import android.net.util.NetdService;
@@ -74,6 +77,8 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -175,6 +180,14 @@ public class IpSecService extends IIpSecService.Stub {
}
/**
+ * Sentinel value placeholder for a real binder in RefcountedResources.
+ *
+ * <p>Used for cases where there the allocating party is a system service, and thus is expected
+ * to track the resource lifecycles instead of IpSecService.
+ */
+ private static final Binder DUMMY_BINDER = new Binder();
+
+ /**
* RefcountedResource manages references and dependencies in an exclusively acyclic graph.
*
* <p>RefcountedResource implements both explicit and implicit resource management. Creating a
@@ -188,24 +201,42 @@ public class IpSecService extends IIpSecService.Stub {
*/
@VisibleForTesting
public class RefcountedResource<T extends IResource> implements IBinder.DeathRecipient {
- private final T mResource;
- private final List<RefcountedResource> mChildren;
+
+ @NonNull private final T mResource;
+ @NonNull private final List<RefcountedResource> mChildren;
int mRefCount = 1; // starts at 1 for user's reference.
- IBinder mBinder;
- RefcountedResource(T resource, IBinder binder, RefcountedResource... children) {
+ /*
+ * This field can take one of three states:
+ * 1. null, when the object has been released by the user (or the user's binder dies)
+ * 2. DUMMY_BINDER, when the refcounted resource is allocated from another system service
+ * and the other system service manages the lifecycle of the resource instead of
+ * IpSecService.
+ * 3. an actual binder, to ensure IpSecService can cleanup after users that forget to close
+ * their resources.
+ */
+ @Nullable IBinder mBinder;
+
+ RefcountedResource(@NonNull T resource, @NonNull RefcountedResource... children) {
+ this(resource, DUMMY_BINDER, children);
+ }
+
+ RefcountedResource(
+ @NonNull T resource,
+ @NonNull IBinder binder,
+ @NonNull RefcountedResource... children) {
synchronized (IpSecService.this) {
this.mResource = resource;
- this.mChildren = new ArrayList<>(children.length);
this.mBinder = binder;
-
+ this.mChildren = Collections.unmodifiableList(Arrays.asList(children));
for (RefcountedResource child : children) {
- mChildren.add(child);
child.mRefCount++;
}
try {
- mBinder.linkToDeath(this, 0);
+ if (mBinder != DUMMY_BINDER) {
+ mBinder.linkToDeath(this, 0);
+ }
} catch (RemoteException e) {
binderDied();
e.rethrowFromSystemServer();
@@ -252,11 +283,12 @@ public class IpSecService extends IIpSecService.Stub {
return;
}
- mBinder.unlinkToDeath(this, 0);
+ if (mBinder != DUMMY_BINDER) {
+ mBinder.unlinkToDeath(this, 0);
+ }
mBinder = null;
mResource.invalidate();
-
releaseReference();
}
@@ -381,6 +413,8 @@ public class IpSecService extends IIpSecService.Stub {
new RefcountedResourceArray<>(EncapSocketRecord.class.getSimpleName());
final RefcountedResourceArray<TunnelInterfaceRecord> mTunnelInterfaceRecords =
new RefcountedResourceArray<>(TunnelInterfaceRecord.class.getSimpleName());
+ final RefcountedResourceArray<NattKeepaliveRecord> mNattKeepaliveRecords =
+ new RefcountedResourceArray<>(NattKeepaliveRecord.class.getSimpleName());
/**
* Trackers for quotas for each of the OwnedResource types.
@@ -394,6 +428,8 @@ public class IpSecService extends IIpSecService.Stub {
final ResourceTracker mSpiQuotaTracker = new ResourceTracker(MAX_NUM_SPIS);
final ResourceTracker mTransformQuotaTracker = new ResourceTracker(MAX_NUM_TRANSFORMS);
final ResourceTracker mSocketQuotaTracker = new ResourceTracker(MAX_NUM_ENCAP_SOCKETS);
+ final ResourceTracker mNattKeepaliveQuotaTracker =
+ new ResourceTracker(MAX_NUM_ENCAP_SOCKETS); // Max 1 NATT keepalive per encap socket
final ResourceTracker mTunnelQuotaTracker = new ResourceTracker(MAX_NUM_TUNNEL_INTERFACES);
void removeSpiRecord(int resourceId) {
@@ -412,6 +448,10 @@ public class IpSecService extends IIpSecService.Stub {
mEncapSocketRecords.remove(resourceId);
}
+ void removeNattKeepaliveRecord(int resourceId) {
+ mNattKeepaliveRecords.remove(resourceId);
+ }
+
@Override
public String toString() {
return new StringBuilder()
@@ -421,6 +461,8 @@ public class IpSecService extends IIpSecService.Stub {
.append(mTransformQuotaTracker)
.append(", mSocketQuotaTracker=")
.append(mSocketQuotaTracker)
+ .append(", mNattKeepaliveQuotaTracker=")
+ .append(mNattKeepaliveQuotaTracker)
.append(", mTunnelQuotaTracker=")
.append(mTunnelQuotaTracker)
.append(", mSpiRecords=")
@@ -429,6 +471,8 @@ public class IpSecService extends IIpSecService.Stub {
.append(mTransformRecords)
.append(", mEncapSocketRecords=")
.append(mEncapSocketRecords)
+ .append(", mNattKeepaliveRecords=")
+ .append(mNattKeepaliveRecords)
.append(", mTunnelInterfaceRecords=")
.append(mTunnelInterfaceRecords)
.append("}")
@@ -573,6 +617,11 @@ public class IpSecService extends IIpSecService.Stub {
mArray.remove(key);
}
+ @VisibleForTesting
+ int size() {
+ return mArray.size();
+ }
+
@Override
public String toString() {
return mArray.toString();
@@ -984,6 +1033,50 @@ public class IpSecService extends IIpSecService.Stub {
}
/**
+ * Tracks a NATT-keepalive instance
+ *
+ * <p>This class ensures that while a NATT-keepalive is active, the UDP encap socket that it is
+ * supporting will stay open until the NATT-keepalive is finished. NATT-keepalive offload
+ * lifecycles will be managed by ConnectivityService, which will validate that the UDP Encap
+ * socket is owned by the requester, and take a reference to it via this NattKeepaliveRecord
+ *
+ * <p>It shall be the responsibility of the caller to ensure that instances of an EncapSocket do
+ * not spawn multiple instances of NATT keepalives (and thereby register duplicate records)
+ */
+ private final class NattKeepaliveRecord extends OwnedResourceRecord {
+ NattKeepaliveRecord(int resourceId) {
+ super(resourceId);
+ }
+
+ @Override
+ @GuardedBy("IpSecService.this")
+ public void freeUnderlyingResources() {
+ Log.d(TAG, "Natt Keepalive released: " + mResourceId);
+
+ getResourceTracker().give();
+ }
+
+ @Override
+ protected ResourceTracker getResourceTracker() {
+ return getUserRecord().mNattKeepaliveQuotaTracker;
+ }
+
+ @Override
+ public void invalidate() {
+ getUserRecord().removeNattKeepaliveRecord(mResourceId);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("{super=")
+ .append(super.toString())
+ .append("}")
+ .toString();
+ }
+ }
+
+ /**
* Constructs a new IpSecService instance
*
* @param context Binder context for this service
@@ -1818,6 +1911,57 @@ public class IpSecService extends IIpSecService.Stub {
}
}
+ private void verifyNetworkStackCaller() {
+ if (mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+ != PackageManager.PERMISSION_GRANTED
+ && mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission NETWORK_STACK or MAINLINE_NETWORK_STACK");
+ }
+ }
+
+ /**
+ * Validates that a provided UID owns the encapSocket, and creates a NATT keepalive record
+ *
+ * <p>For system server use only. Caller must have NETWORK_STACK permission
+ *
+ * @param encapSocketResourceId resource identifier of the encap socket record
+ * @param ownerUid the UID of the caller. Used to verify ownership.
+ * @return
+ */
+ public synchronized int lockEncapSocketForNattKeepalive(
+ int encapSocketResourceId, int ownerUid) {
+ verifyNetworkStackCaller();
+
+ // Verify ownership. Will throw IllegalArgumentException if the UID specified does not
+ // own the specified UDP encapsulation socket
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(ownerUid);
+ RefcountedResource<EncapSocketRecord> refcountedSocketRecord =
+ userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(encapSocketResourceId);
+
+ // Build NattKeepaliveRecord
+ final int resourceId = mNextResourceId++;
+ userRecord.mNattKeepaliveRecords.put(
+ resourceId,
+ new RefcountedResource<NattKeepaliveRecord>(
+ new NattKeepaliveRecord(resourceId), refcountedSocketRecord));
+
+ return resourceId;
+ }
+
+ /**
+ * Release a previously allocated NattKeepalive that has been registered with the system server
+ */
+ @Override
+ public synchronized void releaseNattKeepalive(int nattKeepaliveResourceId, int ownerUid)
+ throws RemoteException {
+ verifyNetworkStackCaller();
+
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(ownerUid);
+ releaseResource(userRecord.mNattKeepaliveRecords, nattKeepaliveResourceId);
+ }
+
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 1ff50b240672..6dbe3ade09f0 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2045,28 +2045,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void createPhysicalNetwork(int netId, int permission) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.networkCreatePhysical(netId, permission);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void createVirtualNetwork(int netId, boolean secure) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.networkCreateVpn(netId, secure);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public void addInterfaceToNetwork(String iface, int netId) {
modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
}
@@ -2143,38 +2121,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
}
- private int parsePermission(String permission) {
- if (permission.equals("NETWORK")) {
- return INetd.PERMISSION_NETWORK;
- }
- if (permission.equals("SYSTEM")) {
- return INetd.PERMISSION_SYSTEM;
- }
- return INetd.PERMISSION_NONE;
- }
-
- @Override
- public void setPermission(String permission, int[] uids) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.networkSetPermissionForUser(parsePermission(permission), uids);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void clearPermission(int[] uids) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.networkClearPermissionForUser(uids);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
@Override
public void allowProtect(int uid) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 40bf7bccff72..d19d2ddd7c3c 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -19,6 +19,7 @@ package com.android.server;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetd;
@@ -53,6 +54,7 @@ import java.net.Inet6Address;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/** @hide */
@@ -226,6 +228,8 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull Looper looper,
@NonNull Context context,
@NonNull String iface,
+ @Nullable LinkProperties lp,
+ boolean isMetered,
int callingUid,
@NonNull IBinder binder)
throws RemoteException, SocketException {
@@ -245,9 +249,19 @@ class TestNetworkService extends ITestNetworkManager.Stub {
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
+ if (!isMetered) {
+ nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ }
// Build LinkProperties
- LinkProperties lp = new LinkProperties();
+ if (lp == null) {
+ lp = new LinkProperties();
+ } else {
+ lp = new LinkProperties(lp);
+ // Use LinkAddress(es) from the interface itself to minimize how much the caller
+ // is trusted.
+ lp.setLinkAddresses(new ArrayList<>());
+ }
lp.setInterfaceName(iface);
// Find the currently assigned addresses, and add them to LinkProperties
@@ -284,7 +298,11 @@ class TestNetworkService extends ITestNetworkManager.Stub {
* <p>This method provides a Network that is useful only for testing.
*/
@Override
- public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
+ public void setupTestNetwork(
+ @NonNull String iface,
+ @Nullable LinkProperties lp,
+ boolean isMetered,
+ @NonNull IBinder binder) {
enforceTestNetworkPermissions(mContext);
checkNotNull(iface, "missing Iface");
@@ -315,6 +333,8 @@ class TestNetworkService extends ITestNetworkManager.Stub {
mHandler.getLooper(),
mContext,
iface,
+ lp,
+ isMetered,
callingUid,
binder);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e18f3740a969..5ebd17360961 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -318,7 +318,6 @@ import android.location.LocationManager;
import android.media.audiofx.AudioEffect;
import android.metrics.LogMaker;
import android.net.Proxy;
-import android.net.ProxyInfo;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
@@ -2252,21 +2251,25 @@ public class ActivityManagerService extends IActivityManager.Stub
}
} break;
case UPDATE_HTTP_PROXY_MSG: {
+ // Update the HTTP proxy for each application thread.
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = mLruProcesses.get(i);
// Don't dispatch to isolated processes as they can't access
- // ConnectivityManager and don't have network privileges anyway.
- if (r.thread != null && !r.isolated) {
+ // ConnectivityManager and don't have network privileges anyway. Exclude
+ // system server and update it separately outside the AMS lock, to avoid
+ // deadlock with Connectivity Service.
+ if (r.pid != MY_PID && r.thread != null && !r.isolated) {
try {
r.thread.updateHttpProxy();
} catch (RemoteException ex) {
- Slog.w(TAG, "Failed to update http proxy for: " +
- r.info.processName);
+ Slog.w(TAG, "Failed to update http proxy for: "
+ + r.info.processName);
}
}
}
}
+ ActivityThread.updateHttpProxy(mContext);
} break;
case PROC_START_TIMEOUT_MSG: {
ProcessRecord app = (ProcessRecord)msg.obj;
@@ -2607,7 +2610,7 @@ public class ActivityManagerService extends IActivityManager.Stub
} break;
}
}
- };
+ }
static final int COLLECT_PSS_BG_MSG = 1;
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 63300a1c05cd..9ff47e0dc0b4 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -55,8 +55,13 @@ final class CoreSettingsObserver extends ContentObserver {
// add other system settings here...
sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GUP_DEV_OPT_IN_APPS, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GUP_BLACK_LIST, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLIST, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_WHITELIST, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLISTS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class);
// add other global settings here...
}
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index e33392d359dd..2321afb7df43 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -263,12 +263,6 @@ public class DnsManager {
}
public void removeNetwork(Network network) {
- try {
- mDnsResolver.clearResolverConfiguration(network.netId);
- } catch (RemoteException | ServiceSpecificException e) {
- Slog.e(TAG, "Error clearing DNS configuration: " + e);
- return;
- }
mPrivateDnsMap.remove(network.netId);
mPrivateDnsValidationMap.remove(network.netId);
}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 77a18e2b3ddc..bde430cc297f 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.net.NattSocketKeepalive.NATT_PORT;
import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER;
@@ -37,6 +38,7 @@ import static android.net.SocketKeepalive.SUCCESS;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.IIpSecService;
import android.net.ISocketKeepaliveCallback;
import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
@@ -52,6 +54,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
@@ -89,11 +92,14 @@ public class KeepaliveTracker {
private final TcpKeepaliveController mTcpController;
@NonNull
private final Context mContext;
+ @NonNull
+ private final IIpSecService mIpSec;
public KeepaliveTracker(Context context, Handler handler) {
mConnectivityServiceHandler = handler;
mTcpController = new TcpKeepaliveController(handler);
mContext = context;
+ mIpSec = IIpSecService.Stub.asInterface(ServiceManager.getService(Context.IPSEC_SERVICE));
}
/**
@@ -112,6 +118,10 @@ public class KeepaliveTracker {
private final int mType;
private final FileDescriptor mFd;
+ private final int mEncapSocketResourceId;
+ // Stores the NATT keepalive resource ID returned by IpSecService.
+ private int mNattIpsecResourceId = INVALID_RESOURCE_ID;
+
public static final int TYPE_NATT = 1;
public static final int TYPE_TCP = 2;
@@ -140,7 +150,8 @@ public class KeepaliveTracker {
@NonNull KeepalivePacketData packet,
int interval,
int type,
- @Nullable FileDescriptor fd) throws InvalidSocketException {
+ @Nullable FileDescriptor fd,
+ int encapSocketResourceId) throws InvalidSocketException {
mCallback = callback;
mPid = Binder.getCallingPid();
mUid = Binder.getCallingUid();
@@ -151,6 +162,9 @@ public class KeepaliveTracker {
mInterval = interval;
mType = type;
+ mEncapSocketResourceId = encapSocketResourceId;
+ mNattIpsecResourceId = INVALID_RESOURCE_ID;
+
// For SocketKeepalive, a dup of fd is kept in mFd so the source port from which the
// keepalives are sent cannot be reused by another app even if the fd gets closed by
// the user. A null is acceptable here for backward compatibility of PacketKeepalive
@@ -158,7 +172,7 @@ public class KeepaliveTracker {
try {
if (fd != null) {
mFd = Os.dup(fd);
- } else {
+ } else {
Log.d(TAG, toString() + " calls with null fd");
if (!mPrivileged) {
throw new SecurityException(
@@ -206,6 +220,8 @@ public class KeepaliveTracker {
+ IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+ " interval=" + mInterval
+ " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
+ + " nattIpsecRId=" + mNattIpsecResourceId
+ + " encapSocketRId=" + mEncapSocketResourceId
+ " packetData=" + HexDump.toHexString(mPacket.getPacket())
+ " ]";
}
@@ -262,6 +278,51 @@ public class KeepaliveTracker {
return SUCCESS;
}
+ private int checkAndLockNattKeepaliveResource() {
+ // Check that apps should be either privileged or fill in an ipsec encapsulated socket
+ // resource id.
+ if (mEncapSocketResourceId == INVALID_RESOURCE_ID) {
+ if (mPrivileged) {
+ return SUCCESS;
+ } else {
+ // Invalid access.
+ return ERROR_INVALID_SOCKET;
+ }
+ }
+
+ // Check if the ipsec encapsulated socket resource id is registered.
+ final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai);
+ if (networkKeepalives == null) {
+ return ERROR_INVALID_NETWORK;
+ }
+ for (KeepaliveInfo ki : networkKeepalives.values()) {
+ if (ki.mEncapSocketResourceId == mEncapSocketResourceId
+ && ki.mNattIpsecResourceId != INVALID_RESOURCE_ID) {
+ Log.d(TAG, "Registered resource found on keepalive " + mSlot
+ + " when verify NATT socket with uid=" + mUid + " rid="
+ + mEncapSocketResourceId);
+ return ERROR_INVALID_SOCKET;
+ }
+ }
+
+ // Ensure that the socket is created by IpSecService, and lock the resource that is
+ // preserved by IpSecService. If succeed, a resource id is stored to keep tracking
+ // the resource preserved by IpSecServce and must be released when stopping keepalive.
+ try {
+ mNattIpsecResourceId =
+ mIpSec.lockEncapSocketForNattKeepalive(mEncapSocketResourceId, mUid);
+ return SUCCESS;
+ } catch (IllegalArgumentException e) {
+ // The UID specified does not own the specified UDP encapsulation socket.
+ Log.d(TAG, "Failed to verify NATT socket with uid=" + mUid + " rid="
+ + mEncapSocketResourceId + ": " + e);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling lockEncapSocketForNattKeepalive with "
+ + this.toString(), e);
+ }
+ return ERROR_INVALID_SOCKET;
+ }
+
private int isValid() {
synchronized (mNai) {
int error = checkInterval();
@@ -275,6 +336,13 @@ public class KeepaliveTracker {
void start(int slot) {
mSlot = slot;
int error = isValid();
+
+ // Check and lock ipsec resource needed by natt kepalive. This should be only called
+ // once per keepalive.
+ if (error == SUCCESS && mType == TYPE_NATT) {
+ error = checkAndLockNattKeepaliveResource();
+ }
+
if (error == SUCCESS) {
Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.name());
switch (mType) {
@@ -350,6 +418,20 @@ public class KeepaliveTracker {
}
}
+ // Release the resource held by keepalive in IpSecService.
+ if (mNattIpsecResourceId != INVALID_RESOURCE_ID) {
+ if (mType != TYPE_NATT) {
+ Log.wtf(TAG, "natt ipsec resource held by incorrect keepalive "
+ + this.toString());
+ }
+ try {
+ mIpSec.releaseNattKeepalive(mNattIpsecResourceId, mUid);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "error calling releaseNattKeepalive with " + this.toString(), e);
+ }
+ mNattIpsecResourceId = INVALID_RESOURCE_ID;
+ }
+
if (reason == SUCCESS) {
try {
mCallback.onStopped();
@@ -538,6 +620,7 @@ public class KeepaliveTracker {
**/
public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
@Nullable FileDescriptor fd,
+ int encapSocketResourceId,
int intervalSeconds,
@NonNull ISocketKeepaliveCallback cb,
@NonNull String srcAddrString,
@@ -569,7 +652,7 @@ public class KeepaliveTracker {
KeepaliveInfo ki = null;
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_NATT, fd);
+ KeepaliveInfo.TYPE_NATT, fd, encapSocketResourceId);
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Fail to construct keepalive", e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
@@ -609,7 +692,7 @@ public class KeepaliveTracker {
KeepaliveInfo ki = null;
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_TCP, fd);
+ KeepaliveInfo.TYPE_TCP, fd, INVALID_RESOURCE_ID /* Unused */);
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Fail to construct keepalive e=" + e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
@@ -628,17 +711,12 @@ public class KeepaliveTracker {
**/
public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
@Nullable FileDescriptor fd,
- int resourceId,
+ int encapSocketResourceId,
int intervalSeconds,
@NonNull ISocketKeepaliveCallback cb,
@NonNull String srcAddrString,
@NonNull String dstAddrString,
int dstPort) {
- // Ensure that the socket is created by IpSecService.
- if (!isNattKeepaliveSocketValid(fd, resourceId)) {
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- }
-
// Get src port to adopt old API.
int srcPort = 0;
try {
@@ -649,23 +727,8 @@ public class KeepaliveTracker {
}
// Forward request to old API.
- startNattKeepalive(nai, fd, intervalSeconds, cb, srcAddrString, srcPort,
- dstAddrString, dstPort);
- }
-
- /**
- * Verify if the IPsec NAT-T file descriptor and resource Id hold for IPsec keepalive is valid.
- **/
- public static boolean isNattKeepaliveSocketValid(@Nullable FileDescriptor fd, int resourceId) {
- // TODO: 1. confirm whether the fd is called from system api or created by IpSecService.
- // 2. If the fd is created from the system api, check that it's bounded. And
- // call dup to keep the fd open.
- // 3. If the fd is created from IpSecService, check if the resource ID is valid. And
- // hold the resource needed in IpSecService.
- if (null == fd) {
- return false;
- }
- return true;
+ startNattKeepalive(nai, fd, encapSocketResourceId, intervalSeconds, cb, srcAddrString,
+ srcPort, dstAddrString, dstPort);
}
public void dump(IndentingPrintWriter pw) {
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
index 38eb0bcfd3cc..81863439c017 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
@@ -16,7 +16,6 @@
package com.android.server.connectivity.tethering;
-import android.net.ConnectivityManager;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -164,11 +163,6 @@ public class IPv6TetheringCoordinator {
}
private LinkProperties getInterfaceIPv6LinkProperties(IpServer ipServer) {
- if (ipServer.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
- // TODO: Figure out IPv6 support on PAN interfaces.
- return null;
- }
-
final Downstream ds = findDownstream(ipServer);
if (ds == null) return null;
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
new file mode 100644
index 000000000000..647727f795da
--- /dev/null
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.gpu;
+
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.gamedriver.GameDriverProto.Blacklist;
+import android.gamedriver.GameDriverProto.Blacklists;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Base64;
+import android.util.Slog;
+
+import com.android.framework.protobuf.InvalidProtocolBufferException;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.SystemService;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service to manage GPU related features.
+ *
+ * <p>GPU service is a core service that monitors, coordinates all GPU related features,
+ * as well as collect metrics about the GPU and GPU driver.</p>
+ */
+public class GpuService extends SystemService {
+ public static final String TAG = "GpuService";
+ public static final boolean DEBUG = false;
+
+ private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+ private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
+ private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
+ private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
+
+ private final Context mContext;
+ private final String mDriverPackageName;
+ private final PackageManager mPackageManager;
+ private final Object mLock = new Object();
+ private ContentResolver mContentResolver;
+ private long mGameDriverVersionCode;
+ private SettingsObserver mSettingsObserver;
+ @GuardedBy("mLock")
+ private Blacklists mBlacklists;
+
+ public GpuService(Context context) {
+ super(context);
+
+ mContext = context;
+ mDriverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ mGameDriverVersionCode = -1;
+ mPackageManager = context.getPackageManager();
+ if (mDriverPackageName != null && !mDriverPackageName.isEmpty()) {
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(ACTION_PACKAGE_CHANGED);
+ packageFilter.addAction(ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme("package");
+ getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
+ packageFilter, null, null);
+ }
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ mContentResolver = mContext.getContentResolver();
+ mSettingsObserver = new SettingsObserver();
+ if (mDriverPackageName == null || mDriverPackageName.isEmpty()) {
+ return;
+ }
+ fetchGameDriverPackageProperties();
+ processBlacklists();
+ setBlacklist();
+ }
+ }
+
+ private final class SettingsObserver extends ContentObserver {
+ private final Uri mGameDriverBlackUri =
+ Settings.Global.getUriFor(Settings.Global.GAME_DRIVER_BLACKLISTS);
+
+ SettingsObserver() {
+ super(new Handler());
+ mContentResolver.registerContentObserver(mGameDriverBlackUri, false, this,
+ UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (uri == null) {
+ return;
+ }
+
+ if (mGameDriverBlackUri.equals(uri)) {
+ processBlacklists();
+ setBlacklist();
+ }
+ }
+ }
+
+ private final class PackageReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
+ final Uri data = intent.getData();
+ if (data == null && DEBUG) {
+ Slog.e(TAG, "Cannot handle package broadcast with null data");
+ return;
+ }
+ final String packageName = data.getSchemeSpecificPart();
+ if (!packageName.equals(mDriverPackageName)) {
+ return;
+ }
+
+ final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+ switch (intent.getAction()) {
+ case ACTION_PACKAGE_ADDED:
+ case ACTION_PACKAGE_CHANGED:
+ case ACTION_PACKAGE_REMOVED:
+ fetchGameDriverPackageProperties();
+ setBlacklist();
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ private static void assetToSettingsGlobal(Context context, Context driverContext,
+ String fileName, String settingsGlobal, CharSequence delimiter) {
+ try {
+ final BufferedReader reader = new BufferedReader(
+ new InputStreamReader(driverContext.getAssets().open(fileName)));
+ final ArrayList<String> assetStrings = new ArrayList<>();
+ for (String assetString; (assetString = reader.readLine()) != null; ) {
+ assetStrings.add(assetString);
+ }
+ Settings.Global.putString(context.getContentResolver(),
+ settingsGlobal,
+ String.join(delimiter, assetStrings));
+ } catch (IOException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Failed to load " + fileName + ", abort.");
+ }
+ }
+ }
+
+ private void fetchGameDriverPackageProperties() {
+ final ApplicationInfo driverInfo;
+ try {
+ driverInfo = mPackageManager.getApplicationInfo(mDriverPackageName,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.e(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ }
+ return;
+ }
+
+ // O drivers are restricted to the sphal linker namespace, so don't try to use
+ // packages unless they declare they're compatible with that restriction.
+ if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ if (DEBUG) {
+ Slog.w(TAG, "Driver package is not known to be compatible with O");
+ }
+ return;
+ }
+
+ // Reset the whitelist.
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_WHITELIST, "");
+ // Reset the sphal libraries
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, "");
+ mGameDriverVersionCode = driverInfo.longVersionCode;
+
+ try {
+ final Context driverContext = mContext.createPackageContext(mDriverPackageName,
+ Context.CONTEXT_RESTRICTED);
+
+ assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
+ Settings.Global.GAME_DRIVER_WHITELIST, ",");
+
+ assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_SPHAL_LIBRARIES_FILENAME,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, ":");
+
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ }
+ }
+ }
+
+ private void processBlacklists() {
+ // TODO(b/121350991) Switch to DeviceConfig with property listener.
+ String base64String =
+ Settings.Global.getString(mContentResolver, Settings.Global.GAME_DRIVER_BLACKLISTS);
+ if (base64String == null || base64String.isEmpty()) {
+ return;
+ }
+
+ synchronized (mLock) {
+ // Reset all blacklists
+ mBlacklists = null;
+ try {
+ mBlacklists = Blacklists.parseFrom(Base64.decode(base64String, BASE64_FLAGS));
+ } catch (IllegalArgumentException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Can't parse blacklist, skip and continue...");
+ }
+ } catch (InvalidProtocolBufferException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Can't parse blacklist, skip and continue...");
+ }
+ }
+ }
+ }
+
+ private void setBlacklist() {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_BLACKLIST, "");
+ synchronized (mLock) {
+ if (mBlacklists == null) {
+ return;
+ }
+ List<Blacklist> blacklists = mBlacklists.getBlacklistsList();
+ for (Blacklist blacklist : blacklists) {
+ if (blacklist.getVersionCode() == mGameDriverVersionCode) {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_BLACKLIST,
+ String.join(",", blacklist.getPackageNamesList()));
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 4baf70b37655..62ea95b21865 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -34,10 +34,10 @@ per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
# security
-per-file KeySetHandle.java = cbrubaker@google.com
-per-file KeySetManagerService.java = cbrubaker@google.com
-per-file PackageKeySetData.java = cbrubaker@google.com
-per-file PackageSignatures.java = cbrubaker@google.com
+per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
+per-file KeySetManagerService.java = cbrubaker@google.com, nnk@google.com
+per-file PackageKeySetData.java = cbrubaker@google.com, nnk@google.com
+per-file PackageSignatures.java = cbrubaker@google.com, nnk@google.com
per-file SELinuxMMAC.java = cbrubaker@google.com, jeffv@google.com, jgalenson@google.com, nnk@google.com
# shortcuts
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 8dda48523c83..0ab1a3e916e3 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -1,3 +1,5 @@
+set noparent
+
ogunwale@google.com
jjaggi@google.com
racarr@google.com
@@ -5,3 +7,6 @@ chaviw@google.com
vishnun@google.com
akulian@google.com
roosa@google.com
+erosky@google.com
+riddlehsu@google.com
+louischang@google.com
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7be7ab2bfb23..f0292aaded18 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -87,6 +87,7 @@ import com.android.server.display.DisplayManagerService;
import com.android.server.dreams.DreamManagerService;
import com.android.server.emergency.EmergencyAffordanceService;
import com.android.server.fingerprint.FingerprintService;
+import com.android.server.gpu.GpuService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
import com.android.server.job.JobSchedulerService;
@@ -747,6 +748,11 @@ public final class SystemServer {
traceBeginAndSlog("StartBugreportManagerService");
mSystemServiceManager.startService(BugreportManagerService.class);
traceEnd();
+
+ // Serivce for GPU and GPU driver.
+ traceBeginAndSlog("GpuService");
+ mSystemServiceManager.startService(GpuService.class);
+ traceEnd();
}
/**
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 8f48f5b3d292..ab11fe4df283 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -3,8 +3,6 @@ aidl_interface {
name: "ipmemorystore-aidl-interfaces",
local_include_dir: "java",
srcs: [
- // TODO: Define and use a filegroup for these files, since they're also used in
- // networkstack-aidl-interfaces. This does not appear to work at the moment.
"java/android/net/IIpMemoryStore.aidl",
"java/android/net/IIpMemoryStoreCallbacks.aidl",
"java/android/net/ipmemorystore/**/*.aidl",
@@ -17,22 +15,25 @@ aidl_interface {
enabled: false,
},
},
- api_dir: "aidl/networkstack",
+ api_dir: "aidl/ipmemorystore",
+ versions: [
+ "1",
+ "2",
+ ],
}
aidl_interface {
name: "networkstack-aidl-interfaces",
local_include_dir: "java",
- include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
+ include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
srcs: [
"java/android/net/DhcpResultsParcelable.aidl",
- "java/android/net/IIpMemoryStore.aidl",
- "java/android/net/IIpMemoryStoreCallbacks.aidl",
"java/android/net/INetworkMonitor.aidl",
"java/android/net/INetworkMonitorCallbacks.aidl",
"java/android/net/INetworkStackConnector.aidl",
"java/android/net/INetworkStackStatusCallback.aidl",
"java/android/net/InitialConfigurationParcelable.aidl",
+ "java/android/net/NattKeepalivePacketDataParcelable.aidl",
"java/android/net/PrivateDnsConfigParcel.aidl",
"java/android/net/ProvisioningConfigurationParcelable.aidl",
"java/android/net/TcpKeepalivePacketDataParcelable.aidl",
@@ -41,7 +42,6 @@ aidl_interface {
"java/android/net/dhcp/IDhcpServerCallbacks.aidl",
"java/android/net/ip/IIpClient.aidl",
"java/android/net/ip/IIpClientCallbacks.aidl",
- "java/android/net/ipmemorystore/**/*.aidl",
],
backend: {
ndk: {
@@ -52,6 +52,12 @@ aidl_interface {
},
},
api_dir: "aidl/networkstack",
+ imports: ["ipmemorystore-aidl-interfaces"],
+ versions: [
+ "1",
+ "2",
+ "3",
+ ],
}
java_library_static {
@@ -59,9 +65,10 @@ java_library_static {
srcs: ["java/**/*.java"],
static_libs: [
"dnsresolver_aidl_interface-java",
+ "ipmemorystore-client",
"netd_aidl_interface-java",
"networkstack-aidl-interfaces-java",
- ]
+ ],
}
java_library_static {
@@ -74,7 +81,7 @@ java_library_static {
],
static_libs: [
"ipmemorystore-aidl-interfaces-java",
- ]
+ ],
}
filegroup {
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
new file mode 100644
index 000000000000..a8cbab26190f
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
@@ -0,0 +1,9 @@
+package android.net;
+interface IIpMemoryStore {
+ oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
+ oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
+ oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
+ oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
new file mode 100644
index 000000000000..cf02c26c2fe3
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface IIpMemoryStoreCallbacks {
+ oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
new file mode 100644
index 000000000000..291dbef817e6
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable Blob {
+ byte[] data;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
new file mode 100644
index 000000000000..52f40d49abd5
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnBlobRetrievedListener {
+ oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
new file mode 100644
index 000000000000..785351435d73
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnL2KeyResponseListener {
+ oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
new file mode 100644
index 000000000000..3dd2ae6e9bab
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnNetworkAttributesRetrievedListener {
+ oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
new file mode 100644
index 000000000000..46d4ecb9ed7c
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnSameL3NetworkResponseListener {
+ oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
new file mode 100644
index 000000000000..54e654b80c9e
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnStatusListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
new file mode 100644
index 000000000000..9531ea3963fb
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -0,0 +1,8 @@
+package android.net.ipmemorystore;
+parcelable NetworkAttributesParcelable {
+ byte[] assignedV4Address;
+ long assignedV4AddressExpiry;
+ String groupHint;
+ android.net.ipmemorystore.Blob[] dnsAddresses;
+ int mtu;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
new file mode 100644
index 000000000000..414272b49f1d
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -0,0 +1,6 @@
+package android.net.ipmemorystore;
+parcelable SameL3NetworkResponseParcelable {
+ String l2Key1;
+ String l2Key2;
+ float confidence;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
new file mode 100644
index 000000000000..92c6779b5dc0
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable StatusParcelable {
+ int resultCode;
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl
new file mode 100644
index 000000000000..a8cbab26190f
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl
@@ -0,0 +1,9 @@
+package android.net;
+interface IIpMemoryStore {
+ oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
+ oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
+ oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
+ oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl
new file mode 100644
index 000000000000..cf02c26c2fe3
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface IIpMemoryStoreCallbacks {
+ oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl
new file mode 100644
index 000000000000..291dbef817e6
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable Blob {
+ byte[] data;
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
new file mode 100644
index 000000000000..52f40d49abd5
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnBlobRetrievedListener {
+ oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
new file mode 100644
index 000000000000..785351435d73
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnL2KeyResponseListener {
+ oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
new file mode 100644
index 000000000000..3dd2ae6e9bab
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnNetworkAttributesRetrievedListener {
+ oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
new file mode 100644
index 000000000000..46d4ecb9ed7c
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnSameL3NetworkResponseListener {
+ oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl
new file mode 100644
index 000000000000..54e654b80c9e
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnStatusListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
new file mode 100644
index 000000000000..9531ea3963fb
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -0,0 +1,8 @@
+package android.net.ipmemorystore;
+parcelable NetworkAttributesParcelable {
+ byte[] assignedV4Address;
+ long assignedV4AddressExpiry;
+ String groupHint;
+ android.net.ipmemorystore.Blob[] dnsAddresses;
+ int mtu;
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
new file mode 100644
index 000000000000..414272b49f1d
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -0,0 +1,6 @@
+package android.net.ipmemorystore;
+parcelable SameL3NetworkResponseParcelable {
+ String l2Key1;
+ String l2Key2;
+ float confidence;
+}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl
new file mode 100644
index 000000000000..92c6779b5dc0
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable StatusParcelable {
+ int resultCode;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 000000000000..92b5345ee221
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,8 @@
+package android.net;
+parcelable DhcpResultsParcelable {
+ android.net.StaticIpConfiguration baseConfiguration;
+ int leaseDuration;
+ int mtu;
+ String serverAddress;
+ String vendorInfo;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
new file mode 100644
index 000000000000..b19f522880ec
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
@@ -0,0 +1,17 @@
+package android.net;
+interface INetworkMonitor {
+ oneway void start();
+ oneway void launchCaptivePortalApp();
+ oneway void notifyCaptivePortalAppFinished(int response);
+ oneway void setAcceptPartialConnectivity();
+ oneway void forceReevaluation(int uid);
+ oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+ oneway void notifyDnsResponse(int returnCode);
+ oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+ oneway void notifyNetworkDisconnected();
+ oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+ oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+ const int NETWORK_TEST_RESULT_VALID = 0;
+ const int NETWORK_TEST_RESULT_INVALID = 1;
+ const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 000000000000..ee9871ddcd15
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,8 @@
+package android.net;
+interface INetworkMonitorCallbacks {
+ oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
+ oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
+ oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
+ oneway void showProvisioningNotification(String action, String packageName);
+ oneway void hideProvisioningNotification();
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
new file mode 100644
index 000000000000..7da11e476c0e
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,7 @@
+package android.net;
+interface INetworkStackConnector {
+ oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+ oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+ oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+ oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 000000000000..f6ca6f7a78e2
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface INetworkStackStatusCallback {
+ oneway void onStatusAvailable(int statusCode);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 000000000000..c80a78785b3b
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable InitialConfigurationParcelable {
+ android.net.LinkAddress[] ipAddresses;
+ android.net.IpPrefix[] directlyConnectedRoutes;
+ String[] dnsServers;
+ String gateway;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 000000000000..2de790bb7754
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,5 @@
+package android.net;
+parcelable PrivateDnsConfigParcel {
+ String hostname;
+ String[] ips;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 000000000000..3a6c30496fd8
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,15 @@
+package android.net;
+parcelable ProvisioningConfigurationParcelable {
+ boolean enableIPv4;
+ boolean enableIPv6;
+ boolean usingMultinetworkPolicyTracker;
+ boolean usingIpReachabilityMonitor;
+ int requestedPreDhcpActionMs;
+ android.net.InitialConfigurationParcelable initialConfig;
+ android.net.StaticIpConfiguration staticIpConfig;
+ android.net.apf.ApfCapabilities apfCapabilities;
+ int provisioningTimeoutMs;
+ int ipv6AddrGenMode;
+ android.net.Network network;
+ String displayName;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..e121c064f7ac
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,13 @@
+package android.net;
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
+ int rcvWnd;
+ int rcvWndScale;
+ int tos;
+ int ttl;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 000000000000..67193ae904bc
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,11 @@
+package android.net.dhcp;
+parcelable DhcpServingParamsParcel {
+ int serverAddr;
+ int serverAddrPrefixLength;
+ int[] defaultRouters;
+ int[] dnsServers;
+ int[] excludedAddrs;
+ long dhcpLeaseTimeSecs;
+ int linkMtu;
+ boolean metered;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 000000000000..914315855496
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,10 @@
+package android.net.dhcp;
+interface IDhcpServer {
+ oneway void start(in android.net.INetworkStackStatusCallback cb);
+ oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
+ oneway void stop(in android.net.INetworkStackStatusCallback cb);
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_INVALID_ARGUMENT = 2;
+ const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 000000000000..dcc4489d52a6
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net.dhcp;
+interface IDhcpServerCallbacks {
+ oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
new file mode 100644
index 000000000000..95a15742a684
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
@@ -0,0 +1,14 @@
+package android.net.ip;
+interface IIpClient {
+ oneway void completedPreDhcpAction();
+ oneway void confirmConfiguration();
+ oneway void readPacketFilterComplete(in byte[] data);
+ oneway void shutdown();
+ oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+ oneway void stop();
+ oneway void setTcpBufferSizes(in String tcpBufferSizes);
+ oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+ oneway void setMulticastFilter(boolean enabled);
+ oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+ oneway void removeKeepalivePacketFilter(int slot);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 000000000000..d6bc8089a0be
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,16 @@
+package android.net.ip;
+interface IIpClientCallbacks {
+ oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+ oneway void onPreDhcpAction();
+ oneway void onPostDhcpAction();
+ oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+ oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+ oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+ oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+ oneway void onReachabilityLost(in String logMsg);
+ oneway void onQuit();
+ oneway void installPacketFilter(in byte[] filter);
+ oneway void startReadPacketFilter();
+ oneway void setFallbackMulticastFilter(boolean enabled);
+ oneway void setNeighborDiscoveryOffload(boolean enable);
+}
diff --git a/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 000000000000..31891de7230a
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,9 @@
+package android.net;
+parcelable DhcpResultsParcelable {
+ android.net.StaticIpConfiguration baseConfiguration;
+ int leaseDuration;
+ int mtu;
+ String serverAddress;
+ String vendorInfo;
+ String serverHostName;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl
new file mode 100644
index 000000000000..029968b6f324
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl
@@ -0,0 +1,24 @@
+package android.net;
+interface INetworkMonitor {
+ oneway void start();
+ oneway void launchCaptivePortalApp();
+ oneway void notifyCaptivePortalAppFinished(int response);
+ oneway void setAcceptPartialConnectivity();
+ oneway void forceReevaluation(int uid);
+ oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+ oneway void notifyDnsResponse(int returnCode);
+ oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+ oneway void notifyNetworkDisconnected();
+ oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+ oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+ const int NETWORK_TEST_RESULT_VALID = 0;
+ const int NETWORK_TEST_RESULT_INVALID = 1;
+ const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+ const int NETWORK_VALIDATION_RESULT_VALID = 1;
+ const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
+ const int NETWORK_VALIDATION_PROBE_DNS = 4;
+ const int NETWORK_VALIDATION_PROBE_HTTP = 8;
+ const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
+ const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
+ const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 000000000000..ee9871ddcd15
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,8 @@
+package android.net;
+interface INetworkMonitorCallbacks {
+ oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
+ oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
+ oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
+ oneway void showProvisioningNotification(String action, String packageName);
+ oneway void hideProvisioningNotification();
+}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl
new file mode 100644
index 000000000000..7da11e476c0e
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,7 @@
+package android.net;
+interface INetworkStackConnector {
+ oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+ oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+ oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+ oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 000000000000..f6ca6f7a78e2
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface INetworkStackStatusCallback {
+ oneway void onStatusAvailable(int statusCode);
+}
diff --git a/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 000000000000..c80a78785b3b
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable InitialConfigurationParcelable {
+ android.net.LinkAddress[] ipAddresses;
+ android.net.IpPrefix[] directlyConnectedRoutes;
+ String[] dnsServers;
+ String gateway;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..65de8833e6c5
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable NattKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 000000000000..2de790bb7754
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,5 @@
+package android.net;
+parcelable PrivateDnsConfigParcel {
+ String hostname;
+ String[] ips;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 000000000000..3a6c30496fd8
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,15 @@
+package android.net;
+parcelable ProvisioningConfigurationParcelable {
+ boolean enableIPv4;
+ boolean enableIPv6;
+ boolean usingMultinetworkPolicyTracker;
+ boolean usingIpReachabilityMonitor;
+ int requestedPreDhcpActionMs;
+ android.net.InitialConfigurationParcelable initialConfig;
+ android.net.StaticIpConfiguration staticIpConfig;
+ android.net.apf.ApfCapabilities apfCapabilities;
+ int provisioningTimeoutMs;
+ int ipv6AddrGenMode;
+ android.net.Network network;
+ String displayName;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..e121c064f7ac
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,13 @@
+package android.net;
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
+ int rcvWnd;
+ int rcvWndScale;
+ int tos;
+ int ttl;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 000000000000..67193ae904bc
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,11 @@
+package android.net.dhcp;
+parcelable DhcpServingParamsParcel {
+ int serverAddr;
+ int serverAddrPrefixLength;
+ int[] defaultRouters;
+ int[] dnsServers;
+ int[] excludedAddrs;
+ long dhcpLeaseTimeSecs;
+ int linkMtu;
+ boolean metered;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 000000000000..914315855496
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,10 @@
+package android.net.dhcp;
+interface IDhcpServer {
+ oneway void start(in android.net.INetworkStackStatusCallback cb);
+ oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
+ oneway void stop(in android.net.INetworkStackStatusCallback cb);
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_INVALID_ARGUMENT = 2;
+ const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 000000000000..dcc4489d52a6
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net.dhcp;
+interface IDhcpServerCallbacks {
+ oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl
new file mode 100644
index 000000000000..77d5917de913
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl
@@ -0,0 +1,15 @@
+package android.net.ip;
+interface IIpClient {
+ oneway void completedPreDhcpAction();
+ oneway void confirmConfiguration();
+ oneway void readPacketFilterComplete(in byte[] data);
+ oneway void shutdown();
+ oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+ oneway void stop();
+ oneway void setTcpBufferSizes(in String tcpBufferSizes);
+ oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+ oneway void setMulticastFilter(boolean enabled);
+ oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+ oneway void removeKeepalivePacketFilter(int slot);
+ oneway void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
+}
diff --git a/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 000000000000..d6bc8089a0be
--- /dev/null
+++ b/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,16 @@
+package android.net.ip;
+interface IIpClientCallbacks {
+ oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+ oneway void onPreDhcpAction();
+ oneway void onPostDhcpAction();
+ oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+ oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+ oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+ oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+ oneway void onReachabilityLost(in String logMsg);
+ oneway void onQuit();
+ oneway void installPacketFilter(in byte[] filter);
+ oneway void startReadPacketFilter();
+ oneway void setFallbackMulticastFilter(boolean enabled);
+ oneway void setNeighborDiscoveryOffload(boolean enable);
+}
diff --git a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 000000000000..31891de7230a
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,9 @@
+package android.net;
+parcelable DhcpResultsParcelable {
+ android.net.StaticIpConfiguration baseConfiguration;
+ int leaseDuration;
+ int mtu;
+ String serverAddress;
+ String vendorInfo;
+ String serverHostName;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
new file mode 100644
index 000000000000..029968b6f324
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
@@ -0,0 +1,24 @@
+package android.net;
+interface INetworkMonitor {
+ oneway void start();
+ oneway void launchCaptivePortalApp();
+ oneway void notifyCaptivePortalAppFinished(int response);
+ oneway void setAcceptPartialConnectivity();
+ oneway void forceReevaluation(int uid);
+ oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+ oneway void notifyDnsResponse(int returnCode);
+ oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+ oneway void notifyNetworkDisconnected();
+ oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+ oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+ const int NETWORK_TEST_RESULT_VALID = 0;
+ const int NETWORK_TEST_RESULT_INVALID = 1;
+ const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+ const int NETWORK_VALIDATION_RESULT_VALID = 1;
+ const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
+ const int NETWORK_VALIDATION_PROBE_DNS = 4;
+ const int NETWORK_VALIDATION_PROBE_HTTP = 8;
+ const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
+ const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
+ const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 000000000000..ee9871ddcd15
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,8 @@
+package android.net;
+interface INetworkMonitorCallbacks {
+ oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
+ oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
+ oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
+ oneway void showProvisioningNotification(String action, String packageName);
+ oneway void hideProvisioningNotification();
+}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
new file mode 100644
index 000000000000..7da11e476c0e
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,7 @@
+package android.net;
+interface INetworkStackConnector {
+ oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+ oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+ oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+ oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 000000000000..f6ca6f7a78e2
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface INetworkStackStatusCallback {
+ oneway void onStatusAvailable(int statusCode);
+}
diff --git a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 000000000000..c80a78785b3b
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable InitialConfigurationParcelable {
+ android.net.LinkAddress[] ipAddresses;
+ android.net.IpPrefix[] directlyConnectedRoutes;
+ String[] dnsServers;
+ String gateway;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..65de8833e6c5
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable NattKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 000000000000..2de790bb7754
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,5 @@
+package android.net;
+parcelable PrivateDnsConfigParcel {
+ String hostname;
+ String[] ips;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 000000000000..3a6c30496fd8
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,15 @@
+package android.net;
+parcelable ProvisioningConfigurationParcelable {
+ boolean enableIPv4;
+ boolean enableIPv6;
+ boolean usingMultinetworkPolicyTracker;
+ boolean usingIpReachabilityMonitor;
+ int requestedPreDhcpActionMs;
+ android.net.InitialConfigurationParcelable initialConfig;
+ android.net.StaticIpConfiguration staticIpConfig;
+ android.net.apf.ApfCapabilities apfCapabilities;
+ int provisioningTimeoutMs;
+ int ipv6AddrGenMode;
+ android.net.Network network;
+ String displayName;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..e121c064f7ac
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,13 @@
+package android.net;
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
+ int rcvWnd;
+ int rcvWndScale;
+ int tos;
+ int ttl;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 000000000000..67193ae904bc
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,11 @@
+package android.net.dhcp;
+parcelable DhcpServingParamsParcel {
+ int serverAddr;
+ int serverAddrPrefixLength;
+ int[] defaultRouters;
+ int[] dnsServers;
+ int[] excludedAddrs;
+ long dhcpLeaseTimeSecs;
+ int linkMtu;
+ boolean metered;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 000000000000..914315855496
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,10 @@
+package android.net.dhcp;
+interface IDhcpServer {
+ oneway void start(in android.net.INetworkStackStatusCallback cb);
+ oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
+ oneway void stop(in android.net.INetworkStackStatusCallback cb);
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_INVALID_ARGUMENT = 2;
+ const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 000000000000..dcc4489d52a6
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net.dhcp;
+interface IDhcpServerCallbacks {
+ oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
new file mode 100644
index 000000000000..176a5ce85373
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
@@ -0,0 +1,16 @@
+package android.net.ip;
+interface IIpClient {
+ oneway void completedPreDhcpAction();
+ oneway void confirmConfiguration();
+ oneway void readPacketFilterComplete(in byte[] data);
+ oneway void shutdown();
+ oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+ oneway void stop();
+ oneway void setTcpBufferSizes(in String tcpBufferSizes);
+ oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+ oneway void setMulticastFilter(boolean enabled);
+ oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+ oneway void removeKeepalivePacketFilter(int slot);
+ oneway void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
+ oneway void addNattKeepalivePacketFilter(int slot, in android.net.NattKeepalivePacketDataParcelable pkt);
+}
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 000000000000..d6bc8089a0be
--- /dev/null
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,16 @@
+package android.net.ip;
+interface IIpClientCallbacks {
+ oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+ oneway void onPreDhcpAction();
+ oneway void onPostDhcpAction();
+ oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+ oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+ oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+ oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+ oneway void onReachabilityLost(in String logMsg);
+ oneway void onQuit();
+ oneway void installPacketFilter(in byte[] filter);
+ oneway void startReadPacketFilter();
+ oneway void setFallbackMulticastFilter(boolean enabled);
+ oneway void setNeighborDiscoveryOffload(boolean enable);
+}
diff --git a/services/net/java/android/net/DhcpResultsParcelable.aidl b/services/net/java/android/net/DhcpResultsParcelable.aidl
index 978638b51ad1..c98d9c201342 100644
--- a/services/net/java/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/java/android/net/DhcpResultsParcelable.aidl
@@ -24,4 +24,5 @@ parcelable DhcpResultsParcelable {
int mtu;
String serverAddress;
String vendorInfo;
-} \ No newline at end of file
+ String serverHostName;
+}
diff --git a/services/net/java/android/net/IIpMemoryStore.aidl b/services/net/java/android/net/IIpMemoryStore.aidl
index 6f88dec8dee9..63feae65756f 100644
--- a/services/net/java/android/net/IIpMemoryStore.aidl
+++ b/services/net/java/android/net/IIpMemoryStore.aidl
@@ -20,8 +20,8 @@ import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.NetworkAttributesParcelable;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
/** {@hide} */
@@ -84,7 +84,7 @@ oneway interface IIpMemoryStore {
* @param listener The listener that will be invoked to return the answer.
* @return (through the listener) A SameL3NetworkResponse containing the answer and confidence.
*/
- void isSameNetwork(String l2Key1, String l2Key2, IOnSameNetworkResponseListener listener);
+ void isSameNetwork(String l2Key1, String l2Key2, IOnSameL3NetworkResponseListener listener);
/**
* Retrieve the network attributes for a key.
@@ -95,7 +95,7 @@ oneway interface IIpMemoryStore {
* @return (through the listener) The network attributes and the L2 key associated with
* the query.
*/
- void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrieved listener);
+ void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrievedListener listener);
/**
* Retrieve previously stored private data.
diff --git a/services/net/java/android/net/INetworkMonitor.aidl b/services/net/java/android/net/INetworkMonitor.aidl
index b32ef12ab24d..3fc81a3dadc5 100644
--- a/services/net/java/android/net/INetworkMonitor.aidl
+++ b/services/net/java/android/net/INetworkMonitor.aidl
@@ -40,6 +40,20 @@ oneway interface INetworkMonitor {
// for https probe.
const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+ // Network validation flags indicate probe result and types. If no NETWORK_VALIDATION_RESULT_*
+ // are set, then it's equal to NETWORK_TEST_RESULT_INVALID. If NETWORK_VALIDATION_RESULT_VALID
+ // is set, then the network validates and equal to NETWORK_TEST_RESULT_VALID. If
+ // NETWORK_VALIDATION_RESULT_PARTIAL is set, then the network has partial connectivity which
+ // is equal to NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY. NETWORK_VALIDATION_PROBE_* is set
+ // when the specific probe result of the network is resolved.
+ const int NETWORK_VALIDATION_RESULT_VALID = 0x01;
+ const int NETWORK_VALIDATION_RESULT_PARTIAL = 0x02;
+ const int NETWORK_VALIDATION_PROBE_DNS = 0x04;
+ const int NETWORK_VALIDATION_PROBE_HTTP = 0x08;
+ const int NETWORK_VALIDATION_PROBE_HTTPS = 0x10;
+ const int NETWORK_VALIDATION_PROBE_FALLBACK = 0x20;
+ const int NETWORK_VALIDATION_PROBE_PRIVDNS = 0x40;
+
void start();
void launchCaptivePortalApp();
void notifyCaptivePortalAppFinished(int response);
diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java
index 9248299e178d..4a115e6ec55b 100644
--- a/services/net/java/android/net/IpMemoryStore.java
+++ b/services/net/java/android/net/IpMemoryStore.java
@@ -41,6 +41,11 @@ public class IpMemoryStore extends IpMemoryStoreClient {
public void onIpMemoryStoreFetched(final IIpMemoryStore memoryStore) {
mService.complete(memoryStore);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
});
}
diff --git a/services/net/java/android/net/IpMemoryStoreClient.java b/services/net/java/android/net/IpMemoryStoreClient.java
index 2f4fdbd8a4a7..379c017b2990 100644
--- a/services/net/java/android/net/IpMemoryStoreClient.java
+++ b/services/net/java/android/net/IpMemoryStoreClient.java
@@ -20,14 +20,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
+import android.net.ipmemorystore.OnBlobRetrievedListener;
+import android.net.ipmemorystore.OnL2KeyResponseListener;
+import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.OnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.OnStatusListener;
import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
import android.os.RemoteException;
import android.util.Log;
@@ -50,12 +49,6 @@ public abstract class IpMemoryStoreClient {
@NonNull
protected abstract IIpMemoryStore getService() throws InterruptedException, ExecutionException;
- protected StatusParcelable internalErrorStatus() {
- final StatusParcelable error = new StatusParcelable();
- error.resultCode = Status.ERROR_UNKNOWN;
- return error;
- }
-
/**
* Store network attributes for a given L2 key.
* If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
@@ -74,12 +67,13 @@ public abstract class IpMemoryStoreClient {
*/
public void storeNetworkAttributes(@NonNull final String l2Key,
@NonNull final NetworkAttributes attributes,
- @Nullable final IOnStatusListener listener) {
+ @Nullable final OnStatusListener listener) {
try {
try {
- getService().storeNetworkAttributes(l2Key, attributes.toParcelable(), listener);
+ getService().storeNetworkAttributes(l2Key, attributes.toParcelable(),
+ OnStatusListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onComplete(internalErrorStatus());
+ listener.onComplete(new Status(Status.ERROR_UNKNOWN));
}
} catch (RemoteException e) {
Log.e(TAG, "Error storing network attributes", e);
@@ -99,12 +93,13 @@ public abstract class IpMemoryStoreClient {
*/
public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId,
@NonNull final String name, @NonNull final Blob data,
- @Nullable final IOnStatusListener listener) {
+ @Nullable final OnStatusListener listener) {
try {
try {
- getService().storeBlob(l2Key, clientId, name, data, listener);
+ getService().storeBlob(l2Key, clientId, name, data,
+ OnStatusListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onComplete(internalErrorStatus());
+ listener.onComplete(new Status(Status.ERROR_UNKNOWN));
}
} catch (RemoteException e) {
Log.e(TAG, "Error storing blob", e);
@@ -126,12 +121,13 @@ public abstract class IpMemoryStoreClient {
* Through the listener, returns the L2 key if one matched, or null.
*/
public void findL2Key(@NonNull final NetworkAttributes attributes,
- @NonNull final IOnL2KeyResponseListener listener) {
+ @NonNull final OnL2KeyResponseListener listener) {
try {
try {
- getService().findL2Key(attributes.toParcelable(), listener);
+ getService().findL2Key(attributes.toParcelable(),
+ OnL2KeyResponseListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onL2KeyResponse(internalErrorStatus(), null);
+ listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error finding L2 Key", e);
@@ -148,12 +144,13 @@ public abstract class IpMemoryStoreClient {
* Through the listener, a SameL3NetworkResponse containing the answer and confidence.
*/
public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
- @NonNull final IOnSameNetworkResponseListener listener) {
+ @NonNull final OnSameL3NetworkResponseListener listener) {
try {
try {
- getService().isSameNetwork(l2Key1, l2Key2, listener);
+ getService().isSameNetwork(l2Key1, l2Key2,
+ OnSameL3NetworkResponseListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onSameNetworkResponse(internalErrorStatus(), null);
+ listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error checking for network sameness", e);
@@ -170,12 +167,13 @@ public abstract class IpMemoryStoreClient {
* the query.
*/
public void retrieveNetworkAttributes(@NonNull final String l2Key,
- @NonNull final IOnNetworkAttributesRetrieved listener) {
+ @NonNull final OnNetworkAttributesRetrievedListener listener) {
try {
try {
- getService().retrieveNetworkAttributes(l2Key, listener);
+ getService().retrieveNetworkAttributes(l2Key,
+ OnNetworkAttributesRetrievedListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onNetworkAttributesRetrieved(internalErrorStatus(), null, null);
+ listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN), null, null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error retrieving network attributes", e);
@@ -194,12 +192,13 @@ public abstract class IpMemoryStoreClient {
* and the name of the data associated with the query.
*/
public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
- @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
+ @NonNull final String name, @NonNull final OnBlobRetrievedListener listener) {
try {
try {
- getService().retrieveBlob(l2Key, clientId, name, listener);
+ getService().retrieveBlob(l2Key, clientId, name,
+ OnBlobRetrievedListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onBlobRetrieved(internalErrorStatus(), null, null, null);
+ listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN), null, null, null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error retrieving blob", e);
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/services/net/java/android/net/NattKeepalivePacketData.java
index bdb246f516a2..27ed11e119b7 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/services/net/java/android/net/NattKeepalivePacketData.java
@@ -19,8 +19,10 @@ package android.net;
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
+import android.annotation.NonNull;
import android.net.SocketKeepalive.InvalidPacketException;
import android.net.util.IpUtils;
+import android.os.Parcelable;
import android.system.OsConstants;
import java.net.Inet4Address;
@@ -29,8 +31,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** @hide */
-public final class NattKeepalivePacketData extends KeepalivePacketData {
-
+public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable {
// This should only be constructed via static factory methods, such as
// nattKeepalivePacket
private NattKeepalivePacketData(InetAddress srcAddress, int srcPort,
@@ -77,4 +78,18 @@ public final class NattKeepalivePacketData extends KeepalivePacketData {
return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
}
+
+ /**
+ * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
+ */
+ @NonNull
+ public NattKeepalivePacketDataParcelable toStableParcelable() {
+ final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
+
+ parcel.srcAddress = srcAddress.getAddress();
+ parcel.srcPort = srcPort;
+ parcel.dstAddress = dstAddress.getAddress();
+ parcel.dstPort = dstPort;
+ return parcel;
+ }
}
diff --git a/services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 000000000000..6f006d4971fb
--- /dev/null
+++ b/services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable NattKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+}
+
diff --git a/services/net/java/android/net/ip/IIpClient.aidl b/services/net/java/android/net/ip/IIpClient.aidl
index 1e7726472ff6..9989c52fc403 100644
--- a/services/net/java/android/net/ip/IIpClient.aidl
+++ b/services/net/java/android/net/ip/IIpClient.aidl
@@ -17,6 +17,7 @@ package android.net.ip;
import android.net.ProxyInfo;
import android.net.ProvisioningConfigurationParcelable;
+import android.net.NattKeepalivePacketDataParcelable;
import android.net.TcpKeepalivePacketDataParcelable;
/** @hide */
@@ -33,4 +34,5 @@ oneway interface IIpClient {
void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt);
void removeKeepalivePacketFilter(int slot);
void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
+ void addNattKeepalivePacketFilter(int slot, in NattKeepalivePacketDataParcelable pkt);
}
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index 90624e0518f8..714ade12435b 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -175,6 +175,11 @@ public class IpClientUtil {
public void setNeighborDiscoveryOffload(boolean enable) {
mCb.setNeighborDiscoveryOffload(enable);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
/**
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index fc1128b80499..66884c60b0bc 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -277,6 +277,11 @@ public class IpServer extends StateMachine {
}
public abstract void callback(int statusCode);
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private class DhcpServerCallbacksImpl extends DhcpServerCallbacks {
diff --git a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index fb4ca3b97895..870e217eb5b7 100644
--- a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -20,7 +20,7 @@ import android.net.ipmemorystore.NetworkAttributesParcelable;
import android.net.ipmemorystore.StatusParcelable;
/** {@hide} */
-oneway interface IOnNetworkAttributesRetrieved {
+oneway interface IOnNetworkAttributesRetrievedListener {
/**
* Network attributes were fetched for the specified L2 key. While the L2 key will never
* be null, the attributes may be if no data is stored about this L2 key.
diff --git a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 294bd3bd4012..b8ccfb99fddd 100644
--- a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -20,10 +20,10 @@ import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
import android.net.ipmemorystore.StatusParcelable;
/** {@hide} */
-oneway interface IOnSameNetworkResponseListener {
+oneway interface IOnSameL3NetworkResponseListener {
/**
* The memory store has come up with the answer to a query that was sent.
*/
- void onSameNetworkResponse(in StatusParcelable status,
+ void onSameL3NetworkResponse(in StatusParcelable status,
in SameL3NetworkResponseParcelable response);
}
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
new file mode 100644
index 000000000000..a17483a84e78
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a blob.
+ * @hide
+ */
+public interface OnBlobRetrievedListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onBlobRetrieved(Status status, String l2Key, String name, Blob blob);
+
+ /** Converts this OnBlobRetrievedListener to a parcelable object */
+ @NonNull
+ static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) {
+ return new IOnBlobRetrievedListener.Stub() {
+ @Override
+ public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
+ final String name, final Blob blob) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
new file mode 100644
index 000000000000..e608aecbf498
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a L2 key.
+ * @hide
+ */
+public interface OnL2KeyResponseListener {
+ /**
+ * The operation has completed with the specified status.
+ */
+ void onL2KeyResponse(Status status, String l2Key);
+
+ /** Converts this OnL2KeyResponseListener to a parcelable object */
+ @NonNull
+ static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) {
+ return new IOnL2KeyResponseListener.Stub() {
+ @Override
+ public void onL2KeyResponse(final StatusParcelable statusParcelable,
+ final String l2Key) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
new file mode 100644
index 000000000000..ca6f3029d496
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return network attributes.
+ * @hide
+ */
+public interface OnNetworkAttributesRetrievedListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attributes);
+
+ /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
+ @NonNull
+ static IOnNetworkAttributesRetrievedListener toAIDL(
+ @NonNull final OnNetworkAttributesRetrievedListener listener) {
+ return new IOnNetworkAttributesRetrievedListener.Stub() {
+ @Override
+ public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
+ final String l2Key,
+ final NetworkAttributesParcelable networkAttributesParcelable) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onNetworkAttributesRetrieved(
+ new Status(statusParcelable), l2Key,
+ new NetworkAttributes(networkAttributesParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
new file mode 100644
index 000000000000..67f8da81c3f2
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a response about network sameness.
+ * @hide
+ */
+public interface OnSameL3NetworkResponseListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onSameL3NetworkResponse(Status status, SameL3NetworkResponse response);
+
+ /** Converts this OnSameL3NetworkResponseListener to a parcelable object */
+ @NonNull
+ static IOnSameL3NetworkResponseListener toAIDL(
+ @NonNull final OnSameL3NetworkResponseListener listener) {
+ return new IOnSameL3NetworkResponseListener.Stub() {
+ @Override
+ public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
+ final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onSameL3NetworkResponse(
+ new Status(statusParcelable),
+ new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
new file mode 100644
index 000000000000..4262efde8843
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * A listener for the IpMemoryStore to return a status to a client.
+ * @hide
+ */
+public interface OnStatusListener {
+ /**
+ * The operation has completed with the specified status.
+ */
+ void onComplete(Status status);
+
+ /** Converts this OnStatusListener to a parcelable object */
+ @NonNull
+ static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) {
+ return new IOnStatusListener.Stub() {
+ @Override
+ public void onComplete(final StatusParcelable statusParcelable) {
+ if (null != listener) {
+ listener.onComplete(new Status(statusParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
index 44d8e0ce3635..172dc24df6b0 100644
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
@@ -41,6 +41,7 @@ public final class IpConfigurationParcelableUtil {
p.mtu = results.mtu;
p.serverAddress = parcelAddress(results.serverAddress);
p.vendorInfo = results.vendorInfo;
+ p.serverHostName = results.serverHostName;
return p;
}
@@ -54,6 +55,7 @@ public final class IpConfigurationParcelableUtil {
results.mtu = p.mtu;
results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
results.vendorInfo = p.vendorInfo;
+ results.serverHostName = p.serverHostName;
return results;
}
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 23f55727d456..c22ca90a79c2 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -51,7 +51,7 @@ android_test {
"liblzma",
"libnativehelper",
"libui",
- "libunwind",
+ "libunwindstack",
"libutils",
"netd_aidl_interface-cpp",
],
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index e61542824083..6a3469c5fa24 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -177,11 +177,15 @@ public final class UsbDescriptorParser {
* Audio Class Specific
*/
case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
- descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+ if (mDeviceDescriptor.getDevClass() == UsbDescriptor.CLASSID_AUDIO) {
+ descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+ }
break;
case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
- descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+ if (mDeviceDescriptor.getDevClass() == UsbDescriptor.CLASSID_AUDIO) {
+ descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+ }
break;
default:
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/DISABLED_TEST_MAPPING
index 8c9d4dfb0894..8c9d4dfb0894 100644
--- a/startop/iorap/TEST_MAPPING
+++ b/startop/iorap/DISABLED_TEST_MAPPING
diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java
index e25c17df4994..0f63853e823f 100644
--- a/telecomm/java/android/telecom/PhoneAccountHandle.java
+++ b/telecomm/java/android/telecom/PhoneAccountHandle.java
@@ -17,6 +17,7 @@
package android.telecom;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.os.Build;
@@ -174,4 +175,21 @@ public final class PhoneAccountHandle implements Parcelable {
in.readString(),
UserHandle.CREATOR.createFromParcel(in));
}
+
+ /**
+ * Determines if two {@link PhoneAccountHandle}s are from the same package.
+ *
+ * @param a Phone account handle to check for same {@link ConnectionService} package.
+ * @param b Other phone account handle to check for same {@link ConnectionService} package.
+ * @return {@code true} if the two {@link PhoneAccountHandle}s passed in belong to the same
+ * {@link ConnectionService} / package, {@code false} otherwise. Note: {@code null} phone
+ * account handles are considered equivalent to other {@code null} phone account handles.
+ * @hide
+ */
+ public static boolean areFromSamePackage(@Nullable PhoneAccountHandle a,
+ @Nullable PhoneAccountHandle b) {
+ String aPackageName = a != null ? a.getComponentName().getPackageName() : null;
+ String bPackageName = b != null ? b.getComponentName().getPackageName() : null;
+ return Objects.equals(aPackageName, bPackageName);
+ }
}
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index ecb0daffeb7b..e727a6e9bacc 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -4259,6 +4259,22 @@ public final class Telephony {
* @hide
*/
public static final String IS_USING_CARRIER_AGGREGATION = "is_using_carrier_aggregation";
+
+ /**
+ * The current registered raw data network operator name in long alphanumeric format.
+ * <p>
+ * This is the same as {@link ServiceState#getOperatorAlphaLongRaw()}.
+ * @hide
+ */
+ public static final String OPERATOR_ALPHA_LONG_RAW = "operator_alpha_long_raw";
+
+ /**
+ * The current registered raw data network operator name in short alphanumeric format.
+ * <p>
+ * This is the same as {@link ServiceState#getOperatorAlphaShortRaw()}.
+ * @hide
+ */
+ public static final String OPERATOR_ALPHA_SHORT_RAW = "operator_alpha_short_raw";
}
/**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 51cff8f8edf8..c449dbf02c2e 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1199,6 +1199,82 @@ public class CarrierConfigManager {
public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
/**
+ * Override the SPN Display Condition 2 integer bits (lsb). B2, B1 is the last two bits of the
+ * spn display condition coding.
+ *
+ * The default value -1 mean this field is not set.
+ *
+ * B1 = 0: display of registered PLMN name not required when registered PLMN is either HPLMN
+ * or a PLMN in the service provider PLMN list (see EF_SPDI).
+ * B1 = 1: display of registered PLMN name required when registered PLMN is either HPLMN or a
+ * PLMN in the service provider PLMN list(see EF_SPDI).
+ * B2 = 0: display of the service provider name is required when registered PLMN is neither
+ * HPLMN nor a PLMN in the service provider PLMN list(see EF_SPDI).
+ * B2 = 1: display of the service provider name is not required when registered PLMN is neither
+ * HPLMN nor a PLMN in the service provider PLMN list(see EF_SPDI).
+ *
+ * Reference: 3GPP TS 31.102 v15.2.0 Section 4.2.12 EF_SPN.
+ * @hide
+ */
+ public static final String KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT =
+ "spn_display_condition_override_int";
+
+ /**
+ * Override the SPDI - an array of PLMN(MCC + MNC) strings.
+ *
+ * Reference: 3GPP TS 31.102 v15.2.0 Section 4.2.66 EF_SPDI.
+ * @hide
+ */
+ public static final String KEY_SPDI_OVERRIDE_STRING_ARRAY = "spdi_override_string_array";
+
+ /**
+ * Override the EHPLMNs - an array of PLMN(MCC + MNC) strings.
+ *
+ * To allow provision for multiple HPLMN codes, PLMN codes that are present within this list
+ * shall replace the HPLMN code derived from the IMSI for PLMN selection purposes.
+ *
+ * Reference: 3GPP TS 31.102 v15.2.0 Section 4.2.84 EF_EHPLMN
+ * Reference: 3GPP TS 23.122 v15.6.0 Section 1.2 Equivalent HPLMN list
+ * @hide
+ */
+ public static final String KEY_EHPLMN_OVERRIDE_STRING_ARRAY = "ehplmn_override_string_array";
+
+ /**
+ * Override the PNN - a string array of comma-separated alpha long and short names:
+ * "alpha_long1,alpha_short1".
+ *
+ * Reference: 3GPP TS 31.102 v15.2.0 Section 4.2.58 EF_PNN.
+ * @hide
+ */
+ public static final String KEY_PNN_OVERRIDE_STRING_ARRAY = "pnn_override_string_array";
+
+ /**
+ * A string array of OPL records, each with comma-delimited data fields as follows:
+ * "plmn1,lactac_start,lactac_end,index".
+ *
+ * Reference: 3GPP TS 31.102 v15.2.0 Section 4.2.59 EF_OPL.
+ * @hide
+ */
+ public static final String KEY_OPL_OVERRIDE_STRING_ARRAY = "opl_override_opl_string_array";
+
+ /**
+ * Allow ERI rules to select a carrier name display string when using 3gpp2 access technologies.
+ * If this bit is not set, the carrier name display string will be selected from the carrier
+ * display name resolver which doesn't apply the ERI rules.
+ *
+ * @hide
+ */
+ public static final String KEY_ALLOW_ERI_BOOL = "allow_cdma_eri_bool";
+
+ /**
+ * If true, use the carrier display name(SPN and PLMN) from the carrier display name resolver.
+ *
+ * @hide
+ */
+ public static final String KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL =
+ "enable_carrier_display_name_resolver_bool";
+
+ /**
* String to override sim country iso.
* Sim country iso is based on sim MCC which is coarse and doesn't work with dual IMSI SIM where
* a SIM can have multiple MCC from different countries.
@@ -1312,6 +1388,24 @@ public class CarrierConfigManager {
"hide_lte_plus_data_icon_bool";
/**
+ * The string is used to filter redundant string from PLMN Network Name that's supplied by
+ * specific carrier.
+ *
+ * @hide
+ */
+ public static final String KEY_OPERATOR_NAME_FILTER_PATTERN_STRING =
+ "operator_name_filter_pattern_string";
+
+ /**
+ * The string is used to compare with operator name. If it matches the pattern then show
+ * specific data icon.
+ *
+ * @hide
+ */
+ public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING =
+ "show_carrier_data_icon_pattern_string";
+
+ /**
* Boolean to decide whether to show precise call failed cause to user
* @hide
*/
@@ -2800,6 +2894,13 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+ sDefaults.putInt(KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT, -1);
+ sDefaults.putStringArray(KEY_SPDI_OVERRIDE_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_PNN_OVERRIDE_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_OPL_OVERRIDE_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_EHPLMN_OVERRIDE_STRING_ARRAY, null);
+ sDefaults.putBoolean(KEY_ALLOW_ERI_BOOL, false);
+ sDefaults.putBoolean(KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, false);
sDefaults.putString(KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, "");
sDefaults.putString(KEY_CARRIER_CALL_SCREENING_APP_STRING, "");
sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
@@ -2946,6 +3047,8 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
+ sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, "");
+ sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
@@ -3056,8 +3159,7 @@ public class CarrierConfigManager {
* May throw an {@link IllegalArgumentException} if {@code overrideValues} contains invalid
* values for the specified config keys.
*
- * NOTE: This API is meant for testing purposes only and may only be accessed from the shell UID
- * during instrumentation testing.
+ * NOTE: This API is meant for testing purposes only.
*
* @param subscriptionId The subscription ID for which the override should be done.
* @param overrideValues Key-value pairs of the values that are to be overridden. If set to
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index a83d8f004f33..cbe5e71ae1e1 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -49,10 +49,10 @@ public abstract class CellIdentity implements Parcelable {
// long alpha Operator Name String or Enhanced Operator Name String
/** @hide */
- protected final String mAlphaLong;
+ protected String mAlphaLong;
// short alpha Operator Name String or Enhanced Operator Name String
/** @hide */
- protected final String mAlphaShort;
+ protected String mAlphaShort;
/** @hide */
protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal,
@@ -145,6 +145,13 @@ public abstract class CellIdentity implements Parcelable {
}
/**
+ * @hide
+ */
+ public void setOperatorAlphaLong(String alphaLong) {
+ mAlphaLong = alphaLong;
+ }
+
+ /**
* @return The short alpha tag associated with the current scan result (may be the operator
* name string or extended operator name string). May be null if unknown.
*/
@@ -154,6 +161,13 @@ public abstract class CellIdentity implements Parcelable {
}
/**
+ * @hide
+ */
+ public void setOperatorAlphaShort(String alphaShort) {
+ mAlphaShort = alphaShort;
+ }
+
+ /**
* @return a CellLocation object for this CellIdentity
* @hide
*/
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 2cb369d28029..3dd931898c18 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -95,6 +95,21 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
this.mIsUsingCarrierAggregation = isUsingCarrierAggregation;
}
+ /**
+ * Constructor from another data specific registration info
+ *
+ * @param dsri another data specific registration info
+ * @hide
+ */
+ DataSpecificRegistrationInfo(DataSpecificRegistrationInfo dsri) {
+ maxDataCalls = dsri.maxDataCalls;
+ isDcNrRestricted = dsri.isDcNrRestricted;
+ isNrAvailable = dsri.isNrAvailable;
+ isEnDcAvailable = dsri.isEnDcAvailable;
+ mLteVopsSupportInfo = dsri.mLteVopsSupportInfo;
+ mIsUsingCarrierAggregation = dsri.mIsUsingCarrierAggregation;
+ }
+
private DataSpecificRegistrationInfo(Parcel source) {
maxDataCalls = source.readInt();
isDcNrRestricted = source.readBoolean();
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 7b9f6d5eb8a1..2fae949cacb3 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -280,6 +280,39 @@ public final class NetworkRegistrationInfo implements Parcelable {
}
/**
+ * Constructor from another network registration info
+ *
+ * @param nri Another network registration info
+ * @hide
+ */
+ public NetworkRegistrationInfo(NetworkRegistrationInfo nri) {
+ mDomain = nri.mDomain;
+ mTransportType = nri.mTransportType;
+ mRegistrationState = nri.mRegistrationState;
+ mRoamingType = nri.mRoamingType;
+ mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
+ mRejectCause = nri.mRejectCause;
+ mEmergencyOnly = nri.mEmergencyOnly;
+ mAvailableServices = new ArrayList<>(nri.mAvailableServices);
+ if (nri.mCellIdentity != null) {
+ Parcel p = Parcel.obtain();
+ nri.mCellIdentity.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ // TODO: Instead of doing this, we should create a formal way for cloning cell identity.
+ // Cell identity is not an immutable object so we have to deep copy it.
+ mCellIdentity = CellIdentity.CREATOR.createFromParcel(p);
+ }
+
+ if (nri.mVoiceSpecificInfo != null) {
+ mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo);
+ }
+ if (nri.mDataSpecificInfo != null) {
+ mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
+ }
+ mNrState = nri.mNrState;
+ }
+
+ /**
* @return The transport type.
*/
public @TransportType int getTransportType() { return mTransportType; }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f4a6984001cb..0ad1abe07417 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -339,6 +339,9 @@ public class ServiceState implements Parcelable {
private List<NetworkRegistrationInfo> mNetworkRegistrationInfos = new ArrayList<>();
+ private String mOperatorAlphaLongRaw;
+ private String mOperatorAlphaShortRaw;
+
/**
* get String description of roaming type
* @hide
@@ -418,8 +421,10 @@ public class ServiceState implements Parcelable {
Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
mNetworkRegistrationInfos = s.mNetworkRegistrationInfos == null ? null :
- new ArrayList<>(s.mNetworkRegistrationInfos);
+ s.getNetworkRegistrationInfoList();
mNrFrequencyRange = s.mNrFrequencyRange;
+ mOperatorAlphaLongRaw = s.mOperatorAlphaLongRaw;
+ mOperatorAlphaShortRaw = s.mOperatorAlphaShortRaw;
}
/**
@@ -453,6 +458,8 @@ public class ServiceState implements Parcelable {
mChannelNumber = in.readInt();
mCellBandwidths = in.createIntArray();
mNrFrequencyRange = in.readInt();
+ mOperatorAlphaLongRaw = in.readString();
+ mOperatorAlphaShortRaw = in.readString();
}
public void writeToParcel(Parcel out, int flags) {
@@ -478,6 +485,8 @@ public class ServiceState implements Parcelable {
out.writeInt(mChannelNumber);
out.writeIntArray(mCellBandwidths);
out.writeInt(mNrFrequencyRange);
+ out.writeString(mOperatorAlphaLongRaw);
+ out.writeString(mOperatorAlphaShortRaw);
}
public int describeContents() {
@@ -836,7 +845,9 @@ public class ServiceState implements Parcelable {
mIsEmergencyOnly,
mLteEarfcnRsrpBoost,
mNetworkRegistrationInfos,
- mNrFrequencyRange);
+ mNrFrequencyRange,
+ mOperatorAlphaLongRaw,
+ mOperatorAlphaShortRaw);
}
@Override
@@ -862,6 +873,8 @@ public class ServiceState implements Parcelable {
&& equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
s.mCdmaDefaultRoamingIndicator)
&& mIsEmergencyOnly == s.mIsEmergencyOnly
+ && equalsHandlesNulls(mOperatorAlphaLongRaw, s.mOperatorAlphaLongRaw)
+ && equalsHandlesNulls(mOperatorAlphaShortRaw, s.mOperatorAlphaShortRaw)
&& (mNetworkRegistrationInfos == null
? s.mNetworkRegistrationInfos == null : s.mNetworkRegistrationInfos != null
&& mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos))
@@ -1019,6 +1032,8 @@ public class ServiceState implements Parcelable {
.append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
.append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
.append(", mNrFrequencyRange=").append(mNrFrequencyRange)
+ .append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw)
+ .append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw)
.append("}").toString();
}
@@ -1056,6 +1071,8 @@ public class ServiceState implements Parcelable {
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
.build());
+ mOperatorAlphaLongRaw = null;
+ mOperatorAlphaShortRaw = null;
}
public void setStateOutOfService() {
@@ -1113,16 +1130,16 @@ public class ServiceState implements Parcelable {
/** @hide */
@TestApi
public void setVoiceRoamingType(@RoamingType int type) {
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setRoamingType(type);
+ regInfo.setRoamingType(type);
+ addNetworkRegistrationInfo(regInfo);
}
/** @hide */
@@ -1134,16 +1151,16 @@ public class ServiceState implements Parcelable {
/** @hide */
@TestApi
public void setDataRoamingType(@RoamingType int type) {
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setRoamingType(type);
+ regInfo.setRoamingType(type);
+ addNetworkRegistrationInfo(regInfo);
}
/**
@@ -1297,6 +1314,8 @@ public class ServiceState implements Parcelable {
m.putInt("ChannelNumber", mChannelNumber);
m.putIntArray("CellBandwidths", mCellBandwidths);
m.putInt("mNrFrequencyRange", mNrFrequencyRange);
+ m.putString("operator-alpha-long-raw", mOperatorAlphaLongRaw);
+ m.putString("operator-alpha-short-raw", mOperatorAlphaShortRaw);
}
/** @hide */
@@ -1305,16 +1324,16 @@ public class ServiceState implements Parcelable {
Rlog.e(LOG_TAG, "ServiceState.setRilVoiceRadioTechnology() called. It's encouraged to "
+ "use addNetworkRegistrationInfo() instead *******");
// Sync to network registration state
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ addNetworkRegistrationInfo(regInfo);
}
@@ -1326,17 +1345,17 @@ public class ServiceState implements Parcelable {
// Sync to network registration state. Always write down the WWAN transport. For AP-assisted
// mode device, use addNetworkRegistrationInfo() to set the correct transport if RAT
// is IWLAN.
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ addNetworkRegistrationInfo(regInfo);
}
/** @hide */
@@ -1378,10 +1397,10 @@ public class ServiceState implements Parcelable {
* @hide
*/
public @NRState int getNrState() {
- final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ final NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) return NetworkRegistrationInfo.NR_STATE_NONE;
- return regState.getNrState();
+ if (regInfo == null) return NetworkRegistrationInfo.NR_STATE_NONE;
+ return regInfo.getNrState();
}
/**
@@ -1775,7 +1794,11 @@ public class ServiceState implements Parcelable {
@SystemApi
public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
synchronized (mNetworkRegistrationInfos) {
- return new ArrayList<>(mNetworkRegistrationInfos);
+ List<NetworkRegistrationInfo> newList = new ArrayList<>();
+ for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) {
+ newList.add(new NetworkRegistrationInfo(nri));
+ }
+ return newList;
}
}
@@ -1795,7 +1818,7 @@ public class ServiceState implements Parcelable {
synchronized (mNetworkRegistrationInfos) {
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getTransportType() == transportType) {
- list.add(networkRegistrationInfo);
+ list.add(new NetworkRegistrationInfo(networkRegistrationInfo));
}
}
}
@@ -1819,7 +1842,7 @@ public class ServiceState implements Parcelable {
synchronized (mNetworkRegistrationInfos) {
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getDomain() == domain) {
- list.add(networkRegistrationInfo);
+ list.add(new NetworkRegistrationInfo(networkRegistrationInfo));
}
}
}
@@ -1844,7 +1867,7 @@ public class ServiceState implements Parcelable {
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getTransportType() == transportType
&& networkRegistrationInfo.getDomain() == domain) {
- return networkRegistrationInfo;
+ return new NetworkRegistrationInfo(networkRegistrationInfo);
}
}
}
@@ -1856,20 +1879,20 @@ public class ServiceState implements Parcelable {
* @hide
*/
@TestApi
- public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
- if (regState == null) return;
+ public void addNetworkRegistrationInfo(NetworkRegistrationInfo nri) {
+ if (nri == null) return;
synchronized (mNetworkRegistrationInfos) {
for (int i = 0; i < mNetworkRegistrationInfos.size(); i++) {
NetworkRegistrationInfo curRegState = mNetworkRegistrationInfos.get(i);
- if (curRegState.getTransportType() == regState.getTransportType()
- && curRegState.getDomain() == regState.getDomain()) {
+ if (curRegState.getTransportType() == nri.getTransportType()
+ && curRegState.getDomain() == nri.getDomain()) {
mNetworkRegistrationInfos.remove(i);
break;
}
}
- mNetworkRegistrationInfos.add(regState);
+ mNetworkRegistrationInfos.add(new NetworkRegistrationInfo(nri));
}
}
@@ -1906,4 +1929,36 @@ public class ServiceState implements Parcelable {
return state;
}
+
+ /**
+ * @hide
+ */
+ public void setOperatorAlphaLongRaw(String operatorAlphaLong) {
+ mOperatorAlphaLongRaw = operatorAlphaLong;
+ }
+
+ /**
+ * The current registered raw data network operator name in long alphanumeric format.
+ *
+ * @hide
+ */
+ public String getOperatorAlphaLongRaw() {
+ return mOperatorAlphaLongRaw;
+ }
+
+ /**
+ * @hide
+ */
+ public void setOperatorAlphaShortRaw(String operatorAlphaShort) {
+ mOperatorAlphaShortRaw = operatorAlphaShort;
+ }
+
+ /**
+ * The current registered raw data network operator name in short alphanumeric format.
+ *
+ * @hide
+ */
+ public String getOperatorAlphaShortRaw() {
+ return mOperatorAlphaShortRaw;
+ }
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index def7fbe5bd3f..be7bb6779f39 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -327,12 +327,12 @@ public final class SmsManager {
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- true /* persistMessage*/);
+ true /* persistMessage*/, ActivityThread.currentPackageName());
}
private void sendTextMessageInternal(String destinationAddress, String scAddress,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
- boolean persistMessage) {
+ boolean persistMessage, String packageName) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -345,9 +345,8 @@ public final class SmsManager {
// If the subscription is invalid or default, we will use the default phone to send the
// SMS and possibly fail later in the SMS sending process.
ISms iSms = getISmsServiceOrThrow();
- iSms.sendTextForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
- destinationAddress,
- scAddress, text, sentIntent, deliveryIntent,
+ iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
+ destinationAddress, scAddress, text, sentIntent, deliveryIntent,
persistMessage);
} catch (RemoteException ex) {
// ignore it
@@ -379,7 +378,7 @@ public final class SmsManager {
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- false /* persistMessage */);
+ false /* persistMessage */, ActivityThread.currentPackageName());
}
/**
@@ -620,13 +619,30 @@ public final class SmsManager {
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, true /* persistMessage*/);
+ deliveryIntents, true /* persistMessage*/, ActivityThread.currentPackageName());
+ }
+
+ /**
+ * @hide
+ * Similar method as #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList)
+ * With an additional argument
+ * @param packageName serves as the default package name if ActivityThread.currentpackageName is
+ * null.
+ */
+ public void sendMultipartTextMessageExternal(
+ String destinationAddress, String scAddress, ArrayList<String> parts,
+ ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
+ String packageName) {
+ sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+ deliveryIntents, true /* persistMessage*/,
+ ActivityThread.currentPackageName() == null
+ ? packageName : ActivityThread.currentPackageName());
}
private void sendMultipartTextMessageInternal(
String destinationAddress, String scAddress, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
- boolean persistMessage) {
+ boolean persistMessage, String packageName) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -638,8 +654,7 @@ public final class SmsManager {
try {
ISms iSms = getISmsServiceOrThrow();
iSms.sendMultipartTextForSubscriber(getSubscriptionId(),
- ActivityThread.currentPackageName(),
- destinationAddress, scAddress, parts,
+ packageName, destinationAddress, scAddress, parts,
sentIntents, deliveryIntents, persistMessage);
} catch (RemoteException ex) {
// ignore it
@@ -653,8 +668,8 @@ public final class SmsManager {
if (deliveryIntents != null && deliveryIntents.size() > 0) {
deliveryIntent = deliveryIntents.get(0);
}
- sendTextMessage(destinationAddress, scAddress, parts.get(0),
- sentIntent, deliveryIntent);
+ sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
+ sentIntent, deliveryIntent, true, packageName);
}
}
@@ -675,7 +690,7 @@ public final class SmsManager {
String destinationAddress, String scAddress, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, false /* persistMessage*/);
+ deliveryIntents, false /* persistMessage*/, ActivityThread.currentPackageName());
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 586c815ae7b5..43acfdddf819 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -294,6 +294,19 @@ public class SubscriptionManager {
public static final String SUBSCRIPTION_TYPE = "subscription_type";
/**
+ * TelephonyProvider column name white_listed_apn_data.
+ * It's a bitmask of APN types that will be allowed on this subscription even if it's metered
+ * and mobile data is turned off by the user.
+ * <P>Type: INTEGER (int)</P> For example, if TYPE_MMS is is true, Telephony will allow MMS
+ * data connection to setup even if MMS is metered and mobile_data is turned off on that
+ * subscription.
+ *
+ * Default value is 0.
+ */
+ /** @hide */
+ public static final String WHITE_LISTED_APN_DATA = "white_listed_apn_data";
+
+ /**
* This constant is to designate a subscription as a Local-SIM Subscription.
* <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
* device.
@@ -2052,7 +2065,6 @@ public class SubscriptionManager {
} else {
logd("putPhoneIdAndSubIdExtra: no valid subs");
intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
- intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
}
}
@@ -2063,9 +2075,6 @@ public class SubscriptionManager {
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
- //FIXME this is using phoneId and slotIndex interchangeably
- //Eventually, this should be removed as it is not the slot id
- intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
}
/**
@@ -3087,6 +3096,31 @@ public class SubscriptionManager {
return subId;
}
+ /**
+ * Set whether a subscription always allows MMS connection. If true, MMS network
+ * request will be accepted by telephony even if user turns "mobile data" off
+ * on this subscription.
+ *
+ * @param subId which subscription it's setting to.
+ * @param alwaysAllow whether Mms data is always allowed.
+ * @return whether operation is successful.
+ *
+ * @hide
+ */
+ public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ return iSub.setAlwaysAllowMmsData(subId, alwaysAllow);
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return false;
+ }
+
private interface CallISubMethodHelper {
int callMethod(ISub iSub) throws RemoteException;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e1425b975525..510e7c9f864f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -64,6 +64,7 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
+import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.ims.aidl.IImsConfig;
@@ -2276,12 +2277,15 @@ public class TelephonyManager {
}
/**
- * Returns the ISO country code equivalent of the MCC (Mobile Country Code) of the current
+ * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current
* registered operator or the cell nearby, if available.
- * .
+ * <p>
+ * The ISO-3166 country code is provided in lowercase 2 character format.
* <p>
* Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine
* if on a CDMA network).
+ * <p>
+ * @return the lowercase 2 character ISO-3166 country code, or empty string if not available.
*/
public String getNetworkCountryIso() {
return getNetworkCountryIsoForPhone(getPhoneId());
@@ -3140,7 +3144,10 @@ public class TelephonyManager {
}
/**
- * Returns the ISO country code equivalent for the SIM provider's country code.
+ * Returns the ISO-3166 country code equivalent for the SIM provider's country code.
+ * <p>
+ * The ISO-3166 country code is provided in lowercase 2 character format.
+ * @return the lowercase 2 character ISO-3166 country code, or empty string is not available.
*/
public String getSimCountryIso() {
return getSimCountryIsoForPhone(getPhoneId());
@@ -3274,7 +3281,7 @@ public class TelephonyManager {
}
/**
- * Gets information about currently inserted UICCs and enabled eUICCs.
+ * Gets information about currently inserted UICCs and eUICCs.
* <p>
* Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
* <p>
@@ -10888,4 +10895,58 @@ public class TelephonyManager {
}
return new Pair<Integer, Integer>(-1, -1);
}
+
+ /**
+ * Return whether data is enabled for certain APN type. This will tell if framework will accept
+ * corresponding network requests on a subId.
+ *
+ * {@link #isDataEnabled()} is directly associated with users' Mobile data toggle on / off. If
+ * {@link #isDataEnabled()} returns false, it means in general all meter-ed data are disabled.
+ *
+ * This per APN type API gives a better idea whether data is allowed on a specific APN type.
+ * It will return true if:
+ *
+ * 1) User data is turned on, or
+ * 2) APN is un-metered for this subscription, or
+ * 3) APN type is whitelisted. E.g. MMS is whitelisted if
+ * {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on.
+ *
+ * @return whether data is enabled for a apn type.
+ *
+ * @hide
+ */
+ public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) {
+ String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.isDataEnabledForApn(apnType, getSubId(), pkgForDebug);
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Whether an APN type is metered or not. It will be evaluated with the subId associated
+ * with the TelephonyManager instance.
+ *
+ * @hide
+ */
+ public boolean isApnMetered(@ApnSetting.ApnType int apnType) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.isApnMetered(apnType, getSubId());
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return true;
+ }
}
diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java
index d95a4992f808..2246ccc315c8 100644
--- a/telephony/java/android/telephony/UiccCardInfo.java
+++ b/telephony/java/android/telephony/UiccCardInfo.java
@@ -101,7 +101,7 @@ public final class UiccCardInfo implements Parcelable {
/**
* Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC
- * (see {@link #isEuicc()}), returns null.
+ * (see {@link #isEuicc()}), or the EID is not available, returns null.
* <p>
* Note that this field may be omitted if the caller does not have the correct permissions
* (see {@link TelephonyManager#getUiccCardsInfo()}).
@@ -115,7 +115,7 @@ public final class UiccCardInfo implements Parcelable {
}
/**
- * Get the ICCID of the UICC.
+ * Get the ICCID of the UICC. If the ICCID is not availble, returns null.
* <p>
* Note that this field may be omitted if the caller does not have the correct permissions
* (see {@link TelephonyManager#getUiccCardsInfo()}).
diff --git a/telephony/java/android/telephony/UiccSlotInfo.java b/telephony/java/android/telephony/UiccSlotInfo.java
index 93a7da04c56e..2bc677562b78 100644
--- a/telephony/java/android/telephony/UiccSlotInfo.java
+++ b/telephony/java/android/telephony/UiccSlotInfo.java
@@ -140,6 +140,14 @@ public class UiccSlotInfo implements Parcelable {
return mIsEuicc;
}
+ /**
+ * Returns the ICCID of the card in the slot, or the EID of an active eUICC.
+ * <p>
+ * If the UICC slot is for an active eUICC, returns the EID.
+ * If the UICC slot is for an inactive eUICC, returns the ICCID of the enabled profile, or the
+ * root profile if all other profiles are disabled.
+ * If the UICC slot is not an eUICC, returns the ICCID.
+ */
public String getCardId() {
return mCardId;
}
diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
index 18a533a46273..d43181e68c28 100644
--- a/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
@@ -65,6 +65,19 @@ public class VoiceSpecificRegistrationInfo implements Parcelable{
this.defaultRoamingIndicator = defaultRoamingIndicator;
}
+ /**
+ * Constructor from another voice specific registration info
+ *
+ * @param vsri another voice specific registration info
+ * @hide
+ */
+ VoiceSpecificRegistrationInfo(VoiceSpecificRegistrationInfo vsri) {
+ cssSupported = vsri.cssSupported;
+ roamingIndicator = vsri.roamingIndicator;
+ systemIsInPrl = vsri.systemIsInPrl;
+ defaultRoamingIndicator = vsri.defaultRoamingIndicator;
+ }
+
private VoiceSpecificRegistrationInfo(Parcel source) {
this.cssSupported = source.readBoolean();
this.roamingIndicator = source.readInt();
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index dba220718818..b144ff761874 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -558,6 +558,24 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
} else if (this.getDisplayPriorityScore()
< emergencyNumber.getDisplayPriorityScore()) {
return 1;
+ } else if (this.getNumber().compareTo(emergencyNumber.getNumber()) != 0) {
+ return this.getNumber().compareTo(emergencyNumber.getNumber());
+ } else if (this.getCountryIso().compareTo(emergencyNumber.getCountryIso()) != 0) {
+ return this.getCountryIso().compareTo(emergencyNumber.getCountryIso());
+ } else if (this.getMnc().compareTo(emergencyNumber.getMnc()) != 0) {
+ return this.getMnc().compareTo(emergencyNumber.getMnc());
+ } else if (this.getEmergencyServiceCategoryBitmask()
+ != emergencyNumber.getEmergencyServiceCategoryBitmask()) {
+ return this.getEmergencyServiceCategoryBitmask()
+ > emergencyNumber.getEmergencyServiceCategoryBitmask() ? -1 : 1;
+ } else if (this.getEmergencyUrns().toString().compareTo(
+ emergencyNumber.getEmergencyUrns().toString()) != 0) {
+ return this.getEmergencyUrns().toString().compareTo(
+ emergencyNumber.getEmergencyUrns().toString());
+ } else if (this.getEmergencyCallRouting()
+ != emergencyNumber.getEmergencyCallRouting()) {
+ return this.getEmergencyCallRouting()
+ > emergencyNumber.getEmergencyCallRouting() ? -1 : 1;
} else {
return 0;
}
@@ -579,13 +597,9 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
if (emergencyNumberList == null) {
return;
}
- Set<EmergencyNumber> mergedEmergencyNumber = new HashSet<>();
+ Set<Integer> duplicatedEmergencyNumberPosition = new HashSet<>();
for (int i = 0; i < emergencyNumberList.size(); i++) {
- // Skip the check because it was merged.
- if (mergedEmergencyNumber.contains(emergencyNumberList.get(i))) {
- continue;
- }
- for (int j = i + 1; j < emergencyNumberList.size(); j++) {
+ for (int j = 0; j < i; j++) {
if (areSameEmergencyNumbers(
emergencyNumberList.get(i), emergencyNumberList.get(j))) {
Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
@@ -594,14 +608,15 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
emergencyNumberList.set(i, mergeSameEmergencyNumbers(
emergencyNumberList.get(i), emergencyNumberList.get(j)));
// Mark the emergency number has been merged
- mergedEmergencyNumber.add(emergencyNumberList.get(j));
+ duplicatedEmergencyNumberPosition.add(j);
}
}
}
- // Remove the marked emergency number in the orignal list
- for (int i = 0; i < emergencyNumberList.size(); i++) {
- if (mergedEmergencyNumber.contains(emergencyNumberList.get(i))) {
- emergencyNumberList.remove(i--);
+
+ // Remove the marked emergency number in the original list
+ for (int i = emergencyNumberList.size() - 1; i >= 0; i--) {
+ if (duplicatedEmergencyNumberPosition.contains(i)) {
+ emergencyNumberList.remove(i);
}
}
Collections.sort(emergencyNumberList);
@@ -635,7 +650,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
!= second.getEmergencyServiceCategoryBitmask()) {
return false;
}
- if (first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
+ if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
return false;
}
if (first.getEmergencyCallRouting() != second.getEmergencyCallRouting()) {
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index f1a5778b2281..ee287d59b607 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -321,6 +321,18 @@ public class EuiccManager {
"android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
/**
+ * Key for an extra set on privileged actions {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED}
+ * providing the physical slot ID of the target slot.
+ *
+ * <p>Expected type of the extra data: int
+ *
+ * @hide
+ */
+ // TODO: Make this a @SystemApi.
+ public static final String EXTRA_PHYSICAL_SLOT_ID =
+ "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
+
+ /**
* Optional meta-data attribute for a carrier app providing an icon to use to represent the
* carrier. If not provided, the app's launcher icon will be used as a fallback.
*/
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 568c11be9077..fd58f7ea2752 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -545,7 +545,8 @@ public final class ImsCallProfile implements Parcelable {
+ ", emergencyUrns=" + mEmergencyUrns
+ ", emergencyCallRouting=" + mEmergencyCallRouting
+ ", emergencyCallTesting=" + mEmergencyCallTesting
- + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency + " }";
+ + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency
+ + ", mRestrictCause=" + mRestrictCause + " }";
}
@Override
@@ -565,6 +566,7 @@ public final class ImsCallProfile implements Parcelable {
out.writeInt(mEmergencyCallRouting);
out.writeBoolean(mEmergencyCallTesting);
out.writeBoolean(mHasKnownUserIntentEmergency);
+ out.writeInt(mRestrictCause);
}
private void readFromParcel(Parcel in) {
@@ -577,6 +579,7 @@ public final class ImsCallProfile implements Parcelable {
mEmergencyCallRouting = in.readInt();
mEmergencyCallTesting = in.readBoolean();
mHasKnownUserIntentEmergency = in.readBoolean();
+ mRestrictCause = in.readInt();
}
public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
index 0bb1b4379679..e90548a4445f 100644
--- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java
+++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
@@ -33,8 +33,8 @@ public class Rcs1To1Thread extends RcsThread {
*
* @hide
*/
- public Rcs1To1Thread(int threadId) {
- super(threadId);
+ public Rcs1To1Thread(RcsControllerCall rcsControllerCall, int threadId) {
+ super(rcsControllerCall, threadId);
mThreadId = threadId;
}
@@ -56,7 +56,9 @@ public class Rcs1To1Thread extends RcsThread {
*/
@WorkerThread
public long getFallbackThreadId() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.get1To1ThreadFallbackThreadId(mThreadId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.get1To1ThreadFallbackThreadId(mThreadId,
+ callingPackage));
}
/**
@@ -69,8 +71,9 @@ public class Rcs1To1Thread extends RcsThread {
*/
@WorkerThread
public void setFallbackThreadId(long fallbackThreadId) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.set1To1ThreadFallbackThreadId(mThreadId, fallbackThreadId));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.set1To1ThreadFallbackThreadId(mThreadId,
+ fallbackThreadId, callingPackage));
}
/**
@@ -81,6 +84,9 @@ public class Rcs1To1Thread extends RcsThread {
@WorkerThread
public RcsParticipant getRecipient() throws RcsMessageStoreException {
return new RcsParticipant(
- RcsControllerCall.call(iRcs -> iRcs.get1To1ThreadOtherParticipantId(mThreadId)));
+ mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.get1To1ThreadOtherParticipantId(mThreadId,
+ callingPackage)));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsControllerCall.java b/telephony/java/android/telephony/ims/RcsControllerCall.java
index 5512c4c7b19d..a2d68ad0cdb0 100644
--- a/telephony/java/android/telephony/ims/RcsControllerCall.java
+++ b/telephony/java/android/telephony/ims/RcsControllerCall.java
@@ -27,38 +27,38 @@ import android.telephony.ims.aidl.IRcs;
* @hide - not meant for public use
*/
class RcsControllerCall {
- static <R> R call(RcsServiceCall<R> serviceCall) throws RcsMessageStoreException {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_RCS_SERVICE));
- if (iRcs == null) {
- throw new RcsMessageStoreException("Could not connect to RCS storage service");
- }
+ private final Context mContext;
- try {
- return serviceCall.methodOnIRcs(iRcs);
- } catch (RemoteException exception) {
- throw new RcsMessageStoreException(exception.getMessage());
- }
+ RcsControllerCall(Context context) {
+ mContext = context;
}
- static void callWithNoReturn(RcsServiceCallWithNoReturn serviceCall)
- throws RcsMessageStoreException {
+ <R> R call(RcsServiceCall<R> serviceCall) throws RcsMessageStoreException {
IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_RCS_SERVICE));
if (iRcs == null) {
throw new RcsMessageStoreException("Could not connect to RCS storage service");
}
try {
- serviceCall.methodOnIRcs(iRcs);
+ return serviceCall.methodOnIRcs(iRcs, mContext.getOpPackageName());
} catch (RemoteException exception) {
throw new RcsMessageStoreException(exception.getMessage());
}
}
+ void callWithNoReturn(RcsServiceCallWithNoReturn serviceCall)
+ throws RcsMessageStoreException {
+ call((iRcs, callingPackage) -> {
+ serviceCall.methodOnIRcs(iRcs, callingPackage);
+ return null;
+ });
+ }
+
interface RcsServiceCall<R> {
- R methodOnIRcs(IRcs iRcs) throws RemoteException;
+ R methodOnIRcs(IRcs iRcs, String callingPackage) throws RemoteException;
}
interface RcsServiceCallWithNoReturn {
- void methodOnIRcs(IRcs iRcs) throws RemoteException;
+ void methodOnIRcs(IRcs iRcs, String callingPackage) throws RemoteException;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsEvent.java b/telephony/java/android/telephony/ims/RcsEvent.java
index 994b27ab7405..9dd07209fcfd 100644
--- a/telephony/java/android/telephony/ims/RcsEvent.java
+++ b/telephony/java/android/telephony/ims/RcsEvent.java
@@ -40,5 +40,5 @@ public abstract class RcsEvent {
*
* @hide
*/
- abstract void persist() throws RcsMessageStoreException;
+ abstract void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException;
}
diff --git a/telephony/java/android/telephony/ims/RcsEventDescriptor.java b/telephony/java/android/telephony/ims/RcsEventDescriptor.java
index 8e3f6cd4d889..b44adeaa62bb 100644
--- a/telephony/java/android/telephony/ims/RcsEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsEventDescriptor.java
@@ -38,7 +38,7 @@ public abstract class RcsEventDescriptor implements Parcelable {
* descriptor.
*/
@VisibleForTesting(visibility = PROTECTED)
- public abstract RcsEvent createRcsEvent();
+ public abstract RcsEvent createRcsEvent(RcsControllerCall rcsControllerCall);
RcsEventDescriptor(Parcel in) {
mTimestamp = in.readLong();
diff --git a/telephony/java/android/telephony/ims/RcsEventQueryResultDescriptor.java b/telephony/java/android/telephony/ims/RcsEventQueryResultDescriptor.java
index e30745b7e633..b972d557fae0 100644
--- a/telephony/java/android/telephony/ims/RcsEventQueryResultDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsEventQueryResultDescriptor.java
@@ -39,9 +39,9 @@ public class RcsEventQueryResultDescriptor implements Parcelable {
mEvents = events;
}
- protected RcsEventQueryResult getRcsEventQueryResult() {
+ protected RcsEventQueryResult getRcsEventQueryResult(RcsControllerCall rcsControllerCall) {
List<RcsEvent> rcsEvents = mEvents.stream()
- .map(RcsEventDescriptor::createRcsEvent)
+ .map(rcsEvent -> rcsEvent.createRcsEvent(rcsControllerCall))
.collect(Collectors.toList());
return new RcsEventQueryResult(mContinuationToken, rcsEvents);
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.java b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
index 3816cd413722..ef66a76a5902 100644
--- a/telephony/java/android/telephony/ims/RcsFileTransferPart.java
+++ b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
@@ -103,12 +103,15 @@ public class RcsFileTransferPart {
public @interface RcsFileTransferStatus {
}
+ private final RcsControllerCall mRcsControllerCall;
+
private int mId;
/**
* @hide
*/
- RcsFileTransferPart(int id) {
+ RcsFileTransferPart(RcsControllerCall rcsControllerCall, int id) {
+ mRcsControllerCall = rcsControllerCall;
mId = id;
}
@@ -134,7 +137,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setFileTransferSessionId(String sessionId) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferSessionId(mId, sessionId));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferSessionId(mId, sessionId,
+ callingPackage));
}
/**
@@ -143,7 +148,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public String getFileTransferSessionId() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferSessionId(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferSessionId(mId, callingPackage));
}
/**
@@ -155,7 +161,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setContentUri(Uri contentUri) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferContentUri(mId, contentUri));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferContentUri(mId, contentUri,
+ callingPackage));
}
/**
@@ -165,7 +173,8 @@ public class RcsFileTransferPart {
@Nullable
@WorkerThread
public Uri getContentUri() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferContentUri(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferContentUri(mId, callingPackage));
}
/**
@@ -177,8 +186,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setContentMimeType(String contentMimeType) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setFileTransferContentType(mId, contentMimeType));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferContentType(mId, contentMimeType,
+ callingPackage));
}
/**
@@ -188,7 +198,8 @@ public class RcsFileTransferPart {
@WorkerThread
@Nullable
public String getContentMimeType() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferContentType(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferContentType(mId, callingPackage));
}
/**
@@ -199,8 +210,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setFileSize(long contentLength) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setFileTransferFileSize(mId, contentLength));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferFileSize(mId, contentLength,
+ callingPackage));
}
/**
@@ -209,7 +221,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public long getFileSize() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferFileSize(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferFileSize(mId, callingPackage));
}
/**
@@ -222,8 +235,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setTransferOffset(long transferOffset) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setFileTransferTransferOffset(mId, transferOffset));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferTransferOffset(mId, transferOffset,
+ callingPackage));
}
/**
@@ -232,7 +246,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public long getTransferOffset() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferTransferOffset(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferTransferOffset(mId, callingPackage));
}
/**
@@ -244,7 +259,8 @@ public class RcsFileTransferPart {
@WorkerThread
public void setFileTransferStatus(@RcsFileTransferStatus int status)
throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferStatus(mId, status));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferStatus(mId, status, callingPackage));
}
/**
@@ -253,7 +269,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public @RcsFileTransferStatus int getFileTransferStatus() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferStatus(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferStatus(mId, callingPackage));
}
/**
@@ -262,7 +279,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public int getWidth() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferWidth(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferWidth(mId, callingPackage));
}
/**
@@ -273,7 +291,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setWidth(int width) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferWidth(mId, width));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferWidth(mId, width, callingPackage));
}
/**
@@ -282,7 +301,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public int getHeight() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferHeight(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferHeight(mId, callingPackage));
}
/**
@@ -293,7 +313,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setHeight(int height) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferHeight(mId, height));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferHeight(mId, height, callingPackage));
}
/**
@@ -302,7 +323,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public long getLength() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferLength(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferLength(mId, callingPackage));
}
/**
@@ -313,7 +335,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setLength(long length) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferLength(mId, length));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferLength(mId, length, callingPackage));
}
/**
@@ -323,7 +346,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public Uri getPreviewUri() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferPreviewUri(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferPreviewUri(mId, callingPackage));
}
/**
@@ -334,7 +358,9 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setPreviewUri(Uri previewUri) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferPreviewUri(mId, previewUri));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferPreviewUri(mId, previewUri,
+ callingPackage));
}
/**
@@ -343,7 +369,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public String getPreviewMimeType() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getFileTransferPreviewType(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransferPreviewType(mId, callingPackage));
}
/**
@@ -354,7 +381,8 @@ public class RcsFileTransferPart {
*/
@WorkerThread
public void setPreviewMimeType(String previewMimeType) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setFileTransferPreviewType(mId, previewMimeType));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setFileTransferPreviewType(mId, previewMimeType,
+ callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java
index baec19ac6669..30abcb4abb3d 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThread.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThread.java
@@ -38,8 +38,8 @@ public class RcsGroupThread extends RcsThread {
*
* @hide
*/
- public RcsGroupThread(int threadId) {
- super(threadId);
+ public RcsGroupThread(RcsControllerCall rcsControllerCall, int threadId) {
+ super(rcsControllerCall, threadId);
}
/**
@@ -58,7 +58,8 @@ public class RcsGroupThread extends RcsThread {
@Nullable
@WorkerThread
public String getGroupName() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadName(mThreadId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getGroupThreadName(mThreadId, callingPackage));
}
/**
@@ -69,7 +70,9 @@ public class RcsGroupThread extends RcsThread {
*/
@WorkerThread
public void setGroupName(String groupName) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setGroupThreadName(mThreadId, groupName));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setGroupThreadName(mThreadId, groupName,
+ callingPackage));
}
/**
@@ -79,7 +82,8 @@ public class RcsGroupThread extends RcsThread {
*/
@Nullable
public Uri getGroupIcon() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadIcon(mThreadId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getGroupThreadIcon(mThreadId, callingPackage));
}
/**
@@ -90,7 +94,9 @@ public class RcsGroupThread extends RcsThread {
*/
@WorkerThread
public void setGroupIcon(@Nullable Uri groupIcon) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setGroupThreadIcon(mThreadId, groupIcon));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setGroupThreadIcon(mThreadId, groupIcon,
+ callingPackage));
}
/**
@@ -100,8 +106,11 @@ public class RcsGroupThread extends RcsThread {
@Nullable
@WorkerThread
public RcsParticipant getOwner() throws RcsMessageStoreException {
- return new RcsParticipant(RcsControllerCall.call(
- iRcs -> iRcs.getGroupThreadOwner(mThreadId)));
+ return new RcsParticipant(
+ mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getGroupThreadOwner(mThreadId,
+ callingPackage)));
}
/**
@@ -114,8 +123,9 @@ public class RcsGroupThread extends RcsThread {
*/
@WorkerThread
public void setOwner(@Nullable RcsParticipant participant) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setGroupThreadOwner(mThreadId, participant.getId()));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setGroupThreadOwner(mThreadId, participant.getId(),
+ callingPackage));
}
/**
@@ -133,8 +143,9 @@ public class RcsGroupThread extends RcsThread {
return;
}
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.addParticipantToGroupThread(mThreadId, participant.getId()));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.addParticipantToGroupThread(mThreadId,
+ participant.getId(), callingPackage));
}
/**
@@ -150,8 +161,9 @@ public class RcsGroupThread extends RcsThread {
return;
}
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.removeParticipantFromGroupThread(mThreadId, participant.getId()));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.removeParticipantFromGroupThread(mThreadId,
+ participant.getId(), callingPackage));
}
/**
@@ -170,8 +182,10 @@ public class RcsGroupThread extends RcsThread {
new RcsParticipantQueryParams.Builder().setThread(this).build();
RcsParticipantQueryResult queryResult = new RcsParticipantQueryResult(
- RcsControllerCall.call(
- iRcs -> iRcs.getParticipants(queryParameters)));
+ mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getParticipants(queryParameters,
+ callingPackage)));
List<RcsParticipant> participantList = queryResult.getParticipants();
Set<RcsParticipant> participantSet = new LinkedHashSet<>(participantList);
@@ -187,7 +201,9 @@ public class RcsGroupThread extends RcsThread {
@Nullable
@WorkerThread
public Uri getConferenceUri() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadConferenceUri(mThreadId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getGroupThreadConferenceUri(mThreadId,
+ callingPackage));
}
/**
@@ -200,7 +216,8 @@ public class RcsGroupThread extends RcsThread {
@Nullable
@WorkerThread
public void setConferenceUri(Uri conferenceUri) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setGroupThreadConferenceUri(mThreadId, conferenceUri));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setGroupThreadConferenceUri(mThreadId, conferenceUri,
+ callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
index 4a6b963a143a..f4beef7f9843 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
@@ -23,14 +23,14 @@ import android.annotation.NonNull;
* @hide
*/
public abstract class RcsGroupThreadEvent extends RcsEvent {
- private final int mRcsGroupThreadId;
- private final int mOriginatingParticipantId;
+ private final RcsGroupThread mRcsGroupThread;
+ private final RcsParticipant mOriginatingParticipant;
- RcsGroupThreadEvent(long timestamp, int rcsGroupThreadId,
- int originatingParticipantId) {
+ RcsGroupThreadEvent(long timestamp, RcsGroupThread rcsGroupThread,
+ RcsParticipant originatingParticipant) {
super(timestamp);
- mRcsGroupThreadId = rcsGroupThreadId;
- mOriginatingParticipantId = originatingParticipantId;
+ mRcsGroupThread = rcsGroupThread;
+ mOriginatingParticipant = originatingParticipant;
}
/**
@@ -38,7 +38,7 @@ public abstract class RcsGroupThreadEvent extends RcsEvent {
*/
@NonNull
public RcsGroupThread getRcsGroupThread() {
- return new RcsGroupThread(mRcsGroupThreadId);
+ return mRcsGroupThread;
}
/**
@@ -46,6 +46,6 @@ public abstract class RcsGroupThreadEvent extends RcsEvent {
*/
@NonNull
public RcsParticipant getOriginatingParticipant() {
- return new RcsParticipant(mOriginatingParticipantId);
+ return mOriginatingParticipant;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
index 3c6c74fac8e2..23e39ffb3680 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
@@ -40,9 +40,10 @@ public final class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent {
* @param newIcon {@link Uri} to the new icon of this {@link RcsGroupThread}
* @see RcsMessageStore#persistRcsEvent(RcsEvent)
*/
- public RcsGroupThreadIconChangedEvent(long timestamp, @NonNull RcsGroupThread rcsGroupThread,
- @NonNull RcsParticipant originatingParticipant, @Nullable Uri newIcon) {
- super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ public RcsGroupThreadIconChangedEvent(long timestamp,
+ @NonNull RcsGroupThread rcsGroupThread, @NonNull RcsParticipant originatingParticipant,
+ @Nullable Uri newIcon) {
+ super(timestamp, rcsGroupThread, originatingParticipant);
mNewIcon = newIcon;
}
@@ -61,10 +62,10 @@ public final class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent {
* @hide - not meant for public use.
*/
@Override
- public void persist() throws RcsMessageStoreException {
+ void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException {
// TODO ensure failure throws
- RcsControllerCall.call(iRcs -> iRcs.createGroupThreadIconChangedEvent(
+ rcsControllerCall.call((iRcs, callingPackage) -> iRcs.createGroupThreadIconChangedEvent(
getTimestamp(), getRcsGroupThread().getThreadId(),
- getOriginatingParticipant().getId(), mNewIcon));
+ getOriginatingParticipant().getId(), mNewIcon, callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEventDescriptor.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEventDescriptor.java
index bcadc80bda54..9350e402c04e 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEventDescriptor.java
@@ -38,9 +38,10 @@ public class RcsGroupThreadIconChangedEventDescriptor extends RcsGroupThreadEven
@Override
@VisibleForTesting(visibility = PROTECTED)
- public RcsGroupThreadIconChangedEvent createRcsEvent() {
- return new RcsGroupThreadIconChangedEvent(mTimestamp, new RcsGroupThread(mRcsGroupThreadId),
- new RcsParticipant(mOriginatingParticipantId), mNewIcon);
+ public RcsGroupThreadIconChangedEvent createRcsEvent(RcsControllerCall rcsControllerCall) {
+ return new RcsGroupThreadIconChangedEvent(mTimestamp,
+ new RcsGroupThread(rcsControllerCall, mRcsGroupThreadId),
+ new RcsParticipant(rcsControllerCall, mOriginatingParticipantId), mNewIcon);
}
public static final @NonNull Creator<RcsGroupThreadIconChangedEventDescriptor> CREATOR =
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
index 54032536601e..a6a0867ca739 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
@@ -41,7 +41,7 @@ public final class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent {
*/
public RcsGroupThreadNameChangedEvent(long timestamp, @NonNull RcsGroupThread rcsGroupThread,
@NonNull RcsParticipant originatingParticipant, @Nullable String newName) {
- super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ super(timestamp, rcsGroupThread, originatingParticipant);
mNewName = newName;
}
@@ -60,9 +60,9 @@ public final class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent {
* @hide - not meant for public use.
*/
@Override
- public void persist() throws RcsMessageStoreException {
- RcsControllerCall.call(iRcs -> iRcs.createGroupThreadNameChangedEvent(
+ void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException {
+ rcsControllerCall.call((iRcs, callingPackage) -> iRcs.createGroupThreadNameChangedEvent(
getTimestamp(), getRcsGroupThread().getThreadId(),
- getOriginatingParticipant().getId(), mNewName));
+ getOriginatingParticipant().getId(), mNewName, callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEventDescriptor.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEventDescriptor.java
index 597fa0a3f9f8..f9ccdd53f0a2 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEventDescriptor.java
@@ -37,11 +37,11 @@ public class RcsGroupThreadNameChangedEventDescriptor extends RcsGroupThreadEven
@Override
@VisibleForTesting(visibility = PROTECTED)
- public RcsGroupThreadNameChangedEvent createRcsEvent() {
+ public RcsGroupThreadNameChangedEvent createRcsEvent(RcsControllerCall rcsControllerCall) {
return new RcsGroupThreadNameChangedEvent(
mTimestamp,
- new RcsGroupThread(mRcsGroupThreadId),
- new RcsParticipant(mOriginatingParticipantId),
+ new RcsGroupThread(rcsControllerCall, mRcsGroupThreadId),
+ new RcsParticipant(rcsControllerCall, mOriginatingParticipantId),
mNewName);
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
index 48be479a1ac6..694c7de96eee 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
@@ -30,19 +30,20 @@ public final class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEv
* Creates a new {@link RcsGroupThreadParticipantJoinedEvent}. This event is not persisted into
* storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
*
- * @param timestamp The timestamp of when this event happened, in milliseconds passed after
- * midnight, January 1st, 1970 UTC
- * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
+ * @param timestamp The timestamp of when this event happened, in milliseconds
+ * passed after
+ * midnight, January 1st, 1970 UTC
+ * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
* @param originatingParticipant The {@link RcsParticipant} that added or invited the new
* {@link RcsParticipant} into the {@link RcsGroupThread}
- * @param joinedParticipant The new {@link RcsParticipant} that joined the
- * {@link RcsGroupThread}
+ * @param joinedParticipant The new {@link RcsParticipant} that joined the
+ * {@link RcsGroupThread}
* @see RcsMessageStore#persistRcsEvent(RcsEvent)
*/
public RcsGroupThreadParticipantJoinedEvent(long timestamp,
@NonNull RcsGroupThread rcsGroupThread, @NonNull RcsParticipant originatingParticipant,
@NonNull RcsParticipant joinedParticipant) {
- super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ super(timestamp, rcsGroupThread, originatingParticipant);
mJoinedParticipantId = joinedParticipant;
}
@@ -59,10 +60,11 @@ public final class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEv
* @hide - not meant for public use.
*/
@Override
- public void persist() throws RcsMessageStoreException {
- RcsControllerCall.call(
- iRcs -> iRcs.createGroupThreadParticipantJoinedEvent(getTimestamp(),
+ void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException {
+ rcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.createGroupThreadParticipantJoinedEvent(
+ getTimestamp(),
getRcsGroupThread().getThreadId(), getOriginatingParticipant().getId(),
- getJoinedParticipant().getId()));
+ getJoinedParticipant().getId(), callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEventDescriptor.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEventDescriptor.java
index abea10a641ac..4a6803ebc52c 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEventDescriptor.java
@@ -36,12 +36,13 @@ public class RcsGroupThreadParticipantJoinedEventDescriptor extends RcsGroupThre
@Override
@VisibleForTesting(visibility = PROTECTED)
- public RcsGroupThreadParticipantJoinedEvent createRcsEvent() {
+ public RcsGroupThreadParticipantJoinedEvent createRcsEvent(
+ RcsControllerCall rcsControllerCall) {
return new RcsGroupThreadParticipantJoinedEvent(
mTimestamp,
- new RcsGroupThread(mRcsGroupThreadId),
- new RcsParticipant(mOriginatingParticipantId),
- new RcsParticipant(mJoinedParticipantId));
+ new RcsGroupThread(rcsControllerCall, mRcsGroupThreadId),
+ new RcsParticipant(rcsControllerCall, mOriginatingParticipantId),
+ new RcsParticipant(rcsControllerCall, mJoinedParticipantId));
}
public static final @NonNull Creator<RcsGroupThreadParticipantJoinedEventDescriptor> CREATOR =
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
index b724a3f2159f..fec4354a293a 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
@@ -44,7 +44,7 @@ public final class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEven
public RcsGroupThreadParticipantLeftEvent(long timestamp,
@NonNull RcsGroupThread rcsGroupThread, @NonNull RcsParticipant originatingParticipant,
@NonNull RcsParticipant leavingParticipant) {
- super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ super(timestamp, rcsGroupThread, originatingParticipant);
mLeavingParticipant = leavingParticipant;
}
@@ -58,10 +58,10 @@ public final class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEven
}
@Override
- public void persist() throws RcsMessageStoreException {
- RcsControllerCall.call(
- iRcs -> iRcs.createGroupThreadParticipantLeftEvent(getTimestamp(),
+ void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException {
+ rcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.createGroupThreadParticipantLeftEvent(getTimestamp(),
getRcsGroupThread().getThreadId(), getOriginatingParticipant().getId(),
- getLeavingParticipant().getId()));
+ getLeavingParticipant().getId(), callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEventDescriptor.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEventDescriptor.java
index f287db19da05..9b1085c3d178 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEventDescriptor.java
@@ -37,12 +37,12 @@ public class RcsGroupThreadParticipantLeftEventDescriptor extends RcsGroupThread
@Override
@VisibleForTesting(visibility = PROTECTED)
- public RcsGroupThreadParticipantLeftEvent createRcsEvent() {
+ public RcsGroupThreadParticipantLeftEvent createRcsEvent(RcsControllerCall rcsControllerCall) {
return new RcsGroupThreadParticipantLeftEvent(
mTimestamp,
- new RcsGroupThread(mRcsGroupThreadId),
- new RcsParticipant(mOriginatingParticipantId),
- new RcsParticipant(mLeavingParticipantId));
+ new RcsGroupThread(rcsControllerCall, mRcsGroupThreadId),
+ new RcsParticipant(rcsControllerCall, mOriginatingParticipantId),
+ new RcsParticipant(rcsControllerCall, mLeavingParticipantId));
}
@NonNull
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.java b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
index 06e2a41accee..2810a49927c5 100644
--- a/telephony/java/android/telephony/ims/RcsIncomingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
@@ -26,8 +26,8 @@ public class RcsIncomingMessage extends RcsMessage {
/**
* @hide
*/
- RcsIncomingMessage(int id) {
- super(id);
+ RcsIncomingMessage(RcsControllerCall rcsControllerCall, int id) {
+ super(rcsControllerCall, id);
}
/**
@@ -39,8 +39,9 @@ public class RcsIncomingMessage extends RcsMessage {
*/
@WorkerThread
public void setArrivalTimestamp(long arrivalTimestamp) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setMessageArrivalTimestamp(mId, true, arrivalTimestamp));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setMessageArrivalTimestamp(mId, true,
+ arrivalTimestamp, callingPackage));
}
/**
@@ -50,7 +51,9 @@ public class RcsIncomingMessage extends RcsMessage {
*/
@WorkerThread
public long getArrivalTimestamp() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessageArrivalTimestamp(mId, true));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageArrivalTimestamp(mId, true,
+ callingPackage));
}
/**
@@ -62,8 +65,9 @@ public class RcsIncomingMessage extends RcsMessage {
*/
@WorkerThread
public void setSeenTimestamp(long notifiedTimestamp) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setMessageSeenTimestamp(mId, true, notifiedTimestamp));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setMessageSeenTimestamp(mId, true, notifiedTimestamp,
+ callingPackage));
}
/**
@@ -73,7 +77,8 @@ public class RcsIncomingMessage extends RcsMessage {
*/
@WorkerThread
public long getSeenTimestamp() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessageSeenTimestamp(mId, true));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageSeenTimestamp(mId, true, callingPackage));
}
/**
@@ -83,7 +88,9 @@ public class RcsIncomingMessage extends RcsMessage {
@WorkerThread
public RcsParticipant getSenderParticipant() throws RcsMessageStoreException {
return new RcsParticipant(
- RcsControllerCall.call(iRcs -> iRcs.getSenderParticipant(mId)));
+ mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getSenderParticipant(mId, callingPackage)));
}
/**
diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java
index 63dc1ac568bf..0d6ca3cc58e1 100644
--- a/telephony/java/android/telephony/ims/RcsManager.java
+++ b/telephony/java/android/telephony/ims/RcsManager.java
@@ -25,20 +25,19 @@ import android.content.Context;
*/
@SystemService(Context.TELEPHONY_RCS_SERVICE)
public class RcsManager {
+ private final RcsMessageStore mRcsMessageStore;
/**
* @hide
*/
- public RcsManager() {
- // empty constructor
+ public RcsManager(Context context) {
+ mRcsMessageStore = new RcsMessageStore(context);
}
- private static final RcsMessageStore sRcsMessageStoreInstance = new RcsMessageStore();
-
/**
* Returns an instance of {@link RcsMessageStore}
*/
public RcsMessageStore getRcsMessageStore() {
- return sRcsMessageStoreInstance;
+ return mRcsMessageStore;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsMessage.java b/telephony/java/android/telephony/ims/RcsMessage.java
index b0d0d5a6a9bb..4601bfd0ff2c 100644
--- a/telephony/java/android/telephony/ims/RcsMessage.java
+++ b/telephony/java/android/telephony/ims/RcsMessage.java
@@ -86,6 +86,11 @@ public abstract class RcsMessage {
/**
* @hide
*/
+ protected final RcsControllerCall mRcsControllerCall;
+
+ /**
+ * @hide
+ */
protected final int mId;
@IntDef({
@@ -95,7 +100,8 @@ public abstract class RcsMessage {
public @interface RcsMessageStatus {
}
- RcsMessage(int id) {
+ RcsMessage(RcsControllerCall rcsControllerCall, int id) {
+ mRcsControllerCall = rcsControllerCall;
mId = id;
}
@@ -115,7 +121,8 @@ public abstract class RcsMessage {
* @see android.telephony.SubscriptionInfo#getSubscriptionId
*/
public int getSubscriptionId() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessageSubId(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageSubId(mId, isIncoming(), callingPackage));
}
/**
@@ -128,7 +135,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setSubscriptionId(int subId) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setMessageSubId(mId, isIncoming(), subId));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setMessageSubId(mId, isIncoming(), subId,
+ callingPackage));
}
/**
@@ -139,8 +148,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setStatus(@RcsMessageStatus int rcsMessageStatus) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setMessageStatus(mId, isIncoming(), rcsMessageStatus));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setMessageStatus(mId, isIncoming(), rcsMessageStatus,
+ callingPackage));
}
/**
@@ -150,7 +160,8 @@ public abstract class RcsMessage {
*/
@WorkerThread
public @RcsMessageStatus int getStatus() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessageStatus(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageStatus(mId, isIncoming(), callingPackage));
}
/**
@@ -163,8 +174,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setOriginationTimestamp(long timestamp) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setMessageOriginationTimestamp(mId, isIncoming(), timestamp));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setMessageOriginationTimestamp(mId, isIncoming(),
+ timestamp, callingPackage));
}
/**
@@ -175,8 +187,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public long getOriginationTimestamp() throws RcsMessageStoreException {
- return RcsControllerCall.call(
- iRcs -> iRcs.getMessageOriginationTimestamp(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageOriginationTimestamp(mId, isIncoming(),
+ callingPackage));
}
/**
@@ -189,8 +202,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setRcsMessageId(String rcsMessageGlobalId) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setGlobalMessageIdForMessage(mId, isIncoming(), rcsMessageGlobalId));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setGlobalMessageIdForMessage(mId, isIncoming(),
+ rcsMessageGlobalId, callingPackage));
}
/**
@@ -200,7 +214,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public String getRcsMessageId() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getGlobalMessageIdForMessage(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getGlobalMessageIdForMessage(mId, isIncoming(),
+ callingPackage));
}
/**
@@ -209,7 +225,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public String getText() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getTextForMessage(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getTextForMessage(mId, isIncoming(),
+ callingPackage));
}
/**
@@ -220,18 +238,21 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setText(String text) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setTextForMessage(mId, isIncoming(), text));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setTextForMessage(mId, isIncoming(), text,
+ callingPackage));
}
/**
* @return Returns the associated latitude for this message, or
* {@link RcsMessage#LOCATION_NOT_SET} if it does not contain a location.
- *
* @throws RcsMessageStoreException if the value could not be read from the storage
*/
@WorkerThread
public double getLatitude() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getLatitudeForMessage(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getLatitudeForMessage(mId, isIncoming(),
+ callingPackage));
}
/**
@@ -242,19 +263,21 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setLatitude(double latitude) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setLatitudeForMessage(mId, isIncoming(), latitude));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setLatitudeForMessage(mId, isIncoming(), latitude,
+ callingPackage));
}
/**
* @return Returns the associated longitude for this message, or
* {@link RcsMessage#LOCATION_NOT_SET} if it does not contain a location.
- *
* @throws RcsMessageStoreException if the value could not be read from the storage
*/
@WorkerThread
public double getLongitude() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getLongitudeForMessage(mId, isIncoming()));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getLongitudeForMessage(mId, isIncoming(),
+ callingPackage));
}
/**
@@ -265,8 +288,9 @@ public abstract class RcsMessage {
*/
@WorkerThread
public void setLongitude(double longitude) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.setLongitudeForMessage(mId, isIncoming(), longitude));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setLongitudeForMessage(mId, isIncoming(), longitude,
+ callingPackage));
}
/**
@@ -282,8 +306,9 @@ public abstract class RcsMessage {
public RcsFileTransferPart insertFileTransfer(
RcsFileTransferCreationParams fileTransferCreationParameters)
throws RcsMessageStoreException {
- return new RcsFileTransferPart(RcsControllerCall.call(
- iRcs -> iRcs.storeFileTransfer(mId, isIncoming(), fileTransferCreationParameters)));
+ return new RcsFileTransferPart(mRcsControllerCall, mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.storeFileTransfer(mId, isIncoming(),
+ fileTransferCreationParameters, callingPackage)));
}
/**
@@ -296,11 +321,12 @@ public abstract class RcsMessage {
public Set<RcsFileTransferPart> getFileTransferParts() throws RcsMessageStoreException {
Set<RcsFileTransferPart> fileTransferParts = new HashSet<>();
- int[] fileTransferIds = RcsControllerCall.call(
- iRcs -> iRcs.getFileTransfersAttachedToMessage(mId, isIncoming()));
+ int[] fileTransferIds = mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getFileTransfersAttachedToMessage(mId, isIncoming(),
+ callingPackage));
for (int fileTransfer : fileTransferIds) {
- fileTransferParts.add(new RcsFileTransferPart(fileTransfer));
+ fileTransferParts.add(new RcsFileTransferPart(mRcsControllerCall, fileTransfer));
}
return Collections.unmodifiableSet(fileTransferParts);
@@ -319,8 +345,9 @@ public abstract class RcsMessage {
return;
}
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.deleteFileTransfer(fileTransferPart.getId()));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.deleteFileTransfer(fileTransferPart.getId(),
+ callingPackage));
}
/**
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
index 5df929baad52..36bb78a0594b 100644
--- a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
@@ -20,13 +20,9 @@ import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.MES
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import com.android.ims.RcsTypeIdPair;
-
-import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
/**
* The result of a {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)}
@@ -35,23 +31,14 @@ import java.util.List;
*
* @hide
*/
-public final class RcsMessageQueryResult implements Parcelable {
- // The token to continue the query to get the next batch of results
- private RcsQueryContinuationToken mContinuationToken;
- // The message type and message ID pairs for all the messages in this query result
- private List<RcsTypeIdPair> mMessageTypeIdPairs;
+public final class RcsMessageQueryResult {
+ private final RcsControllerCall mRcsControllerCall;
+ private final RcsMessageQueryResultParcelable mRcsMessageQueryResultParcelable;
- /**
- * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
- * to create query results
- *
- * @hide
- */
- public RcsMessageQueryResult(
- RcsQueryContinuationToken continuationToken,
- List<RcsTypeIdPair> messageTypeIdPairs) {
- mContinuationToken = continuationToken;
- mMessageTypeIdPairs = messageTypeIdPairs;
+ RcsMessageQueryResult(RcsControllerCall rcsControllerCall,
+ RcsMessageQueryResultParcelable rcsMessageQueryResultParcelable) {
+ mRcsControllerCall = rcsControllerCall;
+ mRcsMessageQueryResultParcelable = rcsMessageQueryResultParcelable;
}
/**
@@ -61,7 +48,7 @@ public final class RcsMessageQueryResult implements Parcelable {
*/
@Nullable
public RcsQueryContinuationToken getContinuationToken() {
- return mContinuationToken;
+ return mRcsMessageQueryResultParcelable.mContinuationToken;
}
/**
@@ -71,45 +58,10 @@ public final class RcsMessageQueryResult implements Parcelable {
*/
@NonNull
public List<RcsMessage> getMessages() {
- List<RcsMessage> messages = new ArrayList<>();
- for (RcsTypeIdPair typeIdPair : mMessageTypeIdPairs) {
- if (typeIdPair.getType() == MESSAGE_TYPE_INCOMING) {
- messages.add(new RcsIncomingMessage(typeIdPair.getId()));
- } else {
- messages.add(new RcsOutgoingMessage(typeIdPair.getId()));
- }
- }
-
- return messages;
- }
-
- private RcsMessageQueryResult(Parcel in) {
- mContinuationToken = in.readParcelable(
- RcsQueryContinuationToken.class.getClassLoader());
- in.readTypedList(mMessageTypeIdPairs, RcsTypeIdPair.CREATOR);
- }
-
- public static final @android.annotation.NonNull Creator<RcsMessageQueryResult> CREATOR =
- new Creator<RcsMessageQueryResult>() {
- @Override
- public RcsMessageQueryResult createFromParcel(Parcel in) {
- return new RcsMessageQueryResult(in);
- }
-
- @Override
- public RcsMessageQueryResult[] newArray(int size) {
- return new RcsMessageQueryResult[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mContinuationToken, flags);
- dest.writeTypedList(mMessageTypeIdPairs);
+ return mRcsMessageQueryResultParcelable.mMessageTypeIdPairs.stream()
+ .map(typeIdPair -> typeIdPair.getType() == MESSAGE_TYPE_INCOMING
+ ? new RcsIncomingMessage(mRcsControllerCall, typeIdPair.getId())
+ : new RcsOutgoingMessage(mRcsControllerCall, typeIdPair.getId()))
+ .collect(Collectors.toList());
}
}
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl b/telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.aidl
index a73ba50b6591..86928bfa41b8 100644
--- a/telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsMessageQueryResult;
+parcelable RcsMessageQueryResultParcelable;
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.java b/telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.java
new file mode 100644
index 000000000000..4972f9bc4956
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResultParcelable.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.ims.RcsTypeIdPair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide - used only for internal communication with the ircs service
+ */
+public class RcsMessageQueryResultParcelable implements Parcelable {
+ // The token to continue the query to get the next batch of results
+ final RcsQueryContinuationToken mContinuationToken;
+ // The message type and message ID pairs for all the messages in this query result
+ final List<RcsTypeIdPair> mMessageTypeIdPairs;
+
+ public RcsMessageQueryResultParcelable(
+ RcsQueryContinuationToken continuationToken,
+ List<RcsTypeIdPair> messageTypeIdPairs) {
+ mContinuationToken = continuationToken;
+ mMessageTypeIdPairs = messageTypeIdPairs;
+ }
+
+ private RcsMessageQueryResultParcelable(Parcel in) {
+ mContinuationToken = in.readParcelable(
+ RcsQueryContinuationToken.class.getClassLoader());
+
+ mMessageTypeIdPairs = new ArrayList<>();
+ in.readTypedList(mMessageTypeIdPairs, RcsTypeIdPair.CREATOR);
+ }
+
+ public static final Creator<RcsMessageQueryResultParcelable> CREATOR =
+ new Creator<RcsMessageQueryResultParcelable>() {
+ @Override
+ public RcsMessageQueryResultParcelable createFromParcel(Parcel in) {
+ return new RcsMessageQueryResultParcelable(in);
+ }
+
+ @Override
+ public RcsMessageQueryResultParcelable[] newArray(int size) {
+ return new RcsMessageQueryResultParcelable[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mContinuationToken, flags);
+ dest.writeTypedList(mMessageTypeIdPairs);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
index 6fcb62b7c092..d1127984f126 100644
--- a/telephony/java/android/telephony/ims/RcsMessageStore.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStore.java
@@ -19,6 +19,7 @@ package android.telephony.ims;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
+import android.content.Context;
import android.net.Uri;
import java.util.List;
@@ -30,6 +31,12 @@ import java.util.List;
* @hide
*/
public class RcsMessageStore {
+ RcsControllerCall mRcsControllerCall;
+
+ RcsMessageStore(Context context) {
+ mRcsControllerCall = new RcsControllerCall(context);
+ }
+
/**
* Returns the first chunk of existing {@link RcsThread}s in the common storage.
*
@@ -41,8 +48,10 @@ public class RcsMessageStore {
@NonNull
public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParams queryParameters)
throws RcsMessageStoreException {
- return new RcsThreadQueryResult(
- RcsControllerCall.call(iRcs -> iRcs.getRcsThreads(queryParameters)));
+ return new RcsThreadQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getRcsThreads(queryParameters,
+ callingPackage)));
}
/**
@@ -56,8 +65,10 @@ public class RcsMessageStore {
@NonNull
public RcsThreadQueryResult getRcsThreads(@NonNull RcsQueryContinuationToken continuationToken)
throws RcsMessageStoreException {
- return new RcsThreadQueryResult(
- RcsControllerCall.call(iRcs -> iRcs.getRcsThreadsWithToken(continuationToken)));
+ return new RcsThreadQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getRcsThreadsWithToken(continuationToken,
+ callingPackage)));
}
/**
@@ -72,8 +83,10 @@ public class RcsMessageStore {
public RcsParticipantQueryResult getRcsParticipants(
@Nullable RcsParticipantQueryParams queryParameters)
throws RcsMessageStoreException {
- return new RcsParticipantQueryResult(
- RcsControllerCall.call(iRcs -> iRcs.getParticipants(queryParameters)));
+ return new RcsParticipantQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getParticipants(queryParameters,
+ callingPackage)));
}
/**
@@ -89,22 +102,26 @@ public class RcsMessageStore {
public RcsParticipantQueryResult getRcsParticipants(
@NonNull RcsQueryContinuationToken continuationToken)
throws RcsMessageStoreException {
- return new RcsParticipantQueryResult(
- RcsControllerCall.call(iRcs -> iRcs.getParticipantsWithToken(continuationToken)));
+ return new RcsParticipantQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getParticipantsWithToken(continuationToken,
+ callingPackage)));
}
/**
* Returns the first chunk of existing {@link RcsMessage}s in the common storage.
*
- * @param queryParameters Parameters to specify to return a subset of all RcsMessages.
- * Passing a value of null will return all messages.
+ * @param queryParams Parameters to specify to return a subset of all RcsMessages.
+ * Passing a value of null will return all messages.
* @throws RcsMessageStoreException if the query could not be completed on the storage
*/
@WorkerThread
@NonNull
public RcsMessageQueryResult getRcsMessages(
- @Nullable RcsMessageQueryParams queryParameters) throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters));
+ @Nullable RcsMessageQueryParams queryParams) throws RcsMessageStoreException {
+ return new RcsMessageQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessages(queryParams, callingPackage)));
}
/**
@@ -118,7 +135,10 @@ public class RcsMessageStore {
@NonNull
public RcsMessageQueryResult getRcsMessages(
@NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessagesWithToken(continuationToken));
+ return new RcsMessageQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessagesWithToken(continuationToken,
+ callingPackage)));
}
/**
@@ -132,8 +152,9 @@ public class RcsMessageStore {
@NonNull
public RcsEventQueryResult getRcsEvents(
@Nullable RcsEventQueryParams queryParams) throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getEvents(queryParams))
- .getRcsEventQueryResult();
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getEvents(queryParams, callingPackage))
+ .getRcsEventQueryResult(mRcsControllerCall);
}
/**
@@ -147,14 +168,16 @@ public class RcsMessageStore {
@NonNull
public RcsEventQueryResult getRcsEvents(
@NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getEventsWithToken(continuationToken))
- .getRcsEventQueryResult();
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getEventsWithToken(continuationToken,
+ callingPackage))
+ .getRcsEventQueryResult(mRcsControllerCall);
}
/**
* Persists an {@link RcsEvent} to common storage.
*
- * @param persistableEvent The {@link RcsEvent} to persist into storage.
+ * @param rcsEvent The {@link RcsEvent} to persist into storage.
* @throws RcsMessageStoreException if the query could not be completed on the storage
* @see RcsGroupThreadNameChangedEvent
* @see RcsGroupThreadIconChangedEvent
@@ -164,8 +187,8 @@ public class RcsMessageStore {
*/
@WorkerThread
@NonNull
- public void persistRcsEvent(RcsEvent persistableEvent) throws RcsMessageStoreException {
- persistableEvent.persist();
+ public void persistRcsEvent(RcsEvent rcsEvent) throws RcsMessageStoreException {
+ rcsEvent.persist(mRcsControllerCall);
}
/**
@@ -180,7 +203,10 @@ public class RcsMessageStore {
public Rcs1To1Thread createRcs1To1Thread(@NonNull RcsParticipant recipient)
throws RcsMessageStoreException {
return new Rcs1To1Thread(
- RcsControllerCall.call(iRcs -> iRcs.createRcs1To1Thread(recipient.getId())));
+ mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.createRcs1To1Thread(recipient.getId(),
+ callingPackage)));
}
/**
@@ -202,8 +228,12 @@ public class RcsMessageStore {
}
int[] finalRecipientIds = recipientIds;
- return new RcsGroupThread(RcsControllerCall.call(
- iRcs -> iRcs.createGroupThread(finalRecipientIds, groupName, groupIcon)));
+
+ int threadId = mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.createGroupThread(finalRecipientIds, groupName,
+ groupIcon, callingPackage));
+
+ return new RcsGroupThread(mRcsControllerCall, threadId);
}
/**
@@ -218,8 +248,9 @@ public class RcsMessageStore {
return;
}
- boolean isDeleteSucceeded = RcsControllerCall.call(
- iRcs -> iRcs.deleteThread(thread.getThreadId(), thread.getThreadType()));
+ boolean isDeleteSucceeded = mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.deleteThread(thread.getThreadId(),
+ thread.getThreadType(), callingPackage));
if (!isDeleteSucceeded) {
throw new RcsMessageStoreException("Could not delete RcsThread");
@@ -237,7 +268,8 @@ public class RcsMessageStore {
@NonNull
public RcsParticipant createRcsParticipant(String canonicalAddress, @Nullable String alias)
throws RcsMessageStoreException {
- return new RcsParticipant(
- RcsControllerCall.call(iRcs -> iRcs.createRcsParticipant(canonicalAddress, alias)));
+ return new RcsParticipant(mRcsControllerCall, mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.createRcsParticipant(canonicalAddress, alias,
+ callingPackage)));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
index 1b4bfe576ac6..7080ec6c5281 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
@@ -27,8 +27,8 @@ import java.util.List;
* @hide
*/
public class RcsOutgoingMessage extends RcsMessage {
- RcsOutgoingMessage(int id) {
- super(id);
+ RcsOutgoingMessage(RcsControllerCall rcsControllerCall, int id) {
+ super(rcsControllerCall, id);
}
/**
@@ -45,12 +45,13 @@ public class RcsOutgoingMessage extends RcsMessage {
int[] deliveryParticipants;
List<RcsOutgoingMessageDelivery> messageDeliveries = new ArrayList<>();
- deliveryParticipants = RcsControllerCall.call(
- iRcs -> iRcs.getMessageRecipients(mId));
+ deliveryParticipants = mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageRecipients(mId, callingPackage));
if (deliveryParticipants != null) {
for (Integer deliveryParticipant : deliveryParticipants) {
- messageDeliveries.add(new RcsOutgoingMessageDelivery(deliveryParticipant, mId));
+ messageDeliveries.add(new RcsOutgoingMessageDelivery(
+ mRcsControllerCall, deliveryParticipant, mId));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
index 2db49c6d0dce..df4a3e45bc03 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
@@ -25,6 +25,7 @@ import android.annotation.WorkerThread;
* @hide
*/
public class RcsOutgoingMessageDelivery {
+ private final RcsControllerCall mRcsControllerCall;
// The participant that this delivery is intended for
private final int mRecipientId;
// The message this delivery is associated with
@@ -35,7 +36,9 @@ public class RcsOutgoingMessageDelivery {
*
* @hide
*/
- RcsOutgoingMessageDelivery(int recipientId, int messageId) {
+ RcsOutgoingMessageDelivery(
+ RcsControllerCall rcsControllerCall, int recipientId, int messageId) {
+ mRcsControllerCall = rcsControllerCall;
mRecipientId = recipientId;
mRcsOutgoingMessageId = messageId;
}
@@ -49,8 +52,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public void setDeliveredTimestamp(long deliveredTimestamp) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliveryDeliveredTimestamp(
- mRcsOutgoingMessageId, mRecipientId, deliveredTimestamp));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setOutgoingDeliveryDeliveredTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, deliveredTimestamp, callingPackage));
}
/**
@@ -61,8 +65,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public long getDeliveredTimestamp() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getOutgoingDeliveryDeliveredTimestamp(
- mRcsOutgoingMessageId, mRecipientId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getOutgoingDeliveryDeliveredTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, callingPackage));
}
/**
@@ -74,8 +79,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public void setSeenTimestamp(long seenTimestamp) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliverySeenTimestamp(
- mRcsOutgoingMessageId, mRecipientId, seenTimestamp));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setOutgoingDeliverySeenTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, seenTimestamp, callingPackage));
}
/**
@@ -86,8 +92,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public long getSeenTimestamp() throws RcsMessageStoreException {
- return RcsControllerCall.call(
- iRcs -> iRcs.getOutgoingDeliverySeenTimestamp(mRcsOutgoingMessageId, mRecipientId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getOutgoingDeliverySeenTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, callingPackage));
}
/**
@@ -99,8 +106,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public void setStatus(@RcsMessage.RcsMessageStatus int status) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliveryStatus(
- mRcsOutgoingMessageId, mRecipientId, status));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setOutgoingDeliveryStatus(
+ mRcsOutgoingMessageId, mRecipientId, status, callingPackage));
}
/**
@@ -109,8 +117,9 @@ public class RcsOutgoingMessageDelivery {
*/
@WorkerThread
public @RcsMessage.RcsMessageStatus int getStatus() throws RcsMessageStoreException {
- return RcsControllerCall.call(
- iRcs -> iRcs.getOutgoingDeliveryStatus(mRcsOutgoingMessageId, mRecipientId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getOutgoingDeliveryStatus(mRcsOutgoingMessageId,
+ mRecipientId, callingPackage));
}
/**
@@ -118,7 +127,7 @@ public class RcsOutgoingMessageDelivery {
*/
@NonNull
public RcsParticipant getRecipient() {
- return new RcsParticipant(mRecipientId);
+ return new RcsParticipant(mRcsControllerCall, mRecipientId);
}
/**
@@ -126,6 +135,6 @@ public class RcsOutgoingMessageDelivery {
*/
@NonNull
public RcsOutgoingMessage getMessage() {
- return new RcsOutgoingMessage(mRcsOutgoingMessageId);
+ return new RcsOutgoingMessage(mRcsControllerCall, mRcsOutgoingMessageId);
}
}
diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java
index bcf134a71ea3..8512e960bfe6 100644
--- a/telephony/java/android/telephony/ims/RcsParticipant.java
+++ b/telephony/java/android/telephony/ims/RcsParticipant.java
@@ -24,8 +24,9 @@ import android.annotation.WorkerThread;
* @hide
*/
public class RcsParticipant {
+ private final RcsControllerCall mRcsControllerCall;
// The row ID of this participant in the database
- private int mId;
+ private final int mId;
/**
* Constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
@@ -33,7 +34,8 @@ public class RcsParticipant {
*
* @hide
*/
- public RcsParticipant(int id) {
+ public RcsParticipant(RcsControllerCall rcsControllerCall, int id) {
+ mRcsControllerCall = rcsControllerCall;
mId = id;
}
@@ -45,7 +47,9 @@ public class RcsParticipant {
@Nullable
@WorkerThread
public String getCanonicalAddress() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantCanonicalAddress(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getRcsParticipantCanonicalAddress(mId,
+ callingPackage));
}
/**
@@ -57,7 +61,8 @@ public class RcsParticipant {
@Nullable
@WorkerThread
public String getAlias() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantAlias(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getRcsParticipantAlias(mId, callingPackage));
}
/**
@@ -70,7 +75,8 @@ public class RcsParticipant {
*/
@WorkerThread
public void setAlias(String alias) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setRcsParticipantAlias(mId, alias));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setRcsParticipantAlias(mId, alias, callingPackage));
}
/**
@@ -82,7 +88,8 @@ public class RcsParticipant {
@Nullable
@WorkerThread
public String getContactId() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantContactId(mId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getRcsParticipantContactId(mId, callingPackage));
}
/**
@@ -95,7 +102,9 @@ public class RcsParticipant {
*/
@WorkerThread
public void setContactId(String contactId) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setRcsParticipantContactId(mId, contactId));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.setRcsParticipantContactId(mId, contactId,
+ callingPackage));
}
@Override
diff --git a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
index 61801f3fbf2c..865bc05132a2 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
@@ -69,8 +69,8 @@ public final class RcsParticipantAliasChangedEvent extends RcsEvent {
* @hide - not meant for public use.
*/
@Override
- public void persist() throws RcsMessageStoreException {
- RcsControllerCall.call(iRcs -> iRcs.createParticipantAliasChangedEvent(
- getTimestamp(), getParticipant().getId(), getNewAlias()));
+ void persist(RcsControllerCall rcsControllerCall) throws RcsMessageStoreException {
+ rcsControllerCall.call((iRcs, callingPackage) -> iRcs.createParticipantAliasChangedEvent(
+ getTimestamp(), getParticipant().getId(), getNewAlias(), callingPackage));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEventDescriptor.java b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEventDescriptor.java
index b29896c12ab8..43b918c3e0f4 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEventDescriptor.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEventDescriptor.java
@@ -41,9 +41,9 @@ public class RcsParticipantAliasChangedEventDescriptor extends RcsEventDescripto
@Override
@VisibleForTesting(visibility = PROTECTED)
- public RcsParticipantAliasChangedEvent createRcsEvent() {
+ public RcsParticipantAliasChangedEvent createRcsEvent(RcsControllerCall rcsControllerCall) {
return new RcsParticipantAliasChangedEvent(
- mTimestamp, new RcsParticipant(mParticipantId), mNewAlias);
+ mTimestamp, new RcsParticipant(rcsControllerCall, mParticipantId), mNewAlias);
}
public static final @NonNull Creator<RcsParticipantAliasChangedEventDescriptor> CREATOR =
diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
index 731c94e22889..0721dfdf5803 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
@@ -30,10 +30,13 @@ import java.util.stream.Collectors;
* @hide
*/
public final class RcsParticipantQueryResult {
+ private final RcsControllerCall mRcsControllerCall;
private final RcsParticipantQueryResultParcelable mRcsParticipantQueryResultParcelable;
RcsParticipantQueryResult(
+ RcsControllerCall rcsControllerCall,
RcsParticipantQueryResultParcelable rcsParticipantQueryResultParcelable) {
+ mRcsControllerCall = rcsControllerCall;
mRcsParticipantQueryResultParcelable = rcsParticipantQueryResultParcelable;
}
@@ -55,7 +58,7 @@ public final class RcsParticipantQueryResult {
@NonNull
public List<RcsParticipant> getParticipants() {
return mRcsParticipantQueryResultParcelable.mParticipantIds.stream()
- .map(RcsParticipant::new)
+ .map(participantId -> new RcsParticipant(mRcsControllerCall, participantId))
.collect(Collectors.toList());
}
}
diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java
index cf1dc76fedfb..efb2cca21c19 100644
--- a/telephony/java/android/telephony/ims/RcsThread.java
+++ b/telephony/java/android/telephony/ims/RcsThread.java
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
public abstract class RcsThread {
/**
* The rcs_participant_thread_id that represents this thread in the database
+ *
* @hide
*/
protected int mThreadId;
@@ -40,8 +41,14 @@ public abstract class RcsThread {
/**
* @hide
*/
- protected RcsThread(int threadId) {
+ protected final RcsControllerCall mRcsControllerCall;
+
+ /**
+ * @hide
+ */
+ protected RcsThread(RcsControllerCall rcsControllerCall, int threadId) {
mThreadId = threadId;
+ mRcsControllerCall = rcsControllerCall;
}
/**
@@ -51,7 +58,8 @@ public abstract class RcsThread {
@WorkerThread
@NonNull
public RcsMessageSnippet getSnippet() throws RcsMessageStoreException {
- return RcsControllerCall.call(iRcs -> iRcs.getMessageSnippet(mThreadId));
+ return mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessageSnippet(mThreadId, callingPackage));
}
/**
@@ -64,8 +72,10 @@ public abstract class RcsThread {
public RcsIncomingMessage addIncomingMessage(
@NonNull RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams)
throws RcsMessageStoreException {
- return new RcsIncomingMessage(RcsControllerCall.call(iRcs -> iRcs.addIncomingMessage(
- mThreadId, rcsIncomingMessageCreationParams)));
+ int messageId = mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.addIncomingMessage(mThreadId,
+ rcsIncomingMessageCreationParams, callingPackage));
+ return new RcsIncomingMessage(mRcsControllerCall, messageId);
}
/**
@@ -78,10 +88,10 @@ public abstract class RcsThread {
public RcsOutgoingMessage addOutgoingMessage(
@NonNull RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams)
throws RcsMessageStoreException {
- int messageId = RcsControllerCall.call(iRcs -> iRcs.addOutgoingMessage(
- mThreadId, rcsOutgoingMessageCreationParams));
+ int messageId = mRcsControllerCall.call((iRcs, callingPackage) -> iRcs.addOutgoingMessage(
+ mThreadId, rcsOutgoingMessageCreationParams, callingPackage));
- return new RcsOutgoingMessage(messageId);
+ return new RcsOutgoingMessage(mRcsControllerCall, messageId);
}
/**
@@ -92,9 +102,10 @@ public abstract class RcsThread {
*/
@WorkerThread
public void deleteMessage(@NonNull RcsMessage rcsMessage) throws RcsMessageStoreException {
- RcsControllerCall.callWithNoReturn(
- iRcs -> iRcs.deleteMessage(rcsMessage.getId(), rcsMessage.isIncoming(), mThreadId,
- isGroup()));
+ mRcsControllerCall.callWithNoReturn(
+ (iRcs, callingPackage) -> iRcs.deleteMessage(rcsMessage.getId(),
+ rcsMessage.isIncoming(), mThreadId,
+ isGroup(), callingPackage));
}
/**
@@ -108,9 +119,11 @@ public abstract class RcsThread {
@WorkerThread
@NonNull
public RcsMessageQueryResult getMessages() throws RcsMessageStoreException {
- RcsMessageQueryParams queryParameters =
+ RcsMessageQueryParams queryParams =
new RcsMessageQueryParams.Builder().setThread(this).build();
- return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters));
+ return new RcsMessageQueryResult(mRcsControllerCall,
+ mRcsControllerCall.call(
+ (iRcs, callingPackage) -> iRcs.getMessages(queryParams, callingPackage)));
}
/**
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
index c77bdb32eb7d..3de25de19430 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
@@ -33,9 +33,12 @@ import java.util.stream.Collectors;
* @hide
*/
public final class RcsThreadQueryResult {
+ private final RcsControllerCall mRcsControllerCall;
private final RcsThreadQueryResultParcelable mRcsThreadQueryResultParcelable;
- RcsThreadQueryResult(RcsThreadQueryResultParcelable rcsThreadQueryResultParcelable) {
+ RcsThreadQueryResult(RcsControllerCall rcsControllerCall,
+ RcsThreadQueryResultParcelable rcsThreadQueryResultParcelable) {
+ mRcsControllerCall = rcsControllerCall;
mRcsThreadQueryResultParcelable = rcsThreadQueryResultParcelable;
}
@@ -58,8 +61,8 @@ public final class RcsThreadQueryResult {
public List<RcsThread> getThreads() {
return mRcsThreadQueryResultParcelable.mRcsThreadIds.stream()
.map(typeIdPair -> typeIdPair.getType() == THREAD_TYPE_1_TO_1
- ? new Rcs1To1Thread(typeIdPair.getId())
- : new RcsGroupThread(typeIdPair.getId()))
+ ? new Rcs1To1Thread(mRcsControllerCall, typeIdPair.getId())
+ : new RcsGroupThread(mRcsControllerCall, typeIdPair.getId()))
.collect(Collectors.toList());
}
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
index 50dc587821fa..9ee15daf67b9 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
@@ -23,7 +23,7 @@ import android.telephony.ims.RcsFileTransferCreationParams;
import android.telephony.ims.RcsIncomingMessageCreationParams;
import android.telephony.ims.RcsMessageSnippet;
import android.telephony.ims.RcsMessageQueryParams;
-import android.telephony.ims.RcsMessageQueryResult;
+import android.telephony.ims.RcsMessageQueryResultParcelable;
import android.telephony.ims.RcsOutgoingMessageCreationParams;
import android.telephony.ims.RcsParticipantQueryParams;
import android.telephony.ims.RcsParticipantQueryResultParcelable;
@@ -39,34 +39,34 @@ interface IRcs {
/////////////////////////
// RcsMessageStore APIs
/////////////////////////
- RcsThreadQueryResultParcelable getRcsThreads(in RcsThreadQueryParams queryParams);
+ RcsThreadQueryResultParcelable getRcsThreads(in RcsThreadQueryParams queryParams, String callingPackage);
RcsThreadQueryResultParcelable getRcsThreadsWithToken(
- in RcsQueryContinuationToken continuationToken);
+ in RcsQueryContinuationToken continuationToken, String callingPackage);
- RcsParticipantQueryResultParcelable getParticipants(in RcsParticipantQueryParams queryParams);
+ RcsParticipantQueryResultParcelable getParticipants(in RcsParticipantQueryParams queryParams, String callingPackage);
RcsParticipantQueryResultParcelable getParticipantsWithToken(
- in RcsQueryContinuationToken continuationToken);
+ in RcsQueryContinuationToken continuationToken, String callingPackage);
- RcsMessageQueryResult getMessages(in RcsMessageQueryParams queryParams);
+ RcsMessageQueryResultParcelable getMessages(in RcsMessageQueryParams queryParams, String callingPackage);
- RcsMessageQueryResult getMessagesWithToken(
- in RcsQueryContinuationToken continuationToken);
+ RcsMessageQueryResultParcelable getMessagesWithToken(
+ in RcsQueryContinuationToken continuationToken, String callingPackage);
- RcsEventQueryResultDescriptor getEvents(in RcsEventQueryParams queryParams);
+ RcsEventQueryResultDescriptor getEvents(in RcsEventQueryParams queryParams, String callingPackage);
RcsEventQueryResultDescriptor getEventsWithToken(
- in RcsQueryContinuationToken continuationToken);
+ in RcsQueryContinuationToken continuationToken, String callingPackage);
// returns true if the thread was successfully deleted
- boolean deleteThread(int threadId, int threadType);
+ boolean deleteThread(int threadId, int threadType, String callingPackage);
// Creates an Rcs1To1Thread and returns its row ID
- int createRcs1To1Thread(int participantId);
+ int createRcs1To1Thread(int participantId, String callingPackage);
// Creates an RcsGroupThread and returns its row ID
- int createGroupThread(in int[] participantIds, String groupName, in Uri groupIcon);
+ int createGroupThread(in int[] participantIds, String groupName, in Uri groupIcon, String callingPackage);
/////////////////////////
// RcsThread APIs
@@ -74,128 +74,128 @@ interface IRcs {
// Creates a new RcsIncomingMessage on the given thread and returns its row ID
int addIncomingMessage(int rcsThreadId,
- in RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams);
+ in RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams, String callingPackage);
// Creates a new RcsOutgoingMessage on the given thread and returns its row ID
int addOutgoingMessage(int rcsThreadId,
- in RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams);
+ in RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams, String callingPackage);
// TODO: modify RcsProvider URI's to allow deleting a message without specifying its thread
- void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup);
+ void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup, String callingPackage);
- RcsMessageSnippet getMessageSnippet(int rcsThreadId);
+ RcsMessageSnippet getMessageSnippet(int rcsThreadId, String callingPackage);
/////////////////////////
// Rcs1To1Thread APIs
/////////////////////////
- void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId);
+ void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId, String callingPackage);
- long get1To1ThreadFallbackThreadId(int rcsThreadId);
+ long get1To1ThreadFallbackThreadId(int rcsThreadId, String callingPackage);
- int get1To1ThreadOtherParticipantId(int rcsThreadId);
+ int get1To1ThreadOtherParticipantId(int rcsThreadId, String callingPackage);
/////////////////////////
// RcsGroupThread APIs
/////////////////////////
- void setGroupThreadName(int rcsThreadId, String groupName);
+ void setGroupThreadName(int rcsThreadId, String groupName, String callingPackage);
- String getGroupThreadName(int rcsThreadId);
+ String getGroupThreadName(int rcsThreadId, String callingPackage);
- void setGroupThreadIcon(int rcsThreadId, in Uri groupIcon);
+ void setGroupThreadIcon(int rcsThreadId, in Uri groupIcon, String callingPackage);
- Uri getGroupThreadIcon(int rcsThreadId);
+ Uri getGroupThreadIcon(int rcsThreadId, String callingPackage);
- void setGroupThreadOwner(int rcsThreadId, int participantId);
+ void setGroupThreadOwner(int rcsThreadId, int participantId, String callingPackage);
- int getGroupThreadOwner(int rcsThreadId);
+ int getGroupThreadOwner(int rcsThreadId, String callingPackage);
- void setGroupThreadConferenceUri(int rcsThreadId, in Uri conferenceUri);
+ void setGroupThreadConferenceUri(int rcsThreadId, in Uri conferenceUri, String callingPackage);
- Uri getGroupThreadConferenceUri(int rcsThreadId);
+ Uri getGroupThreadConferenceUri(int rcsThreadId, String callingPackage);
- void addParticipantToGroupThread(int rcsThreadId, int participantId);
+ void addParticipantToGroupThread(int rcsThreadId, int participantId, String callingPackage);
- void removeParticipantFromGroupThread(int rcsThreadId, int participantId);
+ void removeParticipantFromGroupThread(int rcsThreadId, int participantId, String callingPackage);
/////////////////////////
// RcsParticipant APIs
/////////////////////////
// Creates a new RcsParticipant and returns its rowId
- int createRcsParticipant(String canonicalAddress, String alias);
+ int createRcsParticipant(String canonicalAddress, String alias, String callingPackage);
- String getRcsParticipantCanonicalAddress(int participantId);
+ String getRcsParticipantCanonicalAddress(int participantId, String callingPackage);
- String getRcsParticipantAlias(int participantId);
+ String getRcsParticipantAlias(int participantId, String callingPackage);
- void setRcsParticipantAlias(int id, String alias);
+ void setRcsParticipantAlias(int id, String alias, String callingPackage);
- String getRcsParticipantContactId(int participantId);
+ String getRcsParticipantContactId(int participantId, String callingPackage);
- void setRcsParticipantContactId(int participantId, String contactId);
+ void setRcsParticipantContactId(int participantId, String contactId, String callingPackage);
/////////////////////////
// RcsMessage APIs
/////////////////////////
- void setMessageSubId(int messageId, boolean isIncoming, int subId);
+ void setMessageSubId(int messageId, boolean isIncoming, int subId, String callingPackage);
- int getMessageSubId(int messageId, boolean isIncoming);
+ int getMessageSubId(int messageId, boolean isIncoming, String callingPackage);
- void setMessageStatus(int messageId, boolean isIncoming, int status);
+ void setMessageStatus(int messageId, boolean isIncoming, int status, String callingPackage);
- int getMessageStatus(int messageId, boolean isIncoming);
+ int getMessageStatus(int messageId, boolean isIncoming, String callingPackage);
- void setMessageOriginationTimestamp(int messageId, boolean isIncoming, long originationTimestamp);
+ void setMessageOriginationTimestamp(int messageId, boolean isIncoming, long originationTimestamp, String callingPackage);
- long getMessageOriginationTimestamp(int messageId, boolean isIncoming);
+ long getMessageOriginationTimestamp(int messageId, boolean isIncoming, String callingPackage);
- void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId);
+ void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId, String callingPackage);
- String getGlobalMessageIdForMessage(int messageId, boolean isIncoming);
+ String getGlobalMessageIdForMessage(int messageId, boolean isIncoming, String callingPackage);
- void setMessageArrivalTimestamp(int messageId, boolean isIncoming, long arrivalTimestamp);
+ void setMessageArrivalTimestamp(int messageId, boolean isIncoming, long arrivalTimestamp, String callingPackage);
- long getMessageArrivalTimestamp(int messageId, boolean isIncoming);
+ long getMessageArrivalTimestamp(int messageId, boolean isIncoming, String callingPackage);
- void setMessageSeenTimestamp(int messageId, boolean isIncoming, long seenTimestamp);
+ void setMessageSeenTimestamp(int messageId, boolean isIncoming, long seenTimestamp, String callingPackage);
- long getMessageSeenTimestamp(int messageId, boolean isIncoming);
+ long getMessageSeenTimestamp(int messageId, boolean isIncoming, String callingPackage);
- void setTextForMessage(int messageId, boolean isIncoming, String text);
+ void setTextForMessage(int messageId, boolean isIncoming, String text, String callingPackage);
- String getTextForMessage(int messageId, boolean isIncoming);
+ String getTextForMessage(int messageId, boolean isIncoming, String callingPackage);
- void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude);
+ void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude, String callingPackage);
- double getLatitudeForMessage(int messageId, boolean isIncoming);
+ double getLatitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
- void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude);
+ void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude, String callingPackage);
- double getLongitudeForMessage(int messageId, boolean isIncoming);
+ double getLongitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
// Returns the ID's of the file transfers attached to the given message
- int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming);
+ int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming, String callingPackage);
- int getSenderParticipant(int messageId);
+ int getSenderParticipant(int messageId, String callingPackage);
/////////////////////////
// RcsOutgoingMessageDelivery APIs
/////////////////////////
// Returns the participant ID's that this message is intended to be delivered to
- int[] getMessageRecipients(int messageId);
+ int[] getMessageRecipients(int messageId, String callingPackage);
- long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId);
+ long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, String callingPackage);
- void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, long deliveredTimestamp);
+ void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, long deliveredTimestamp, String callingPackage);
- long getOutgoingDeliverySeenTimestamp(int messageId, int participantId);
+ long getOutgoingDeliverySeenTimestamp(int messageId, int participantId, String callingPackage);
- void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, long seenTimestamp);
+ void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, long seenTimestamp, String callingPackage);
- int getOutgoingDeliveryStatus(int messageId, int participantId);
+ int getOutgoingDeliveryStatus(int messageId, int participantId, String callingPackage);
- void setOutgoingDeliveryStatus(int messageId, int participantId, int status);
+ void setOutgoingDeliveryStatus(int messageId, int participantId, int status, String callingPackage);
/////////////////////////
// RcsFileTransferPart APIs
@@ -203,64 +203,64 @@ interface IRcs {
// Performs the initial write to storage and returns the row ID.
int storeFileTransfer(int messageId, boolean isIncoming,
- in RcsFileTransferCreationParams fileTransferCreationParams);
+ in RcsFileTransferCreationParams fileTransferCreationParams, String callingPackage);
- void deleteFileTransfer(int partId);
+ void deleteFileTransfer(int partId, String callingPackage);
- void setFileTransferSessionId(int partId, String sessionId);
+ void setFileTransferSessionId(int partId, String sessionId, String callingPackage);
- String getFileTransferSessionId(int partId);
+ String getFileTransferSessionId(int partId, String callingPackage);
- void setFileTransferContentUri(int partId, in Uri contentUri);
+ void setFileTransferContentUri(int partId, in Uri contentUri, String callingPackage);
- Uri getFileTransferContentUri(int partId);
+ Uri getFileTransferContentUri(int partId, String callingPackage);
- void setFileTransferContentType(int partId, String contentType);
+ void setFileTransferContentType(int partId, String contentType, String callingPackage);
- String getFileTransferContentType(int partId);
+ String getFileTransferContentType(int partId, String callingPackage);
- void setFileTransferFileSize(int partId, long fileSize);
+ void setFileTransferFileSize(int partId, long fileSize, String callingPackage);
- long getFileTransferFileSize(int partId);
+ long getFileTransferFileSize(int partId, String callingPackage);
- void setFileTransferTransferOffset(int partId, long transferOffset);
+ void setFileTransferTransferOffset(int partId, long transferOffset, String callingPackage);
- long getFileTransferTransferOffset(int partId);
+ long getFileTransferTransferOffset(int partId, String callingPackage);
- void setFileTransferStatus(int partId, int transferStatus);
+ void setFileTransferStatus(int partId, int transferStatus, String callingPackage);
- int getFileTransferStatus(int partId);
+ int getFileTransferStatus(int partId, String callingPackage);
- void setFileTransferWidth(int partId, int width);
+ void setFileTransferWidth(int partId, int width, String callingPackage);
- int getFileTransferWidth(int partId);
+ int getFileTransferWidth(int partId, String callingPackage);
- void setFileTransferHeight(int partId, int height);
+ void setFileTransferHeight(int partId, int height, String callingPackage);
- int getFileTransferHeight(int partId);
+ int getFileTransferHeight(int partId, String callingPackage);
- void setFileTransferLength(int partId, long length);
+ void setFileTransferLength(int partId, long length, String callingPackage);
- long getFileTransferLength(int partId);
+ long getFileTransferLength(int partId, String callingPackage);
- void setFileTransferPreviewUri(int partId, in Uri uri);
+ void setFileTransferPreviewUri(int partId, in Uri uri, String callingPackage);
- Uri getFileTransferPreviewUri(int partId);
+ Uri getFileTransferPreviewUri(int partId, String callingPackage);
- void setFileTransferPreviewType(int partId, String type);
+ void setFileTransferPreviewType(int partId, String type, String callingPackage);
- String getFileTransferPreviewType(int partId);
+ String getFileTransferPreviewType(int partId, String callingPackage);
/////////////////////////
// RcsEvent APIs
/////////////////////////
- int createGroupThreadNameChangedEvent(long timestamp, int threadId, int originationParticipantId, String newName);
+ int createGroupThreadNameChangedEvent(long timestamp, int threadId, int originationParticipantId, String newName, String callingPackage);
- int createGroupThreadIconChangedEvent(long timestamp, int threadId, int originationParticipantId, in Uri newIcon);
+ int createGroupThreadIconChangedEvent(long timestamp, int threadId, int originationParticipantId, in Uri newIcon, String callingPackage);
- int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, int originationParticipantId, int participantId);
+ int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
- int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, int originationParticipantId, int participantId);
+ int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
- int createParticipantAliasChangedEvent(long timestamp, int participantId, String newAlias);
+ int createParticipantAliasChangedEvent(long timestamp, int participantId, String newAlias, String callingPackage);
} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 6e8d038eda4f..bb5c251b69e1 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -94,6 +94,7 @@ public class DctConstants {
public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50;
+ public static final int EVENT_APN_WHITE_LIST_CHANGE = BASE + 51;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 118f5e26e6e7..f248893ec638 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -283,4 +283,6 @@ interface ISub {
int getSimStateForSlotIndex(int slotIndex);
boolean isActiveSubId(int subId, String callingPackage);
+
+ boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d173cc9c44e5..71ea881fbf5d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1586,7 +1586,7 @@ interface ITelephony {
int getCardIdForDefaultEuicc(int subId, String callingPackage);
/**
- * Gets information about currently inserted UICCs and enabled eUICCs.
+ * Gets information about currently inserted UICCs and eUICCs.
* <p>
* Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
* <p>
@@ -1958,4 +1958,8 @@ interface ITelephony {
int getRadioHalVersion();
boolean isModemEnabledForSlot(int slotIndex, String callingPackage);
+
+ boolean isDataEnabledForApn(int apnType, int subId, String callingPackage);
+
+ boolean isApnMetered(int apnType, int subId);
}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
index 89d32ab5a925..658c3edb4642 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
@@ -49,9 +49,7 @@ public class RcsGroupThreadIconChangedEventTest {
RcsGroupThreadIconChangedEventDescriptor.CREATOR.createFromParcel(parcel);
RcsGroupThreadIconChangedEvent iconChangedEvent =
- iconChangedEventDescriptor.createRcsEvent();
-
-
+ iconChangedEventDescriptor.createRcsEvent(null);
assertThat(iconChangedEvent.getNewIcon()).isEqualTo(newIconUri);
assertThat(iconChangedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
index 726b9cd6641f..9fe67ad62b7c 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
@@ -48,7 +48,7 @@ public class RcsGroupThreadNameChangedEventTest {
.createFromParcel(parcel);
RcsGroupThreadNameChangedEvent nameChangedEvent =
- nameChangedEventDescriptor.createRcsEvent();
+ nameChangedEventDescriptor.createRcsEvent(null);
assertThat(nameChangedEvent.getNewName()).isEqualTo(newName);
assertThat(nameChangedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
index a109310076d2..18d5621f8e20 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
@@ -47,7 +47,7 @@ public class RcsGroupThreadParticipantJoinedEventTest {
.createFromParcel(parcel);
RcsGroupThreadParticipantJoinedEvent participantJoinedEvent =
- participantJoinedEventDescriptor.createRcsEvent();
+ participantJoinedEventDescriptor.createRcsEvent(null);
assertThat(participantJoinedEvent.getJoinedParticipant().getId()).isEqualTo(2);
assertThat(participantJoinedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
index de2688c5b8c8..53a6bba52a3e 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
@@ -48,7 +48,7 @@ public class RcsGroupThreadParticipantLeftEventTest {
.createFromParcel(parcel);
RcsGroupThreadParticipantLeftEvent participantLeftEvent =
- participantLeftEventDescriptor.createRcsEvent();
+ participantLeftEventDescriptor.createRcsEvent(null);
assertThat(participantLeftEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
assertThat(participantLeftEvent.getLeavingParticipant().getId()).isEqualTo(2);
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
index 57240545e5d8..dcf68ffa3324 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
@@ -47,7 +47,7 @@ public class RcsParticipantAliasChangedEventTest {
.createFromParcel(parcel);
RcsParticipantAliasChangedEvent aliasChangedEvent =
- aliasChangedEventDescriptor.createRcsEvent();
+ aliasChangedEventDescriptor.createRcsEvent(null);
assertThat(aliasChangedEvent.getParticipant().getId()).isEqualTo(mParticipantId);
assertThat(aliasChangedEvent.getNewAlias()).isEqualTo(NEW_ALIAS);
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
index beb4f8ad28e2..551a228282cd 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
@@ -33,7 +33,7 @@ public class RcsThreadQueryParamsTest {
@Test
public void testCanUnparcel() {
- RcsParticipant rcsParticipant = new RcsParticipant(1);
+ RcsParticipant rcsParticipant = new RcsParticipant(null, 1);
RcsThreadQueryParams rcsThreadQueryParams = new RcsThreadQueryParams.Builder()
.setThreadType(THREAD_TYPE_GROUP)
.setParticipant(rcsParticipant)
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 9098f90fd777..1fbb6580c389 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -6,6 +6,7 @@ java_defaults {
static_libs: [
"FrameworksNetCommonTests",
"frameworks-base-testutils",
+ "frameworks-net-testutils",
"framework-protos",
"androidx.test.rules",
"mockito-target-minus-junit4",
@@ -63,7 +64,7 @@ java_defaults {
android_test {
name: "FrameworksNetTests",
defaults: ["FrameworksNetTests-jni-defaults"],
- srcs: ["java/**/*.java"],
+ srcs: ["java/**/*.java", "java/**/*.kt"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index 0a1ac75aac80..07525a6ea49c 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -18,10 +18,12 @@
// They must be fast and stable, and exercise public or test APIs.
java_library {
name: "FrameworksNetCommonTests",
- srcs: ["java/**/*.java"],
+ srcs: ["java/**/*.java", "java/**/*.kt"],
static_libs: [
"androidx.test.rules",
+ "frameworks-net-testutils",
"junit",
+ "mockito-target-minus-junit4",
],
libs: [
"android.test.base.stubs",
diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java
new file mode 100644
index 000000000000..eed7159ffddc
--- /dev/null
+++ b/tests/net/common/java/android/net/CaptivePortalTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.RemoteException;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class CaptivePortalTest {
+ private static final int DEFAULT_TIMEOUT_MS = 5000;
+ private static final String TEST_PACKAGE_NAME = "com.google.android.test";
+
+ private final class MyCaptivePortalImpl extends ICaptivePortal.Stub {
+ int mCode = -1;
+ String mPackageName = null;
+
+ @Override
+ public void appResponse(final int response) throws RemoteException {
+ mCode = response;
+ }
+
+ @Override
+ public void logEvent(int eventId, String packageName) throws RemoteException {
+ mCode = eventId;
+ mPackageName = packageName;
+ }
+ }
+
+ private interface TestFunctor {
+ void useCaptivePortal(CaptivePortal o);
+ }
+
+ private MyCaptivePortalImpl runCaptivePortalTest(TestFunctor f) {
+ final MyCaptivePortalImpl cp = new MyCaptivePortalImpl();
+ f.useCaptivePortal(new CaptivePortal(cp.asBinder()));
+ return cp;
+ }
+
+ @Test
+ public void testReportCaptivePortalDismissed() {
+ final MyCaptivePortalImpl result =
+ runCaptivePortalTest(c -> c.reportCaptivePortalDismissed());
+ assertEquals(result.mCode, CaptivePortal.APP_RETURN_DISMISSED);
+ }
+
+ @Test
+ public void testIgnoreNetwork() {
+ final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.ignoreNetwork());
+ assertEquals(result.mCode, CaptivePortal.APP_RETURN_UNWANTED);
+ }
+
+ @Test
+ public void testUseNetwork() {
+ final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.useNetwork());
+ assertEquals(result.mCode, CaptivePortal.APP_RETURN_WANTED_AS_IS);
+ }
+
+ @Test
+ public void testLogEvent() {
+ final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent(
+ MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY,
+ TEST_PACKAGE_NAME));
+ assertEquals(result.mCode, MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
+ assertEquals(result.mPackageName, TEST_PACKAGE_NAME);
+ }
+}
diff --git a/tests/net/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index d462441b22fa..d462441b22fa 100644
--- a/tests/net/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 417729150be8..709f5f69aa2b 100644
--- a/tests/net/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -868,12 +868,12 @@ public class LinkPropertiesTest {
source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
- TestUtils.assertParcelingIsLossless(source, LinkProperties.CREATOR);
+ TestUtils.assertParcelingIsLossless(source);
}
@Test
public void testParcelUninitialized() throws Exception {
LinkProperties empty = new LinkProperties();
- TestUtils.assertParcelingIsLossless(empty, LinkProperties.CREATOR);
+ TestUtils.assertParcelingIsLossless(empty);
}
}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index ad76388b3c9b..6bc7c1bb30f8 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -33,6 +33,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
@@ -585,4 +587,20 @@ public class NetworkCapabilitiesTest {
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
assertEquals(nc1, nc2);
}
+
+ @Test
+ public void testGetTransportTypes() {
+ final NetworkCapabilities nc = new NetworkCapabilities();
+ nc.addTransportType(TRANSPORT_CELLULAR);
+ nc.addTransportType(TRANSPORT_WIFI);
+ nc.addTransportType(TRANSPORT_VPN);
+ nc.addTransportType(TRANSPORT_TEST);
+
+ final int[] transportTypes = nc.getTransportTypes();
+ assertEquals(4, transportTypes.length);
+ assertEquals(TRANSPORT_CELLULAR, transportTypes[0]);
+ assertEquals(TRANSPORT_WIFI, transportTypes[1]);
+ assertEquals(TRANSPORT_VPN, transportTypes[2]);
+ assertEquals(TRANSPORT_TEST, transportTypes[3]);
+ }
}
diff --git a/tests/net/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index 0bee7cd29d29..bef66b27df62 100644
--- a/tests/net/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -155,4 +155,12 @@ public class NetworkTest {
private static <T> void assertNotEqual(T t1, T t2) {
assertFalse(Objects.equals(t1, t2));
}
+
+ @Test
+ public void testGetPrivateDnsBypassingCopy() {
+ final Network copy = mNetwork.getPrivateDnsBypassingCopy();
+ assertEquals(mNetwork.netId, copy.netId);
+ assertNotEqual(copy.netId, copy.getNetIdForResolv());
+ assertNotEqual(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv());
+ }
}
diff --git a/tests/net/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 2edbd403b5b5..2edbd403b5b5 100644
--- a/tests/net/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
diff --git a/tests/net/java/android/net/StaticIpConfigurationTest.java b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
index 8449ca76d580..5096be221cbf 100644
--- a/tests/net/java/android/net/StaticIpConfigurationTest.java
+++ b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
@@ -31,7 +31,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
@RunWith(AndroidJUnit4.class)
@@ -46,6 +48,7 @@ public class StaticIpConfigurationTest {
private static final InetAddress DNS2 = IpAddress("8.8.4.4");
private static final InetAddress DNS3 = IpAddress("4.2.2.2");
private static final String IFACE = "eth0";
+ private static final String FAKE_DOMAINS = "google.com";
private static InetAddress IpAddress(String addr) {
return InetAddress.parseNumericAddress(addr);
@@ -69,7 +72,7 @@ public class StaticIpConfigurationTest {
s.dnsServers.add(DNS1);
s.dnsServers.add(DNS2);
s.dnsServers.add(DNS3);
- s.domains = "google.com";
+ s.domains = FAKE_DOMAINS;
return s;
}
@@ -178,8 +181,8 @@ public class StaticIpConfigurationTest {
expected.addDnsServer(DNS3);
assertEquals(expected, s.toLinkProperties(IFACE));
- s.domains = "google.com";
- expected.setDomains("google.com");
+ s.domains = FAKE_DOMAINS;
+ expected.setDomains(FAKE_DOMAINS);
assertEquals(expected, s.toLinkProperties(IFACE));
s.gateway = null;
@@ -218,4 +221,53 @@ public class StaticIpConfigurationTest {
StaticIpConfiguration s2 = passThroughParcel(s);
assertEquals(s, s2);
}
+
+ @Test
+ public void testBuilder() {
+ final ArrayList<InetAddress> dnsServers = new ArrayList<>();
+ dnsServers.add(DNS1);
+
+ final StaticIpConfiguration s = new StaticIpConfiguration.Builder()
+ .setIpAddress(ADDR)
+ .setGateway(GATEWAY)
+ .setDomains(FAKE_DOMAINS)
+ .setDnsServers(dnsServers)
+ .build();
+
+ assertEquals(s.ipAddress, s.getIpAddress());
+ assertEquals(ADDR, s.getIpAddress());
+ assertEquals(s.gateway, s.getGateway());
+ assertEquals(GATEWAY, s.getGateway());
+ assertEquals(s.domains, s.getDomains());
+ assertEquals(FAKE_DOMAINS, s.getDomains());
+ assertTrue(s.dnsServers.equals(s.getDnsServers()));
+ assertEquals(1, s.getDnsServers().size());
+ assertEquals(DNS1, s.getDnsServers().get(0));
+ }
+
+ @Test
+ public void testAddDnsServers() {
+ final StaticIpConfiguration s = new StaticIpConfiguration((StaticIpConfiguration) null);
+ checkEmpty(s);
+
+ s.addDnsServer(DNS1);
+ assertEquals(1, s.getDnsServers().size());
+ assertEquals(DNS1, s.getDnsServers().get(0));
+
+ s.addDnsServer(DNS2);
+ s.addDnsServer(DNS3);
+ assertEquals(3, s.getDnsServers().size());
+ assertEquals(DNS2, s.getDnsServers().get(1));
+ assertEquals(DNS3, s.getDnsServers().get(2));
+ }
+
+ @Test
+ public void testGetRoutes() {
+ final StaticIpConfiguration s = makeTestObject();
+ final List<RouteInfo> routeInfoList = s.getRoutes(IFACE);
+
+ assertEquals(2, routeInfoList.size());
+ assertEquals(new RouteInfo(ADDR, (InetAddress) null, IFACE), routeInfoList.get(0));
+ assertEquals(new RouteInfo((IpPrefix) null, GATEWAY, IFACE), routeInfoList.get(1));
+ }
}
diff --git a/tests/net/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 75752c33da5c..3ed8a86b2fb5 100644
--- a/tests/net/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -19,11 +19,10 @@ package android.net.apf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import android.net.shared.ParcelableTestUtil;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.ParcelableTestUtil;
import com.android.internal.util.TestUtils;
import org.junit.Test;
@@ -37,7 +36,7 @@ public class ApfCapabilitiesTest {
final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
ParcelableTestUtil.assertFieldCountEquals(3, ApfCapabilities.class);
- TestUtils.assertParcelingIsLossless(caps, ApfCapabilities.CREATOR);
+ TestUtils.assertParcelingIsLossless(caps);
}
@Test
diff --git a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
new file mode 100644
index 000000000000..8d055c93c4c5
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ApfProgramEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ private infix fun Int.hasFlag(flag: Int) = (this and (1 shl flag)) != 0
+
+ @Test
+ fun testBuilderAndParcel() {
+ val apfProgramEvent = ApfProgramEvent.Builder()
+ .setLifetime(1)
+ .setActualLifetime(2)
+ .setFilteredRas(3)
+ .setCurrentRas(4)
+ .setProgramLength(5)
+ .setFlags(true, true)
+ .build()
+
+ assertEquals(1, apfProgramEvent.lifetime)
+ assertEquals(2, apfProgramEvent.actualLifetime)
+ assertEquals(3, apfProgramEvent.filteredRas)
+ assertEquals(4, apfProgramEvent.currentRas)
+ assertEquals(5, apfProgramEvent.programLength)
+ assertEquals(ApfProgramEvent.flagsFor(true, true), apfProgramEvent.flags)
+
+ testParcel(apfProgramEvent, 6)
+ }
+
+ @Test
+ fun testFlagsFor() {
+ var flags = ApfProgramEvent.flagsFor(false, false)
+ assertFalse(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)
+ assertFalse(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)
+
+ flags = ApfProgramEvent.flagsFor(true, false)
+ assertTrue(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)
+ assertFalse(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)
+
+ flags = ApfProgramEvent.flagsFor(false, true)
+ assertFalse(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)
+ assertTrue(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)
+
+ flags = ApfProgramEvent.flagsFor(true, true)
+ assertTrue(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)
+ assertTrue(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
new file mode 100644
index 000000000000..f8eb40cccd35
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ApfStatsTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testBuilderAndParcel() {
+ val apfStats = ApfStats.Builder()
+ .setDurationMs(Long.MAX_VALUE)
+ .setReceivedRas(1)
+ .setMatchingRas(2)
+ .setDroppedRas(3)
+ .setZeroLifetimeRas(4)
+ .setParseErrors(5)
+ .setProgramUpdates(6)
+ .setProgramUpdatesAll(7)
+ .setProgramUpdatesAllowingMulticast(8)
+ .setMaxProgramSize(9)
+ .build()
+
+ assertEquals(Long.MAX_VALUE, apfStats.durationMs)
+ assertEquals(1, apfStats.receivedRas)
+ assertEquals(2, apfStats.matchingRas)
+ assertEquals(3, apfStats.droppedRas)
+ assertEquals(4, apfStats.zeroLifetimeRas)
+ assertEquals(5, apfStats.parseErrors)
+ assertEquals(6, apfStats.programUpdates)
+ assertEquals(7, apfStats.programUpdatesAll)
+ assertEquals(8, apfStats.programUpdatesAllowingMulticast)
+ assertEquals(9, apfStats.maxProgramSize)
+
+ testParcel(apfStats, 10)
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
new file mode 100644
index 000000000000..36e9f8c94f6a
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val FAKE_MESSAGE = "test"
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DhcpClientEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testBuilderAndParcel() {
+ val dhcpClientEvent = DhcpClientEvent.Builder()
+ .setMsg(FAKE_MESSAGE)
+ .setDurationMs(Integer.MAX_VALUE)
+ .build()
+
+ assertEquals(FAKE_MESSAGE, dhcpClientEvent.msg)
+ assertEquals(Integer.MAX_VALUE, dhcpClientEvent.durationMs)
+
+ testParcel(dhcpClientEvent, 2)
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
new file mode 100644
index 000000000000..e9d5e6db1c7e
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
@@ -0,0 +1,65 @@
+package android.net.metrics
+
+import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
+import android.net.metrics.DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.TestUtils.parcelingRoundTrip
+import java.lang.reflect.Modifier
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_ERROR_CODE = 12345
+//DHCP Optional Type: DHCP Subnet Mask (Copy from DhcpPacket.java due to it's protected)
+private const val DHCP_SUBNET_MASK = 1
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DhcpErrorEventTest {
+
+ @Test
+ fun testConstructor() {
+ val event = DhcpErrorEvent(TEST_ERROR_CODE)
+ assertEquals(TEST_ERROR_CODE, event.errorCode)
+ }
+
+ @Test
+ fun testParcelUnparcel() {
+ val event = DhcpErrorEvent(TEST_ERROR_CODE)
+ val parceled = parcelingRoundTrip(event)
+ assertEquals(TEST_ERROR_CODE, parceled.errorCode)
+ }
+
+ @Test
+ fun testErrorCodeWithOption() {
+ val errorCode = errorCodeWithOption(DHCP_INVALID_OPTION_LENGTH, DHCP_SUBNET_MASK);
+ assertTrue((DHCP_INVALID_OPTION_LENGTH and errorCode) == DHCP_INVALID_OPTION_LENGTH);
+ assertTrue((DHCP_SUBNET_MASK and errorCode) == DHCP_SUBNET_MASK);
+ }
+
+ @Test
+ fun testToString() {
+ val names = listOf("L2_ERROR", "L3_ERROR", "L4_ERROR", "DHCP_ERROR", "MISC_ERROR")
+ val errorFields = DhcpErrorEvent::class.java.declaredFields.filter {
+ it.type == Int::class.javaPrimitiveType
+ && Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers)
+ && it.name !in names
+ }
+
+ errorFields.forEach {
+ val intValue = it.getInt(null)
+ val stringValue = DhcpErrorEvent(intValue).toString()
+ assertTrue("Invalid string for error 0x%08X (field %s): %s".format(intValue, it.name,
+ stringValue),
+ stringValue.contains(it.name))
+ }
+ }
+
+ @Test
+ fun testToString_InvalidErrorCode() {
+ assertNotNull(DhcpErrorEvent(TEST_ERROR_CODE).toString())
+ }
+} \ No newline at end of file
diff --git a/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java b/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java
new file mode 100644
index 000000000000..d4780d3a5d7b
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.net.ConnectivityMetricsEvent;
+import android.net.IIpConnectivityMetrics;
+import android.net.Network;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.BitUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpConnectivityLogTest {
+ private static final int FAKE_NET_ID = 100;
+ private static final int[] FAKE_TRANSPORT_TYPES = BitUtils.unpackBits(TRANSPORT_WIFI);
+ private static final long FAKE_TIME_STAMP = System.currentTimeMillis();
+ private static final String FAKE_INTERFACE_NAME = "test";
+ private static final IpReachabilityEvent FAKE_EV =
+ new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
+
+ @Mock IIpConnectivityMetrics mMockService;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testLoggingEvents() throws Exception {
+ IpConnectivityLog logger = new IpConnectivityLog(mMockService);
+
+ assertTrue(logger.log(FAKE_EV));
+ assertTrue(logger.log(FAKE_TIME_STAMP, FAKE_EV));
+ assertTrue(logger.log(FAKE_NET_ID, FAKE_TRANSPORT_TYPES, FAKE_EV));
+ assertTrue(logger.log(new Network(FAKE_NET_ID), FAKE_TRANSPORT_TYPES, FAKE_EV));
+ assertTrue(logger.log(FAKE_INTERFACE_NAME, FAKE_EV));
+ assertTrue(logger.log(makeExpectedEvent(FAKE_TIME_STAMP, FAKE_NET_ID, TRANSPORT_WIFI,
+ FAKE_INTERFACE_NAME)));
+
+ List<ConnectivityMetricsEvent> got = verifyEvents(6);
+ assertEventsEqual(makeExpectedEvent(got.get(0).timestamp, 0, 0, null), got.get(0));
+ assertEventsEqual(makeExpectedEvent(FAKE_TIME_STAMP, 0, 0, null), got.get(1));
+ assertEventsEqual(makeExpectedEvent(got.get(2).timestamp, FAKE_NET_ID,
+ TRANSPORT_WIFI, null), got.get(2));
+ assertEventsEqual(makeExpectedEvent(got.get(3).timestamp, FAKE_NET_ID,
+ TRANSPORT_WIFI, null), got.get(3));
+ assertEventsEqual(makeExpectedEvent(got.get(4).timestamp, 0, 0, FAKE_INTERFACE_NAME),
+ got.get(4));
+ assertEventsEqual(makeExpectedEvent(FAKE_TIME_STAMP, FAKE_NET_ID,
+ TRANSPORT_WIFI, FAKE_INTERFACE_NAME), got.get(5));
+ }
+
+ @Test
+ public void testLoggingEventsWithMultipleCallers() throws Exception {
+ IpConnectivityLog logger = new IpConnectivityLog(mMockService);
+
+ final int nCallers = 10;
+ final int nEvents = 10;
+ for (int n = 0; n < nCallers; n++) {
+ final int i = n;
+ new Thread() {
+ public void run() {
+ for (int j = 0; j < nEvents; j++) {
+ assertTrue(logger.log(makeExpectedEvent(
+ FAKE_TIME_STAMP + i * 100 + j,
+ FAKE_NET_ID + i * 100 + j,
+ ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR,
+ FAKE_INTERFACE_NAME)));
+ }
+ }
+ }.start();
+ }
+
+ List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
+ Collections.sort(got, EVENT_COMPARATOR);
+ Iterator<ConnectivityMetricsEvent> iter = got.iterator();
+ for (int i = 0; i < nCallers; i++) {
+ for (int j = 0; j < nEvents; j++) {
+ final long expectedTimestamp = FAKE_TIME_STAMP + i * 100 + j;
+ final int expectedNetId = FAKE_NET_ID + i * 100 + j;
+ final long expectedTransports =
+ ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR;
+ assertEventsEqual(makeExpectedEvent(expectedTimestamp, expectedNetId,
+ expectedTransports, FAKE_INTERFACE_NAME), iter.next());
+ }
+ }
+ }
+
+ private List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
+ ArgumentCaptor<ConnectivityMetricsEvent> captor =
+ ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
+ verify(mMockService, timeout(timeoutMs).times(n)).logEvent(captor.capture());
+ return captor.getAllValues();
+ }
+
+ private List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
+ return verifyEvents(n, 10);
+ }
+
+
+ private ConnectivityMetricsEvent makeExpectedEvent(long timestamp, int netId, long transports,
+ String ifname) {
+ ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
+ ev.timestamp = timestamp;
+ ev.data = FAKE_EV;
+ ev.netId = netId;
+ ev.transports = transports;
+ ev.ifname = ifname;
+ return ev;
+ }
+
+ /** Outer equality for ConnectivityMetricsEvent to avoid overriding equals() and hashCode(). */
+ private void assertEventsEqual(ConnectivityMetricsEvent expected,
+ ConnectivityMetricsEvent got) {
+ assertEquals(expected.data, got.data);
+ assertEquals(expected.timestamp, got.timestamp);
+ assertEquals(expected.netId, got.netId);
+ assertEquals(expected.transports, got.transports);
+ assertEquals(expected.ifname, got.ifname);
+ }
+
+ static final Comparator<ConnectivityMetricsEvent> EVENT_COMPARATOR =
+ Comparator.comparingLong((ev) -> ev.timestamp);
+}
diff --git a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
new file mode 100644
index 000000000000..5144ca56bf28
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class IpManagerEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testConstructorAndParcel() {
+ (IpManagerEvent.PROVISIONING_OK..IpManagerEvent.ERROR_INTERFACE_NOT_FOUND).forEach {
+ val ipManagerEvent = IpManagerEvent(it, Long.MAX_VALUE)
+ assertEquals(it, ipManagerEvent.eventType)
+ assertEquals(Long.MAX_VALUE, ipManagerEvent.durationMs)
+
+ testParcel(ipManagerEvent, 2)
+ }
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
new file mode 100644
index 000000000000..d76ebf67ff1d
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class IpReachabilityEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testConstructorAndParcel() {
+ (IpReachabilityEvent.PROBE..IpReachabilityEvent.PROVISIONING_LOST_ORGANIC).forEach {
+ val ipReachabilityEvent = IpReachabilityEvent(it)
+ assertEquals(it, ipReachabilityEvent.eventType)
+
+ testParcel(ipReachabilityEvent, 1)
+ }
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
new file mode 100644
index 000000000000..8b52e81eea1e
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testConstructorAndParcel() {
+ (NetworkEvent.NETWORK_CONNECTED..NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY).forEach {
+ var networkEvent = NetworkEvent(it)
+ assertEquals(it, networkEvent.eventType)
+ assertEquals(0, networkEvent.durationMs)
+
+ networkEvent = NetworkEvent(it, Long.MAX_VALUE)
+ assertEquals(it, networkEvent.eventType)
+ assertEquals(Long.MAX_VALUE, networkEvent.durationMs)
+
+ testParcel(networkEvent, 2)
+ }
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/RaEventTest.kt b/tests/net/common/java/android/net/metrics/RaEventTest.kt
new file mode 100644
index 000000000000..f38d32844230
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/RaEventTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val NO_LIFETIME: Long = -1L
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class RaEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ @Test
+ fun testConstructorAndParcel() {
+ var raEvent = RaEvent.Builder().build()
+ assertEquals(NO_LIFETIME, raEvent.routerLifetime)
+ assertEquals(NO_LIFETIME, raEvent.prefixValidLifetime)
+ assertEquals(NO_LIFETIME, raEvent.prefixPreferredLifetime)
+ assertEquals(NO_LIFETIME, raEvent.routeInfoLifetime)
+ assertEquals(NO_LIFETIME, raEvent.rdnssLifetime)
+ assertEquals(NO_LIFETIME, raEvent.dnsslLifetime)
+
+ raEvent = RaEvent.Builder()
+ .updateRouterLifetime(1)
+ .updatePrefixValidLifetime(2)
+ .updatePrefixPreferredLifetime(3)
+ .updateRouteInfoLifetime(4)
+ .updateRdnssLifetime(5)
+ .updateDnsslLifetime(6)
+ .build()
+ assertEquals(1, raEvent.routerLifetime)
+ assertEquals(2, raEvent.prefixValidLifetime)
+ assertEquals(3, raEvent.prefixPreferredLifetime)
+ assertEquals(4, raEvent.routeInfoLifetime)
+ assertEquals(5, raEvent.rdnssLifetime)
+ assertEquals(6, raEvent.dnsslLifetime)
+
+ raEvent = RaEvent.Builder()
+ .updateRouterLifetime(Long.MIN_VALUE)
+ .updateRouterLifetime(Long.MAX_VALUE)
+ .build()
+ assertEquals(Long.MIN_VALUE, raEvent.routerLifetime)
+
+ raEvent = RaEvent(1, 2, 3, 4, 5, 6)
+ assertEquals(1, raEvent.routerLifetime)
+ assertEquals(2, raEvent.prefixValidLifetime)
+ assertEquals(3, raEvent.prefixPreferredLifetime)
+ assertEquals(4, raEvent.routeInfoLifetime)
+ assertEquals(5, raEvent.rdnssLifetime)
+ assertEquals(6, raEvent.dnsslLifetime)
+
+ testParcel(raEvent, 6)
+ }
+}
diff --git a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
new file mode 100644
index 000000000000..c0cef8fe91fd
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.ParcelableTestUtil
+import com.android.internal.util.TestUtils
+import java.lang.reflect.Modifier
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val FIRST_VALIDATION: Int = 1 shl 8
+private const val REVALIDATION: Int = 2 shl 8
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ValidationProbeEventTest {
+ private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
+ ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
+ TestUtils.assertParcelingIsLossless(obj)
+ }
+
+ private infix fun Int.hasType(type: Int) = (type and this) == type
+
+ @Test
+ fun testBuilderAndParcel() {
+ var validationProbeEvent = ValidationProbeEvent.Builder()
+ .setProbeType(ValidationProbeEvent.PROBE_DNS, false).build()
+
+ assertTrue(validationProbeEvent.probeType hasType REVALIDATION)
+
+ validationProbeEvent = ValidationProbeEvent.Builder()
+ .setDurationMs(Long.MAX_VALUE)
+ .setProbeType(ValidationProbeEvent.PROBE_DNS, true)
+ .setReturnCode(ValidationProbeEvent.DNS_SUCCESS)
+ .build()
+
+ assertEquals(Long.MAX_VALUE, validationProbeEvent.durationMs)
+ assertTrue(validationProbeEvent.probeType hasType ValidationProbeEvent.PROBE_DNS)
+ assertTrue(validationProbeEvent.probeType hasType FIRST_VALIDATION)
+ assertEquals(ValidationProbeEvent.DNS_SUCCESS, validationProbeEvent.returnCode)
+
+ testParcel(validationProbeEvent, 3)
+ }
+
+ @Test
+ fun testGetProbeName() {
+ val probeFields = ValidationProbeEvent::class.java.declaredFields.filter {
+ it.type == Int::class.javaPrimitiveType
+ && Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers)
+ && it.name.contains("PROBE")
+ }
+
+ probeFields.forEach {
+ val intValue = it.getInt(null)
+ val stringValue = ValidationProbeEvent.getProbeName(intValue)
+ assertEquals(it.name, stringValue)
+ }
+
+ }
+}
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index e0b722761c34..583d3fd536aa 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -79,7 +79,7 @@ public final class TcpKeepalivePacketDataTest {
assertEquals(testInfo.tos, resultData.ipTos);
assertEquals(testInfo.ttl, resultData.ipTtl);
- TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
+ TestUtils.assertParcelingIsLossless(resultData);
final byte[] packet = resultData.getPacket();
// IP version and IHL
diff --git a/tests/net/java/android/net/shared/InitialConfigurationTest.java b/tests/net/java/android/net/shared/InitialConfigurationTest.java
index 27bc13d75440..2fb8b19abcd4 100644
--- a/tests/net/java/android/net/shared/InitialConfigurationTest.java
+++ b/tests/net/java/android/net/shared/InitialConfigurationTest.java
@@ -17,7 +17,8 @@
package android.net.shared;
import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
+
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index 21a4988950db..f9dbdc7fbf3e 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -19,7 +19,8 @@ package android.net.shared;
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
+
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
@@ -54,9 +55,10 @@ public class IpConfigurationParcelableUtilTest {
mDhcpResults.serverAddress = (Inet4Address) parseNumericAddress("192.168.44.44");
mDhcpResults.vendorInfo = "TEST_VENDOR_INFO";
mDhcpResults.leaseDuration = 3600;
+ mDhcpResults.serverHostName = "dhcp.example.com";
mDhcpResults.mtu = 1450;
// Any added DhcpResults field must be included in equals() to be tested properly
- assertFieldCountEquals(8, DhcpResults.class);
+ assertFieldCountEquals(9, DhcpResults.class);
}
@Test
@@ -100,6 +102,12 @@ public class IpConfigurationParcelableUtilTest {
doDhcpResultsParcelUnparcelTest();
}
+ @Test
+ public void testParcelUnparcelDhcpResults_NullServerHostName() {
+ mDhcpResults.serverHostName = null;
+ doDhcpResultsParcelUnparcelTest();
+ }
+
private void doDhcpResultsParcelUnparcelTest() {
final DhcpResults unparceled = fromStableParcelable(toStableParcelable(mDhcpResults));
assertEquals(mDhcpResults, unparceled);
diff --git a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
index 6fad89ec50b2..382afe0279be 100644
--- a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
@@ -17,9 +17,10 @@
package android.net.shared;
import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
import static android.net.shared.ProvisioningConfiguration.fromStableParcelable;
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e3c6c4113cc5..37af461b1305 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
@@ -103,6 +105,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
@@ -146,6 +149,7 @@ import android.net.metrics.IpConnectivityLog;
import android.net.shared.NetworkMonitorUtils;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
+import android.os.Binder;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -272,6 +276,7 @@ public class ConnectivityServiceTest {
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
+ @Mock PackageManager mPackageManager;
@Mock UserManager mUserManager;
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
@@ -357,7 +362,12 @@ public class ConnectivityServiceTest {
public Resources getResources() {
return mResources;
}
- }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+ }
public void waitForIdle(int timeoutMsAsInt) {
long timeoutMs = timeoutMsAsInt;
@@ -557,6 +567,16 @@ public class ConnectivityServiceTest {
protected void preventAutomaticReconnect() {
mPreventReconnectReceived.open();
}
+
+ @Override
+ protected void addKeepalivePacketFilter(Message msg) {
+ Log.i(TAG, "Add keepalive packet filter.");
+ }
+
+ @Override
+ protected void removeKeepalivePacketFilter(Message msg) {
+ Log.i(TAG, "Remove keepalive packet filter.");
+ }
};
assertEquals(mNetworkAgent.netId, nmNetworkCaptor.getValue().netId);
@@ -1232,6 +1252,7 @@ public class ConnectivityServiceTest {
if (Looper.myLooper() == null) {
Looper.prepare();
}
+ mockDefaultPackages();
FakeSettingsProvider.clearSettingsProvider();
mServiceContext = new MockContext(InstrumentationRegistry.getContext(),
@@ -1284,7 +1305,24 @@ public class ConnectivityServiceTest {
FakeSettingsProvider.clearSettingsProvider();
}
- private static int transportToLegacyType(int transport) {
+ private void mockDefaultPackages() throws Exception {
+ final String testPackageName = mContext.getPackageName();
+ final PackageInfo testPackageInfo = mContext.getPackageManager().getPackageInfo(
+ testPackageName, PackageManager.GET_PERMISSIONS);
+ when(mPackageManager.getPackagesForUid(Binder.getCallingUid())).thenReturn(
+ new String[] {testPackageName});
+ when(mPackageManager.getPackageInfoAsUser(eq(testPackageName), anyInt(),
+ eq(UserHandle.getCallingUserId()))).thenReturn(testPackageInfo);
+
+ when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
+ Arrays.asList(new PackageInfo[] {
+ buildPackageInfo(/* SYSTEM */ false, APP1_UID),
+ buildPackageInfo(/* SYSTEM */ false, APP2_UID),
+ buildPackageInfo(/* SYSTEM */ false, VPN_UID)
+ }));
+ }
+
+ private static int transportToLegacyType(int transport) {
switch (transport) {
case TRANSPORT_ETHERNET:
return TYPE_ETHERNET;
@@ -4228,6 +4266,25 @@ public class ConnectivityServiceTest {
callback.expectStarted();
ka.stop();
callback.expectStopped();
+
+ // Check that the same NATT socket cannot be used by 2 keepalives.
+ try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ // Check that second keepalive cannot be started if the first one is running.
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ ka2.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ ka.stop();
+ callback.expectStopped();
+
+ // Check that second keepalive can be started/stopped normally if the first one is
+ // stopped.
+ ka2.start(validKaInterval);
+ callback.expectStarted();
+ ka2.stop();
+ callback.expectStopped();
+ }
}
// Check that deleting the IP address stops the keepalive.
@@ -4291,6 +4348,10 @@ public class ConnectivityServiceTest {
testSocket.close();
testSocket2.close();
}
+
+ // Check that the closed socket cannot be used to start keepalive.
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
}
// Check that there is no port leaked after all keepalives and sockets are closed.
@@ -4868,7 +4929,10 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(false);
waitForIdle();
- // CS tells netd about the empty DNS config for this network.
+
+ verify(mMockDnsResolver, times(1)).createNetworkCache(
+ eq(mCellNetworkAgent.getNetwork().netId));
+ // CS tells dnsresolver about the empty DNS config for this network.
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
reset(mMockDnsResolver);
@@ -4952,6 +5016,8 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(false);
waitForIdle();
+ verify(mMockDnsResolver, times(1)).createNetworkCache(
+ eq(mCellNetworkAgent.getNetwork().netId));
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
mResolverParamsParcelCaptor.capture());
ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
@@ -5825,12 +5891,17 @@ public class ConnectivityServiceTest {
cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
reset(mNetworkManagementService);
reset(mMockDnsResolver);
+ reset(mMockNetd);
when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
.thenReturn(getClatInterfaceConfig(myIpv4));
// Connect with ipv6 link properties. Expect prefix discovery to be started.
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(true);
+
+ verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt());
+ verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
+
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
@@ -6022,7 +6093,7 @@ public class ConnectivityServiceTest {
verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
verify(mMockDnsResolver, times(1))
- .clearResolverConfiguration(eq(mCellNetworkAgent.getNetwork().netId));
+ .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
// Disconnect wifi
ConditionVariable cv = waitForConnectivityBroadcasts(1);
@@ -6146,7 +6217,6 @@ public class ConnectivityServiceTest {
}
@Test
- @Ignore
public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6173,7 +6243,6 @@ public class ConnectivityServiceTest {
}
@Test
- @Ignore
public void testLegacyVpnDoesNotResultInInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6187,7 +6256,6 @@ public class ConnectivityServiceTest {
}
@Test
- @Ignore
public void testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule()
throws Exception {
LinkProperties lp = new LinkProperties();
@@ -6203,7 +6271,6 @@ public class ConnectivityServiceTest {
}
@Test
- @Ignore
public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6253,7 +6320,6 @@ public class ConnectivityServiceTest {
}
@Test
- @Ignore
public void testUidUpdateChangesInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 4a35015044ff..6b5a2203ce74 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -118,6 +118,7 @@ public class IpSecServiceTest {
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
+ int mUid = Os.getuid();
@Before
public void setUp() throws Exception {
@@ -665,4 +666,99 @@ public class IpSecServiceTest {
mIpSecService.releaseNetId(releasedNetId);
assertEquals(releasedNetId, mIpSecService.reserveNetId());
}
+
+ @Test
+ public void testLockEncapSocketForNattKeepalive() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(udpEncapResp.resourceId, mUid);
+
+ // Validate response, and record was added
+ assertNotEquals(IpSecManager.INVALID_RESOURCE_ID, nattKeepaliveResourceId);
+ assertEquals(1, userRecord.mNattKeepaliveRecords.size());
+
+ // Validate keepalive can be released and removed.
+ mIpSecService.releaseNattKeepalive(nattKeepaliveResourceId, mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
+ }
+
+ @Test
+ public void testLockEncapSocketForNattKeepaliveInvalidUid() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ try {
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(
+ udpEncapResp.resourceId, mUid + 1);
+ fail("Expected SecurityException for invalid user");
+ } catch (SecurityException expected) {
+ }
+
+ // Validate keepalive was not added to lists
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+ }
+
+ @Test
+ public void testLockEncapSocketForNattKeepaliveInvalidResourceId() throws Exception {
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ try {
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(12345, mUid);
+ fail("Expected IllegalArgumentException for invalid resource ID");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // Validate keepalive was not added to lists
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+ }
+
+ @Test
+ public void testEncapSocketReleasedBeforeKeepaliveReleased() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Get encap socket record, verify initial starting refcount.
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ IpSecService.RefcountedResource encapSocketRefcountedRecord =
+ userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(
+ udpEncapResp.resourceId);
+ assertEquals(1, encapSocketRefcountedRecord.mRefCount);
+
+ // Verify that the reference was added
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(udpEncapResp.resourceId, mUid);
+ assertNotEquals(IpSecManager.INVALID_RESOURCE_ID, nattKeepaliveResourceId);
+ assertEquals(2, encapSocketRefcountedRecord.mRefCount);
+
+ // Close UDP encap socket, but expect the refcountedRecord to still have a reference.
+ mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
+ assertEquals(1, encapSocketRefcountedRecord.mRefCount);
+
+ // Verify UDP encap socket cleaned up once reference is removed. Expect -1 if cleanup
+ // was properly completed.
+ mIpSecService.releaseNattKeepalive(nattKeepaliveResourceId, mUid);
+ assertEquals(-1, encapSocketRefcountedRecord.mRefCount);
+ }
}
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
new file mode 100644
index 000000000000..f045369459c9
--- /dev/null
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server
+
+import android.net.ConnectivityManager.TYPE_ETHERNET
+import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.ConnectivityManager.TYPE_WIMAX
+import android.net.NetworkInfo.DetailedState.CONNECTED
+import android.net.NetworkInfo.DetailedState.DISCONNECTED
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.server.ConnectivityService.LegacyTypeTracker
+import com.android.server.connectivity.NetworkAgentInfo
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertSame
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+
+const val UNSUPPORTED_TYPE = TYPE_WIMAX
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class LegacyTypeTrackerTest {
+ private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET)
+
+ private val mMockService = mock(ConnectivityService::class.java).apply {
+ doReturn(false).`when`(this).isDefaultNetwork(any())
+ }
+ private val mTracker = LegacyTypeTracker(mMockService).apply {
+ supportedTypes.forEach {
+ addSupportedType(it)
+ }
+ }
+
+ @Test
+ fun testSupportedTypes() {
+ try {
+ mTracker.addSupportedType(supportedTypes[0])
+ fail("Expected IllegalStateException")
+ } catch (expected: IllegalStateException) {}
+ supportedTypes.forEach {
+ assertTrue(mTracker.isTypeSupported(it))
+ }
+ assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE))
+ }
+
+ @Test
+ fun testAddNetwork() {
+ val mobileNai = mock(NetworkAgentInfo::class.java)
+ val wifiNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, mobileNai)
+ mTracker.add(TYPE_WIFI, wifiNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a second NAI does not change the results.
+ val secondMobileNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure removing a network that wasn't added for this type is a no-op.
+ mTracker.remove(TYPE_MOBILE, wifiNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Remove the top network for mobile and make sure the second one becomes the network
+ // of record for this type.
+ mTracker.remove(TYPE_MOBILE, mobileNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a network for an unsupported type does not register it.
+ mTracker.add(UNSUPPORTED_TYPE, mobileNai)
+ assertNull(mTracker.getNetworkForType(UNSUPPORTED_TYPE))
+ }
+
+ @Test
+ fun testBroadcastOnDisconnect() {
+ val mobileNai1 = mock(NetworkAgentInfo::class.java)
+ val mobileNai2 = mock(NetworkAgentInfo::class.java)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai1)
+ mTracker.add(TYPE_MOBILE, mobileNai1)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, CONNECTED, TYPE_MOBILE)
+ reset(mMockService)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai2)
+ mTracker.add(TYPE_MOBILE, mobileNai2)
+ verify(mMockService, never()).sendLegacyNetworkBroadcast(any(), any(), anyInt())
+ mTracker.remove(TYPE_MOBILE, mobileNai1, false /* wasDefault */)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, DISCONNECTED, TYPE_MOBILE)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai2, CONNECTED, TYPE_MOBILE)
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index d5b2c87ffe46..3a071667a542 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -21,11 +21,8 @@ import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -59,16 +56,11 @@ import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -98,48 +90,6 @@ public class IpConnectivityMetricsTest {
}
@Test
- public void testLoggingEvents() throws Exception {
- IpConnectivityLog logger = new IpConnectivityLog(mMockService);
-
- assertTrue(logger.log(1, FAKE_EV));
- assertTrue(logger.log(2, FAKE_EV));
- assertTrue(logger.log(3, FAKE_EV));
-
- List<ConnectivityMetricsEvent> got = verifyEvents(3);
- assertEventsEqual(expectedEvent(1), got.get(0));
- assertEventsEqual(expectedEvent(2), got.get(1));
- assertEventsEqual(expectedEvent(3), got.get(2));
- }
-
- @Test
- public void testLoggingEventsWithMultipleCallers() throws Exception {
- IpConnectivityLog logger = new IpConnectivityLog(mMockService);
-
- final int nCallers = 10;
- final int nEvents = 10;
- for (int n = 0; n < nCallers; n++) {
- final int i = n;
- new Thread() {
- public void run() {
- for (int j = 0; j < nEvents; j++) {
- assertTrue(logger.log(1 + i * 100 + j, FAKE_EV));
- }
- }
- }.start();
- }
-
- List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
- Collections.sort(got, EVENT_COMPARATOR);
- Iterator<ConnectivityMetricsEvent> iter = got.iterator();
- for (int i = 0; i < nCallers; i++) {
- for (int j = 0; j < nEvents; j++) {
- int expectedTimestamp = 1 + i * 100 + j;
- assertEventsEqual(expectedEvent(expectedTimestamp), iter.next());
- }
- }
- }
-
- @Test
public void testBufferFlushing() {
String output1 = getdump("flush");
assertEquals("", output1);
@@ -653,16 +603,7 @@ public class IpConnectivityMetricsTest {
return nai;
}
- List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
- ArgumentCaptor<ConnectivityMetricsEvent> captor =
- ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
- verify(mMockService, timeout(timeoutMs).times(n)).logEvent(captor.capture());
- return captor.getAllValues();
- }
- List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
- return verifyEvents(n, 10);
- }
static void verifySerialization(String want, String output) {
try {
@@ -674,28 +615,4 @@ public class IpConnectivityMetricsTest {
fail(e.toString());
}
}
-
- static String joinLines(String ... elems) {
- StringBuilder b = new StringBuilder();
- for (String s : elems) {
- b.append(s).append("\n");
- }
- return b.toString();
- }
-
- static ConnectivityMetricsEvent expectedEvent(int timestamp) {
- ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
- ev.timestamp = timestamp;
- ev.data = FAKE_EV;
- return ev;
- }
-
- /** Outer equality for ConnectivityMetricsEvent to avoid overriding equals() and hashCode(). */
- static void assertEventsEqual(ConnectivityMetricsEvent expected, ConnectivityMetricsEvent got) {
- assertEquals(expected.timestamp, got.timestamp);
- assertEquals(expected.data, got.data);
- }
-
- static final Comparator<ConnectivityMetricsEvent> EVENT_COMPARATOR =
- Comparator.comparingLong((ev) -> ev.timestamp);
}
diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
index fb84611cb662..a83faf34776d 100644
--- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
+++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.net.ipmemorystore;
+package com.android.server.connectivity.ipmemorystore;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/util/Android.bp b/tests/net/util/Android.bp
new file mode 100644
index 000000000000..d8c502d46871
--- /dev/null
+++ b/tests/net/util/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Common utilities for network tests.
+java_library {
+ name: "frameworks-net-testutils",
+ srcs: ["java/**/*.java"],
+ // test_current to be also appropriate for CTS tests
+ sdk_version: "test_current",
+ static_libs: [
+ "androidx.annotation_annotation",
+ "junit",
+ ],
+ libs: [
+ "android.test.base.stubs",
+ ],
+} \ No newline at end of file
diff --git a/tests/net/java/android/net/shared/ParcelableTestUtil.java b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
index 088ea3c1d1ed..87537b93887b 100644
--- a/tests/net/java/android/net/shared/ParcelableTestUtil.java
+++ b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.shared;
+package com.android.internal.util;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/java/com/android/internal/util/TestUtils.java b/tests/net/util/java/com/android/internal/util/TestUtils.java
index 57cc1723835c..a99cd4716f9a 100644
--- a/tests/net/java/com/android/internal/util/TestUtils.java
+++ b/tests/net/util/java/com/android/internal/util/TestUtils.java
@@ -19,7 +19,6 @@ package com.android.internal.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import android.annotation.NonNull;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -27,6 +26,8 @@ import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.NonNull;
+
import java.util.concurrent.Executor;
public final class TestUtils {
@@ -36,7 +37,7 @@ public final class TestUtils {
* Block until the given Handler thread becomes idle, or until timeoutMs has passed.
*/
public static void waitForIdleHandler(HandlerThread handlerThread, long timeoutMs) {
- waitForIdleHandler(handlerThread.getThreadHandler(), timeoutMs);
+ waitForIdleLooper(handlerThread.getLooper(), timeoutMs);
}
/**
@@ -68,9 +69,17 @@ public final class TestUtils {
}
}
- // TODO : fetch the creator through reflection or something instead of passing it
- public static <T extends Parcelable, C extends Parcelable.Creator<T>>
- void assertParcelingIsLossless(T source, C creator) {
+ /**
+ * Return a new instance of {@code T} after being parceled then unparceled.
+ */
+ public static <T extends Parcelable> T parcelingRoundTrip(T source) {
+ final Parcelable.Creator<T> creator;
+ try {
+ creator = (Parcelable.Creator<T>) source.getClass().getField("CREATOR").get(null);
+ } catch (IllegalAccessException | NoSuchFieldException e) {
+ fail("Missing CREATOR field: " + e.getMessage());
+ return null;
+ }
Parcel p = Parcel.obtain();
source.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
@@ -78,7 +87,14 @@ public final class TestUtils {
p = Parcel.obtain();
p.unmarshall(marshalled, 0, marshalled.length);
p.setDataPosition(0);
- T dest = creator.createFromParcel(p);
- assertEquals(source, dest);
+ return creator.createFromParcel(p);
+ }
+
+ /**
+ * Assert that after being parceled then unparceled, {@code source} is equal to the original
+ * object.
+ */
+ public static <T extends Parcelable> void assertParcelingIsLossless(T source) {
+ assertEquals(source, parcelingRoundTrip(source));
}
}
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 99420de47fca..609e3660375e 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -497,9 +497,9 @@ Maybe<int> ParseSdkVersion(const StringPiece& str) {
}
// Try parsing the code name.
- std::pair<StringPiece, int> entry = GetDevelopmentSdkCodeNameAndVersion();
- if (entry.first == trimmed_str) {
- return entry.second;
+ Maybe<int> entry = GetDevelopmentSdkCodeNameVersion(trimmed_str);
+ if (entry) {
+ return entry.value();
}
return {};
}
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 8ebde752bc4b..b4b6ff1daaaa 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -18,15 +18,17 @@
#include <algorithm>
#include <string>
-#include <unordered_map>
+#include <unordered_set>
#include <vector>
using android::StringPiece;
namespace aapt {
-static const char* sDevelopmentSdkCodeName = "P";
-static ApiVersion sDevelopmentSdkLevel = 28;
+static ApiVersion sDevelopmentSdkLevel = 10000;
+static const auto sDevelopmentSdkCodeNames = std::unordered_set<StringPiece>({
+ "Q", "R"
+});
static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
{0x021c, 1},
@@ -54,6 +56,7 @@ static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
{0x0530, SDK_NOUGAT_MR1},
{0x0568, SDK_O},
{0x056d, SDK_O_MR1},
+ {0x0586, SDK_P},
};
static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) {
@@ -71,8 +74,9 @@ ApiVersion FindAttributeSdkLevel(const ResourceId& id) {
return iter->second;
}
-std::pair<StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion() {
- return std::make_pair(StringPiece(sDevelopmentSdkCodeName), sDevelopmentSdkLevel);
+Maybe<ApiVersion> GetDevelopmentSdkCodeNameVersion(const StringPiece& code_name) {
+ return (sDevelopmentSdkCodeNames.find(code_name) == sDevelopmentSdkCodeNames.end())
+ ? Maybe<ApiVersion>() : sDevelopmentSdkLevel;
}
} // namespace aapt
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index 9fa29f25c29c..adb034a95328 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -57,7 +57,7 @@ enum : ApiVersion {
};
ApiVersion FindAttributeSdkLevel(const ResourceId& id);
-std::pair<android::StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion();
+Maybe<ApiVersion> GetDevelopmentSdkCodeNameVersion(const android::StringPiece& code_name);
} // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 4c23bd3d6e3e..2ef8b999a192 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -705,35 +705,24 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
}
TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
- static constexpr const char* xml = R"xml(
+ auto doc = test::BuildXmlDom(R"xml(
<android-sdk
- label="P"
+ label="Q"
minSdkVersion="25"
- targetSdkVersion="%s"
- maxSdkVersion="%s">
- </android-sdk>)xml";
-
- const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
- const char* codename = dev_sdk.first.data();
- const ApiVersion& version = dev_sdk.second;
-
- auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
+ targetSdkVersion="Q"
+ maxSdkVersion="Q">
+ </android-sdk>)xml");
PostProcessingConfiguration config;
- bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
- ASSERT_TRUE(ok);
-
+ ASSERT_TRUE(AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
ASSERT_EQ(1ul, config.android_sdks.size());
- ASSERT_EQ(1u, config.android_sdks.count("P"));
-
- auto& out = config.android_sdks["P"];
+ ASSERT_EQ(1u, config.android_sdks.count("Q"));
AndroidSdk sdk;
sdk.min_sdk_version = 25;
- sdk.target_sdk_version = version;
- sdk.max_sdk_version = version;
-
- ASSERT_EQ(sdk, out);
+ sdk.target_sdk_version = 10000;
+ sdk.max_sdk_version = 10000;
+ ASSERT_EQ(sdk, config.android_sdks["Q"]);
}
TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index c856cc36d6f6..e883c6bed755 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -29,6 +29,7 @@ FLAG_GREYLIST = "greylist"
FLAG_BLACKLIST = "blacklist"
FLAG_GREYLIST_MAX_O = "greylist-max-o"
FLAG_GREYLIST_MAX_P = "greylist-max-p"
+FLAG_GREYLIST_MAX_Q = "greylist-max-q"
FLAG_CORE_PLATFORM_API = "core-platform-api"
FLAG_PUBLIC_API = "public-api"
FLAG_SYSTEM_API = "system-api"
@@ -41,6 +42,7 @@ FLAGS_API_LIST = [
FLAG_BLACKLIST,
FLAG_GREYLIST_MAX_O,
FLAG_GREYLIST_MAX_P,
+ FLAG_GREYLIST_MAX_Q,
]
ALL_FLAGS = FLAGS_API_LIST + [
FLAG_CORE_PLATFORM_API,
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
index edb9a49f4106..828cce72dda9 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
@@ -13,6 +13,9 @@
*/
package lockedregioncodeinjection;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -24,8 +27,6 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
public class Main {
public static void main(String[] args) throws IOException {
@@ -74,6 +75,7 @@ public class Main {
while (srcEntries.hasMoreElements()) {
ZipEntry entry = srcEntries.nextElement();
ZipEntry newEntry = new ZipEntry(entry.getName());
+ newEntry.setTime(entry.getTime());
zos.putNextEntry(newEntry);
BufferedInputStream bis = new BufferedInputStream(zipSrc.getInputStream(entry));
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 49eee0708a45..dc18b8d14dc7 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -219,6 +219,14 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
errorCount++;
continue;
}
+
+ // Doubles are not supported yet.
+ if (javaType == JAVA_TYPE_DOUBLE) {
+ print_error(field, "Doubles are not supported in atoms. Please change field %s to float\n",
+ field->name().c_str());
+ errorCount++;
+ continue;
+ }
}
// Check that if there's an attribution chain, it's at position 1.
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index e0ea207793f9..8e4cb9f44029 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -48,6 +48,7 @@ typedef enum {
JAVA_TYPE_DOUBLE = 6,
JAVA_TYPE_STRING = 7,
JAVA_TYPE_ENUM = 8,
+ JAVA_TYPE_KEY_VALUE_PAIR = 9,
JAVA_TYPE_OBJECT = -1,
JAVA_TYPE_BYTE_ARRAY = -2,
@@ -118,4 +119,4 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, vector<java_type_t>
} // namespace android
-#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H \ No newline at end of file
+#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 2d9b9885c5ba..43b79cc4d784 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -27,6 +27,11 @@ int maxPushedAtomId = 2;
const string DEFAULT_MODULE_NAME = "DEFAULT";
const string DEFAULT_CPP_NAMESPACE = "android,util";
const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
+const string DEFAULT_JAVA_PACKAGE = "android.util";
+const string DEFAULT_JAVA_CLASS = "StatsLogInternal";
+
+const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
+const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
using android::os::statsd::Atom;
@@ -807,11 +812,350 @@ static void write_java_method(
}
}
+static void write_java_helpers_for_module(
+ FILE * out,
+ const AtomDecl &attributionDecl,
+ const int requiredHelpers) {
+ fprintf(out, " private static void copyInt(byte[] buff, int pos, int val) {\n");
+ fprintf(out, " buff[pos] = (byte) (val);\n");
+ fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n");
+ fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n");
+ fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+
+ fprintf(out, " private static void copyLong(byte[] buff, int pos, long val) {\n");
+ fprintf(out, " buff[pos] = (byte) (val);\n");
+ fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n");
+ fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n");
+ fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n");
+ fprintf(out, " buff[pos + 4] = (byte) (val >> 32);\n");
+ fprintf(out, " buff[pos + 5] = (byte) (val >> 40);\n");
+ fprintf(out, " buff[pos + 6] = (byte) (val >> 48);\n");
+ fprintf(out, " buff[pos + 7] = (byte) (val >> 56);\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+
+ if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) {
+ fprintf(out, " private static void copyFloat(byte[] buff, int pos, float val) {\n");
+ fprintf(out, " copyInt(buff, pos, Float.floatToIntBits(val));\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+
+ if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
+ fprintf(out, " private static void writeAttributionChain(byte[] buff, int pos");
+ for (auto chainField : attributionDecl.fields) {
+ fprintf(out, ", %s[] %s",
+ java_type_name(chainField.javaType), chainField.name.c_str());
+ }
+ fprintf(out, ") {\n");
+
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+
+ // Write the first list begin.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = (byte) (%s.length);\n", tagName);
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Iterate through the attribution chain and write the nodes.
+ fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName);
+ // Write the list begin.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = %lu;\n", attributionDecl.fields.size());
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Write the uid.
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, %s[i]);\n", uidName);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+
+ // Write the tag.
+ fprintf(out, " String %sStr = (%s[i] == null) ? \"\" : %s[i];\n",
+ tagName, tagName, tagName);
+ fprintf(out, " byte[] %sByte = %sStr.getBytes(UTF_8);\n", tagName, tagName);
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, %sByte.length);\n", tagName);
+ fprintf(out, " System.arraycopy("
+ "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n",
+ tagName, tagName);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", tagName);
+ fprintf(out, " }\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+}
+
+
+static int write_java_non_chained_method_for_module(
+ FILE* out,
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const string& moduleName
+ ) {
+ for (auto signature_to_modules_it = signatures_to_modules.begin();
+ signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+
+ // Print method signature.
+ vector<java_type_t> signature = signature_to_modules_it->first;
+ fprintf(out, " public static void write_non_chained(int code");
+ int argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ // Non chained signatures should not have attribution chains.
+ return 1;
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ // Module logging does not yet support key value pair.
+ return 1;
+ } else {
+ fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ") {\n");
+
+ fprintf(out, " write(code");
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ // First two args are uid and tag of attribution chain.
+ if (argIndex == 1) {
+ fprintf(out, ", new int[] {arg%d}", argIndex);
+ } else if (argIndex == 2) {
+ fprintf(out, ", new java.lang.String[] {arg%d}", argIndex);
+ } else {
+ fprintf(out, ", arg%d", argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ");\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+ return 0;
+}
+
+static int write_java_method_for_module(
+ FILE* out,
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const AtomDecl &attributionDecl,
+ const string& moduleName,
+ int* requiredHelpers
+ ) {
+
+ for (auto signature_to_modules_it = signatures_to_modules.begin();
+ signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+
+ // Print method signature.
+ vector<java_type_t> signature = signature_to_modules_it->first;
+ fprintf(out, " public static void write(int code");
+ int argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ for (auto chainField : attributionDecl.fields) {
+ fprintf(out, ", %s[] %s",
+ java_type_name(chainField.javaType), chainField.name.c_str());
+ }
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ // Module logging does not yet support key value pair.
+ return 1;
+ } else {
+ fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ") {\n");
+
+ // Calculate the size of the buffer.
+ fprintf(out, " // Initial overhead of the list, timestamp, and atom tag.\n");
+ fprintf(out, " int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n");
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_BOOLEAN:
+ case JAVA_TYPE_INT:
+ case JAVA_TYPE_FLOAT:
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " needed += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_LONG:
+ // Longs take 9 bytes, 1 for the type and 8 for the value.
+ fprintf(out, " needed += LONG_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_STRING:
+ // Strings take 5 metadata bytes + length of byte encoded string.
+ fprintf(out, " if (arg%d == null) {\n", argIndex);
+ fprintf(out, " arg%d = \"\";\n", argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " byte[] arg%dBytes= arg%d.getBytes(UTF_8);\n",
+ argIndex, argIndex);
+ fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+ argIndex);
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ // Byte arrays take 5 metadata bytes + length of byte array.
+ fprintf(out, " if (arg%d == null) {\n", argIndex);
+ fprintf(out, " arg%d = new byte[0];\n", argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+ break;
+ case JAVA_TYPE_ATTRIBUTION_CHAIN:
+ {
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ // Null checks on the params.
+ fprintf(out, " if (%s == null) {\n", uidName);
+ fprintf(out, " %s = new %s[0];\n", uidName,
+ java_type_name(attributionDecl.fields.front().javaType));
+ fprintf(out, " }\n");
+ fprintf(out, " if (%s == null) {\n", tagName);
+ fprintf(out, " %s = new %s[0];\n", tagName,
+ java_type_name(attributionDecl.fields.back().javaType));
+ fprintf(out, " }\n");
+
+ // First check that the lengths of the uid and tag arrays are the same.
+ fprintf(out, " if (%s.length != %s.length) {\n", uidName, tagName);
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, " int attrSize = LIST_TYPE_OVERHEAD;\n");
+ fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName);
+ fprintf(out, " String str%d = (%s[i] == null) ? \"\" : %s[i];\n",
+ argIndex, tagName, tagName);
+ fprintf(out, " int str%dlen = str%d.getBytes(UTF_8).length;\n",
+ argIndex, argIndex);
+ fprintf(out,
+ " attrSize += "
+ "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n",
+ argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " needed += attrSize;\n");
+ break;
+ }
+ default:
+ // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+ return 1;
+ }
+ argIndex++;
+ }
+
+ // Now we have the size that is needed. Check for overflow and return if needed.
+ fprintf(out, " if (needed > MAX_EVENT_PAYLOAD) {\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+
+ // Create new buffer, and associated data types.
+ fprintf(out, " byte[] buff = new byte[needed];\n");
+ fprintf(out, " int pos = 0;\n");
+
+ // Initialize the buffer with list data type.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = %lu;\n", signature.size() + 2);
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Write timestamp.
+ fprintf(out, " long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n");
+ fprintf(out, " buff[pos] = LONG_TYPE;\n");
+ fprintf(out, " copyLong(buff, pos + 1, elapsedRealtime);\n");
+ fprintf(out, " pos += LONG_TYPE_SIZE;\n");
+
+ // Write atom code.
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, code);\n");
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+
+ // Write the args.
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_BOOLEAN:
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d? 1 : 0);\n", argIndex);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_INT:
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_FLOAT:
+ *requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
+ fprintf(out, " buff[pos] = FLOAT_TYPE;\n");
+ fprintf(out, " copyFloat(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += FLOAT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_LONG:
+ fprintf(out, " buff[pos] = LONG_TYPE;\n");
+ fprintf(out, " copyLong(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += LONG_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_STRING:
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%dBytes.length);\n", argIndex);
+ fprintf(out, " System.arraycopy("
+ "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n",
+ argIndex, argIndex);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+ argIndex);
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d.length);\n", argIndex);
+ fprintf(out, " System.arraycopy("
+ "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n",
+ argIndex, argIndex);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+ break;
+ case JAVA_TYPE_ATTRIBUTION_CHAIN:
+ {
+ *requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION;
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+
+ fprintf(out, " writeAttributionChain(buff, pos, %s, %s);\n",
+ uidName, tagName);
+ fprintf(out, " pos += attrSize;\n");
+ break;
+ }
+ default:
+ // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+ return 1;
+ }
+ argIndex++;
+ }
+
+ fprintf(out, " StatsLog.writeRaw(buff, pos);\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+ return 0;
+}
+
static void write_java_work_source_method(FILE* out,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules) {
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const string& moduleName) {
fprintf(out, "\n // WorkSource methods.\n");
for (auto signature_to_modules_it = signatures_to_modules.begin();
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
vector<java_type_t> signature = signature_to_modules_it->first;
// Determine if there is Attribution in this signature.
int attributionArg = -1;
@@ -834,7 +1178,9 @@ static void write_java_work_source_method(FILE* out,
}
// Method header (signature)
- fprintf(out, " /** @hide */\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " /** @hide */\n");
+ }
fprintf(out, " public static void write(int code");
int argIndex = 1;
for (vector<java_type_t>::const_iterator arg = signature.begin();
@@ -859,7 +1205,7 @@ static void write_java_work_source_method(FILE* out,
}
}
fprintf(out, ");\n");
- fprintf(out, " }\n"); // close flor-loop
+ fprintf(out, " }\n"); // close for-loop
// write() component.
fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
@@ -880,23 +1226,7 @@ static void write_java_work_source_method(FILE* out,
}
}
-static int
-write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
-{
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package android.util;\n");
- fprintf(out, "\n");
- fprintf(out, "import android.os.WorkSource;\n");
- fprintf(out, "import java.util.ArrayList;\n");
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " * @hide\n");
- fprintf(out, " */\n");
- fprintf(out, "public class StatsLogInternal {\n");
+static void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) {
fprintf(out, " // Constants for atom codes.\n");
std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map;
@@ -905,6 +1235,10 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD
// Print constants for the atom codes.
for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
atom != atoms.decls.end(); atom++) {
+ // Skip if the atom is not needed for the module.
+ if (!atom_needed_for_module(*atom, moduleName)) {
+ continue;
+ }
string constant = make_constant_name(atom->name);
fprintf(out, "\n");
fprintf(out, " /**\n");
@@ -914,16 +1248,23 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD
if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second);
}
- fprintf(out, " * @hide\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " * @hide\n");
+ }
fprintf(out, " */\n");
fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code);
}
fprintf(out, "\n");
+}
- // Print constants for the enum values.
+static void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) {
fprintf(out, " // Constants for enum values.\n\n");
for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
atom != atoms.decls.end(); atom++) {
+ // Skip if the atom is not needed for the module.
+ if (!atom_needed_for_module(*atom, moduleName)) {
+ continue;
+ }
for (vector<AtomField>::const_iterator field = atom->fields.begin();
field != atom->fields.end(); field++) {
if (field->javaType == JAVA_TYPE_ENUM) {
@@ -931,7 +1272,9 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD
field->name.c_str());
for (map<int, string>::const_iterator value = field->enumValues.begin();
value != field->enumValues.end(); value++) {
- fprintf(out, " /** @hide */\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " /** @hide */\n");
+ }
fprintf(out, " public static final int %s__%s__%s = %d;\n",
make_constant_name(atom->message).c_str(),
make_constant_name(field->name).c_str(),
@@ -942,19 +1285,107 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD
}
}
}
+}
+
+static int
+write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
+{
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+ fprintf(out, "package android.util;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import android.os.WorkSource;\n");
+ fprintf(out, "import android.util.SparseArray;\n");
+ fprintf(out, "import java.util.ArrayList;\n");
+ fprintf(out, "\n");
+ fprintf(out, "\n");
+ fprintf(out, "/**\n");
+ fprintf(out, " * API For logging statistics events.\n");
+ fprintf(out, " * @hide\n");
+ fprintf(out, " */\n");
+ fprintf(out, "public class StatsLogInternal {\n");
+ write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME);
+
+ write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME);
// Print write methods
fprintf(out, " // Write methods\n");
write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
attributionDecl);
- write_java_work_source_method(out, atoms.signatures_to_modules);
+ write_java_work_source_method(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
fprintf(out, "}\n");
return 0;
}
+// TODO: Merge this with write_stats_log_java so that we can get rid of StatsLogInternal JNI.
+static int
+write_stats_log_java_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& javaClass, const string& javaPackage)
+{
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+ fprintf(out, "package %s;\n", javaPackage.c_str());
+ fprintf(out, "\n");
+ fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import android.util.StatsLog;\n");
+ fprintf(out, "import android.os.SystemClock;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import java.util.ArrayList;\n");
+ fprintf(out, "\n");
+ fprintf(out, "\n");
+ fprintf(out, "/**\n");
+ fprintf(out, " * Utility class for logging statistics events.\n");
+ fprintf(out, " */\n");
+ fprintf(out, "public class %s {\n", javaClass.c_str());
+
+ // TODO: ideally these match with the native values (and automatically change if they change).
+ fprintf(out, " private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n");
+ fprintf(out,
+ " private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n");
+ // Value types. Must match with EventLog.java and log.h.
+ fprintf(out, " private static final byte INT_TYPE = 0;\n");
+ fprintf(out, " private static final byte LONG_TYPE = 1;\n");
+ fprintf(out, " private static final byte STRING_TYPE = 2;\n");
+ fprintf(out, " private static final byte LIST_TYPE = 3;\n");
+ fprintf(out, " private static final byte FLOAT_TYPE = 4;\n");
+
+ // Size of each value type.
+ // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value.
+ fprintf(out, " private static final int INT_TYPE_SIZE = 5;\n");
+ fprintf(out, " private static final int FLOAT_TYPE_SIZE = 5;\n");
+ // Longs take 9 bytes, 1 for the type and 8 for the value.
+ fprintf(out, " private static final int LONG_TYPE_SIZE = 9;\n");
+ // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length.
+ fprintf(out, " private static final int STRING_TYPE_OVERHEAD = 5;\n");
+ fprintf(out, " private static final int LIST_TYPE_OVERHEAD = 2;\n");
+
+ write_java_atom_codes(out, atoms, moduleName);
+
+ write_java_enum_values(out, atoms, moduleName);
+
+ int errors = 0;
+ int requiredHelpers = 0;
+ // Print write methods
+ fprintf(out, " // Write methods\n");
+ errors += write_java_method_for_module(out, atoms.signatures_to_modules, attributionDecl,
+ moduleName, &requiredHelpers);
+ errors += write_java_non_chained_method_for_module(out, atoms.non_chained_signatures_to_modules,
+ moduleName);
+
+ fprintf(out, " // Helper methods for copying primitives\n");
+ write_java_helpers_for_module(out, attributionDecl, requiredHelpers);
+
+ fprintf(out, "}\n");
+
+ return errors;
+}
+
static const char*
jni_type_name(java_type_t type)
{
@@ -1346,7 +1777,11 @@ print_usage()
fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n");
fprintf(stderr, " comma separated namespace of the files\n");
fprintf(stderr, " --importHeader NAME required for cpp/jni to say which header to import\n");
-}
+ fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n");
+ fprintf(stderr, " required for java with module\n");
+ fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
+ fprintf(stderr, " Optional for Java with module.\n");
+ fprintf(stderr, " Default is \"StatsLogInternal\"\n");}
/**
* Do the argument parsing and execute the tasks.
@@ -1362,6 +1797,8 @@ run(int argc, char const*const* argv)
string moduleName = DEFAULT_MODULE_NAME;
string cppNamespace = DEFAULT_CPP_NAMESPACE;
string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
+ string javaPackage = DEFAULT_JAVA_PACKAGE;
+ string javaClass = DEFAULT_JAVA_CLASS;
int index = 1;
while (index < argc) {
@@ -1417,6 +1854,20 @@ run(int argc, char const*const* argv)
return 1;
}
cppHeaderImport = argv[index];
+ } else if (0 == strcmp("--javaPackage", argv[index])) {
+ index++;
+ if (index >= argc) {
+ print_usage();
+ return 1;
+ }
+ javaPackage = argv[index];
+ } else if (0 == strcmp("--javaClass", argv[index])) {
+ index++;
+ if (index >= argc) {
+ print_usage();
+ return 1;
+ }
+ javaClass = argv[index];
}
index++;
}
@@ -1486,8 +1937,18 @@ run(int argc, char const*const* argv)
fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
return 1;
}
- errorCount = android::stats_log_api_gen::write_stats_log_java(
- out, atoms, attributionDecl);
+ // If this is for a specific module, the java package must also be provided.
+ if (moduleName != DEFAULT_MODULE_NAME && javaPackage== DEFAULT_JAVA_PACKAGE) {
+ fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n");
+ return 1;
+ }
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ errorCount = android::stats_log_api_gen::write_stats_log_java(
+ out, atoms, attributionDecl);
+ } else {
+ errorCount = android::stats_log_api_gen::write_stats_log_java_for_module(
+ out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+ }
fclose(out);
}
@@ -1503,7 +1964,7 @@ run(int argc, char const*const* argv)
fclose(out);
}
- return 0;
+ return errorCount;
}
}
diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh
index 4e52b8f23399..9eb9a92bd53f 100755
--- a/wifi/tests/runtests.sh
+++ b/wifi/tests/runtests.sh
@@ -19,7 +19,8 @@ set -x # print commands
adb root
adb wait-for-device
-adb install -r -g "$OUT/data/app/FrameworksWifiApiTests/FrameworksWifiApiTests.apk"
+TARGET_ARCH=$($ANDROID_BUILD_TOP/build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH)
+adb install -r -g "$OUT/testcases/FrameworksWifiApiTests/$TARGET_ARCH/FrameworksWifiApiTests.apk"
adb shell am instrument --no-hidden-api-checks -w "$@" \
'android.net.wifi.test/android.support.test.runner.AndroidJUnitRunner'