summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp85
-rw-r--r--Android.mk2
-rw-r--r--ApiDocs.bp6
-rw-r--r--METADATA3
-rw-r--r--StubLibraries.bp22
-rw-r--r--apex/Android.bp62
-rw-r--r--apex/sdkextensions/Android.bp84
-rw-r--r--apex/sdkextensions/OWNERS2
-rw-r--r--apex/sdkextensions/TEST_MAPPING10
-rw-r--r--apex/sdkextensions/com.android.sdkext.avbpubkeybin1032 -> 0 bytes
-rw-r--r--apex/sdkextensions/com.android.sdkext.pem51
-rw-r--r--apex/sdkextensions/com.android.sdkext.pk8bin2375 -> 0 bytes
-rw-r--r--apex/sdkextensions/com.android.sdkext.x509.pem35
-rw-r--r--apex/sdkextensions/derive_sdk/Android.bp55
-rw-r--r--apex/sdkextensions/derive_sdk/derive_sdk.cpp79
-rw-r--r--apex/sdkextensions/derive_sdk/derive_sdk.rc5
-rw-r--r--apex/sdkextensions/derive_sdk/sdk.proto25
-rw-r--r--apex/sdkextensions/framework/Android.bp114
-rw-r--r--apex/sdkextensions/framework/api/current.txt1
-rw-r--r--apex/sdkextensions/framework/api/module-lib-current.txt1
-rw-r--r--apex/sdkextensions/framework/api/module-lib-removed.txt1
-rw-r--r--apex/sdkextensions/framework/api/removed.txt1
-rw-r--r--apex/sdkextensions/framework/api/system-current.txt9
-rw-r--r--apex/sdkextensions/framework/api/system-removed.txt1
-rw-r--r--apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java72
-rw-r--r--apex/sdkextensions/framework/java/android/os/ext/package.html5
-rw-r--r--apex/sdkextensions/gen_sdkinfo.py19
-rw-r--r--apex/sdkextensions/manifest.json4
-rw-r--r--apex/sdkextensions/sdk.proto25
-rw-r--r--apex/sdkextensions/testing/Android.bp46
-rw-r--r--apex/sdkextensions/testing/test_manifest.json4
-rw-r--r--api/current.txt16
-rwxr-xr-xapi/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--cmds/bootanimation/bootanim.rc2
-rw-r--r--cmds/device_config/Android.bp7
-rw-r--r--cmds/device_config/Android.mk10
-rw-r--r--cmds/statsd/Android.bp2
-rw-r--r--cmds/statsd/src/atoms.proto14
-rw-r--r--config/OWNERS4
-rw-r--r--core/java/android/annotation/CallbackExecutor.java10
-rw-r--r--core/java/android/annotation/OWNERS2
-rw-r--r--core/java/android/annotation/RequiresPermission.java9
-rw-r--r--core/java/android/app/Activity.java1
-rw-r--r--core/java/android/app/ActivityManager.java3
-rw-r--r--core/java/android/app/AlarmManager.java8
-rw-r--r--core/java/android/app/IActivityManager.aidl3
-rw-r--r--core/java/android/app/Instrumentation.java2
-rw-r--r--core/java/android/app/Notification.java6
-rw-r--r--core/java/android/app/NotificationManager.java2
-rw-r--r--core/java/android/app/backup/BackupManager.java2
-rw-r--r--core/java/android/app/job/JobScheduler.java4
-rw-r--r--core/java/android/app/role/RoleManager.java2
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeScanner.java15
-rw-r--r--core/java/android/content/Context.java1
-rw-r--r--core/java/android/hardware/hdmi/HdmiControlManager.java7
-rw-r--r--core/java/android/net/ConnectivityDiagnosticsManager.java6
-rw-r--r--core/java/android/net/ConnectivityManager.java25
-rw-r--r--core/java/android/net/IConnectivityManager.aidl5
-rw-r--r--core/java/android/net/Ikev2VpnProfile.java125
-rw-r--r--core/java/android/net/MatchAllNetworkSpecifier.java3
-rw-r--r--core/java/android/net/NetworkCapabilities.java29
-rw-r--r--core/java/android/net/NetworkScoreManager.java3
-rw-r--r--core/java/android/net/VpnService.java2
-rwxr-xr-xcore/java/android/os/Build.java6
-rw-r--r--core/java/android/os/Parcelable.java16
-rw-r--r--core/java/android/os/Registrant.java5
-rw-r--r--core/java/android/os/RegistrantList.java16
-rw-r--r--core/java/android/os/StrictMode.java1
-rw-r--r--core/java/android/os/UpdateEngine.java3
-rw-r--r--core/java/android/os/VibrationEffect.java6
-rw-r--r--core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java1
-rw-r--r--core/java/android/provider/CalendarContract.java3
-rw-r--r--core/java/android/provider/DeviceConfig.java8
-rw-r--r--core/java/android/provider/DocumentsContract.java25
-rw-r--r--core/java/android/provider/Settings.java11
-rw-r--r--core/java/android/service/autofill/CustomDescription.java2
-rw-r--r--core/java/android/service/autofill/ImageTransformation.java2
-rw-r--r--core/java/android/service/autofill/SaveInfo.java4
-rw-r--r--core/java/android/telephony/PhoneStateListener.java9
-rw-r--r--core/java/android/text/format/Time.java20
-rw-r--r--core/java/android/view/Surface.java4
-rw-r--r--core/java/android/view/SurfaceControl.java2
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/WindowManager.java1
-rw-r--r--core/java/android/view/inspector/StaticInspectionCompanionProvider.java2
-rw-r--r--core/java/android/widget/ProgressBar.java15
-rw-r--r--core/java/com/android/internal/accessibility/OWNERS4
-rw-r--r--core/java/com/android/internal/app/SystemUserHomeActivity.java17
-rw-r--r--core/java/com/android/internal/compat/OWNERS1
-rw-r--r--core/java/com/android/internal/net/VpnProfile.java32
-rw-r--r--core/java/com/android/internal/os/RoSystemProperties.java12
-rw-r--r--core/jni/AndroidRuntime.cpp11
-rw-r--r--core/jni/android/graphics/pdf/PdfEditor.cpp2
-rw-r--r--core/jni/android_os_Parcel.cpp6
-rw-r--r--core/jni/android_os_SharedMemory.cpp6
-rw-r--r--core/jni/fd_utils.cpp16
-rw-r--r--core/proto/android/providers/settings/global.proto9
-rw-r--r--core/res/res/layout/system_user_home.xml (renamed from packages/Shell/res/layout/null_home_finishing_boot.xml)4
-rw-r--r--core/res/res/values-mcc334-mnc020/config.xml5
-rw-r--r--core/res/res/values-mcc334-mnc020/strings.xml25
-rw-r--r--core/res/res/values/attrs.xml2
-rw-r--r--core/res/res/values/config.xml16
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--core/res/res/values/symbols.xml10
-rw-r--r--core/res/res/xml/sms_short_codes.xml4
-rw-r--r--core/tests/PlatformCompatFramework/OWNERS1
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/hdmitests/Android.bp27
-rw-r--r--core/tests/hdmitests/Android.mk31
-rw-r--r--core/tests/packagemanagertests/Android.bp14
-rw-r--r--core/tests/packagemanagertests/Android.mk22
-rw-r--r--core/tests/privacytests/Android.bp14
-rw-r--r--core/tests/privacytests/Android.mk20
-rw-r--r--core/xsd/vts/Android.bp4
-rw-r--r--core/xsd/vts/Android.mk22
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--data/fonts/Android.bp36
-rw-r--r--data/fonts/Android.mk57
-rw-r--r--data/keyboards/Vendor_0f0d_Product_00c1.kl55
-rw-r--r--graphics/java/android/graphics/RenderNode.java2
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java2
-rw-r--r--graphics/java/android/graphics/fonts/FontStyle.java2
-rw-r--r--graphics/java/android/graphics/text/LineBreaker.java4
-rw-r--r--identity/java/android/security/identity/AccessControlProfileId.java2
-rw-r--r--identity/java/android/security/identity/IdentityCredentialStore.java2
-rw-r--r--keystore/java/android/security/KeyStore.java11
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java28
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java48
-rw-r--r--keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java5
-rw-r--r--lowpan/tests/Android.bp41
-rw-r--r--lowpan/tests/Android.mk63
-rw-r--r--media/Android.bp5
-rw-r--r--media/java/android/media/AudioFocusRequest.java4
-rw-r--r--media/java/android/media/AudioTrack.java2
-rw-r--r--native/android/Android.bp2
-rw-r--r--packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java11
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/Shell/AndroidManifest.xml22
-rw-r--r--packages/Shell/src/com/android/shell/NullHome.java43
-rw-r--r--packages/SystemUI/OWNERS2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java18
-rw-r--r--packages/Tethering/Android.bp10
-rw-r--r--packages/Tethering/apex/Android.bp11
-rw-r--r--packages/Tethering/common/TetheringLib/Android.bp40
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values/config.xml13
-rw-r--r--packages/Tethering/res/values/overlayable.xml6
-rw-r--r--packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java12
-rw-r--r--packages/Tethering/src/android/net/ip/IpServer.java277
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java177
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java19
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java92
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java125
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/Tethering.java65
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java69
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java20
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java271
-rw-r--r--packages/Tethering/tests/integration/Android.bp1
-rw-r--r--packages/Tethering/tests/unit/Android.bp2
-rw-r--r--packages/Tethering/tests/unit/AndroidManifest.xml3
-rw-r--r--packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java211
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java138
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java4
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java16
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java118
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java215
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java90
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java365
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java182
-rw-r--r--services/Android.bp4
-rw-r--r--services/core/Android.bp6
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java114
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java61
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java23
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java2
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java26
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java7
-rw-r--r--services/core/java/com/android/server/compat/OWNERS1
-rw-r--r--services/core/java/com/android/server/connectivity/Nat464Xlat.java17
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java7
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java63
-rw-r--r--services/core/java/com/android/server/connectivity/VpnIkev2Utils.java92
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java43
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java12
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java6
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java4
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsFactory.java5
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java150
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java49
-rw-r--r--services/core/java/com/android/server/pm/OWNERS2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java44
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java28
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java48
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotPersister.java32
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java15
-rw-r--r--services/core/jni/com_android_server_AlarmManagerService.cpp19
-rw-r--r--services/core/jni/com_android_server_SerialService.cpp1
-rw-r--r--services/core/jni/com_android_server_UsbDeviceManager.cpp29
-rw-r--r--services/core/jni/com_android_server_UsbHostManager.cpp1
-rw-r--r--services/core/jni/com_android_server_UsbMidiDevice.cpp46
-rw-r--r--services/java/com/android/server/SystemServer.java13
-rw-r--r--services/net/Android.bp6
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java24
-rw-r--r--telecomm/java/android/telecom/Conference.java20
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java5
-rw-r--r--telecomm/java/android/telecom/GatewayInfo.java4
-rw-r--r--telecomm/java/android/telecom/ParcelableCall.java4
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java2
-rw-r--r--telephony/api/system-current.txt2140
-rw-r--r--telephony/common/com/android/internal/telephony/CellBroadcastUtils.java65
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java169
-rw-r--r--telephony/java/android/telephony/CellIdentity.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityCdma.java1
-rw-r--r--telephony/java/android/telephony/CellIdentityGsm.java1
-rw-r--r--telephony/java/android/telephony/CellIdentityLte.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityNr.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityTdscdma.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityWcdma.java2
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthNr.java4
-rw-r--r--telephony/java/android/telephony/DisconnectCause.java5
-rw-r--r--telephony/java/android/telephony/MbmsDownloadSession.java66
-rw-r--r--telephony/java/android/telephony/PinResult.java6
-rw-r--r--telephony/java/android/telephony/ServiceState.java5
-rw-r--r--telephony/java/android/telephony/SignalStrength.java12
-rw-r--r--telephony/java/android/telephony/TelephonyDisplayInfo.java13
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java25
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java68
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java14
-rw-r--r--telephony/java/android/telephony/ims/ImsRcsManager.java24
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java2
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java87
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java3
-rw-r--r--telephony/java/android/telephony/mbms/MbmsErrors.java41
-rwxr-xr-xtelephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl2
-rw-r--r--telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java22
-rw-r--r--telephony/java/com/android/internal/telephony/DctConstants.java9
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl5
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneConstants.java1
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java2
-rw-r--r--test-base/api/lint-baseline.txt3
-rw-r--r--test-mock/api/lint-baseline.txt143
-rw-r--r--test-mock/api/system-lint-baseline.txt15
-rw-r--r--test-runner/api/lint-baseline.txt173
-rw-r--r--tests/GamePerformance/Android.bp32
-rw-r--r--tests/GamePerformance/Android.mk39
-rw-r--r--tests/NullHomeTest/Android.bp22
-rw-r--r--tests/NullHomeTest/AndroidManifest.xml31
-rw-r--r--tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java72
-rw-r--r--tests/ProtoInputStreamTests/Android.bp33
-rw-r--r--tests/ProtoInputStreamTests/Android.mk34
-rw-r--r--tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt4
-rw-r--r--tests/net/integration/AndroidManifest.xml45
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt65
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt13
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt3
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt12
-rw-r--r--tests/net/integration/util/com/android/server/NetworkAgentWrapper.java3
-rw-r--r--tests/net/java/android/net/Ikev2VpnProfileTest.java76
-rw-r--r--tests/net/java/com/android/internal/net/VpnProfileTest.java47
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java193
-rw-r--r--tests/net/java/com/android/server/LegacyTypeTrackerTest.kt5
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java3
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java7
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsBaseTest.java9
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java58
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java36
-rw-r--r--tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn9
-rw-r--r--tests/testables/src/android/testing/TestableLooper.java4
-rw-r--r--tools/aapt2/cmd/Link.cpp13
-rw-r--r--tools/aapt2/cmd/Link.h7
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp22
-rw-r--r--tools/aapt2/link/ManifestFixer.h4
-rw-r--r--tools/aapt2/link/ManifestFixer_test.cpp26
-rw-r--r--tools/bit/adb.cpp2
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists.py8
-rw-r--r--tools/incident_section_gen/main.cpp7
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java2
-rw-r--r--wifi/java/android/net/wifi/WpsInfo.java2
296 files changed, 5271 insertions, 4710 deletions
diff --git a/Android.bp b/Android.bp
index 1aaa6044111a..baa715e3bcac 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,22 +35,96 @@ filegroup {
}
// These are subset of framework-core-sources that are needed by the
-// android.test.mock library. Ideally, the library should use public APIs only,
-// but unfortunately its API signature has some references to these private APIs.
+// android.test.mock library. The implementation of android.test.mock references
+// private members of various components to allow mocking of classes that cannot
+// be mocked without access to those internal implementation details.
filegroup {
name: "framework-core-sources-for-test-mock",
srcs: [
+ "core/java/android/accounts/AccountManagerCallback.java",
+ "core/java/android/accounts/AccountManagerFuture.java",
+ "core/java/android/accounts/AccountManager.java",
+ "core/java/android/accounts/AccountsException.java",
+ "core/java/android/accounts/AuthenticatorException.java",
+ "core/java/android/accounts/OperationCanceledException.java",
+ "core/java/android/annotation/AnimatorRes.java",
+ "core/java/android/annotation/AnimRes.java",
+ "core/java/android/annotation/AnyRes.java",
+ "core/java/android/annotation/ArrayRes.java",
+ "core/java/android/annotation/AttrRes.java",
+ "core/java/android/annotation/BoolRes.java",
+ "core/java/android/annotation/BroadcastBehavior.java",
+ "core/java/android/annotation/CallbackExecutor.java",
+ "core/java/android/annotation/CallSuper.java",
+ "core/java/android/annotation/CheckResult.java",
+ "core/java/android/annotation/ColorInt.java",
+ "core/java/android/annotation/ColorRes.java",
+ "core/java/android/annotation/DimenRes.java",
+ "core/java/android/annotation/DrawableRes.java",
+ "core/java/android/annotation/FontRes.java",
+ "core/java/android/annotation/FractionRes.java",
+ "core/java/android/annotation/IntDef.java",
+ "core/java/android/annotation/IntegerRes.java",
+ "core/java/android/annotation/IntRange.java",
+ "core/java/android/annotation/LayoutRes.java",
+ "core/java/android/annotation/NonNull.java",
+ "core/java/android/annotation/Nullable.java",
+ "core/java/android/annotation/PluralsRes.java",
+ "core/java/android/annotation/RawRes.java",
+ "core/java/android/annotation/RequiresPermission.java",
+ "core/java/android/annotation/SdkConstant.java",
+ "core/java/android/annotation/Size.java",
+ "core/java/android/annotation/StringDef.java",
+ "core/java/android/annotation/StringRes.java",
+ "core/java/android/annotation/StyleableRes.java",
+ "core/java/android/annotation/StyleRes.java",
+ "core/java/android/annotation/SuppressLint.java",
+ "core/java/android/annotation/SystemApi.java",
+ "core/java/android/annotation/SystemService.java",
+ "core/java/android/annotation/TestApi.java",
+ "core/java/android/annotation/UserIdInt.java",
+ "core/java/android/annotation/XmlRes.java",
+ "core/java/android/app/Application.java",
"core/java/android/app/IApplicationThread.aidl",
"core/java/android/app/IServiceConnection.aidl",
+ "core/java/android/app/PackageDeleteObserver.java",
+ "core/java/android/content/ComponentCallbacks2.java",
+ "core/java/android/content/ComponentCallbacks.java",
+ "core/java/android/content/ContentInterface.java",
+ "core/java/android/content/ContentProvider.java",
+ "core/java/android/content/ContentProviderNative.java",
+ "core/java/android/content/ContentResolver.java",
+ "core/java/android/content/Context.java",
+ "core/java/android/content/ContextWrapper.java",
+ "core/java/android/content/DialogInterface.java",
"core/java/android/content/IContentProvider.java",
- "core/java/android/content/pm/IPackageDataObserver.aidl",
+ "core/java/android/content/Intent.java",
+ "core/java/android/content/IntentSender.java",
+ "core/java/android/content/OperationApplicationException.java",
+ "core/java/android/content/pm/ActivityInfo.java",
+ "core/java/android/content/pm/ApplicationInfo.java",
"core/java/android/content/pm/InstantAppInfo.java",
+ "core/java/android/content/pm/IPackageDataObserver.aidl",
"core/java/android/content/pm/KeySet.java",
"core/java/android/content/pm/PackageManager.java",
"core/java/android/content/pm/VerifierDeviceIdentity.java",
"core/java/android/content/res/Resources.java",
+ "core/java/android/database/CrossProcessCursor.java",
+ "core/java/android/database/CrossProcessCursorWrapper.java",
+ "core/java/android/database/Cursor.java",
+ "core/java/android/database/CursorWrapper.java",
+ "core/java/android/os/Binder.java",
+ "core/java/android/os/Bundle.java",
+ "core/java/android/os/IBinder.java",
+ "core/java/android/os/IInterface.java",
+ "core/java/android/os/Parcelable.java",
+ "core/java/android/os/ParcelFileDescriptor.java",
+ "core/java/android/os/RemoteException.java",
"core/java/android/os/storage/VolumeInfo.java",
+ "core/java/android/util/AndroidException.java",
"core/java/android/view/DisplayAdjustments.java",
+ "core/java/android/view/ViewDebug.java",
+ "core/java/com/android/internal/annotations/VisibleForTesting.java",
],
path: "core/java",
visibility: ["//frameworks/base/test-mock"],
@@ -608,7 +682,7 @@ filegroup {
java_library {
name: "framework-annotations-lib",
srcs: [ ":framework-annotations" ],
- sdk_version: "current",
+ sdk_version: "core_current",
}
filegroup {
@@ -739,7 +813,7 @@ java_library {
"core/proto/android/privacy.proto",
"core/proto/android/section.proto",
],
- sdk_version: "current",
+ sdk_version: "9",
srcs: [
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
@@ -762,6 +836,7 @@ java_library {
"core/proto/android/privacy.proto",
"core/proto/android/section.proto",
],
+ sdk_version: "core_current",
// Protos have lots of MissingOverride and similar.
errorprone: {
javacflags: ["-XepDisableAllChecks"],
diff --git a/Android.mk b/Android.mk
index d3627e118ae3..d8532489a786 100644
--- a/Android.mk
+++ b/Android.mk
@@ -60,7 +60,7 @@ $(SDK_METADATA): .KATI_IMPLICIT_OUTPUTS := $(filter-out $(SDK_METADATA),$(SDK_ME
$(SDK_METADATA): $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/framework-doc-stubs-metadata.zip
rm -rf $(SDK_METADATA_DIR)
mkdir -p $(SDK_METADATA_DIR)
- unzip -qo $< -d $(SDK_METADATA_DIR)
+ unzip -DDqo $< -d $(SDK_METADATA_DIR)
.PHONY: framework-doc-stubs
framework-doc-stubs: $(SDK_METADATA)
diff --git a/ApiDocs.bp b/ApiDocs.bp
index bd4a32bfab7a..029699efe3b9 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -66,7 +66,7 @@ stubs_defaults {
":opt-telephony-srcs",
":opt-net-voip-srcs",
":art-module-public-api-stubs-source",
- ":conscrypt.module.public.api.stubs.source",
+ ":conscrypt.module.public.api{.public.stubs.source}",
":android_icu4j_public_api_files",
"test-mock/src/**/*.java",
"test-runner/src/**/*.java",
@@ -79,7 +79,7 @@ stubs_defaults {
"sdk-dir",
"api-versions-jars-dir",
],
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
@@ -101,7 +101,7 @@ droidstubs {
arg_files: [
"core/res/AndroidManifest.xml",
],
- args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\) ",
+ args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
write_sdk_values: true,
}
diff --git a/METADATA b/METADATA
new file mode 100644
index 000000000000..d97975ca3b99
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 74b0524f4fd2..7d1b3d069f59 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -48,13 +48,12 @@ stubs_defaults {
":opt-telephony-srcs",
":opt-net-voip-srcs",
":art-module-public-api-stubs-source",
- ":conscrypt.module.public.api.stubs.source",
":android_icu4j_public_api_files",
],
libs: ["framework-internal-utils"],
installable: false,
annotations_enabled: true,
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
@@ -65,7 +64,10 @@ stubs_defaults {
stubs_defaults {
name: "metalava-full-api-stubs-default",
defaults: ["metalava-base-api-stubs-default"],
- srcs: [":framework-updatable-sources"],
+ srcs: [
+ ":conscrypt.module.public.api{.public.stubs.source}",
+ ":framework-updatable-sources",
+ ],
sdk_version: "core_platform",
}
@@ -97,13 +99,13 @@ droidstubs {
removed_api_file: "api/removed.txt",
},
last_released: {
- api_file: ":last-released-public-api",
+ api_file: ":android.api.public.latest",
removed_api_file: "api/removed.txt",
baseline_file: ":public-api-incompatibilities-with-last-released",
},
api_lint: {
enabled: true,
- new_since: ":last-released-public-api",
+ new_since: ":android.api.public.latest",
baseline_file: "api/lint-baseline.txt",
},
},
@@ -139,13 +141,13 @@ droidstubs {
removed_api_file: "api/system-removed.txt",
},
last_released: {
- api_file: ":last-released-system-api",
+ api_file: ":android.api.system.latest",
removed_api_file: "api/system-removed.txt",
baseline_file: ":system-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-system-api",
+ new_since: ":android.api.system.latest",
baseline_file: "api/system-lint-baseline.txt",
},
},
@@ -207,13 +209,13 @@ droidstubs {
removed_api_file: "api/module-lib-removed.txt",
},
last_released: {
- api_file: ":last-released-module-lib-api",
+ api_file: ":android.api.module-lib.latest",
removed_api_file: "api/module-lib-removed.txt",
baseline_file: ":module-lib-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-module-lib-api",
+ new_since: ":android.api.module-lib.latest",
baseline_file: "api/module-lib-lint-baseline.txt",
},
},
@@ -314,7 +316,7 @@ droidstubs {
installable: false,
sdk_version: "core_platform",
annotations_enabled: true,
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
diff --git a/apex/Android.bp b/apex/Android.bp
index c381c0f100a5..505c3fc12d05 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -63,6 +63,68 @@ mainline_service_stubs_args =
"--hide-annotation android.annotation.Hide " +
"--hide InternalClasses " // com.android.* classes are okay in this interface
+// Defaults for mainline module provided java_sdk_library instances.
+java_defaults {
+ name: "framework-module-defaults",
+
+ // Additional annotations used for compiling both the implementation and the
+ // stubs libraries.
+ libs: ["framework-annotations-lib"],
+
+ // Framework modules are not generally shared libraries, i.e. they are not
+ // intended, and must not be allowed, to be used in a <uses-library> manifest
+ // entry.
+ shared_library: false,
+
+ // Enable api lint. This will eventually become the default for java_sdk_library
+ // but it cannot yet be turned on because some usages have not been cleaned up.
+ // TODO(b/156126315) - Remove when no longer needed.
+ api_lint: {
+ enabled: true,
+ },
+
+ // The API scope specific properties.
+ public: {
+ enabled: true,
+ sdk_version: "module_current",
+ },
+ system: {
+ enabled: true,
+ sdk_version: "module_current",
+ },
+ module_lib: {
+ enabled: true,
+ sdk_version: "module_current",
+ },
+
+ // Configure framework module specific metalava options.
+ droiddoc_options: [mainline_stubs_args],
+
+ // The stub libraries must be visible to frameworks/base so they can be combined
+ // into API specific libraries.
+ stubs_library_visibility: [
+ "//frameworks/base", // Framework
+ ],
+
+ // Set the visibility of the modules creating the stubs source.
+ stubs_source_visibility: [
+ // Ignore any visibility rules specified on the java_sdk_library when
+ // setting the visibility of the stubs source modules.
+ "//visibility:override",
+
+ // Currently, the stub source is not required for anything other than building
+ // the stubs library so is private to avoid misuse.
+ "//visibility:private",
+ ],
+
+ // Collates API usages from each module for further analysis.
+ plugins: ["java_api_finder"],
+
+ // Mainline modules should only rely on 'module_lib' APIs provided by other modules
+ // and the non updatable parts of the platform.
+ sdk_version: "module_current",
+}
+
stubs_defaults {
name: "framework-module-stubs-defaults-publicapi",
args: mainline_framework_stubs_args,
diff --git a/apex/sdkextensions/Android.bp b/apex/sdkextensions/Android.bp
deleted file mode 100644
index dbb5bd3d660f..000000000000
--- a/apex/sdkextensions/Android.bp
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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 {
- default_visibility: [":__subpackages__"],
-}
-
-apex {
- name: "com.android.sdkext",
- defaults: [ "com.android.sdkext-defaults" ],
- binaries: [ "derive_sdk" ],
- prebuilts: [ "cur_sdkinfo" ],
- manifest: "manifest.json",
- min_sdk_version: "current",
-}
-
-apex_defaults {
- name: "com.android.sdkext-defaults",
- updatable: true,
- min_sdk_version: "R",
- java_libs: [ "framework-sdkextensions" ],
- prebuilts: [
- "derive_sdk.rc",
- ],
- key: "com.android.sdkext.key",
- certificate: ":com.android.sdkext.certificate",
-}
-
-sdk {
- name: "sdkextensions-sdk",
- java_header_libs: [ "framework-sdkextensions-stubs-systemapi" ],
-}
-
-apex_key {
- name: "com.android.sdkext.key",
- public_key: "com.android.sdkext.avbpubkey",
- private_key: "com.android.sdkext.pem",
-}
-
-android_app_certificate {
- name: "com.android.sdkext.certificate",
- certificate: "com.android.sdkext",
-}
-
-python_binary_host {
- name: "gen_sdkinfo",
- srcs: [
- "sdk.proto",
- "gen_sdkinfo.py",
- ],
- proto: {
- canonical_path_from_root: false,
- },
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
-}
-
-gensrcs {
- name: "cur_sdkinfo_src",
- srcs: [""],
- tools: [ "gen_sdkinfo" ],
- cmd: "$(location) -v 0 -o $(out)",
-}
-
-prebuilt_etc {
- name: "cur_sdkinfo",
- src: ":cur_sdkinfo_src",
- filename: "sdkinfo.binarypb",
- installable: false,
-}
diff --git a/apex/sdkextensions/OWNERS b/apex/sdkextensions/OWNERS
deleted file mode 100644
index a6e55228596b..000000000000
--- a/apex/sdkextensions/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-dariofreni@google.com
-hansson@google.com
diff --git a/apex/sdkextensions/TEST_MAPPING b/apex/sdkextensions/TEST_MAPPING
deleted file mode 100644
index 3dc1b9fa5dd0..000000000000
--- a/apex/sdkextensions/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "presubmit": [
- {
- "name": "CtsSdkExtensionsTestCases"
- },
- {
- "name": "sdkextensions_e2e_tests"
- }
- ]
-}
diff --git a/apex/sdkextensions/com.android.sdkext.avbpubkey b/apex/sdkextensions/com.android.sdkext.avbpubkey
deleted file mode 100644
index 8f47741ed3b8..000000000000
--- a/apex/sdkextensions/com.android.sdkext.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/sdkextensions/com.android.sdkext.pem b/apex/sdkextensions/com.android.sdkext.pem
deleted file mode 100644
index 816460183aa3..000000000000
--- a/apex/sdkextensions/com.android.sdkext.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAr72pTSavrziDP54AtQZlRclDxJf9HXRZwFRbYx9hWZ4z7ZtO
-pNBDPvPJCiAOVUsILgCQhBUolz2dyLob25Fd0PVp0n9ibIPEQYjTfHjOK40qb57N
-LhEp2ceGiAfsywPSi0TH1PQ6JgbCe/RM4TefI/sj3gYJPka3ksMvylhMIgUVLgME
-kYizhzwHqlLMspB858SioREZdGwcdZrMMIajGFU69Q9ZRDBzhPvxyKhYoObcOtk1
-uVaiE/fNoi3wKGJz2l2vhUuNrQW7MWlVMag+Qes4YACUTk9LZrOVFEJFjWc8xGUi
-ABtfKGs5JgNr/sWnhvifLn8lJuf0/BJmjD+L5QwXYs2cS7gcZJtTM12J94r0Twgw
-wF2lNmIxAE9sYqj5Rh3dIlTPE5vMUECmQEGjIBB/hzT65VxVqSjU/IlS506JTg3p
-IOQtZ15cUzTBpda4jrvqcq6RNVvgBCu2bV5D8Z4z9FUlPyvD+Zq/6lcoJfLtznAs
-G2463hyPAHTGBIcZ5p5bTuGxoAb6ivyqo4b9Qi4yYA6je9HJmuy8T3Mn5JROoeu9
-BH1K54r/mpT4TQPwuKUvRRtBAV2OPHjo+zp0Gd4Y6rxDYxEIdfEae7pQr/QExSPB
-q/QCr9RhixR1mO373LHuja+MxdAxIxugb2HTS61PQo+PbYrhJMcVuxTwJOECAwEA
-AQKCAgAH7ToRrMkH0ji5SdsmTx+KQkW4PFLCXVke/68PjX7KmAQnl3W4oVwnHr/W
-oROEbVn1GTlre7jU+YaAY0SWZrwgjLE1OWGrG1ZizlUbrCdAd6GOX09J4KROml1L
-DXB0x7tbZMLOrCVjSbLD/ITrM6MN8Gnxvbv0/yOQjxU8vzbP4gLOjHxMRCo001RV
-Ll7lPvcjTQ84zJilU6sE8vJ6zdfVZSK/ou2X0cekG+kP7+fvefo8/UcbEPlGhUrV
-IdVPPQGUu90K2hmN0FBdLi8Vik0klAN68Qu/bHwuKbNzsnmIoztucFFUR+fG3u84
-87aPS0L/J3+mjT2Tv6qhJANUGBmrK/h7MkelpKXlRTCITJLX9xP7hfSbJ4f6aLVq
-ZYPPciGxSBbUDgAwvPtOlMDzccg7YsYyiBBO28wh8MN97rePmc0z6nGmjeXhcbCC
-QktG50VYFCyqp5muKgqQmRfRjHFHLWs8GEqgxMeEL3U3HjYfCYr+6E8Sr5OnOBeH
-3buCi1+zgnNYCvbamgY/OJmW7f9h5O31hxmTplc2E1ZuxUGQZthabt1rN3bmNkyf
-KUmPwnIYkDkWBSV5lzyQExfS3/EVvj0EnHhx8faamimNrGo8xCcfnLT3c0WEFVmo
-yIyVRX3EpXJFM2JkeJ21/IEZXTzHSoNxk12CBG8i8lLSflWSMQKCAQEA2ZqVnOuV
-SZfLCUYUUh8Hvhc5zONstfq7ma1Zsttsdaj9t68nLRiBDvLOGnMjDkYZzoSd4fyl
-oy+YqWGBqcqa5kg1NOCH0I46p9d8RcWAfDnB4sqbLgWh70qsvni6igRijmsMDvkA
-U9HeEdPaLCjQ4UXw7GQvN5rRxuRt+OSqV3tV/Pk9JYyYjz7faC8dmbKDrWHHuOvm
-/9y6Xy+L5IgftykNlUeddSCIoMOAadM7BiRjsrHnOYBQ8xBcn0OYafpIswItrgVi
-IrsPJaBFidx8QYK4MVibyka6U0cm28OocDSPtSk/4jrnCEEhLjFUnWwuMXuBGlrd
-W7wP/muoJqb1VwKCAQEAzsAT90kkOCvAcrfGRE3KkUjwWAsQyP8u2+27JIQPqrpW
-GfWAzJXFt80TSp0Zf/Lrq3/SQ9n4AaL4K9dcMoreedoQN9C9JI7zPtZAWNrJVUcV
-dq2gZjBQ78+oK7uQgvFNWxga5D+Nh+Y+9Tp537fc5HIh0Y13PgsxxPk2OnZJTvLX
-HM5H7Aua9ssmqChsrKihuUsDSPozfBz+H7FNHEdKMqVLqJJSK6m0uMxuLovdVfka
-5S7iBMjEGZc46Iz3ckE0pdOiQLooNqfEQqFe5Uou/KZxxKI1NW25rEEBTVyQWt+2
-BNUCfKP7noZ45u5sUY3eJrgI7BrPEDbNS81WYaLchwKCAQA8Q4mHyd6wYO+EA/qA
-u8NDK9+AFMP4qhXme5HJ7Obetwx9IG7zGEQ1xZy6yoQ84cEn5qZq/bNJvFbFIhHs
-2gWIHRtPJ5e1dI5eCVmLYSUyQjSmAIJ1fm3YfY/VuE3BB3HcC11tkBw9GnQr78YO
-UMd4fAw7C4vgFGpgcMbcFUfvrmKkCsqaaZOeqETq75F9DWlWTSwo1HxHA/RBhENz
-6RcPfLkcTJcY5wevrjUUGcHQ86cAyDBHRngkuLVODkRZpU0Y9lN8TFVfVPre6sIX
-ag6nffJRCD8tB+V2RtBGMKunV4ctHt1oY/Oz34W260aJynoIjjG1ANEpJK4xQdNx
-0O9FAoIBAQCz2AGGKemHswdEwveEkuaSWpA3Bekj7lYkmTchHH9EU7JyAkx3qhDD
-QXB2hxGXawf1tsqAmypQwiJ+gGeCz6mW9UkGRF1DX9XX4yc2I5rew2a4RXAxc/Xz
-pP70i8O5I43Wn7FEusOyY2aAis1Y/eb4EQ+56QTAw5wXa3DwidRbCIJ2XDnT6oRy
-CWUnAYMG7ek/9TB2Wq5OWCn2B5S79IdmZsLZb+5qbMT3u1xcwO1Xy8jJc27IGpv6
-ZsDqCTV1/aJ+XQnWpBg28tiV3Sle6pjUzTRJh5AhWcEZRbKMSOiJI/CBY4k2Qq6t
-xuuEdgFjL7T+mTepqehUglcyiPuLEtAhAoIBAQDDQ5pTFOlunfYzm+CIvvImAgy7
-vrEabJYABATytAbXRMMbrKoEdU2ApEDyEW7PgysDnYLAZ+icObnJlBTYvNdlWFly
-XiviGVfpjFWDT9U/gUwFQu2lfEjoiivoGS92USHUy4UMVHiiznnm20VLLkgd3xna
-HUNSDdHIEgzOTmDsKJwMfA9zGckx23JJimPR5ekv6vr6QllYtECs4lTC1gVQAp2f
-5daxHRbkmO6gw1RgQADLkAnYz3aI1jNuHm5VyAZGt/d3JCtZ3Wwwejll8uJ4J09G
-oEtqyY9RVeHK50bLO4lyAXFiE+J6qqXjsGC20cpxeZYW5llMY/dhA6WV4YXV
------END RSA PRIVATE KEY-----
diff --git a/apex/sdkextensions/com.android.sdkext.pk8 b/apex/sdkextensions/com.android.sdkext.pk8
deleted file mode 100644
index ccc0bf438cd1..000000000000
--- a/apex/sdkextensions/com.android.sdkext.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/sdkextensions/com.android.sdkext.x509.pem b/apex/sdkextensions/com.android.sdkext.x509.pem
deleted file mode 100644
index 45d2ade354d4..000000000000
--- a/apex/sdkextensions/com.android.sdkext.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGIzCCBAugAwIBAgIUXuDL7QvzQh7S6rihWz2KRvCFVT0wDQYJKoZIhvcNAQEL
-BQAwgZ8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMRswGQYDVQQDDBJjb20uYW5kcm9pZC5zZGtleHQxIjAgBgkqhkiG9w0BCQEW
-E2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMjAyMTQyNDM0WhgPNDc1NzEwMjgx
-NDI0MzRaMIGfMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
-A1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwH
-QW5kcm9pZDEbMBkGA1UEAwwSY29tLmFuZHJvaWQuc2RrZXh0MSIwIAYJKoZIhvcN
-AQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
-MIICCgKCAgEAxFvZZ6ES1oqAu1K74/ZxnC3SOhHnLISLBgJEe7DqtdpuNFAwvdVO
-RL/HULhDbjYlOhpU2x3SavDIZZ2lRfiS9Q+M25WftxTRHVjBcpgwbV77TVxPKlAa
-tVN2lUVOY+s4QAVMNIXjC4kCKK/pCQtacH715EtdV47fWdg/Nx4iP/Aord8k3KGI
-9iI2ZOUjaugTRxu5lKRNDrv0bw5rEzyYmDyMud+kR/iS3/5oog57wPE0ffAkZXWE
-p3L2Cejre3ekCizsvVh6EmH6ForKLtL6f0z5Zir1f4R9+YcENspTlJR3pDhg7y3I
-uTQT/iDCtV0l+g2PjGZPEeAQHND3+kDQR7Sno/WC1Nhws6vcu1MdrC+kIh1ewx4y
-8moy/yqb5M98PJDzTSi/AOTB/OiqLXo/T8rjLBmirs9y3fTT6gJ6qXxOWgt8dle9
-7TBfa84Xi8uVY61c+A+YI0nLal7QDPsP3RPv5sJSQ9x9YnweVfD9Q0EOi52sSNu+
-QuN/kcUrMgPgha20VhfH/CkkPDyIp6aZyHHM69MIl+cYEm8vPa5uy3dosuRomT0f
-I4HOBjULDIuj+rIi+Rg3qHvmpuejwZXI/FBNWIhLEUG3ytgksjMaBoYAYflGdrcj
-BQexuF3EO+j4uo7JGjNcaT7wRoCH9gt29VHckDg2qz6VWXrlpmME4UkCAwEAAaNT
-MFEwHQYDVR0OBBYEFISN2nmUHllgPZMZ62U7mU3ZxzlXMB8GA1UdIwQYMBaAFISN
-2nmUHllgPZMZ62U7mU3ZxzlXMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
-BQADggIBAFHIwyBNIVyHXUsDUdcjxfojXQsF/BCL9ehE3pgdkvDfQanaIREWn0nc
-oCFDFkYMRqaXOGC5TKq4OCjXOLsdfODt8HQ3F9J1B0ghQ5tfOdw7xDugNAszqP/Q
-h7kpvqLTycjrqOeZ5KjxEEYtP/KlUmALgOKcTcSH+XhWyxhjF4j24T9F2yJRr3/A
-r1NGU/djH953bHKC8OpJ2teUpDLA4TxVp/EhslH2eVigF80c/w74QPLEWkD9zv/4
-YeRg/R5N83zHs99NtlWMIeHfK6fUbzMyaSZtvm+jK20tkByQb/OQRed+drk25MtL
-68IRvxqri367qRScdpTZbu0ByLO4X8gFdubRUWr+tcO4pZX+DJRVriExbOkU2xhS
-Vtslq23V/hwTuUNm1CXjR70mPS13BTmHrIQDqLoIw/WTQlGh+vxnlAFRIHM3KB2c
-OdzUBu+NcB4aZEd0KKtct600A0DKPr1MQPb5jDq9wEtPSQYwMF0nRFNnXltbrXMd
-4hhwnhKr74fVMUmb+7eQP56XE/Nk4D+npMO54vv1pav+DI2/nxCND9BOLBweY38p
-Tvd2RjesMok0zXuVXiCIu4GEpwo7WkSnv25xrb0Ey2M8QWnGNnCcX7Kv6ip3RdWy
-HiN0G8RJrs/yNEVSDRx8ZhtwTpXVPQxbARbmhNF4/fnolElkmrMP
------END CERTIFICATE-----
diff --git a/apex/sdkextensions/derive_sdk/Android.bp b/apex/sdkextensions/derive_sdk/Android.bp
deleted file mode 100644
index 41eae09b1351..000000000000
--- a/apex/sdkextensions/derive_sdk/Android.bp
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-cc_defaults {
- name: "derive_sdk-defaults",
- srcs: [
- "derive_sdk.cpp",
- "sdk.proto",
- ],
- proto: {
- type: "lite",
- static: true,
- },
- min_sdk_version: "current",
- shared_libs: ["liblog"],
- // static c++/libbase for smaller size
- stl: "c++_static",
- static_libs: ["libbase"],
-}
-
-cc_binary {
- name: "derive_sdk",
- defaults: [ "derive_sdk-defaults" ],
- apex_available: [ "com.android.sdkext" ],
- visibility: [ "//frameworks/base/apex/sdkextensions" ]
-}
-
-// Work around testing using a 64-bit test suite on 32-bit test device by
-// using a prefer32 version of derive_sdk in testing.
-cc_binary {
- name: "derive_sdk_prefer32",
- defaults: [ "derive_sdk-defaults" ],
- compile_multilib: "prefer32",
- stem: "derive_sdk",
- apex_available: [ "test_com.android.sdkext" ],
- visibility: [ "//frameworks/base/apex/sdkextensions/testing" ],
- installable: false,
-}
-
-prebuilt_etc {
- name: "derive_sdk.rc",
- src: "derive_sdk.rc",
- installable: false,
-}
diff --git a/apex/sdkextensions/derive_sdk/derive_sdk.cpp b/apex/sdkextensions/derive_sdk/derive_sdk.cpp
deleted file mode 100644
index 900193a6bd0d..000000000000
--- a/apex/sdkextensions/derive_sdk/derive_sdk.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "derive_sdk"
-
-#include <algorithm>
-#include <dirent.h>
-#include <iostream>
-#include <sys/stat.h>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-#include "frameworks/base/apex/sdkextensions/derive_sdk/sdk.pb.h"
-
-using com::android::sdkext::proto::SdkVersion;
-
-int main(int, char**) {
- std::unique_ptr<DIR, decltype(&closedir)> apex(opendir("/apex"), closedir);
- if (!apex) {
- LOG(ERROR) << "Could not read /apex";
- return EXIT_FAILURE;
- }
- struct dirent* de;
- std::vector<std::string> paths;
- while ((de = readdir(apex.get()))) {
- std::string name = de->d_name;
- if (name[0] == '.' || name.find('@') != std::string::npos) {
- // Skip <name>@<ver> dirs, as they are bind-mounted to <name>
- continue;
- }
- std::string path = "/apex/" + name + "/etc/sdkinfo.binarypb";
- struct stat statbuf;
- if (stat(path.c_str(), &statbuf) == 0) {
- paths.push_back(path);
- }
- }
-
- std::vector<int> versions;
- for (const auto& path : paths) {
- std::string contents;
- if (!android::base::ReadFileToString(path, &contents, true)) {
- LOG(ERROR) << "failed to read " << path;
- continue;
- }
- SdkVersion sdk_version;
- if (!sdk_version.ParseFromString(contents)) {
- LOG(ERROR) << "failed to parse " << path;
- continue;
- }
- LOG(INFO) << "Read version " << sdk_version.version() << " from " << path;
- versions.push_back(sdk_version.version());
- }
- auto itr = std::min_element(versions.begin(), versions.end());
- std::string prop_value = itr == versions.end() ? "0" : std::to_string(*itr);
-
- if (!android::base::SetProperty("build.version.extensions.r", prop_value)) {
- LOG(ERROR) << "failed to set sdk_info prop";
- return EXIT_FAILURE;
- }
-
- LOG(INFO) << "R extension version is " << prop_value;
- return EXIT_SUCCESS;
-}
diff --git a/apex/sdkextensions/derive_sdk/derive_sdk.rc b/apex/sdkextensions/derive_sdk/derive_sdk.rc
deleted file mode 100644
index 18f021ccadff..000000000000
--- a/apex/sdkextensions/derive_sdk/derive_sdk.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service derive_sdk /apex/com.android.sdkext/bin/derive_sdk
- user nobody
- group nobody
- oneshot
- disabled
diff --git a/apex/sdkextensions/derive_sdk/sdk.proto b/apex/sdkextensions/derive_sdk/sdk.proto
deleted file mode 100644
index d15b93552ff4..000000000000
--- a/apex/sdkextensions/derive_sdk/sdk.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 = "proto3";
-package com.android.sdkext.proto;
-
-option java_outer_classname = "SdkProto";
-option optimize_for = LITE_RUNTIME;
-
-message SdkVersion {
- int32 version = 1;
-}
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
deleted file mode 100644
index 707113b9672c..000000000000
--- a/apex/sdkextensions/framework/Android.bp
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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 {
- default_visibility: [ ":__pkg__" ]
-}
-
-filegroup {
- name: "framework-sdkextensions-sources",
- srcs: [
- "java/**/*.java",
- ],
- path: "java",
- visibility: [ "//frameworks/base" ] // For the "global" stubs.
-}
-
-java_library {
- name: "framework-sdkextensions",
- srcs: [ ":framework-sdkextensions-sources" ],
- sdk_version: "system_current",
- libs: [ "framework-annotations-lib" ],
- permitted_packages: [ "android.os.ext" ],
- installable: true,
- plugins: ["java_api_finder"],
- visibility: [
- "//frameworks/base/apex/sdkextensions",
- "//frameworks/base/apex/sdkextensions/testing",
- ],
- hostdex: true, // for hiddenapi check
- apex_available: [
- "com.android.sdkext",
- "test_com.android.sdkext",
- ],
-}
-
-stubs_defaults {
- name: "framework-sdkextensions-stubs-defaults",
- srcs: [ ":framework-sdkextensions-sources" ],
- libs: [ "framework-annotations-lib" ],
- sdk_version: "system_current",
-}
-
-droidstubs {
- name: "framework-sdkextensions-stubs-srcs-publicapi",
- defaults: [
- "framework-module-stubs-defaults-publicapi",
- "framework-sdkextensions-stubs-defaults",
- ]
-}
-
-droidstubs {
- name: "framework-sdkextensions-stubs-srcs-systemapi",
- defaults: [
- "framework-module-stubs-defaults-systemapi",
- "framework-sdkextensions-stubs-defaults",
- ]
-}
-
-droidstubs {
- name: "framework-sdkextensions-api-module_libs_api",
- defaults: [
- "framework-module-api-defaults-module_libs_api",
- "framework-sdkextensions-stubs-defaults",
- ]
-}
-
-droidstubs {
- name: "framework-sdkextensions-stubs-srcs-module_libs_api",
- defaults: [
- "framework-module-stubs-defaults-module_libs_api",
- "framework-sdkextensions-stubs-defaults",
- ]
-}
-
-java_library {
- name: "framework-sdkextensions-stubs-publicapi",
- srcs: [":framework-sdkextensions-stubs-srcs-publicapi"],
- defaults: ["framework-module-stubs-lib-defaults-publicapi"],
- visibility: [
- "//frameworks/base", // Framework
- "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
-}
-
-java_library {
- name: "framework-sdkextensions-stubs-systemapi",
- srcs: [":framework-sdkextensions-stubs-srcs-systemapi"],
- defaults: ["framework-module-stubs-lib-defaults-systemapi"],
- visibility: [
- "//frameworks/base", // Framework
- "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
-}
-
-java_library {
- name: "framework-sdkextensions-stubs-module_libs_api",
- srcs: [":framework-sdkextensions-stubs-srcs-module_libs_api"],
- defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
- visibility: [
- "//frameworks/base", // Framework
- "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
-}
diff --git a/apex/sdkextensions/framework/api/current.txt b/apex/sdkextensions/framework/api/current.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/sdkextensions/framework/api/current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/module-lib-current.txt b/apex/sdkextensions/framework/api/module-lib-current.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/sdkextensions/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/module-lib-removed.txt b/apex/sdkextensions/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/sdkextensions/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/removed.txt b/apex/sdkextensions/framework/api/removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/sdkextensions/framework/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/system-current.txt b/apex/sdkextensions/framework/api/system-current.txt
deleted file mode 100644
index bbff4c5ae6f4..000000000000
--- a/apex/sdkextensions/framework/api/system-current.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-// Signature format: 2.0
-package android.os.ext {
-
- public class SdkExtensions {
- method public static int getExtensionVersion(int);
- }
-
-}
-
diff --git a/apex/sdkextensions/framework/api/system-removed.txt b/apex/sdkextensions/framework/api/system-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/sdkextensions/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java b/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java
deleted file mode 100644
index c268ff4291e4..000000000000
--- a/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.os.ext;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.os.Build.VERSION_CODES;
-import android.os.SystemProperties;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Methods for interacting with the extension SDK.
- *
- * This class provides information about the extension SDK version present
- * on this device. Use the {@link #getExtensionVersion(int) getExtension} to
- * query for the extension version for the given SDK version.
-
- * @hide
- */
-@SystemApi
-public class SdkExtensions {
-
- private static final int R_EXTENSION_INT;
- static {
- R_EXTENSION_INT = SystemProperties.getInt("build.version.extensions.r", 0);
- }
-
- /**
- * Values suitable as parameters for {@link #getExtensionVersion(int)}.
- * @hide
- */
- @IntDef(value = { VERSION_CODES.R })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SdkVersion {}
-
- private SdkExtensions() { }
-
- /**
- * Return the version of the extension to the given SDK.
- *
- * @param sdk the SDK version to get the extension version of.
- * @see SdkVersion
- * @throws IllegalArgumentException if sdk is not an sdk version with extensions
- */
- public static int getExtensionVersion(@SdkVersion int sdk) {
- if (sdk < VERSION_CODES.R) {
- throw new IllegalArgumentException(String.valueOf(sdk) + " does not have extensions");
- }
-
- if (sdk == VERSION_CODES.R) {
- return R_EXTENSION_INT;
- }
- return 0;
- }
-
-}
diff --git a/apex/sdkextensions/framework/java/android/os/ext/package.html b/apex/sdkextensions/framework/java/android/os/ext/package.html
deleted file mode 100644
index 34c1697c01fd..000000000000
--- a/apex/sdkextensions/framework/java/android/os/ext/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides APIs to interface with the SDK extensions.
-</BODY>
-</HTML>
diff --git a/apex/sdkextensions/gen_sdkinfo.py b/apex/sdkextensions/gen_sdkinfo.py
deleted file mode 100644
index 5af478ba7fe6..000000000000
--- a/apex/sdkextensions/gen_sdkinfo.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sdk_pb2
-import sys
-
-if __name__ == '__main__':
- argv = sys.argv[1:]
- if not len(argv) == 4 or sorted([argv[0], argv[2]]) != ['-o', '-v']:
- print('usage: gen_sdkinfo -v <version> -o <output-file>')
- sys.exit(1)
-
- for i in range(len(argv)):
- if sys.argv[i] == '-o':
- filename = sys.argv[i+1]
- if sys.argv[i] == '-v':
- version = int(sys.argv[i+1])
-
- proto = sdk_pb2.SdkVersion()
- proto.version = version
- with open(filename, 'wb') as f:
- f.write(proto.SerializeToString())
diff --git a/apex/sdkextensions/manifest.json b/apex/sdkextensions/manifest.json
deleted file mode 100644
index 048f5c4f177b..000000000000
--- a/apex/sdkextensions/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.sdkext",
- "version": 1
-}
diff --git a/apex/sdkextensions/sdk.proto b/apex/sdkextensions/sdk.proto
deleted file mode 100644
index d15b93552ff4..000000000000
--- a/apex/sdkextensions/sdk.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 = "proto3";
-package com.android.sdkext.proto;
-
-option java_outer_classname = "SdkProto";
-option optimize_for = LITE_RUNTIME;
-
-message SdkVersion {
- int32 version = 1;
-}
diff --git a/apex/sdkextensions/testing/Android.bp b/apex/sdkextensions/testing/Android.bp
deleted file mode 100644
index f2f5b321fafe..000000000000
--- a/apex/sdkextensions/testing/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.
-
-apex_test {
- name: "test_com.android.sdkext",
- visibility: [ "//system/apex/tests" ],
- defaults: ["com.android.sdkext-defaults"],
- manifest: "test_manifest.json",
- prebuilts: [ "sdkinfo_45" ],
- file_contexts: ":com.android.sdkext-file_contexts",
- installable: false, // Should never be installed on the systemimage
- multilib: {
- prefer32: {
- binaries: ["derive_sdk_prefer32"],
- },
- },
- // The automated test infra ends up building this apex for 64+32-bit and
- // then installs it on a 32-bit-only device. Work around this weirdness
- // by preferring 32-bit.
- compile_multilib: "prefer32",
-}
-
-genrule {
- name: "sdkinfo_45_src",
- out: [ "sdkinfo.binarypb" ],
- tools: [ "gen_sdkinfo" ],
- cmd: "$(location) -v 45 -o $(out)",
-}
-
-prebuilt_etc {
- name: "sdkinfo_45",
- src: ":sdkinfo_45_src",
- filename: "sdkinfo.binarypb",
- installable: false,
-}
diff --git a/apex/sdkextensions/testing/test_manifest.json b/apex/sdkextensions/testing/test_manifest.json
deleted file mode 100644
index 1b4a2b0c6e60..000000000000
--- a/apex/sdkextensions/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.sdkext",
- "version": 2147483647
-}
diff --git a/api/current.txt b/api/current.txt
index c84f00669b5f..8163426f953c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29175,6 +29175,7 @@ package android.net {
field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
field public static final int NET_CAPABILITY_RCS = 8; // 0x8
field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
+ field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
@@ -34538,6 +34539,7 @@ package android.os {
field public static final String PRODUCT;
field @Deprecated public static final String RADIO;
field @Deprecated public static final String SERIAL;
+ field @NonNull public static final String SKU;
field public static final String[] SUPPORTED_32_BIT_ABIS;
field public static final String[] SUPPORTED_64_BIT_ABIS;
field public static final String[] SUPPORTED_ABIS;
@@ -41302,6 +41304,7 @@ package android.security.keystore {
method public int getPurposes();
method @NonNull public String[] getSignaturePaddings();
method public int getUserAuthenticationValidityDurationSeconds();
+ method public boolean isDevicePropertiesAttestationIncluded();
method @NonNull public boolean isDigestsSpecified();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isRandomizedEncryptionRequired();
@@ -41323,6 +41326,7 @@ package android.security.keystore {
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(@NonNull java.util.Date);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(@NonNull java.math.BigInteger);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(@NonNull javax.security.auth.x500.X500Principal);
+ method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDevicePropertiesAttestationIncluded(boolean);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean);
@@ -45279,6 +45283,7 @@ package android.telephony {
field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
+ field public static final int EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE = 78; // 0x4e
field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
field public static final int ERROR_UNSPECIFIED = 36; // 0x24
@@ -45297,6 +45302,7 @@ package android.telephony {
field public static final int LOST_SIGNAL = 14; // 0xe
field public static final int LOW_BATTERY = 61; // 0x3d
field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
+ field public static final int MEDIA_TIMEOUT = 77; // 0x4d
field public static final int MMI = 6; // 0x6
field public static final int NORMAL = 2; // 0x2
field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
@@ -45318,6 +45324,7 @@ package android.telephony {
field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
+ field public static final int WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79; // 0x4f
field public static final int WIFI_LOST = 59; // 0x3b
}
@@ -45337,12 +45344,14 @@ package android.telephony {
public class MbmsDownloadSession implements java.lang.AutoCloseable {
method public void addProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadProgressListener);
+ method public void addServiceAnnouncementFile(@NonNull byte[]);
method public void addStatusListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadStatusListener);
method public void cancelDownload(@NonNull android.telephony.mbms.DownloadRequest);
method public void close();
method public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback);
method @Nullable public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, int, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback);
method public void download(@NonNull android.telephony.mbms.DownloadRequest);
+ method public static int getMaximumServiceAnnouncementFileSize();
method @Nullable public java.io.File getTempFileRootDirectory();
method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
method public void removeProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull android.telephony.mbms.DownloadProgressListener);
@@ -46629,12 +46638,8 @@ package android.telephony.ims {
method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
}
- public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ public class ImsRcsManager {
method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
}
@@ -46953,6 +46958,7 @@ package android.telephony.mbms {
public static class MbmsErrors.DownloadErrors {
field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
+ field public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE = 404; // 0x194
field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 3b349bf6a9bb..26153caebfce 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6572,6 +6572,7 @@ package android.provider {
field public static final String NAMESPACE_APP_COMPAT = "app_compat";
field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service";
field public static final String NAMESPACE_AUTOFILL = "autofill";
+ field public static final String NAMESPACE_BLUETOOTH = "bluetooth";
field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
field public static final String NAMESPACE_DEX_BOOT = "dex_boot";
@@ -10320,6 +10321,7 @@ package android.telephony.mbms.vendor {
public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
ctor public MbmsDownloadServiceBase();
method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+ method public int addServiceAnnouncementFile(int, @NonNull byte[]);
method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
method public android.os.IBinder asBinder();
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 31b4ca82c68e..9747647845ed 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1440,6 +1440,7 @@ package android.net {
}
public class ConnectivityManager {
+ method @RequiresPermission(anyOf={"android.permission.MANAGE_TEST_NETWORKS", android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
@@ -4098,6 +4099,7 @@ package android.telephony.mbms.vendor {
public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
ctor public MbmsDownloadServiceBase();
method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+ method public int addServiceAnnouncementFile(int, @NonNull byte[]);
method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
method public android.os.IBinder asBinder();
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
index 9f4f314a4324..ad4de0ab737a 100644
--- a/cmds/bootanimation/bootanim.rc
+++ b/cmds/bootanimation/bootanim.rc
@@ -5,4 +5,4 @@ service bootanim /system/bin/bootanimation
disabled
oneshot
ioprio rt 0
- writepid /dev/stune/top-app/tasks
+ task_profiles MaxPerformance
diff --git a/cmds/device_config/Android.bp b/cmds/device_config/Android.bp
new file mode 100644
index 000000000000..67e014a20506
--- /dev/null
+++ b/cmds/device_config/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2018 The Android Open Source Project
+//
+
+sh_binary {
+ name: "device_config",
+ src: "device_config",
+}
diff --git a/cmds/device_config/Android.mk b/cmds/device_config/Android.mk
deleted file mode 100644
index 4041e01927df..000000000000
--- a/cmds/device_config/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2018 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := device_config
-LOCAL_SRC_FILES := device_config
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 72a8bea9a918..24fbf21f463f 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -382,7 +382,7 @@ cc_benchmark {
// ==== java proto device library (for test only) ==============================
java_library {
name: "statsdprotolite",
- sdk_version: "core_platform",
+ sdk_version: "core_current",
proto: {
type: "lite",
include_dirs: ["external/protobuf/src"],
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 3519a157472b..52e93856a0c7 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -149,8 +149,10 @@ message Atom {
HardwareFailed hardware_failed = 72;
PhysicalDropDetected physical_drop_detected = 73;
ChargeCyclesReported charge_cycles_reported = 74;
- MobileConnectionStateChanged mobile_connection_state_changed = 75;
- MobileRadioTechnologyChanged mobile_radio_technology_changed = 76;
+ MobileConnectionStateChanged mobile_connection_state_changed =
+ 75 [(log_from_module) = "telephony"];
+ MobileRadioTechnologyChanged mobile_radio_technology_changed =
+ 76 [(log_from_module) = "telephony"];
UsbDeviceAttached usb_device_attached = 77;
AppCrashOccurred app_crash_occurred = 78;
ANROccurred anr_occurred = 79;
@@ -5882,11 +5884,11 @@ message NetworkDnsEventReported {
* Logs when a data stall event occurs.
*
* Log from:
- * frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+ * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
*/
message DataStallEvent {
// Data stall evaluation type.
- // See frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+ // See packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
// Refer to the definition of DATA_STALL_EVALUATION_TYPE_*.
optional int32 evaluation_type = 1;
// See definition in data_stall_event.proto.
@@ -5899,6 +5901,10 @@ message DataStallEvent {
optional com.android.server.connectivity.CellularData cell_info = 5 [(log_mode) = MODE_BYTES];
// See definition in data_stall_event.proto.
optional com.android.server.connectivity.DnsEvent dns_event = 6 [(log_mode) = MODE_BYTES];
+ // The tcp packets fail rate from the latest tcp polling.
+ optional int32 tcp_fail_rate = 7;
+ // Number of packets sent since the last received packet.
+ optional int32 tcp_sent_since_last_recv = 8;
}
/*
diff --git a/config/OWNERS b/config/OWNERS
index 53f80e698d83..3d4924df3462 100644
--- a/config/OWNERS
+++ b/config/OWNERS
@@ -1,5 +1,5 @@
# compat-team@ for changes to hiddenapi files
-per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com
+per-file hiddenapi-* = andreionea@google.com, mathewi@google.com, satayev@google.com
# Escalations:
-per-file hiddenapi-* = bdc@google.com, narayan@google.com \ No newline at end of file
+per-file hiddenapi-* = bdc@google.com, narayan@google.com
diff --git a/core/java/android/annotation/CallbackExecutor.java b/core/java/android/annotation/CallbackExecutor.java
index 5671a3d2b6d6..4258f730eb16 100644
--- a/core/java/android/annotation/CallbackExecutor.java
+++ b/core/java/android/annotation/CallbackExecutor.java
@@ -19,9 +19,6 @@ package android.annotation;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
-import android.content.Context;
-import android.os.AsyncTask;
-
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.Executor;
@@ -30,9 +27,10 @@ import java.util.concurrent.Executor;
* @paramDoc Callback and listener events are dispatched through this
* {@link Executor}, providing an easy way to control which thread is
* used. To dispatch events through the main thread of your
- * application, you can use {@link Context#getMainExecutor()}. To
- * dispatch events through a shared thread pool, you can use
- * {@link AsyncTask#THREAD_POOL_EXECUTOR}.
+ * application, you can use
+ * {@link android.content.Context#getMainExecutor() Context.getMainExecutor()}.
+ * To dispatch events through a shared thread pool, you can use
+ * {@link android.os.AsyncTask#THREAD_POOL_EXECUTOR AsyncTask#THREAD_POOL_EXECUTOR}.
* @hide
*/
@Retention(SOURCE)
diff --git a/core/java/android/annotation/OWNERS b/core/java/android/annotation/OWNERS
index 8aceb565315c..e1ef54460b56 100644
--- a/core/java/android/annotation/OWNERS
+++ b/core/java/android/annotation/OWNERS
@@ -1,3 +1,3 @@
tnorbye@google.com
aurimas@google.com
-per-file UnsupportedAppUsage.java = mathewi@google.com, dbrazdil@google.com, atrost@google.com, andreionea@google.com
+per-file UnsupportedAppUsage.java = mathewi@google.com, satayev@google.com, andreionea@google.com
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
index e5c0654f8bbe..1d89e31b2b99 100644
--- a/core/java/android/annotation/RequiresPermission.java
+++ b/core/java/android/annotation/RequiresPermission.java
@@ -15,9 +15,6 @@
*/
package android.annotation;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@@ -25,6 +22,9 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
/**
* Denotes that the annotated element requires (or may require) one or more permissions.
* <p/>
@@ -55,7 +55,8 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
* <p>
* When specified on a parameter, the annotation indicates that the method requires
* a permission which depends on the value of the parameter. For example, consider
- * {@link android.app.Activity#startActivity(android.content.Intent)}:
+ * {@link android.app.Activity#startActivity(android.content.Intent)
+ * Activity#startActivity(Intent)}:
* <pre>{@code
* public void startActivity(@RequiresPermission Intent intent) { ... }
* }</pre>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b6f61a2b8f01..4f1d7f2c761c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3618,7 +3618,6 @@ public class Activity extends ContextThemeWrapper
* To receive this callback, you must return true from onKeyDown for the current
* event stream.
*
- * @see KeyEvent.Callback#onKeyLongPress()
* @see KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
*/
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bdaa44034565..85cd21dec283 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2082,8 +2082,7 @@ public class ActivityManager {
* has access to it.
*
* @see ActivityOptions#setLaunchDisplayId(int)
- * @see android.view.Display.FLAG_PRIVATE
- * @see android.view.Display.TYPE_VIRTUAL
+ * @see android.view.Display#FLAG_PRIVATE
*
* @param context Source context, from which an activity will be started.
* @param displayId Target display id.
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index b669d775b3c1..647f63025cf7 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -37,7 +37,6 @@ import android.util.proto.ProtoOutputStream;
import libcore.timezone.ZoneInfoDb;
-import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -998,12 +997,7 @@ public class AlarmManager {
// Reject this timezone if it isn't an Olson zone we recognize.
if (mTargetSdkVersion >= Build.VERSION_CODES.M) {
- boolean hasTimeZone = false;
- try {
- hasTimeZone = ZoneInfoDb.getInstance().hasTimeZone(timeZone);
- } catch (IOException ignored) {
- }
-
+ boolean hasTimeZone = ZoneInfoDb.getInstance().hasTimeZone(timeZone);
if (!hasTimeZone) {
throw new IllegalArgumentException("Timezone: " + timeZone + " is not an Olson ID");
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 7a560c07a365..0feed7383020 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -299,7 +299,8 @@ interface IActivityManager {
void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask,
in StrictMode.ViolationInfo crashInfo);
boolean isTopActivityImmersive();
- void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message);
+ void crashApplication(int uid, int initialPid, in String packageName, int userId,
+ in String message, boolean force);
@UnsupportedAppUsage
String getProviderMimeType(in Uri uri, int userId);
// Cause the specified process to dump the specified heap.
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index cff6411c882c..2049b3408c64 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -729,7 +729,7 @@ public class Instrumentation {
* a non-null value if the intent needs to be intercepted.
*
* <p> Whenever a new activity is started, this method will be called on instances created
- * using {@link #Instrumentation.ActivityMonitor()} to check if there is a match. In case
+ * using {@link #ActivityMonitor()} to check if there is a match. In case
* of a match, the activity start will be blocked and the returned result will be used.
*
* @param intent The intent used for starting the activity.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index cefec441e702..f2b2635c8636 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3437,7 +3437,7 @@ public class Notification implements Parcelable
}
/**
- * @deprecated use {@link Notification.Builder#Notification.Builder(Context, String)}
+ * @deprecated use {@link #Builder(Context, String)}
* instead. All posted Notifications must specify a NotificationChannel Id.
*/
@Deprecated
@@ -7071,7 +7071,7 @@ public class Notification implements Parcelable
* Should be unique amongst all individuals in the conversation, and should be
* consistent during re-posts of the notification.
*
- * @see Message#Notification.MessagingStyle.Message(CharSequence, long, CharSequence)
+ * @see Message#Message(CharSequence, long, CharSequence)
*
* @return this object for method chaining
*
@@ -7091,7 +7091,7 @@ public class Notification implements Parcelable
* Should be <code>null</code> for messages by the current user, in which case
* the platform will insert the user set in {@code MessagingStyle(Person)}.
*
- * @see Message#Notification.MessagingStyle.Message(CharSequence, long, CharSequence)
+ * @see Message#Message(CharSequence, long, CharSequence)
*
* @return this object for method chaining
*/
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index e25558f16f26..925586feaf1d 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -294,7 +294,7 @@ public class NotificationManager {
* </p>
* </p>
*
- * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
+ * @see #addAutomaticZenRule(AutomaticZenRule)
*/
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_AUTOMATIC_ZEN_RULE =
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index dc815b631e46..067a35fe1aba 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -803,7 +803,7 @@ public class BackupManager {
* has a work profile that was restored from another work profile with serial number
* {@code ancestralSerialNumber}.
*
- * @see UserManager#getSerialNumberForUser(UserHandle)
+ * @see android.os.UserManager#getSerialNumberForUser(UserHandle)
*/
@Nullable
public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 08b1c2b9f548..ec9c57466310 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -41,7 +41,7 @@ import java.util.List;
* system will execute this job on your application's {@link android.app.job.JobService}.
* You identify the service component that implements the logic for your job when you
* construct the JobInfo using
- * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
+ * {@link android.app.job.JobInfo.Builder#Builder(int,android.content.ComponentName)}.
* </p>
* <p>
* The framework will be intelligent about when it executes jobs, and attempt to batch
@@ -147,7 +147,7 @@ public abstract class JobScheduler {
* method is ignored.
*
* @param jobId unique identifier for the job to be canceled, as supplied to
- * {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName)
+ * {@link JobInfo.Builder#Builder(int, android.content.ComponentName)
* JobInfo.Builder(int, android.content.ComponentName)}.
*/
public abstract void cancel(int jobId);
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 2eb9459af877..4e5443a18bf2 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -102,8 +102,6 @@ public final class RoleManager {
/**
* The name of the emergency role
- *
- * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
*/
public static final String ROLE_EMERGENCY = "android.app.role.EMERGENCY";
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 9a17346334d1..2888fbd8a363 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -110,8 +110,9 @@ public final class BluetoothLeScanner {
* off to save power. Scanning is resumed when screen is turned on again. To avoid this, use
* {@link #startScan(List, ScanSettings, ScanCallback)} with desired {@link ScanFilter}.
* <p>
- * An app must hold
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * An app must have
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
+ * in order to get results. An App targeting Android Q or later must have
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
* in order to get results.
*
@@ -129,8 +130,9 @@ public final class BluetoothLeScanner {
* resumed when screen is turned on again. To avoid this, do filetered scanning by
* using proper {@link ScanFilter}.
* <p>
- * An app must hold
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * An app must have
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
+ * in order to get results. An App targeting Android Q or later must have
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
* in order to get results.
*
@@ -150,8 +152,9 @@ public final class BluetoothLeScanner {
* the PendingIntent. Use this method of scanning if your process is not always running and it
* should be started when scan results are available.
* <p>
- * An app must hold
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * An app must have
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
+ * in order to get results. An App targeting Android Q or later must have
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
* in order to get results.
* <p>
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3ed585c18e57..6e0ce3ff032a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3519,7 +3519,6 @@ public abstract class Context {
* @see android.telephony.CarrierConfigManager
* @see #EUICC_SERVICE
* @see android.telephony.euicc.EuiccManager
- * @see #MMS_SERVICE
* @see android.telephony.MmsManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index d5dadbff419f..7e8bb08e0086 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -16,8 +16,6 @@
package android.hardware.hdmi;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,7 +29,7 @@ import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.RemoteException;
-import android.os.SystemProperties;
+import android.sysprop.HdmiProperties;
import android.util.ArrayMap;
import android.util.Log;
@@ -316,8 +314,7 @@ public final class HdmiControlManager {
mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK);
mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
- mIsSwitchDevice = SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
}
private static boolean hasDeviceType(int[] types, int type) {
diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java
index 9086d49231bb..275e38c74451 100644
--- a/core/java/android/net/ConnectivityDiagnosticsManager.java
+++ b/core/java/android/net/ConnectivityDiagnosticsManager.java
@@ -437,7 +437,7 @@ public class ConnectivityDiagnosticsManager {
*/
private long mReportTimestamp;
- /** The detection method used to identify the suspected data stall */
+ /** A bitmask of the detection methods used to identify the suspected data stall */
@DetectionMethod private final int mDetectionMethod;
/** LinkProperties available on the Network at the reported timestamp */
@@ -499,9 +499,9 @@ public class ConnectivityDiagnosticsManager {
}
/**
- * Returns the detection method used to identify this suspected data stall.
+ * Returns the bitmask of detection methods used to identify this suspected data stall.
*
- * @return The detection method used to identify the suspected data stall
+ * @return The bitmask of detection methods used to identify the suspected data stall
*/
public int getDetectionMethod() {
return mDetectionMethod;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ad07e7cf4d5f..6b713602215a 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -48,6 +48,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -4735,4 +4736,28 @@ public class ConnectivityManager {
Log.d(TAG, "StackLog:" + sb.toString());
}
}
+
+ /**
+ * Simulates a Data Stall for the specified Network.
+ *
+ * <p>The caller must be the owner of the specified Network.
+ *
+ * @param detectionMethod The detection method used to identify the Data Stall.
+ * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds.
+ * @param network The Network for which a Data Stall is being simluated.
+ * @param extras The PersistableBundle of extras included in the Data Stall notification.
+ * @throws SecurityException if the caller is not the owner of the given network.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS,
+ android.Manifest.permission.NETWORK_STACK})
+ public void simulateDataStall(int detectionMethod, long timestampMillis,
+ @NonNull Network network, @NonNull PersistableBundle extras) {
+ try {
+ mService.simulateDataStall(detectionMethod, timestampMillis, network, extras);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b0f79bcc0b23..d7f178cd0a9b 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -18,6 +18,7 @@ package android.net;
import android.app.PendingIntent;
import android.net.ConnectionInfo;
+import android.net.ConnectivityDiagnosticsManager;
import android.net.IConnectivityDiagnosticsCallback;
import android.net.LinkProperties;
import android.net.Network;
@@ -33,6 +34,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
import android.os.ResultReceiver;
import com.android.internal.net.LegacyVpnInfo;
@@ -228,4 +230,7 @@ interface IConnectivityManager
void unregisterConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback);
IBinder startOrGetTestNetworkService();
+
+ void simulateDataStall(int detectionMethod, long timestampMillis, in Network network,
+ in PersistableBundle extras);
}
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 81d03f07d0be..407ff04dc4a3 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -70,6 +70,15 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
private static final String MISSING_PARAM_MSG_TMPL = "Required parameter was not provided: %s";
private static final String EMPTY_CERT = "";
+ /** @hide */
+ public static final List<String> DEFAULT_ALGORITHMS =
+ Collections.unmodifiableList(Arrays.asList(
+ IpSecAlgorithm.CRYPT_AES_CBC,
+ IpSecAlgorithm.AUTH_HMAC_SHA256,
+ IpSecAlgorithm.AUTH_HMAC_SHA384,
+ IpSecAlgorithm.AUTH_HMAC_SHA512,
+ IpSecAlgorithm.AUTH_CRYPT_AES_GCM));
+
@NonNull private final String mServerAddr;
@NonNull private final String mUserIdentity;
@@ -92,6 +101,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
private final boolean mIsBypassable; // Defaults in builder
private final boolean mIsMetered; // Defaults in builder
private final int mMaxMtu; // Defaults in builder
+ private final boolean mIsRestrictedToTestNetworks;
private Ikev2VpnProfile(
int type,
@@ -107,7 +117,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
@NonNull List<String> allowedAlgorithms,
boolean isBypassable,
boolean isMetered,
- int maxMtu) {
+ int maxMtu,
+ boolean restrictToTestNetworks) {
super(type);
checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address");
@@ -131,6 +142,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
mIsBypassable = isBypassable;
mIsMetered = isMetered;
mMaxMtu = maxMtu;
+ mIsRestrictedToTestNetworks = restrictToTestNetworks;
validate();
}
@@ -172,7 +184,56 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
throw new IllegalArgumentException("Invalid auth method set");
}
- VpnProfile.validateAllowedAlgorithms(mAllowedAlgorithms);
+ validateAllowedAlgorithms(mAllowedAlgorithms);
+ }
+
+ /**
+ * Validates that the allowed algorithms are a valid set for IPsec purposes
+ *
+ * <p>In order for the algorithm list to be a valid set, it must contain at least one algorithm
+ * that provides Authentication, and one that provides Encryption. Authenticated Encryption with
+ * Associated Data (AEAD) algorithms are counted as providing Authentication and Encryption.
+ *
+ * @param allowedAlgorithms The list to be validated
+ */
+ private static void validateAllowedAlgorithms(@NonNull List<String> algorithmNames) {
+ VpnProfile.validateAllowedAlgorithms(algorithmNames);
+
+ // First, make sure no insecure algorithms were proposed.
+ if (algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_MD5)
+ || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA1)) {
+ throw new IllegalArgumentException("Algorithm not supported for IKEv2 VPN profiles");
+ }
+
+ // Validate that some valid combination (AEAD or AUTH + CRYPT) is present
+ if (hasAeadAlgorithms(algorithmNames) || hasNormalModeAlgorithms(algorithmNames)) {
+ return;
+ }
+
+ throw new IllegalArgumentException("Algorithm set missing support for Auth, Crypt or both");
+ }
+
+ /**
+ * Checks if the provided list has AEAD algorithms
+ *
+ * @hide
+ */
+ public static boolean hasAeadAlgorithms(@NonNull List<String> algorithmNames) {
+ return algorithmNames.contains(IpSecAlgorithm.AUTH_CRYPT_AES_GCM);
+ }
+
+ /**
+ * Checks the provided list has acceptable (non-AEAD) authentication and encryption algorithms
+ *
+ * @hide
+ */
+ public static boolean hasNormalModeAlgorithms(@NonNull List<String> algorithmNames) {
+ final boolean hasCrypt = algorithmNames.contains(IpSecAlgorithm.CRYPT_AES_CBC);
+ final boolean hasAuth = algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA256)
+ || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA384)
+ || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA512);
+
+ return hasCrypt && hasAuth;
}
/** Retrieves the server address string. */
@@ -271,6 +332,15 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
return mMaxMtu;
}
+ /**
+ * Returns whether or not this VPN profile is restricted to test networks.
+ *
+ * @hide
+ */
+ public boolean isRestrictedToTestNetworks() {
+ return mIsRestrictedToTestNetworks;
+ }
+
@Override
public int hashCode() {
return Objects.hash(
@@ -287,7 +357,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
mAllowedAlgorithms,
mIsBypassable,
mIsMetered,
- mMaxMtu);
+ mMaxMtu,
+ mIsRestrictedToTestNetworks);
}
@Override
@@ -310,7 +381,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
&& Objects.equals(mAllowedAlgorithms, other.mAllowedAlgorithms)
&& mIsBypassable == other.mIsBypassable
&& mIsMetered == other.mIsMetered
- && mMaxMtu == other.mMaxMtu;
+ && mMaxMtu == other.mMaxMtu
+ && mIsRestrictedToTestNetworks == other.mIsRestrictedToTestNetworks;
}
/**
@@ -323,7 +395,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
*/
@NonNull
public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException {
- final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */);
+ final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */,
+ mIsRestrictedToTestNetworks);
profile.type = mType;
profile.server = mServerAddr;
profile.ipsecIdentifier = mUserIdentity;
@@ -391,6 +464,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
builder.setBypassable(profile.isBypassable);
builder.setMetered(profile.isMetered);
builder.setMaxMtu(profile.maxMtu);
+ if (profile.isRestrictedToTestNetworks) {
+ builder.restrictToTestNetworks();
+ }
switch (profile.type) {
case TYPE_IKEV2_IPSEC_USER_PASS:
@@ -559,10 +635,11 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
@Nullable private X509Certificate mUserCert;
@Nullable private ProxyInfo mProxyInfo;
- @NonNull private List<String> mAllowedAlgorithms = new ArrayList<>();
+ @NonNull private List<String> mAllowedAlgorithms = DEFAULT_ALGORITHMS;
private boolean mIsBypassable = false;
private boolean mIsMetered = true;
private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT;
+ private boolean mIsRestrictedToTestNetworks = false;
/**
* Creates a new builder with the basic parameters of an IKEv2/IPsec VPN.
@@ -745,7 +822,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
* @param isMetered {@code true} if the VPN network should be treated as metered regardless
* of underlying network meteredness. Defaults to {@code true}.
* @return this {@link Builder} object to facilitate chaining of method calls
- * @see NetworkCapabilities.NET_CAPABILITY_NOT_METERED
+ * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED
*/
@NonNull
public Builder setMetered(boolean isMetered) {
@@ -756,7 +833,19 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
/**
* Sets the allowable set of IPsec algorithms
*
- * <p>A list of allowed IPsec algorithms as defined in {@link IpSecAlgorithm}
+ * <p>If set, this will constrain the set of algorithms that the IPsec tunnel will use for
+ * integrity verification and encryption to the provided list.
+ *
+ * <p>The set of allowed IPsec algorithms is defined in {@link IpSecAlgorithm}. Adding of
+ * algorithms that are considered insecure (such as AUTH_HMAC_MD5 and AUTH_HMAC_SHA1) is not
+ * permitted, and will result in an IllegalArgumentException being thrown.
+ *
+ * <p>The provided algorithm list must contain at least one algorithm that provides
+ * Authentication, and one that provides Encryption. Authenticated Encryption with
+ * Associated Data (AEAD) algorithms provide both Authentication and Encryption.
+ *
+ * <p>By default, this profile will use any algorithm defined in {@link IpSecAlgorithm},
+ * with the exception of those considered insecure (as described above).
*
* @param algorithmNames the list of supported IPsec algorithms
* @return this {@link Builder} object to facilitate chaining of method calls
@@ -765,13 +854,28 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
@NonNull
public Builder setAllowedAlgorithms(@NonNull List<String> algorithmNames) {
checkNotNull(algorithmNames, MISSING_PARAM_MSG_TMPL, "algorithmNames");
- VpnProfile.validateAllowedAlgorithms(algorithmNames);
+ validateAllowedAlgorithms(algorithmNames);
mAllowedAlgorithms = algorithmNames;
return this;
}
/**
+ * Restricts this profile to use test networks (only).
+ *
+ * <p>This method is for testing only, and must not be used by apps. Calling
+ * provisionVpnProfile() with a profile where test-network usage is enabled will require the
+ * MANAGE_TEST_NETWORKS permission.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder restrictToTestNetworks() {
+ mIsRestrictedToTestNetworks = true;
+ return this;
+ }
+
+ /**
* Validates, builds and provisions the VpnProfile.
*
* @throws IllegalArgumentException if any of the required keys or values were invalid
@@ -792,7 +896,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
mAllowedAlgorithms,
mIsBypassable,
mIsMetered,
- mMaxMtu);
+ mMaxMtu,
+ mIsRestrictedToTestNetworks);
}
}
}
diff --git a/core/java/android/net/MatchAllNetworkSpecifier.java b/core/java/android/net/MatchAllNetworkSpecifier.java
index 68a39355198b..70c4a7235b9d 100644
--- a/core/java/android/net/MatchAllNetworkSpecifier.java
+++ b/core/java/android/net/MatchAllNetworkSpecifier.java
@@ -43,7 +43,8 @@ public final class MatchAllNetworkSpecifier extends NetworkSpecifier implements
}
/** @hide */
- public boolean satisfiedBy(NetworkSpecifier other) {
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
/*
* The method is called by a NetworkRequest to see if it is satisfied by a proposed
* network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index fea3245784b2..57d5d03a6cf2 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -169,6 +169,7 @@ public final class NetworkCapabilities implements Parcelable {
NET_CAPABILITY_OEM_PAID,
NET_CAPABILITY_MCX,
NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ NET_CAPABILITY_TEMPORARILY_NOT_METERED,
})
public @interface NetCapability { }
@@ -336,8 +337,16 @@ public final class NetworkCapabilities implements Parcelable {
@SystemApi
public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24;
+ /**
+ * This capability will be set for networks that are generally metered, but are currently
+ * unmetered, e.g., because the user is in a particular area. This capability can be changed at
+ * any time. When it is removed, applications are responsible for stopping any data transfer
+ * that should not occur on a metered network.
+ */
+ public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PARTIAL_CONNECTIVITY;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_TEMPORARILY_NOT_METERED;
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -353,7 +362,8 @@ public final class NetworkCapabilities implements Parcelable {
| (1 << NET_CAPABILITY_FOREGROUND)
| (1 << NET_CAPABILITY_NOT_CONGESTED)
| (1 << NET_CAPABILITY_NOT_SUSPENDED)
- | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
+ | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY
+ | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED));
/**
* Network capabilities that are not allowed in NetworkRequests. This exists because the
@@ -424,6 +434,7 @@ public final class NetworkCapabilities implements Parcelable {
*/
private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
(1 << NET_CAPABILITY_NOT_METERED)
+ | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED)
| (1 << NET_CAPABILITY_NOT_RESTRICTED)
| (1 << NET_CAPABILITY_NOT_VPN)
| (1 << NET_CAPABILITY_NOT_ROAMING)
@@ -666,16 +677,27 @@ public final class NetworkCapabilities implements Parcelable {
* restrictions.
* @hide
*/
- public void restrictCapabilitesForTestNetwork() {
+ public void restrictCapabilitesForTestNetwork(int creatorUid) {
final long originalCapabilities = mNetworkCapabilities;
final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
final int originalSignalStrength = mSignalStrength;
+ final int originalOwnerUid = getOwnerUid();
+ final int[] originalAdministratorUids = getAdministratorUids();
clearAll();
// Reset the transports to only contain TRANSPORT_TEST.
mTransportTypes = (1 << TRANSPORT_TEST);
mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
mNetworkSpecifier = originalSpecifier;
mSignalStrength = originalSignalStrength;
+
+ // Only retain the owner and administrator UIDs if they match the app registering the remote
+ // caller that registered the network.
+ if (originalOwnerUid == creatorUid) {
+ setOwnerUid(creatorUid);
+ }
+ if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) {
+ setAdministratorUids(new int[] {creatorUid});
+ }
}
/**
@@ -1866,6 +1888,7 @@ public final class NetworkCapabilities implements Parcelable {
case NET_CAPABILITY_OEM_PAID: return "OEM_PAID";
case NET_CAPABILITY_MCX: return "MCX";
case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY";
+ case NET_CAPABILITY_TEMPORARILY_NOT_METERED: return "TEMPORARILY_NOT_METERED";
default: return Integer.toString(capability);
}
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c233ec0e52cf..6539e0563794 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
@@ -468,11 +469,13 @@ public class NetworkScoreManager {
*
* @param networks List of {@link ScoredNetwork} containing updated scores.
*/
+ @SuppressLint("CallbackMethodName")
void updateScores(@NonNull List<ScoredNetwork> networks);
/**
* Invokes when all the previously provided scores are no longer valid.
*/
+ @SuppressLint("CallbackMethodName")
void clearScores();
}
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 63e510733907..9c2c5b839302 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -836,7 +836,7 @@ public class VpnService extends Service {
* @param isMetered {@code true} if VPN network should be treated as metered regardless of
* underlying network meteredness
* @return this {@link Builder} object to facilitate chaining method calls
- * @see #setUnderlyingNetworks(Networks[])
+ * @see #setUnderlyingNetworks(Network[])
* @see ConnectivityManager#isActiveNetworkMetered()
*/
@NonNull
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index eb67492483f1..0f53d4f84920 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -106,6 +106,12 @@ public class Build {
public static final String HARDWARE = getString("ro.hardware");
/**
+ * The hardware variant (SKU), if available.
+ */
+ @NonNull
+ public static final String SKU = getString("ro.boot.product.hardware.sku");
+
+ /**
* Whether this build was for an emulator device.
* @hide
*/
diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java
index 6632ca51e74c..9b360edb7238 100644
--- a/core/java/android/os/Parcelable.java
+++ b/core/java/android/os/Parcelable.java
@@ -118,7 +118,21 @@ public interface Parcelable {
* by this Parcelable object instance.
*/
public @ContentsFlags int describeContents();
-
+
+ /**
+ * 'Stable' means this parcelable is guaranteed to be stable for multiple years.
+ * It must be guaranteed by setting stability field in aidl_interface,
+ * OR explicitly override this method from @JavaOnlyStableParcelable marked Parcelable.
+ * WARNING: isStable() is only expected to be overridden by auto-generated code,
+ * OR @JavaOnlyStableParcelable marked Parcelable only if there is guaranteed to
+ * be only once copy of the parcelable on the system.
+ * @return true if this parcelable is stable.
+ * @hide
+ */
+ default boolean isStable() {
+ return false;
+ }
+
/**
* Flatten this object in to a Parcel.
*
diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java
index d6afd049f156..bde7ec14f37a 100644
--- a/core/java/android/os/Registrant.java
+++ b/core/java/android/os/Registrant.java
@@ -46,7 +46,7 @@ public class Registrant
{
internalNotifyRegistrant (null, null);
}
-
+
@UnsupportedAppUsage
public void
notifyResult(Object result)
@@ -81,9 +81,7 @@ public class Registrant
Message msg = Message.obtain();
msg.what = what;
-
msg.obj = new AsyncResult(userObj, result, exception);
-
h.sendMessage(msg);
}
}
@@ -126,4 +124,3 @@ public class Registrant
int what;
Object userObj;
}
-
diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java
index 98f949bbfd84..b36734bcd199 100644
--- a/core/java/android/os/RegistrantList.java
+++ b/core/java/android/os/RegistrantList.java
@@ -42,9 +42,9 @@ public class RegistrantList
{
// if the handler is already in the registrant list, remove it
remove(h);
- add(new Registrant(h, what, obj));
+ add(new Registrant(h, what, obj));
}
-
+
@UnsupportedAppUsage
public synchronized void
add(Registrant r)
@@ -59,13 +59,17 @@ public class RegistrantList
{
for (int i = registrants.size() - 1; i >= 0 ; i--) {
Registrant r = (Registrant) registrants.get(i);
-
+
if (r.refH == null) {
registrants.remove(i);
}
}
}
+ public synchronized void removeAll() {
+ registrants.clear();
+ }
+
@UnsupportedAppUsage
public synchronized int
size()
@@ -88,7 +92,7 @@ public class RegistrantList
r.internalNotifyRegistrant(result, exception);
}
}
-
+
@UnsupportedAppUsage
public /*synchronized*/ void
notifyRegistrants()
@@ -109,14 +113,14 @@ public class RegistrantList
internalNotifyRegistrants (result, null);
}
-
+
@UnsupportedAppUsage
public /*synchronized*/ void
notifyRegistrants(AsyncResult ar)
{
internalNotifyRegistrants(ar.result, ar.exception);
}
-
+
@UnsupportedAppUsage
public synchronized void
remove(Handler h)
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 3faaff73a0ea..81457074f2fc 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1015,7 +1015,6 @@ public final class StrictMode {
* behaviors or empty states. Instead, apps should store data needed
* while a user is locked under device protected storage areas.
*
- * @see Context#createCredentialProtectedStorageContext()
* @see Context#createDeviceProtectedStorageContext()
*/
public @NonNull Builder detectCredentialProtectedWhileLocked() {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index de274c082c80..e907e2204b7b 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -614,9 +614,6 @@ public class UpdateEngine {
* encountered. Device is corrupted, and future updates must not be applied.
* The device cannot recover without flashing and factory resets.
* </ul>
- *
- * @throws ServiceSpecificException if other transient errors has occurred.
- * A reboot may or may not help resolving the issue.
*/
@WorkerThread
@ErrorCode
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 75b4724c7d26..890057371471 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -55,21 +55,16 @@ public abstract class VibrationEffect implements Parcelable {
/**
* A click effect. Use this effect as a baseline, as it's the most common type of click effect.
- *
- * @see #get(int)
*/
public static final int EFFECT_CLICK = Effect.CLICK;
/**
* A double click effect.
- *
- * @see #get(int)
*/
public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
/**
* A tick effect. This effect is less strong compared to {@link #EFFECT_CLICK}.
- * @see #get(int)
*/
public static final int EFFECT_TICK = Effect.TICK;
@@ -93,7 +88,6 @@ public abstract class VibrationEffect implements Parcelable {
/**
* A heavy click effect. This effect is stronger than {@link #EFFECT_CLICK}.
- * @see #get(int)
*/
public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
diff --git a/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
index 12503f650ab5..89cd43003529 100644
--- a/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
+++ b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
@@ -28,7 +28,6 @@ import android.content.Context;
* store data needed while a user is locked under device protected storage
* areas.
*
- * @see Context#createCredentialProtectedStorageContext()
* @see Context#createDeviceProtectedStorageContext()
*/
public final class CredentialProtectedWhileLockedViolation extends Violation {
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 9c6c92ace483..17fae1cafe62 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -797,7 +797,6 @@ public final class CalendarContract {
* to changes.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
@@ -1796,7 +1795,6 @@ public final class CalendarContract {
* to changes.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
@@ -2010,7 +2008,6 @@ public final class CalendarContract {
* {@link DevicePolicyManager#setCrossProfileCalendarPackages(ComponentName, Set)}.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index c837b9346173..5e1b22399d57 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -110,6 +110,14 @@ public final class DeviceConfig {
public static final String NAMESPACE_AUTOFILL = "autofill";
/**
+ * Namespace for all Bluetooth related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_BLUETOOTH = "bluetooth";
+
+ /**
* Namespace for all networking connectivity related features.
*
* @hide
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 4bbd213753c2..3980a5f75eda 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ContentInterface;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -248,14 +247,14 @@ public final class DocumentsContract {
* Get string array identifies the type or types of metadata returned
* using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TYPES = "android:documentMetadataTypes";
/**
* Get Exif information using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_EXIF = "android:documentExif";
@@ -263,7 +262,7 @@ public final class DocumentsContract {
* Get total count of all documents currently stored under the given
* directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TREE_COUNT = "android:metadataTreeCount";
@@ -271,7 +270,7 @@ public final class DocumentsContract {
* Get total size of all documents currently stored under the given
* directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TREE_SIZE = "android:metadataTreeSize";
@@ -395,7 +394,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be represented as a thumbnail.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#getDocumentThumbnail(ContentInterface, Uri,
+ * @see DocumentsContract#getDocumentThumbnail(ContentResolver, Uri,
* Point, CancellationSignal)
* @see DocumentsProvider#openDocumentThumbnail(String, Point,
* android.os.CancellationSignal)
@@ -421,7 +420,7 @@ public final class DocumentsContract {
* Flag indicating that a document is deletable.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#deleteDocument(ContentInterface, Uri)
+ * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
* @see DocumentsProvider#deleteDocument(String)
*/
public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
@@ -459,7 +458,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be renamed.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#renameDocument(ContentInterface, Uri, String)
+ * @see DocumentsContract#renameDocument(ContentResolver, Uri, String)
* @see DocumentsProvider#renameDocument(String, String)
*/
public static final int FLAG_SUPPORTS_RENAME = 1 << 6;
@@ -469,7 +468,7 @@ public final class DocumentsContract {
* within the same document provider.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#copyDocument(ContentInterface, Uri, Uri)
+ * @see DocumentsContract#copyDocument(ContentResolver, Uri, Uri)
* @see DocumentsProvider#copyDocument(String, String)
*/
public static final int FLAG_SUPPORTS_COPY = 1 << 7;
@@ -479,7 +478,7 @@ public final class DocumentsContract {
* within the same document provider.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#moveDocument(ContentInterface, Uri, Uri, Uri)
+ * @see DocumentsContract#moveDocument(ContentResolver, Uri, Uri, Uri)
* @see DocumentsProvider#moveDocument(String, String, String)
*/
public static final int FLAG_SUPPORTS_MOVE = 1 << 8;
@@ -503,7 +502,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be removed from a parent.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#removeDocument(ContentInterface, Uri, Uri)
+ * @see DocumentsContract#removeDocument(ContentResolver, Uri, Uri)
* @see DocumentsProvider#removeDocument(String, String)
*/
public static final int FLAG_SUPPORTS_REMOVE = 1 << 10;
@@ -539,7 +538,7 @@ public final class DocumentsContract {
* using DocumentsContract#getDocumentMetadata
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#getDocumentMetadata(ContentInterface, Uri)
+ * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
*/
public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
}
@@ -721,7 +720,7 @@ public final class DocumentsContract {
* Flag indicating that this root can be ejected.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#ejectRoot(ContentInterface, Uri)
+ * @see DocumentsContract#ejectRoot(ContentResolver, Uri)
* @see DocumentsProvider#ejectRoot(String)
*/
public static final int FLAG_SUPPORTS_EJECT = 1 << 5;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7923b586ada5..cadae5cecc6d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12061,17 +12061,6 @@ public final class Settings {
public static final String ALWAYS_ON_DISPLAY_CONSTANTS = "always_on_display_constants";
/**
- * System VDSO global setting. This links to the "sys.vdso" system property.
- * The following values are supported:
- * false -> both 32 and 64 bit vdso disabled
- * 32 -> 32 bit vdso enabled
- * 64 -> 64 bit vdso enabled
- * Any other value defaults to both 32 bit and 64 bit true.
- * @hide
- */
- public static final String SYS_VDSO = "sys_vdso";
-
- /**
* UidCpuPower global setting. This links the sys.uidcpupower system property.
* The following values are supported:
* 0 -> /proc/uid_cpupower/* are disabled
diff --git a/core/java/android/service/autofill/CustomDescription.java b/core/java/android/service/autofill/CustomDescription.java
index c28d2bbe30ea..e274460cdf03 100644
--- a/core/java/android/service/autofill/CustomDescription.java
+++ b/core/java/android/service/autofill/CustomDescription.java
@@ -262,7 +262,7 @@ public final class CustomDescription implements Parcelable {
*
* @param condition condition used to trigger the updates.
* @param updates actions to be applied to the
- * {@link #CustomDescription.Builder(RemoteViews) template presentation} when the condition
+ * {@link #Builder(RemoteViews) template presentation} when the condition
* is satisfied.
*
* @return this builder
diff --git a/core/java/android/service/autofill/ImageTransformation.java b/core/java/android/service/autofill/ImageTransformation.java
index 12376e85e63e..974f0ead9d19 100644
--- a/core/java/android/service/autofill/ImageTransformation.java
+++ b/core/java/android/service/autofill/ImageTransformation.java
@@ -123,7 +123,7 @@ public final class ImageTransformation extends InternalTransformation implements
* {@link RemoteViews presentation} must contain a {@link ImageView} child with that id.
*
* @deprecated use
- * {@link #ImageTransformation.Builder(AutofillId, Pattern, int, CharSequence)} instead.
+ * {@link #Builder(AutofillId, Pattern, int, CharSequence)} instead.
*/
@Deprecated
public Builder(@NonNull AutofillId id, @NonNull Pattern regex, @DrawableRes int resId) {
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 94b9d050a44d..3a70befb3558 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -628,7 +628,7 @@ public final class SaveInfo implements Parcelable {
*
* <p>The sanitizer can also be used as an alternative for a
* {@link #setValidator(Validator) validator}. If any of the {@code ids} is a
- * {@link #SaveInfo.Builder(int, AutofillId[]) required id} and the {@code sanitizer} fails
+ * {@link #Builder(int, AutofillId[]) required id} and the {@code sanitizer} fails
* because of it, then the save UI is not shown.
*
* @param sanitizer an implementation provided by the Android System.
@@ -686,7 +686,7 @@ public final class SaveInfo implements Parcelable {
* Builds a new {@link SaveInfo} instance.
*
* @throws IllegalStateException if no
- * {@link #SaveInfo.Builder(int, AutofillId[]) required ids},
+ * {@link #Builder(int, AutofillId[]) required ids},
* or {@link #setOptionalIds(AutofillId[]) optional ids}, or {@link #FLAG_DELAY_SAVE}
* were set
*/
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index b92731e6d6d4..d64077525905 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -379,8 +379,6 @@ public class PhoneStateListener {
*
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
- *
- * @see #onEmergencyNumberListChanged
*/
public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000;
@@ -459,7 +457,7 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
- * @see #onRegistrationFailed()
+ * @see #onRegistrationFailed
*/
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000;
@@ -470,7 +468,7 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
- * @see #onBarringInfoChanged()
+ * @see #onBarringInfoChanged
*/
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public static final int LISTEN_BARRING_INFO = 0x80000000;
@@ -764,7 +762,8 @@ public class PhoneStateListener {
*
*/
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
- public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
+ public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause,
+ int preciseDisconnectCause) {
// default implementation empty
}
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 248e321df467..8e8409d15143 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -21,7 +21,6 @@ import android.util.TimeFormatException;
import libcore.timezone.ZoneInfoDb;
import libcore.util.ZoneInfo;
-import java.io.IOException;
import java.util.Locale;
import java.util.TimeZone;
@@ -1106,19 +1105,14 @@ public class Time {
}
private static ZoneInfo lookupZoneInfo(String timezoneId) {
- try {
- ZoneInfo zoneInfo = ZoneInfoDb.getInstance().makeTimeZone(timezoneId);
- if (zoneInfo == null) {
- zoneInfo = ZoneInfoDb.getInstance().makeTimeZone("GMT");
- }
- if (zoneInfo == null) {
- throw new AssertionError("GMT not found: \"" + timezoneId + "\"");
- }
- return zoneInfo;
- } catch (IOException e) {
- // This should not ever be thrown.
- throw new AssertionError("Error loading timezone: \"" + timezoneId + "\"", e);
+ ZoneInfo zoneInfo = ZoneInfoDb.getInstance().makeTimeZone(timezoneId);
+ if (zoneInfo == null) {
+ zoneInfo = ZoneInfoDb.getInstance().makeTimeZone("GMT");
+ }
+ if (zoneInfo == null) {
+ throw new AssertionError("GMT not found: \"" + timezoneId + "\"");
}
+ return zoneInfo;
}
public void switchTimeZone(String timezone) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 3a6c8dd3720f..489307beb878 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -189,12 +189,12 @@ public class Surface implements Parcelable {
}
/**
- * Create a Surface assosciated with a given {@link SurfaceControl}. Buffers submitted to this
+ * Create a Surface associated with a given {@link SurfaceControl}. Buffers submitted to this
* surface will be displayed by the system compositor according to the parameters
* specified by the control. Multiple surfaces may be constructed from one SurfaceControl,
* but only one can be connected (e.g. have an active EGL context) at a time.
*
- * @param from The SurfaceControl to assosciate this Surface with
+ * @param from The SurfaceControl to associate this Surface with
*/
public Surface(@NonNull SurfaceControl from) {
copyFrom(from);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index fcd8127bbaa4..4f7bedaf1117 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -2259,7 +2259,7 @@ public final class SurfaceControl implements Parcelable {
}
/**
- * Specify how the buffer assosciated with this Surface is mapped in to the
+ * Specify how the buffer associated with this Surface is mapped in to the
* parent coordinate space. The source frame will be scaled to fit the destination
* frame, after being rotated according to the orientation parameter.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fe60bba92739..40dfcfc391a0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -25801,9 +25801,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Returns the View object that had been passed to the
- * {@link #View.DragShadowBuilder(View)}
+ * {@link #DragShadowBuilder(View)}
* constructor. If that View parameter was {@code null} or if the
- * {@link #View.DragShadowBuilder()}
+ * {@link #DragShadowBuilder()}
* constructor was used to instantiate the builder object, this method will return
* null.
*
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d9d92788a434..859b137dc2ce 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -614,7 +614,6 @@ public interface WindowManager extends ViewManager {
* @see #TYPE_TOAST
* @see #TYPE_SYSTEM_OVERLAY
* @see #TYPE_PRIORITY_PHONE
- * @see #TYPE_STATUS_BAR_PANEL
* @see #TYPE_SYSTEM_DIALOG
* @see #TYPE_KEYGUARD_DIALOG
* @see #TYPE_SYSTEM_ERROR
diff --git a/core/java/android/view/inspector/StaticInspectionCompanionProvider.java b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
index 42a892dedf4d..903fc13a03ea 100644
--- a/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
+++ b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
@@ -21,8 +21,6 @@ import android.annotation.Nullable;
/**
* An inspection companion provider that finds companions as inner classes or generated code.
- *
- * @see android.processor.view.inspector.PlatformInspectableProcessor
*/
public class StaticInspectionCompanionProvider implements InspectionCompanionProvider {
/**
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 9cbb03508d67..f44f24a4d492 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -16,6 +16,8 @@
package android.widget;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.InterpolatorRes;
import android.annotation.NonNull;
@@ -246,6 +248,8 @@ public class ProgressBar extends View {
private AccessibilityEventSender mAccessibilityEventSender;
+ private ObjectAnimator mLastProgressAnimator;
+
/**
* Create a new progress bar with range 0...100 and initial progress of 0.
* @param context the application environment
@@ -1544,8 +1548,19 @@ public class ProgressBar extends View {
animator.setAutoCancel(true);
animator.setDuration(PROGRESS_ANIM_DURATION);
animator.setInterpolator(PROGRESS_ANIM_INTERPOLATOR);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLastProgressAnimator = null;
+ }
+ });
animator.start();
+ mLastProgressAnimator = animator;
} else {
+ if (isPrimary && mLastProgressAnimator != null) {
+ mLastProgressAnimator.cancel();
+ mLastProgressAnimator = null;
+ }
setVisualProgress(id, scale);
}
diff --git a/core/java/com/android/internal/accessibility/OWNERS b/core/java/com/android/internal/accessibility/OWNERS
new file mode 100644
index 000000000000..b3c09e9d539a
--- /dev/null
+++ b/core/java/com/android/internal/accessibility/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 44214
+svetoslavganov@google.com
+pweaver@google.com
+qasid@google.com
diff --git a/core/java/com/android/internal/app/SystemUserHomeActivity.java b/core/java/com/android/internal/app/SystemUserHomeActivity.java
index 26fbf6f826a8..ee936a3f9abc 100644
--- a/core/java/com/android/internal/app/SystemUserHomeActivity.java
+++ b/core/java/com/android/internal/app/SystemUserHomeActivity.java
@@ -17,10 +17,27 @@
package com.android.internal.app;
import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.R;
/**
* Placeholder home activity, which is always installed on the system user. At least one home
* activity must be present and enabled in order for the system to boot.
*/
public class SystemUserHomeActivity extends Activity {
+ private static final String TAG = "SystemUserHome";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.i(TAG, "onCreate");
+ setContentView(R.layout.system_user_home);
+ }
+
+ protected void onDestroy() {
+ super.onDestroy();
+ Log.i(TAG, "onDestroy");
+ }
}
diff --git a/core/java/com/android/internal/compat/OWNERS b/core/java/com/android/internal/compat/OWNERS
index 2b7cdb0cbce9..cfd0a4b079ad 100644
--- a/core/java/com/android/internal/compat/OWNERS
+++ b/core/java/com/android/internal/compat/OWNERS
@@ -2,6 +2,5 @@
platform-compat-eng+reviews@google.com
andreionea@google.com
-atrost@google.com
mathewi@google.com
satayev@google.com
diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java
index 829bd8a5a2a7..8ea5aa815a1c 100644
--- a/core/java/com/android/internal/net/VpnProfile.java
+++ b/core/java/com/android/internal/net/VpnProfile.java
@@ -136,13 +136,19 @@ public final class VpnProfile implements Cloneable, Parcelable {
public boolean isMetered = false; // 21
public int maxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT; // 22
public boolean areAuthParamsInline = false; // 23
+ public final boolean isRestrictedToTestNetworks; // 24
// Helper fields.
@UnsupportedAppUsage
public transient boolean saveLogin = false;
public VpnProfile(String key) {
+ this(key, false);
+ }
+
+ public VpnProfile(String key, boolean isRestrictedToTestNetworks) {
this.key = key;
+ this.isRestrictedToTestNetworks = isRestrictedToTestNetworks;
}
@UnsupportedAppUsage
@@ -171,6 +177,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
isMetered = in.readBoolean();
maxMtu = in.readInt();
areAuthParamsInline = in.readBoolean();
+ isRestrictedToTestNetworks = in.readBoolean();
}
/**
@@ -220,6 +227,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
out.writeBoolean(isMetered);
out.writeInt(maxMtu);
out.writeBoolean(areAuthParamsInline);
+ out.writeBoolean(isRestrictedToTestNetworks);
}
/**
@@ -237,12 +245,21 @@ public final class VpnProfile implements Cloneable, Parcelable {
String[] values = new String(value, StandardCharsets.UTF_8).split(VALUE_DELIMITER, -1);
// Acceptable numbers of values are:
// 14-19: Standard profile, with option for serverCert, proxy
- // 24: Standard profile with serverCert, proxy and platform-VPN parameters.
- if ((values.length < 14 || values.length > 19) && values.length != 24) {
+ // 24: Standard profile with serverCert, proxy and platform-VPN parameters
+ // 25: Standard profile with platform-VPN parameters and isRestrictedToTestNetworks
+ if ((values.length < 14 || values.length > 19)
+ && values.length != 24 && values.length != 25) {
return null;
}
- VpnProfile profile = new VpnProfile(key);
+ final boolean isRestrictedToTestNetworks;
+ if (values.length >= 25) {
+ isRestrictedToTestNetworks = Boolean.parseBoolean(values[24]);
+ } else {
+ isRestrictedToTestNetworks = false;
+ }
+
+ VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks);
profile.name = values[0];
profile.type = Integer.parseInt(values[1]);
if (profile.type < 0 || profile.type > TYPE_MAX) {
@@ -283,6 +300,8 @@ public final class VpnProfile implements Cloneable, Parcelable {
profile.areAuthParamsInline = Boolean.parseBoolean(values[23]);
}
+ // isRestrictedToTestNetworks (values[24]) assigned as part of the constructor
+
profile.saveLogin = !profile.username.isEmpty() || !profile.password.isEmpty();
return profile;
} catch (Exception e) {
@@ -330,6 +349,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
builder.append(VALUE_DELIMITER).append(isMetered);
builder.append(VALUE_DELIMITER).append(maxMtu);
builder.append(VALUE_DELIMITER).append(areAuthParamsInline);
+ builder.append(VALUE_DELIMITER).append(isRestrictedToTestNetworks);
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
@@ -421,7 +441,8 @@ public final class VpnProfile implements Cloneable, Parcelable {
return Objects.hash(
key, type, server, username, password, dnsServers, searchDomains, routes, mppe,
l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert,
- proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline);
+ proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline,
+ isRestrictedToTestNetworks);
}
/** Checks VPN profiles for interior equality. */
@@ -453,7 +474,8 @@ public final class VpnProfile implements Cloneable, Parcelable {
&& isBypassable == other.isBypassable
&& isMetered == other.isMetered
&& maxMtu == other.maxMtu
- && areAuthParamsInline == other.areAuthParamsInline;
+ && areAuthParamsInline == other.areAuthParamsInline
+ && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks;
}
@NonNull
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 8182d60ef459..8b659f927633 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -18,6 +18,7 @@ package com.android.internal.os;
import android.os.SystemProperties;
import android.sysprop.CryptoProperties;
+import android.sysprop.HdmiProperties;
/**
* This is a cache of various ro.* properties so that they can be read just once
@@ -37,16 +38,7 @@ public class RoSystemProperties {
* mode is off.
*/
public static final boolean CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF =
- SystemProperties.getBoolean(
- "ro.hdmi.cec_audio_device_forward_volume_keys_system_audio_mode_off", false);
-
- /**
- * Property to indicate if the current device is a cec switch device.
- *
- * <p> Default is false.
- */
- public static final String PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH =
- "ro.hdmi.property_is_device_hdmi_cec_switch";
+ HdmiProperties.forward_volume_keys_when_system_audio_mode_off().orElse(false);
// ------ ro.config.* -------- //
public static final boolean CONFIG_AVOID_GFX_ACCEL =
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index b30fed674309..544340eaba89 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -693,6 +693,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
char extraOptsBuf[PROPERTY_VALUE_MAX];
char voldDecryptBuf[PROPERTY_VALUE_MAX];
+ char perfettoHprofOptBuf[sizeof("-XX:PerfettoHprof=") + PROPERTY_VALUE_MAX];
enum {
kEMDefault,
kEMIntPortable,
@@ -807,6 +808,16 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
addOption("-verbose:gc");
//addOption("-verbose:class");
+ // On Android, we always want to allow loading the PerfettoHprof plugin.
+ // Even with this option set, we will still only actually load the plugin
+ // if we are on a userdebug build or the app is debuggable or profileable.
+ // This is enforced in art/runtime/runtime.cc.
+ //
+ // We want to be able to disable this, because this does not work on host,
+ // and we do not want to enable it in tests.
+ parseRuntimeOption("dalvik.vm.perfetto_hprof", perfettoHprofOptBuf, "-XX:PerfettoHprof=",
+ "true");
+
if (primary_zygote) {
addOption("-Xprimaryzygote");
}
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index 10c30260d7e3..913952f9e76c 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -111,7 +111,7 @@ static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPt
jlong transformPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom) {
FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
- FPDF_PAGE* page = (FPDF_PAGE*) FPDF_LoadPage(document, pageIndex);
+ FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
if (!page) {
jniThrowException(env, "java/lang/IllegalStateException",
"cannot open page");
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index d723ecc13dd0..eb8d26e7bf71 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -475,7 +475,11 @@ static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, j
if (fd < 0) return NULL;
fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0) return NULL;
- return jniCreateFileDescriptor(env, fd);
+ jobject jifd = jniCreateFileDescriptor(env, fd);
+ if (jifd == NULL) {
+ close(fd);
+ }
+ return jifd;
}
return NULL;
}
diff --git a/core/jni/android_os_SharedMemory.cpp b/core/jni/android_os_SharedMemory.cpp
index c33405def25e..a812c35036f3 100644
--- a/core/jni/android_os_SharedMemory.cpp
+++ b/core/jni/android_os_SharedMemory.cpp
@@ -69,7 +69,11 @@ jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) {
return nullptr;
}
- return jniCreateFileDescriptor(env, fd);
+ jobject jifd = jniCreateFileDescriptor(env, fd);
+ if (jifd == nullptr) {
+ close(fd);
+ }
+ return jifd;
}
jint SharedMemory_nGetSize(JNIEnv* env, jobject, jobject fileDescriptor) {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index ca4735ec665a..8fc1758c44dc 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -35,6 +35,7 @@
static const char* kPathWhitelist[] = {
"/apex/com.android.conscrypt/javalib/conscrypt.jar",
"/apex/com.android.ipsec/javalib/ike.jar",
+ "/apex/com.android.i18n/javalib/core-icu4j.jar",
"/apex/com.android.media/javalib/updatable-media.jar",
"/apex/com.android.sdkext/javalib/framework-sdkextensions.jar",
"/apex/com.android.tethering/javalib/framework-tethering.jar",
@@ -81,11 +82,18 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
}
// Framework jars are allowed.
- static const char* kFrameworksPrefix = "/system/framework/";
+ static const char* kFrameworksPrefix[] = {
+ "/system/framework/",
+ "/system_ext/framework/",
+ };
+
static const char* kJarSuffix = ".jar";
- if (android::base::StartsWith(path, kFrameworksPrefix)
- && android::base::EndsWith(path, kJarSuffix)) {
- return true;
+
+ for (const auto& frameworks_prefix : kFrameworksPrefix) {
+ if (android::base::StartsWith(path, frameworks_prefix)
+ && android::base::EndsWith(path, kJarSuffix)) {
+ return true;
+ }
}
// Jars from the ART APEX are allowed.
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 3d99b726e6fe..829e1f7d0d96 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -905,13 +905,8 @@ message GlobalSettingsProto {
optional SettingProto storage_full_threshold_bytes = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto storage_cache_percentage = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto storage_cache_max_bytes = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // System VDSO global setting. This links to the "sys.vdso" system property.
- // The following values are supported:
- // false -> both 32 and 64 bit vdso disabled
- // 32 -> 32 bit vdso enabled
- // 64 -> 64 bit vdso enabled
- // Any other value defaults to both 32 bit and 64 bit true.
- optional SettingProto vdso = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Used to be sys_vdso
+ reserved 7;
// UidCpuPower global setting. This links the sys.uidcpupower system property.
// The following values are supported:
// 0 -> /proc/uid_cpupower/* are disabled
diff --git a/packages/Shell/res/layout/null_home_finishing_boot.xml b/core/res/res/layout/system_user_home.xml
index 5f9563a5d25c..8afa42338e36 100644
--- a/packages/Shell/res/layout/null_home_finishing_boot.xml
+++ b/core/res/res/layout/system_user_home.xml
@@ -30,9 +30,9 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="40sp"
+ android:textSize="20sp"
android:textColor="?android:attr/textColorPrimary"
- android:text="@*android:string/android_start_title"/>
+ android:text="Framework Fallback Home"/>
<ProgressBar
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
diff --git a/core/res/res/values-mcc334-mnc020/config.xml b/core/res/res/values-mcc334-mnc020/config.xml
index 0970517835b6..82b3ee6448e3 100644
--- a/core/res/res/values-mcc334-mnc020/config.xml
+++ b/core/res/res/values-mcc334-mnc020/config.xml
@@ -18,4 +18,7 @@
-->
<resources>
<bool name="config_use_sim_language_file">false</bool>
-</resources> \ No newline at end of file
+
+ <bool name="config_pdp_reject_enable_retry">true</bool>
+ <integer name="config_pdp_reject_retry_delay_ms">45000</integer>
+</resources>
diff --git a/core/res/res/values-mcc334-mnc020/strings.xml b/core/res/res/values-mcc334-mnc020/strings.xml
new file mode 100644
index 000000000000..91b560aeef7e
--- /dev/null
+++ b/core/res/res/values-mcc334-mnc020/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2020, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="config_pdp_reject_dialog_title"></string>
+ <string name="config_pdp_reject_user_authentication_failed">AUTHENTICATION FAILURE -29-.</string>
+ <string name="config_pdp_reject_service_not_subscribed">NOT SUBSCRIBED TO SERVICE -33-.</string>
+ <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed">Multiple PDN connections for a given APN not allowed -55-.</string>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2f301946402b..b908ab8b709e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4742,7 +4742,7 @@
May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
When not specified or an empty string is given, it will fallback to the default one.
{@see android.os.LocaleList#forLanguageTags(String)}
- {@see android.text.TextView#setTextLocales(android.os.LocaleList)} -->
+ {@see android.widget.TextView#setTextLocales(android.os.LocaleList)} -->
<attr name="textLocale" format="string" />
<!-- Text color for links. -->
<attr name="textColorLink" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d7ab426ec9dd..6551b28bd5a3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -419,13 +419,14 @@
<!-- Regex of wired ethernet ifaces -->
<string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
-
-
<!-- Configuration of Ethernet interfaces in the following format:
<interface name|mac address>;[Network Capabilities];[IP config];[Override Transport]
Where
[Network Capabilities] Optional. A comma seprated list of network capabilities.
- Values must be from NetworkCapabilities#NET_CAPABILITIES_* constants.
+ Values must be from NetworkCapabilities#NET_CAPABILITY_* constants.
+ The NOT_ROAMING, NOT_CONGESTED and NOT_SUSPENDED capabilities are always
+ added automatically because this configuration provides no way to update
+ them dynamically.
[IP config] Optional. If empty or not specified - DHCP will be used, otherwise
use the following format to specify static IP configuration:
ip=<ip-address/mask> gateway=<ip-address> dns=<comma-sep-ip-addresses>
@@ -451,10 +452,6 @@
-->
</string-array>
- <!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] -->
- <string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastservice
- </string>
-
<!-- If the mobile hotspot feature requires provisioning, a package name and class name
can be provided to launch a supported application that provisions the devices.
@@ -4367,4 +4364,9 @@
<!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing
check after reboot or airplane mode toggling -->
<bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
+
+ <!-- pdp data retry for cause 29, 33 and 55-->
+ <bool name="config_pdp_reject_enable_retry">false</bool>
+ <!--pdp data reject retry delay in ms-->
+ <integer name="config_pdp_reject_retry_delay_ms">-1</integer>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7f463807e1e9..12fc1bb8553c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5653,4 +5653,10 @@ ul.</string>
<string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS">IMPI unlock successful.</string>
<!-- Success message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
<string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS">Network subset service provider unlock successful.</string>
+
+ <!-- pdp data reject dialog string for cause 29, 33 and 55-->
+ <string name="config_pdp_reject_dialog_title"></string>
+ <string name="config_pdp_reject_user_authentication_failed"></string>
+ <string name="config_pdp_reject_service_not_subscribed"></string>
+ <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed"></string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 355186cc507b..3cee3407296c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -745,7 +745,6 @@
<java-symbol type="string" name="config_ethernet_iface_regex" />
<java-symbol type="array" name="config_ethernet_interfaces" />
<java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
- <java-symbol type="string" name="cellbroadcast_default_package" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
@@ -1546,6 +1545,7 @@
<java-symbol type="layout" name="select_dialog" />
<java-symbol type="layout" name="simple_dropdown_hint" />
<java-symbol type="layout" name="status_bar_latest_event_content" />
+ <java-symbol type="layout" name="system_user_home" />
<java-symbol type="layout" name="text_edit_action_popup_text" />
<java-symbol type="layout" name="text_drag_thumbnail" />
<java-symbol type="layout" name="typing_filter" />
@@ -3871,4 +3871,12 @@
<java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
<java-symbol type="bool" name="reset_geo_fencing_check_after_boot_or_apm" />
+
+ <!-- For Pdn throttle feature -->
+ <java-symbol type="bool" name="config_pdp_reject_enable_retry" />
+ <java-symbol type="integer" name="config_pdp_reject_retry_delay_ms" />
+ <java-symbol type="string" name="config_pdp_reject_dialog_title" />
+ <java-symbol type="string" name="config_pdp_reject_user_authentication_failed" />
+ <java-symbol type="string" name="config_pdp_reject_service_not_subscribed" />
+ <java-symbol type="string" name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" />
</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 70917e76f8b4..d5733e34a8ef 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -39,7 +39,7 @@
<!-- Albania: 5 digits, known short codes listed -->
<shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
- <!-- Argentia: 5 digits, known short codes listed -->
+ <!-- Argentina: 5 digits, known short codes listed -->
<shortcode country="ar" pattern="\\d{5}" free="11711|28291" />
<!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
@@ -70,7 +70,7 @@
<shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
<!-- Canada: 5-6 digits -->
- <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" />
+ <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" free="455677" />
<!-- 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|30075|30047" />
diff --git a/core/tests/PlatformCompatFramework/OWNERS b/core/tests/PlatformCompatFramework/OWNERS
index 2b7cdb0cbce9..cfd0a4b079ad 100644
--- a/core/tests/PlatformCompatFramework/OWNERS
+++ b/core/tests/PlatformCompatFramework/OWNERS
@@ -2,6 +2,5 @@
platform-compat-eng+reviews@google.com
andreionea@google.com
-atrost@google.com
mathewi@google.com
satayev@google.com
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 802b106a107c..cb91db1934a4 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -454,7 +454,6 @@ public class SettingsBackupTest {
Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES,
Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE,
- Settings.Global.SYS_VDSO,
Settings.Global.SYS_UIDCPUPOWER,
Settings.Global.SYS_TRACED,
Settings.Global.FPS_DEVISOR,
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
new file mode 100644
index 000000000000..2194d4b030ce
--- /dev/null
+++ b/core/tests/hdmitests/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 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: "HdmiCecTests",
+ // Include all test java files
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "frameworks-base-testutils",
+ "truth-prebuilt",
+ ],
+ libs: ["android.test.runner"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/core/tests/hdmitests/Android.mk b/core/tests/hdmitests/Android.mk
deleted file mode 100644
index f155feba0588..000000000000
--- a/core/tests/hdmitests/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018 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
-
-# Include all test java files
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules frameworks-base-testutils truth-prebuilt
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_PACKAGE_NAME := HdmiCecTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/core/tests/packagemanagertests/Android.bp b/core/tests/packagemanagertests/Android.bp
new file mode 100644
index 000000000000..6f39af8bd468
--- /dev/null
+++ b/core/tests/packagemanagertests/Android.bp
@@ -0,0 +1,14 @@
+android_test {
+ name: "FrameworksCorePackageManagerTests",
+ // We only want this apk build for tests.
+ // Include all test java files.
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "frameworks-base-testutils",
+ "mockito-target-minus-junit4",
+ ],
+ libs: ["android.test.runner"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/core/tests/packagemanagertests/Android.mk b/core/tests/packagemanagertests/Android.mk
deleted file mode 100644
index 8c00d14ce856..000000000000
--- a/core/tests/packagemanagertests/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules \
- frameworks-base-testutils \
- mockito-target-minus-junit4
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_PACKAGE_NAME := FrameworksCorePackageManagerTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp
new file mode 100644
index 000000000000..7f5699287796
--- /dev/null
+++ b/core/tests/privacytests/Android.bp
@@ -0,0 +1,14 @@
+android_test {
+ name: "FrameworksPrivacyLibraryTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "junit",
+ "rappor-tests",
+ "androidx.test.rules",
+ "truth-prebuilt",
+ ],
+ libs: ["android.test.runner"],
+ platform_apis: true,
+ certificate: "platform",
+ test_suites: ["device-tests"],
+}
diff --git a/core/tests/privacytests/Android.mk b/core/tests/privacytests/Android.mk
deleted file mode 100644
index 7765977c03e8..000000000000
--- a/core/tests/privacytests/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := junit rappor-tests androidx.test.rules truth-prebuilt
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_PACKAGE_NAME := FrameworksPrivacyLibraryTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp
index ca655f18149c..4b43b4136076 100644
--- a/core/xsd/vts/Android.bp
+++ b/core/xsd/vts/Android.bp
@@ -40,3 +40,7 @@ cc_test {
],
test_config: "vts_permission_validate_test.xml",
}
+
+vts_config {
+ name: "VtsValidatePermission",
+}
diff --git a/core/xsd/vts/Android.mk b/core/xsd/vts/Android.mk
deleted file mode 100644
index a5754a494d94..000000000000
--- a/core/xsd/vts/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := VtsValidatePermission
-include test/vts/tools/build/Android.host_config.mk
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a1c8e1366803..5b0ef8ef2130 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -291,6 +291,7 @@ applications that come with the platform
<permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
<permission name="android.permission.MANAGE_USB"/>
<permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
+ <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/data/fonts/Android.bp b/data/fonts/Android.bp
new file mode 100644
index 000000000000..94e6a8096849
--- /dev/null
+++ b/data/fonts/Android.bp
@@ -0,0 +1,36 @@
+// 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.
+
+prebuilt_font {
+ name: "DroidSansMono.ttf",
+ src: "DroidSansMono.ttf",
+ required: [
+ "DroidSans.ttf",
+ "DroidSans-Bold.ttf",
+ ],
+}
+
+prebuilt_font {
+ name: "AndroidClock.ttf",
+ src: "AndroidClock.ttf",
+}
+
+/////////////////////////////////
+// Copies the font configuration file into system/etc for the product as fonts.xml.
+// Additional fonts should be installed to /product/fonts/ alongside a corresponding
+// fonts_customiztion.xml in /product/etc/
+prebuilt_etc {
+ name: "fonts.xml",
+ src: "fonts.xml",
+}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 4226e0882538..e22b72346249 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -12,9 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# We have to use BUILD_PREBUILT instead of PRODUCT_COPY_FIES,
-# because MINIMAL_FONT_FOOTPRINT is only available in Android.mks.
-
LOCAL_PATH := $(call my-dir)
##########################################
@@ -37,61 +34,7 @@ endef
##########################################
$(eval $(call create-font-symlink,DroidSans.ttf,Roboto-Regular.ttf))
$(eval $(call create-font-symlink,DroidSans-Bold.ttf,Roboto-Bold.ttf))
-$(eval $(call create-font-symlink,DroidSerif-Regular.ttf,NotoSerif-Regular.ttf))
-$(eval $(call create-font-symlink,DroidSerif-Bold.ttf,NotoSerif-Bold.ttf))
-$(eval $(call create-font-symlink,DroidSerif-Italic.ttf,NotoSerif-Italic.ttf))
-$(eval $(call create-font-symlink,DroidSerif-BoldItalic.ttf,NotoSerif-BoldItalic.ttf))
-
-extra_font_files := \
- DroidSans.ttf \
- DroidSans-Bold.ttf
-
-################################
-# Use DroidSansMono to hang extra_font_files on
-include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSansMono.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-LOCAL_REQUIRED_MODULES := $(extra_font_files)
-include $(BUILD_PREBUILT)
-extra_font_files :=
-
-################################
-# Build the rest of font files as prebuilt.
-
-# $(1): The source file name in LOCAL_PATH.
-# It also serves as the module name and the dest file name.
-define build-one-font-module
-$(eval include $(CLEAR_VARS))\
-$(eval LOCAL_MODULE := $(1))\
-$(eval LOCAL_SRC_FILES := $(1))\
-$(eval LOCAL_MODULE_CLASS := ETC)\
-$(eval LOCAL_MODULE_TAGS := optional)\
-$(eval LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts)\
-$(eval include $(BUILD_PREBUILT))
-endef
-
-font_src_files := \
- AndroidClock.ttf
-
-$(foreach f, $(font_src_files), $(call build-one-font-module, $(f)))
-
-build-one-font-module :=
-font_src_files :=
-
-################################
-# Copies the font configuration file into system/etc for the product as fonts.xml.
-# Additional fonts should be installed to /product/fonts/ alongside a corresponding
-# fonts_customiztion.xml in /product/etc/
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fonts.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_PREBUILT_MODULE_FILE := frameworks/base/data/fonts/fonts.xml
-include $(BUILD_PREBUILT)
# Run sanity tests on fonts on checkbuild
checkbuild: fontchain_lint
diff --git a/data/keyboards/Vendor_0f0d_Product_00c1.kl b/data/keyboards/Vendor_0f0d_Product_00c1.kl
new file mode 100644
index 000000000000..c74512a3a4b0
--- /dev/null
+++ b/data/keyboards/Vendor_0f0d_Product_00c1.kl
@@ -0,0 +1,55 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Device name: HORI CO.,LTD. HORIPAD S
+# HORIPAD for Nintendo Switch, USB game controller
+# https://hori.co.uk/horipad-for-nintendo-switch/
+
+# Button labeled as "Y" but should really produce keycode "X"
+key 0x130 BUTTON_X
+# Button labeled as "B" but should really produce keycode "A"
+key 0x131 BUTTON_A
+# Button labeled as "A" but should really produce keycode "B"
+key 0x132 BUTTON_B
+# Button labeled as "X" but should really product keycode "Y"
+key 0x133 BUTTON_Y
+
+key 0x134 BUTTON_L1
+key 0x135 BUTTON_R1
+key 0x136 BUTTON_L2
+key 0x137 BUTTON_R2
+
+# Minus
+key 0x138 BUTTON_SELECT
+# Plus
+key 0x139 BUTTON_START
+
+# Analog stick buttons
+key 0x13a BUTTON_THUMBL
+key 0x13b BUTTON_THUMBR
+
+# Home
+key 0x13c HOME
+# Capture
+key 0x13d BUTTON_MODE
+
+# Left analog stick
+axis 0x00 X
+axis 0x01 Y
+# Right analog stick
+axis 0x02 Z
+axis 0x05 RZ
+# D-pad
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index ae7fe6c46f2f..c3c56dbbc6aa 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -998,7 +998,7 @@ public final class RenderNode {
* Sets the rotation value for the display list around the Z axis.
*
* @param rotation The rotation value of the display list, in degrees
- * @see View#setRotationZ(float)
+ * @see View#setRotation(float)
* @see #getRotationZ()
* @return True if the value changed, false if the new value was the same as the previous value.
*/
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index e70529b6cd1a..9cf12f121e0a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -617,7 +617,7 @@ public abstract class Drawable {
* {@link #setTintList(ColorStateList) tint}.
* </p>
*
- * @see {@link #setColorFilter(ColorFilter)} }
+ * @see #setColorFilter(ColorFilter)
* @deprecated use {@link #setColorFilter(ColorFilter)} with an instance
* of {@link android.graphics.BlendModeColorFilter}
*/
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
index af517d623b01..09799fdf5a13 100644
--- a/graphics/java/android/graphics/fonts/FontStyle.java
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -217,7 +217,7 @@ public final class FontStyle {
/**
* Gets the weight value
*
- * @see FontStyle#setWeight(int)
+ * @see #FontStyle(int, int)
* @return a weight value
*/
public @IntRange(from = 0, to = 1000) int getWeight() {
diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
index 54622c5e74df..babcfc3815f4 100644
--- a/graphics/java/android/graphics/text/LineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -320,7 +320,7 @@ public class LineBreaker {
/**
* Returns the array of tab stops in pixels.
*
- * @see #setTabStops(float[], int)
+ * @see #setTabStops
*/
public @Nullable float[] getTabStops() {
return mVariableTabStops;
@@ -329,7 +329,7 @@ public class LineBreaker {
/**
* Returns the default tab stops in pixels.
*
- * @see #setTabStop(float[], int)
+ * @see #setTabStops
*/
public @Px @FloatRange(from = 0) float getDefaultTabStop() {
return mDefaultTabStop;
diff --git a/identity/java/android/security/identity/AccessControlProfileId.java b/identity/java/android/security/identity/AccessControlProfileId.java
index 3d5945065ad7..6caac0a8a065 100644
--- a/identity/java/android/security/identity/AccessControlProfileId.java
+++ b/identity/java/android/security/identity/AccessControlProfileId.java
@@ -25,6 +25,8 @@ public class AccessControlProfileId {
/**
* Constructs a new object holding a numerical identifier.
*
+ * <p>The identifier must be a non-negative number and less than 32.
+ *
* @param id the identifier.
*/
public AccessControlProfileId(int id) {
diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java
index 4f834d2b87b5..3843d9279900 100644
--- a/identity/java/android/security/identity/IdentityCredentialStore.java
+++ b/identity/java/android/security/identity/IdentityCredentialStore.java
@@ -46,7 +46,7 @@ import java.lang.annotation.RetentionPolicy;
* access control profile IDs. Names are strings and values are typed and can be any
* value supported by <a href="http://cbor.io/">CBOR</a>.</li>
*
- * <li>A set of access control profiles, each with a profile ID and a specification
+ * <li>A set of access control profiles (up to 32), each with a profile ID and a specification
* of the conditions which satisfy the profile's requirements.</li>
*
* <li>An asymmetric key pair which is used to authenticate the credential to the Issuing
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index e9bc8026d25e..d35642e362b1 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1067,6 +1067,17 @@ public class KeyStore {
return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
}
+ /**
+ * Notify keystore about the latest user locked state. This is to support keyguard-bound key.
+ */
+ public void onUserLockedStateChanged(int userHandle, boolean locked) {
+ try {
+ mBinder.onKeyguardVisibilityChanged(locked, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to update user locked state " + userHandle, e);
+ }
+ }
+
private class KeyAttestationCallbackResult {
private KeystoreResponse keystoreResponse;
private KeymasterCertificateChain certificateChain;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 91aac8367976..11775caa8ad4 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -17,11 +17,10 @@
package android.security.keystore;
import android.annotation.Nullable;
+import android.os.Build;
import android.security.Credentials;
-import android.security.GateKeeper;
import android.security.KeyPairGeneratorSpec;
import android.security.KeyStore;
-import android.security.KeyStoreException;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterCertificateChain;
@@ -52,6 +51,7 @@ import libcore.util.EmptyArray;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@@ -494,6 +494,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
if (challenge != null) {
KeymasterArguments args = new KeymasterArguments();
args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge);
+
+ if (mSpec.isDevicePropertiesAttestationIncluded()) {
+ args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND,
+ Build.BRAND.getBytes(StandardCharsets.UTF_8));
+ args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE,
+ Build.DEVICE.getBytes(StandardCharsets.UTF_8));
+ args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT,
+ Build.PRODUCT.getBytes(StandardCharsets.UTF_8));
+ args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER,
+ Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8));
+ args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL,
+ Build.MODEL.getBytes(StandardCharsets.UTF_8));
+ }
+
return getAttestationChain(privateKeyAlias, keyPair, args);
}
@@ -603,8 +617,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
private Iterable<byte[]> getAttestationChain(String privateKeyAlias,
KeyPair keyPair, KeymasterArguments args)
throws ProviderException {
- KeymasterCertificateChain outChain = new KeymasterCertificateChain();
- int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
+ final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
+ final int errorCode;
+ if (mSpec.isDevicePropertiesAttestationIncluded()
+ && mSpec.getAttestationChallenge() == null) {
+ throw new ProviderException("An attestation challenge must be provided when requesting "
+ + "device properties attestation.");
+ }
+ errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
if (errorCode != KeyStore.NO_ERROR) {
throw new ProviderException("Failed to generate attestation certificate chain",
KeyStore.getKeyStoreException(errorCode));
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 630a6dd081a3..e7e410a9ddb3 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -24,6 +24,7 @@ import android.app.KeyguardManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
+import android.os.Build;
import android.security.GateKeeper;
import android.security.KeyStore;
import android.text.TextUtils;
@@ -264,6 +265,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mUserPresenceRequired;
private final byte[] mAttestationChallenge;
+ private final boolean mDevicePropertiesAttestationIncluded;
private final boolean mUniqueIdIncluded;
private final boolean mUserAuthenticationValidWhileOnBody;
private final boolean mInvalidatedByBiometricEnrollment;
@@ -301,6 +303,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
int userAuthenticationValidityDurationSeconds,
boolean userPresenceRequired,
byte[] attestationChallenge,
+ boolean devicePropertiesAttestationIncluded,
boolean uniqueIdIncluded,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
@@ -350,6 +353,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
mUserPresenceRequired = userPresenceRequired;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge);
+ mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded;
mUniqueIdIncluded = uniqueIdIncluded;
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
@@ -644,6 +648,21 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
}
/**
+ * Returns {@code true} if attestation for the base device properties ({@link Build#BRAND},
+ * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, {@link Build#PRODUCT})
+ * was requested to be added in the attestation certificate for the generated key.
+ *
+ * {@link javax.crypto.KeyGenerator#generateKey()} will throw
+ * {@link java.security.ProviderException} if device properties attestation fails or is not
+ * supported.
+ *
+ * @see Builder#setDevicePropertiesAttestationIncluded(boolean)
+ */
+ public boolean isDevicePropertiesAttestationIncluded() {
+ return mDevicePropertiesAttestationIncluded;
+ }
+
+ /**
* @hide This is a system-only API
*
* Returns {@code true} if the attestation certificate will contain a unique ID field.
@@ -734,6 +753,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
private int mUserAuthenticationValidityDurationSeconds = -1;
private boolean mUserPresenceRequired = false;
private byte[] mAttestationChallenge = null;
+ private boolean mDevicePropertiesAttestationIncluded = false;
private boolean mUniqueIdIncluded = false;
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
@@ -797,6 +817,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
sourceSpec.getUserAuthenticationValidityDurationSeconds();
mUserPresenceRequired = sourceSpec.isUserPresenceRequired();
mAttestationChallenge = sourceSpec.getAttestationChallenge();
+ mDevicePropertiesAttestationIncluded =
+ sourceSpec.isDevicePropertiesAttestationIncluded();
mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded();
mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody();
mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment();
@@ -1252,6 +1274,31 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
}
/**
+ * Sets whether to include the base device properties in the attestation certificate.
+ *
+ * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for
+ * this key pair will contain an extension that describes the details of the key's
+ * configuration and authorizations, including the device properties values (brand, device,
+ * manufacturer, model, product). These should be the same as in ({@link Build#BRAND},
+ * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL},
+ * {@link Build#PRODUCT}). The attestation certificate chain can
+ * be retrieved with {@link java.security.KeyStore#getCertificateChain(String)}.
+ *
+ * <p> If {@code attestationChallenge} is {@code null}, the public key certificate for
+ * this key pair will not contain the extension with the requested attested values.
+ *
+ * <p> {@link javax.crypto.KeyGenerator#generateKey()} will throw
+ * {@link java.security.ProviderException} if device properties attestation fails or is not
+ * supported.
+ */
+ @NonNull
+ public Builder setDevicePropertiesAttestationIncluded(
+ boolean devicePropertiesAttestationIncluded) {
+ mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded;
+ return this;
+ }
+
+ /**
* @hide Only system apps can use this method.
*
* Sets whether to include a temporary unique ID field in the attestation certificate.
@@ -1360,6 +1407,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
mUserAuthenticationValidityDurationSeconds,
mUserPresenceRequired,
mAttestationChallenge,
+ mDevicePropertiesAttestationIncluded,
mUniqueIdIncluded,
mUserAuthenticationValidWhileOnBody,
mInvalidatedByBiometricEnrollment,
diff --git a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
index d8030fb8ab79..0518f45ae1bb 100644
--- a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
@@ -16,8 +16,8 @@
package android.security.keystore;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
@@ -99,6 +99,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
out.writeInt(mSpec.getUserAuthenticationValidityDurationSeconds());
out.writeBoolean(mSpec.isUserPresenceRequired());
out.writeByteArray(mSpec.getAttestationChallenge());
+ out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded());
out.writeBoolean(mSpec.isUniqueIdIncluded());
out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody());
out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment());
@@ -154,6 +155,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
final int userAuthenticationValidityDurationSeconds = in.readInt();
final boolean userPresenceRequired = in.readBoolean();
final byte[] attestationChallenge = in.createByteArray();
+ final boolean devicePropertiesAttestationIncluded = in.readBoolean();
final boolean uniqueIdIncluded = in.readBoolean();
final boolean userAuthenticationValidWhileOnBody = in.readBoolean();
final boolean invalidatedByBiometricEnrollment = in.readBoolean();
@@ -185,6 +187,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
userAuthenticationValidityDurationSeconds,
userPresenceRequired,
attestationChallenge,
+ devicePropertiesAttestationIncluded,
uniqueIdIncluded,
userAuthenticationValidWhileOnBody,
invalidatedByBiometricEnrollment,
diff --git a/lowpan/tests/Android.bp b/lowpan/tests/Android.bp
new file mode 100644
index 000000000000..ad2bc27d1b39
--- /dev/null
+++ b/lowpan/tests/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 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.
+
+// Make test APK
+// ============================================================
+android_test {
+ name: "FrameworksLowpanApiTests",
+ srcs: ["**/*.java"],
+ // Filter all src files to just java files
+ jacoco: {
+ include_filter: ["android.net.lowpan.*"],
+ exclude_filter: [
+ "android.net.lowpan.LowpanInterfaceTest*",
+ "android.net.lowpan.LowpanManagerTest*",
+ ],
+ },
+ static_libs: [
+ "androidx.test.rules",
+ "guava",
+ "mockito-target-minus-junit4",
+ "frameworks-base-testutils",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ ],
+ platform_apis: true,
+ test_suites: ["device-tests"],
+ certificate: "platform",
+}
diff --git a/lowpan/tests/Android.mk b/lowpan/tests/Android.mk
deleted file mode 100644
index 832ed2f53f7b..000000000000
--- a/lowpan/tests/Android.mk
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Make test APK
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-# This list is generated from the java source files in this module
-# The list is a comma separated list of class names with * matching zero or more characters.
-# Example:
-# Input files: src/com/android/server/lowpan/Test.java src/com/android/server/lowpan/AnotherTest.java
-# Generated exclude list: com.android.server.lowpan.Test*,com.android.server.lowpan.AnotherTest*
-
-# Filter all src files to just java files
-local_java_files := $(filter %.java,$(LOCAL_SRC_FILES))
-# Transform java file names into full class names.
-# This only works if the class name matches the file name and the directory structure
-# matches the package.
-local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files)))
-# Convert class name list to jacoco exclude list
-# This appends a * to all classes and replace the space separators with commas.
-# These patterns will match all classes in this module and their inner classes.
-jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
-
-jacoco_include := android.net.lowpan.*
-
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include)
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules \
- guava \
- mockito-target-minus-junit4 \
- frameworks-base-testutils \
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.runner \
- android.test.base \
-
-LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_CERTIFICATE := platform
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-include $(BUILD_PACKAGE)
diff --git a/media/Android.bp b/media/Android.bp
index 43635684d9b3..a432c8d2a64d 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -26,8 +26,10 @@ java_library {
installable: true,
- // Make sure that the implementaion only relies on SDK or system APIs.
+ // TODO: build against stable API surface. Use core_platform for now to avoid
+ // link-check failure with exoplayer building against "current".
sdk_version: "core_platform",
+ min_sdk_version: "29",
libs: [
// The order matters. android_system_* library should come later.
"framework_media_annotation",
@@ -94,4 +96,5 @@ java_library {
name: "framework_media_annotation",
srcs: [":framework-media-annotation-srcs"],
installable: false,
+ sdk_version: "core_current",
}
diff --git a/media/java/android/media/AudioFocusRequest.java b/media/java/android/media/AudioFocusRequest.java
index 4e7050129058..4c0850b675a8 100644
--- a/media/java/android/media/AudioFocusRequest.java
+++ b/media/java/android/media/AudioFocusRequest.java
@@ -80,9 +80,9 @@ import android.os.Looper;
* <p>An {@code AudioFocusRequest} instance always contains one of the four types of requests
* explained above. It is passed when building an {@code AudioFocusRequest} instance with its
* builder in the {@link Builder} constructor
- * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(int)}, or
+ * {@link AudioFocusRequest.Builder#Builder(int)}, or
* with {@link AudioFocusRequest.Builder#setFocusGain(int)} after copying an existing instance with
- * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(AudioFocusRequest)}.
+ * {@link AudioFocusRequest.Builder#Builder(AudioFocusRequest)}.
*
* <h3>Qualifying your focus request</h3>
* <h4>Use case requiring a focus request</h4>
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 0ced68ef8695..babe0723dc01 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1098,7 +1098,7 @@ public class AudioTrack extends PlayerBase
* Can only be called only if the AudioTrack is opened in offload mode
* {@see Builder#setOffloadedPlayback(boolean)}.
* Can only be called only if the AudioTrack is in state {@link #PLAYSTATE_PLAYING}
- * {@see #getPlaystate()}.
+ * {@see #getPlayState()}.
* Use this method in the same thread as any write() operation.
*/
public void setOffloadEndOfStream() {
diff --git a/native/android/Android.bp b/native/android/Android.bp
index ae8cb3a47a05..8f36decec400 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -137,4 +137,4 @@ filegroup {
"aidl/com/android/internal/compat/IPlatformCompatNative.aidl",
],
path: "aidl",
-} \ No newline at end of file
+}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 50542818e0d7..6fab9e4641b6 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -106,6 +106,7 @@ public class CaptivePortalLoginActivity extends Activity {
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDomStorageEnabled(true);
+ webSettings.setAllowFileAccess(false);
mWebViewClient = new MyWebViewClient();
mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(new MyWebChromeClient());
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index d48aa246ecba..231809bfece4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -242,7 +242,16 @@ public class ZoneGetter {
final TimeZoneNames.NameType nameType =
tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT
: TimeZoneNames.NameType.LONG_STANDARD;
- return names.getDisplayName(tz.getID(), nameType, now.getTime());
+ return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime());
+ }
+
+ private static String getCanonicalZoneId(TimeZone timeZone) {
+ final String id = timeZone.getID();
+ final String canonicalId = android.icu.util.TimeZone.getCanonicalID(id);
+ if (canonicalId != null) {
+ return canonicalId;
+ }
+ return id;
}
private static void appendWithTtsSpan(SpannableStringBuilder builder, CharSequence content,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 21129f927873..65f68cc5c5b5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1352,9 +1352,6 @@ class SettingsProtoDumpUtil {
Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES,
GlobalSettingsProto.Sys.STORAGE_CACHE_MAX_BYTES);
dumpSetting(s, p,
- Settings.Global.SYS_VDSO,
- GlobalSettingsProto.Sys.VDSO);
- dumpSetting(s, p,
Settings.Global.SYS_UIDCPUPOWER,
GlobalSettingsProto.Sys.UIDCPUPOWER);
p.end(sysToken);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index ff91c797e9b1..c1ec9b0f3215 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -219,6 +219,9 @@
<uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
<uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+ <!-- Permission required for CTS test - BatterySaverTest -->
+ <uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
+
<!-- Permission required for CTS test - UiModeManagerTest -->
<uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
@@ -247,6 +250,9 @@
<!-- Permission required for testing system audio effect APIs. -->
<uses-permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/>
+ <!-- Permissions needed to test shared libraries -->
+ <uses-permission android:name="android.permission.ACCESS_SHARED_LIBRARIES" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
@@ -293,22 +299,6 @@
android:excludeFromRecents="true"
android:exported="false" />
- <!--
- The following is used as a no-op/null home activity when
- no other MAIN/HOME activity is present (e.g., in CSI).
- -->
- <activity android:name=".NullHome"
- android:excludeFromRecents="true"
- android:label=""
- android:screenOrientation="nosensor">
- <!-- The priority here is set to be lower than that for Settings -->
- <intent-filter android:priority="-1100">
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.HOME" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
<receiver
android:name=".BugreportReceiver"
android:permission="android.permission.DUMP">
diff --git a/packages/Shell/src/com/android/shell/NullHome.java b/packages/Shell/src/com/android/shell/NullHome.java
deleted file mode 100644
index bd975614a50a..000000000000
--- a/packages/Shell/src/com/android/shell/NullHome.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.shell;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- * This covers the fallback case where no launcher is available.
- * Usually Settings.apk has one fallback home activity.
- * Settings.apk, however, is not part of CSI, which needs to be
- * standalone (bootable and testable).
- */
-public class NullHome extends Activity {
- private static final String TAG = "NullHome";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Log.i(TAG, "onCreate");
- setContentView(R.layout.null_home_finishing_boot);
- }
-
- protected void onDestroy() {
- super.onDestroy();
- Log.i(TAG, "onDestroy");
- }
-}
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index c8cf7f503468..304f81b4e77f 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -43,7 +43,7 @@ twickham@google.com
winsonc@google.com
#Android Auto
-stenning@google.com
+hseog@google.com
#Android TV
rgl@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 688e8eb8f2e3..7c49c3f961c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -566,6 +566,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded);
+ mLockscreenUserManager.addUserChangedListener(userId ->
+ updateSensitiveness(false /* animated */));
setOutlineProvider(mOutlineProvider);
// Blocking helper manager wants to know the expanded state, update as well.
@@ -4602,7 +4604,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void setHideSensitive(boolean hideSensitive, boolean animate) {
+ private void updateSensitiveness(boolean animate) {
+ boolean hideSensitive = mLockscreenUserManager.isAnyProfilePublicMode();
if (hideSensitive != mAmbientState.isHideSensitive()) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -5306,7 +5309,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
SysuiStatusBarStateController state = (SysuiStatusBarStateController)
Dependency.get(StatusBarStateController.class);
- setHideSensitive(publicMode, state.goingToFullShade() /* animate */);
+ updateSensitiveness(state.goingToFullShade() /* animate */);
setDimmed(onKeyguard, state.fromShadeLocked() /* animate */);
setExpandingEnabled(!onKeyguard);
ActivatableNotificationView activatedChild = getActivatedChild();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 31054260eb15..f2ed3e648220 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -57,6 +57,8 @@ import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
@@ -119,6 +121,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private MetricsLogger mMetricsLogger;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
+ private UserChangedListener mUserChangedListener;
private TestableNotificationEntryManager mEntryManager;
private int mOriginalInterruptionModelSetting;
@@ -137,7 +141,9 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mDependency.injectTestDependency(
NotificationBlockingHelperManager.class,
mBlockingHelperManager);
- mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState);
+ mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
+ mLockscreenUserManager);
+ mDependency.injectTestDependency(StatusBarStateController.class, mBarState);
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(NotificationRemoteInputManager.class,
mRemoteInputManager);
@@ -152,6 +158,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
NotificationShelf notificationShelf = mock(NotificationShelf.class);
+ ArgumentCaptor<UserChangedListener> userChangedCaptor = ArgumentCaptor
+ .forClass(UserChangedListener.class);
// The actual class under test. You may need to work with this class directly when
// testing anonymous class members of mStackScroller, like mMenuEventListener,
@@ -174,6 +182,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
mStackScroller.setIconAreaController(mNotificationIconAreaController);
+ verify(mLockscreenUserManager).addUserChangedListener(userChangedCaptor.capture());
+ mUserChangedListener = userChangedCaptor.getValue();
// Stub out functionality that isn't necessary to test.
doNothing().when(mBar)
@@ -247,6 +257,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ public void testOnStatePostChange_verifyIfProfileIsPublic() {
+ mUserChangedListener.onUserChanged(0);
+ verify(mLockscreenUserManager).isAnyProfilePublicMode();
+ }
+
+ @Test
public void manageNotifications_visible() {
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 27297c44573c..eb72b81fb766 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -27,7 +27,7 @@ java_defaults {
"androidx.annotation_annotation",
"netd_aidl_interface-V3-java",
"netlink-client",
- "networkstack-aidl-interfaces-unstable-java",
+ "networkstack-aidl-interfaces-java",
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"net-utils-framework-common",
@@ -50,6 +50,11 @@ android_library {
cc_library {
name: "libtetherutilsjni",
sdk_version: "current",
+ apex_available: [
+ "//apex_available:platform", // Used by InProcessTethering
+ "com.android.tethering",
+ ],
+ min_sdk_version: "current",
srcs: [
"jni/android_net_util_TetheringUtils.cpp",
],
@@ -108,6 +113,8 @@ android_app {
manifest: "AndroidManifest_InProcess.xml",
// InProcessTethering is a replacement for Tethering
overrides: ["Tethering"],
+ apex_available: ["com.android.tethering"],
+ min_sdk_version: "current",
}
// Updatable tethering packaged as an application
@@ -121,4 +128,5 @@ android_app {
// The permission configuration *must* be included to ensure security of the device
required: ["NetworkPermissionConfig"],
apex_available: ["com.android.tethering"],
+ min_sdk_version: "current",
}
diff --git a/packages/Tethering/apex/Android.bp b/packages/Tethering/apex/Android.bp
index 24df5f696077..67097a79e5c0 100644
--- a/packages/Tethering/apex/Android.bp
+++ b/packages/Tethering/apex/Android.bp
@@ -17,7 +17,7 @@
apex {
name: "com.android.tethering",
updatable: true,
- min_sdk_version: "R",
+ min_sdk_version: "current",
java_libs: ["framework-tethering"],
apps: ["Tethering"],
manifest: "manifest.json",
@@ -36,3 +36,12 @@ android_app_certificate {
name: "com.android.tethering.certificate",
certificate: "com.android.tethering",
}
+
+override_apex {
+ name: "com.android.tethering.inprocess",
+ base: "com.android.tethering",
+ package_name: "com.android.tethering.inprocess",
+ apps: [
+ "InProcessTethering",
+ ],
+}
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index ee6b9f12f9d2..79a178297aa5 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -13,43 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// AIDL interfaces between the core system and the tethering mainline module.
-aidl_interface {
- name: "tethering-aidl-interfaces",
- unstable: true,
- local_include_dir: "src",
- include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
- srcs: [
- // @JavaOnlyStableParcelable aidl declarations must not be listed here, as this would cause
- // compilation to fail (b/148001843).
- "src/android/net/IIntResultListener.aidl",
- "src/android/net/ITetheringConnector.aidl",
- "src/android/net/ITetheringEventCallback.aidl",
- "src/android/net/TetheringCallbackStartedParcel.aidl",
- "src/android/net/TetheringConfigurationParcel.aidl",
- "src/android/net/TetheringRequestParcel.aidl",
- "src/android/net/TetherStatesParcel.aidl",
- ],
- backend: {
- ndk: {
- enabled: false,
- },
- cpp: {
- enabled: false,
- },
- },
-}
-
java_library {
name: "framework-tethering",
sdk_version: "module_current",
srcs: [
- "src/android/net/TetheredClient.java",
- "src/android/net/TetheringManager.java",
- "src/android/net/TetheringConstants.java",
- ],
- static_libs: [
- "tethering-aidl-interfaces-java",
+ ":framework-tethering-srcs",
],
jarjar_rules: "jarjar-rules.txt",
installable: true,
@@ -67,6 +35,7 @@ java_library {
stubs_defaults {
name: "framework-tethering-stubs-defaults",
srcs: [":framework-tethering-srcs"],
+ dist: { dest: "framework-tethering.txt" },
}
filegroup {
@@ -123,16 +92,19 @@ java_library {
name: "framework-tethering-stubs-publicapi",
srcs: [":framework-tethering-stubs-srcs-publicapi"],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-systemapi",
srcs: [":framework-tethering-stubs-srcs-systemapi"],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-module_libs_api",
srcs: [":framework-tethering-stubs-srcs-module_libs_api"],
- defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-tethering.jar" },
}
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
index 2a7330098faf..d074f1569933 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
index ea04821e33bd..f4b15aab19b7 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
index 05b90692ea7b..528a1e52925c 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
@@ -16,9 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網路共用連上網際網路"</string>
<string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉數據連線"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或數據連線已開啟"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網路共用"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或網路共用已開啟"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
index 617c50dd0ce8..1503244f5000 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
index 0e437593ee87..2ea2467e5879 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
index ea01b943fbe8..cd653df1dac6 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
@@ -16,9 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網路共用連上網際網路"</string>
<string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉數據連線"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或數據連線已開啟"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網路共用"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或網路共用已開啟"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string>
</resources>
diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml
index 9d738a76eb0e..50a50bf7a996 100644
--- a/packages/Tethering/res/values-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-zh-rTW/strings.xml
@@ -16,11 +16,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"網路共用或無線基地台已啟用"</string>
<string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"網路共用已停用"</string>
<string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與網路共用狀態"</string>
<string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
<string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
<string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml
index effc24ac4de5..3f5bc901d07b 100644
--- a/packages/Tethering/res/values/config.xml
+++ b/packages/Tethering/res/values/config.xml
@@ -55,6 +55,12 @@
<item>"bt-pan"</item>
</string-array>
+ <!-- Use the BPF offload for tethering when the kernel has support. True by default.
+ If the device doesn't want to support tether BPF offload, this should be false.
+ Note that this setting could be overridden by device config.
+ -->
+ <bool translatable="false" name="config_tether_enable_bpf_offload">true</bool>
+
<!-- Use the old dnsmasq DHCP server for tethering instead of the framework implementation. -->
<bool translatable="false" name="config_tether_enable_legacy_dhcp_server">false</bool>
@@ -62,6 +68,13 @@
<string-array translatable="false" name="config_tether_dhcp_range">
</string-array>
+ <!-- Used to config periodic polls tether offload stats from tethering offload HAL to make the
+ data warnings work. 5000(ms) by default. If the device doesn't want to poll tether
+ offload stats, this should be -1. Note that this setting could be override by
+ runtime resource overlays.
+ -->
+ <integer translatable="false" name="config_tether_offload_poll_interval">5000</integer>
+
<!-- Array of ConnectivityManager.TYPE_{BLUETOOTH, ETHERNET, MOBILE, MOBILE_DUN, MOBILE_HIPRI,
WIFI} values allowable for tethering.
diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml
index 16ae8ade19da..4e2bb1e31b2a 100644
--- a/packages/Tethering/res/values/overlayable.xml
+++ b/packages/Tethering/res/values/overlayable.xml
@@ -23,7 +23,13 @@
<item type="array" name="config_tether_wifi_p2p_regexs"/>
<item type="array" name="config_tether_bluetooth_regexs"/>
<item type="array" name="config_tether_dhcp_range"/>
+ <!-- Use the BPF offload for tethering when the kernel has support. True by default.
+ If the device doesn't want to support tether BPF offload, this should be false.
+ Note that this setting could be overridden by device config.
+ -->
+ <item type="bool" name="config_tether_enable_bpf_offload"/>
<item type="bool" name="config_tether_enable_legacy_dhcp_server"/>
+ <item type="integer" name="config_tether_offload_poll_interval"/>
<item type="array" name="config_tether_upstream_types"/>
<item type="bool" name="config_tether_upstream_automatic"/>
<!-- Configuration values for tethering entitlement check -->
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
index 4f8ad8a221ef..4710a30b2998 100644
--- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
@@ -173,6 +173,18 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
return this;
}
+ /**
+ * Set whether the DHCP server should request a new prefix from IpServer when receiving
+ * DHCPDECLINE message in certain particular link (e.g. there is only one downstream USB
+ * tethering client). If it's false, process DHCPDECLINE message as RFC2131#4.3.3 suggests.
+ *
+ * <p>If not set, the default value is false.
+ */
+ public DhcpServingParamsParcelExt setChangePrefixOnDecline(boolean changePrefixOnDecline) {
+ this.changePrefixOnDecline = changePrefixOnDecline;
+ return this;
+ }
+
private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
int[] res = new int[addrs.size()];
int i = 0;
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 83727bcdc67e..659d344acfcd 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -50,6 +50,7 @@ import android.net.shared.NetdUtils;
import android.net.shared.RouteUtils;
import android.net.util.InterfaceParams;
import android.net.util.InterfaceSet;
+import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.Looper;
@@ -60,6 +61,7 @@ import android.util.Log;
import android.util.SparseArray;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.State;
@@ -115,6 +117,15 @@ public class IpServer extends StateMachine {
private static final String ETHERNET_IFACE_ADDR = "192.168.50.1";
private static final int ETHERNET_IFACE_PREFIX_LENGTH = 24;
+ // TODO: remove this constant after introducing PrivateAddressCoordinator.
+ private static final List<IpPrefix> NCM_PREFIXES = Collections.unmodifiableList(
+ Arrays.asList(
+ new IpPrefix("192.168.42.0/24"),
+ new IpPrefix("192.168.51.0/24"),
+ new IpPrefix("192.168.52.0/24"),
+ new IpPrefix("192.168.53.0/24")
+ ));
+
// TODO: have PanService use some visible version of this constant
private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
@@ -212,6 +223,8 @@ public class IpServer extends StateMachine {
public static final int CMD_IPV6_TETHER_UPDATE = BASE_IPSERVER + 10;
// new neighbor cache entry on our interface
public static final int CMD_NEIGHBOR_EVENT = BASE_IPSERVER + 11;
+ // request from DHCP server that it wants to have a new prefix
+ public static final int CMD_NEW_PREFIX_REQUEST = BASE_IPSERVER + 12;
private final State mInitialState;
private final State mLocalHotspotState;
@@ -227,6 +240,7 @@ public class IpServer extends StateMachine {
private final int mInterfaceType;
private final LinkProperties mLinkProperties;
private final boolean mUsingLegacyDhcp;
+ private final boolean mUsingBpfOffload;
private final Dependencies mDeps;
@@ -302,9 +316,12 @@ public class IpServer extends StateMachine {
private final IpNeighborMonitor mIpNeighborMonitor;
+ // TODO: Add a dependency object to pass the data members or variables from the tethering
+ // object. It helps to reduce the arguments of the constructor.
public IpServer(
String ifaceName, Looper looper, int interfaceType, SharedLog log,
- INetd netd, Callback callback, boolean usingLegacyDhcp, Dependencies deps) {
+ INetd netd, Callback callback, boolean usingLegacyDhcp, boolean usingBpfOffload,
+ Dependencies deps) {
super(ifaceName, looper);
mLog = log.forSubComponent(ifaceName);
mNetd = netd;
@@ -314,6 +331,7 @@ public class IpServer extends StateMachine {
mInterfaceType = interfaceType;
mLinkProperties = new LinkProperties();
mUsingLegacyDhcp = usingLegacyDhcp;
+ mUsingBpfOffload = usingBpfOffload;
mDeps = deps;
resetLinkProperties();
mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
@@ -321,7 +339,12 @@ public class IpServer extends StateMachine {
mIpNeighborMonitor = mDeps.getIpNeighborMonitor(getHandler(), mLog,
new MyNeighborEventConsumer());
- if (!mIpNeighborMonitor.start()) {
+
+ // IP neighbor monitor monitors the neighbor events for adding/removing offload
+ // forwarding rules per client. If BPF offload is not supported, don't start listening
+ // for neighbor events. See updateIpv6ForwardingRules, addIpv6ForwardingRule,
+ // removeIpv6ForwardingRule.
+ if (mUsingBpfOffload && !mIpNeighborMonitor.start()) {
mLog.e("Failed to create IpNeighborMonitor on " + mIfaceName);
}
@@ -452,7 +475,7 @@ public class IpServer extends StateMachine {
handleError();
}
}
- }, new DhcpLeaseCallback());
+ }, new DhcpEventCallback());
} catch (RemoteException e) {
throw new IllegalStateException(e);
}
@@ -465,7 +488,7 @@ public class IpServer extends StateMachine {
}
}
- private class DhcpLeaseCallback extends IDhcpEventCallbacks.Stub {
+ private class DhcpEventCallback extends IDhcpEventCallbacks.Stub {
@Override
public void onLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables) {
final ArrayList<TetheredClient> leases = new ArrayList<>();
@@ -499,8 +522,9 @@ public class IpServer extends StateMachine {
}
@Override
- public void onNewPrefixRequest(IpPrefix currentPrefix) {
- //TODO: add specific implementation.
+ public void onNewPrefixRequest(@NonNull final IpPrefix currentPrefix) {
+ Objects.requireNonNull(currentPrefix);
+ sendMessage(CMD_NEW_PREFIX_REQUEST, currentPrefix);
}
@Override
@@ -514,26 +538,38 @@ public class IpServer extends StateMachine {
}
}
+ private RouteInfo getDirectConnectedRoute(@NonNull final LinkAddress ipv4Address) {
+ Objects.requireNonNull(ipv4Address);
+ return new RouteInfo(PrefixUtils.asIpPrefix(ipv4Address), null, mIfaceName, RTN_UNICAST);
+ }
+
+ private DhcpServingParamsParcel makeServingParams(@NonNull final Inet4Address defaultRouter,
+ @NonNull final Inet4Address dnsServer, @NonNull LinkAddress serverAddr,
+ @Nullable Inet4Address clientAddr) {
+ final boolean changePrefixOnDecline =
+ (mInterfaceType == TetheringManager.TETHERING_NCM && clientAddr == null);
+ return new DhcpServingParamsParcelExt()
+ .setDefaultRouters(defaultRouter)
+ .setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
+ .setDnsServers(dnsServer)
+ .setServerAddr(serverAddr)
+ .setMetered(true)
+ .setSingleClientAddr(clientAddr)
+ .setChangePrefixOnDecline(changePrefixOnDecline);
+ // TODO: also advertise link MTU
+ }
+
private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
if (mUsingLegacyDhcp) {
return true;
}
final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
- final int prefixLen = serverLinkAddr.getPrefixLength();
final Inet4Address clientAddr = clientLinkAddr == null ? null :
(Inet4Address) clientLinkAddr.getAddress();
- final DhcpServingParamsParcel params;
- params = new DhcpServingParamsParcelExt()
- .setDefaultRouters(addr)
- .setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
- .setDnsServers(addr)
- .setServerAddr(serverLinkAddr)
- .setMetered(true)
- .setSingleClientAddr(clientAddr);
- // TODO: also advertise link MTU
-
+ final DhcpServingParamsParcel params = makeServingParams(addr /* defaultRouter */,
+ addr /* dnsServer */, serverLinkAddr, clientAddr);
mDhcpServerStartIndex++;
mDeps.makeDhcpServer(
mIfaceName, params, new DhcpServerCallbacksImpl(mDhcpServerStartIndex));
@@ -560,7 +596,7 @@ public class IpServer extends StateMachine {
});
mDhcpServer = null;
} catch (RemoteException e) {
- mLog.e("Error stopping DHCP", e);
+ mLog.e("Error stopping DHCP server", e);
// Not much more we can do here
}
}
@@ -642,31 +678,33 @@ public class IpServer extends StateMachine {
return false;
}
- // Directly-connected route.
- final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
- mIpv4Address.getPrefixLength());
- final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST);
if (enabled) {
mLinkProperties.addLinkAddress(mIpv4Address);
- mLinkProperties.addRoute(route);
+ mLinkProperties.addRoute(getDirectConnectedRoute(mIpv4Address));
} else {
mLinkProperties.removeLinkAddress(mIpv4Address);
- mLinkProperties.removeRoute(route);
+ mLinkProperties.removeRoute(getDirectConnectedRoute(mIpv4Address));
}
-
return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
}
- private String getRandomWifiIPv4Address() {
+ private Inet4Address getRandomIPv4Address(@NonNull final byte[] rawAddr) {
+ final byte[] ipv4Addr = rawAddr;
+ ipv4Addr[3] = getRandomSanitizedByte(DOUG_ADAMS, asByte(0), asByte(1), FF);
try {
- byte[] bytes = parseNumericAddress(WIFI_HOST_IFACE_ADDR).getAddress();
- bytes[3] = getRandomSanitizedByte(DOUG_ADAMS, asByte(0), asByte(1), FF);
- return InetAddress.getByAddress(bytes).getHostAddress();
- } catch (Exception e) {
- return WIFI_HOST_IFACE_ADDR;
+ return (Inet4Address) InetAddress.getByAddress(ipv4Addr);
+ } catch (UnknownHostException e) {
+ mLog.e("Failed to construct Inet4Address from raw IPv4 addr");
+ return null;
}
}
+ private String getRandomWifiIPv4Address() {
+ final Inet4Address ipv4Addr =
+ getRandomIPv4Address(parseNumericAddress(WIFI_HOST_IFACE_ADDR).getAddress());
+ return ipv4Addr != null ? ipv4Addr.getHostAddress() : WIFI_HOST_IFACE_ADDR;
+ }
+
private boolean startIPv6() {
mInterfaceParams = mDeps.getInterfaceParams(mIfaceName);
if (mInterfaceParams == null) {
@@ -700,7 +738,7 @@ public class IpServer extends StateMachine {
//
// TODO: Evaluate using a data structure than is more directly suited to
// communicating only the relevant information.
- private void updateUpstreamIPv6LinkProperties(LinkProperties v6only) {
+ private void updateUpstreamIPv6LinkProperties(LinkProperties v6only, int ttlAdjustment) {
if (mRaDaemon == null) return;
// Avoid unnecessary work on spurious updates.
@@ -715,15 +753,15 @@ public class IpServer extends StateMachine {
final String upstreamIface = v6only.getInterfaceName();
params = new RaParams();
- // We advertise an mtu lower by 16, which is the closest multiple of 8 >= 14,
- // the ethernet header size. This makes kernel ebpf tethering offload happy.
- // This hack should be reverted once we have the kernel fixed up.
+ // When BPF offload is enabled, we advertise an mtu lower by 16, which is the closest
+ // multiple of 8 >= 14, the ethernet header size. This makes kernel ebpf tethering
+ // offload happy. This hack should be reverted once we have the kernel fixed up.
// Note: this will automatically clamp to at least 1280 (ipv6 minimum mtu)
// see RouterAdvertisementDaemon.java putMtu()
- params.mtu = v6only.getMtu() - 16;
+ params.mtu = mUsingBpfOffload ? v6only.getMtu() - 16 : v6only.getMtu();
params.hasDefaultRoute = v6only.hasIpv6DefaultRoute();
- if (params.hasDefaultRoute) params.hopLimit = getHopLimit(upstreamIface);
+ if (params.hasDefaultRoute) params.hopLimit = getHopLimit(upstreamIface, ttlAdjustment);
for (LinkAddress linkAddr : v6only.getLinkAddresses()) {
if (linkAddr.getPrefixLength() != RFC7421_PREFIX_LENGTH) continue;
@@ -751,21 +789,43 @@ public class IpServer extends StateMachine {
mLastIPv6UpstreamIfindex = upstreamIfindex;
}
+ private void removeRoutesFromLocalNetwork(@NonNull final List<RouteInfo> toBeRemoved) {
+ final int removalFailures = RouteUtils.removeRoutesFromLocalNetwork(
+ mNetd, toBeRemoved);
+ if (removalFailures > 0) {
+ mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
+ removalFailures));
+ }
+
+ for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
+ }
+
+ private void addRoutesToLocalNetwork(@NonNull final List<RouteInfo> toBeAdded) {
+ try {
+ // It's safe to call networkAddInterface() even if
+ // the interface is already in the local_network.
+ mNetd.networkAddInterface(INetd.LOCAL_NET_ID, mIfaceName);
+ try {
+ // Add routes from local network. Note that adding routes that
+ // already exist does not cause an error (EEXIST is silently ignored).
+ RouteUtils.addRoutesToLocalNetwork(mNetd, mIfaceName, toBeAdded);
+ } catch (IllegalStateException e) {
+ mLog.e("Failed to add IPv4/v6 routes to local table: " + e);
+ return;
+ }
+ } catch (ServiceSpecificException | RemoteException e) {
+ mLog.e("Failed to add " + mIfaceName + " to local table: ", e);
+ return;
+ }
+
+ for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
+ }
+
private void configureLocalIPv6Routes(
HashSet<IpPrefix> deprecatedPrefixes, HashSet<IpPrefix> newPrefixes) {
// [1] Remove the routes that are deprecated.
if (!deprecatedPrefixes.isEmpty()) {
- final ArrayList<RouteInfo> toBeRemoved =
- getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
- // Remove routes from local network.
- final int removalFailures = RouteUtils.removeRoutesFromLocalNetwork(
- mNetd, toBeRemoved);
- if (removalFailures > 0) {
- mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
- removalFailures));
- }
-
- for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
+ removeRoutesFromLocalNetwork(getLocalRoutesFor(mIfaceName, deprecatedPrefixes));
}
// [2] Add only the routes that have not previously been added.
@@ -776,24 +836,7 @@ public class IpServer extends StateMachine {
}
if (!addedPrefixes.isEmpty()) {
- final ArrayList<RouteInfo> toBeAdded =
- getLocalRoutesFor(mIfaceName, addedPrefixes);
- try {
- // It's safe to call networkAddInterface() even if
- // the interface is already in the local_network.
- mNetd.networkAddInterface(INetd.LOCAL_NET_ID, mIfaceName);
- try {
- // Add routes from local network. Note that adding routes that
- // already exist does not cause an error (EEXIST is silently ignored).
- RouteUtils.addRoutesToLocalNetwork(mNetd, mIfaceName, toBeAdded);
- } catch (IllegalStateException e) {
- mLog.e("Failed to add IPv6 routes to local table: " + e);
- }
- } catch (ServiceSpecificException | RemoteException e) {
- mLog.e("Failed to add " + mIfaceName + " to local table: ", e);
- }
-
- for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
+ addRoutesToLocalNetwork(getLocalRoutesFor(mIfaceName, addedPrefixes));
}
}
}
@@ -844,6 +887,11 @@ public class IpServer extends StateMachine {
}
private void addIpv6ForwardingRule(Ipv6ForwardingRule rule) {
+ // Theoretically, we don't need this check because IP neighbor monitor doesn't start if BPF
+ // offload is disabled. Add this check just in case.
+ // TODO: Perhaps remove this protection check.
+ if (!mUsingBpfOffload) return;
+
try {
mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
mIpv6ForwardingRules.put(rule.address, rule);
@@ -853,6 +901,11 @@ public class IpServer extends StateMachine {
}
private void removeIpv6ForwardingRule(Ipv6ForwardingRule rule, boolean removeFromMap) {
+ // Theoretically, we don't need this check because IP neighbor monitor doesn't start if BPF
+ // offload is disabled. Add this check just in case.
+ // TODO: Perhaps remove this protection check.
+ if (!mUsingBpfOffload) return;
+
try {
mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
if (removeFromMap) {
@@ -925,12 +978,85 @@ public class IpServer extends StateMachine {
}
}
- private byte getHopLimit(String upstreamIface) {
+ // TODO: call PrivateAddressCoordinator.requestDownstreamAddress instead of this temporary
+ // logic.
+ private Inet4Address requestDownstreamAddress(@NonNull final IpPrefix currentPrefix) {
+ final int oldIndex = NCM_PREFIXES.indexOf(currentPrefix);
+ if (oldIndex == -1) {
+ mLog.e("current prefix isn't supported for NCM link: " + currentPrefix);
+ return null;
+ }
+
+ final IpPrefix newPrefix = NCM_PREFIXES.get((oldIndex + 1) % NCM_PREFIXES.size());
+ return getRandomIPv4Address(newPrefix.getRawAddress());
+ }
+
+ private void handleNewPrefixRequest(@NonNull final IpPrefix currentPrefix) {
+ if (!currentPrefix.contains(mIpv4Address.getAddress())
+ || currentPrefix.getPrefixLength() != mIpv4Address.getPrefixLength()) {
+ Log.e(TAG, "Invalid prefix: " + currentPrefix);
+ return;
+ }
+
+ final LinkAddress deprecatedLinkAddress = mIpv4Address;
+ final Inet4Address srvAddr = requestDownstreamAddress(currentPrefix);
+ if (srvAddr == null) {
+ mLog.e("Fail to request a new downstream prefix");
+ return;
+ }
+ mIpv4Address = new LinkAddress(srvAddr, currentPrefix.getPrefixLength());
+
+ // Add new IPv4 address on the interface.
+ if (!mInterfaceCtrl.addAddress(srvAddr, currentPrefix.getPrefixLength())) {
+ mLog.e("Failed to add new IP " + srvAddr);
+ return;
+ }
+
+ // Remove deprecated routes from local network.
+ removeRoutesFromLocalNetwork(
+ Collections.singletonList(getDirectConnectedRoute(deprecatedLinkAddress)));
+ mLinkProperties.removeLinkAddress(deprecatedLinkAddress);
+
+ // Add new routes to local network.
+ addRoutesToLocalNetwork(
+ Collections.singletonList(getDirectConnectedRoute(mIpv4Address)));
+ mLinkProperties.addLinkAddress(mIpv4Address);
+
+ // Update local DNS caching server with new IPv4 address, otherwise, dnsmasq doesn't
+ // listen on the interface configured with new IPv4 address, that results DNS validation
+ // failure of downstream client even if appropriate routes have been configured.
+ try {
+ mNetd.tetherApplyDnsInterfaces();
+ } catch (ServiceSpecificException | RemoteException e) {
+ mLog.e("Failed to update local DNS caching server");
+ return;
+ }
+ sendLinkProperties();
+
+ // Notify DHCP server that new prefix/route has been applied on IpServer.
+ final Inet4Address clientAddr = mStaticIpv4ClientAddr == null ? null :
+ (Inet4Address) mStaticIpv4ClientAddr.getAddress();
+ final DhcpServingParamsParcel params = makeServingParams(srvAddr /* defaultRouter */,
+ srvAddr /* dnsServer */, mIpv4Address /* serverLinkAddress */, clientAddr);
+ try {
+ mDhcpServer.updateParams(params, new OnHandlerStatusCallback() {
+ @Override
+ public void callback(int statusCode) {
+ if (statusCode != STATUS_SUCCESS) {
+ mLog.e("Error updating DHCP serving params: " + statusCode);
+ }
+ }
+ });
+ } catch (RemoteException e) {
+ mLog.e("Error updating DHCP serving params", e);
+ }
+ }
+
+ private byte getHopLimit(String upstreamIface, int adjustTTL) {
try {
int upstreamHopLimit = Integer.parseUnsignedInt(
mNetd.getProcSysNet(INetd.IPV6, INetd.CONF, upstreamIface, "hop_limit"));
- // Add one hop to account for this forwarding device
- upstreamHopLimit++;
+ upstreamHopLimit = upstreamHopLimit + adjustTTL;
// Cap the hop limit to 255.
return (byte) Integer.min(upstreamHopLimit, 255);
} catch (Exception e) {
@@ -1018,7 +1144,7 @@ public class IpServer extends StateMachine {
transitionTo(mUnavailableState);
break;
case CMD_IPV6_TETHER_UPDATE:
- updateUpstreamIPv6LinkProperties((LinkProperties) message.obj);
+ updateUpstreamIPv6LinkProperties((LinkProperties) message.obj, message.arg1);
break;
default:
return NOT_HANDLED;
@@ -1036,11 +1162,9 @@ public class IpServer extends StateMachine {
}
try {
- final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
- mIpv4Address.getPrefixLength());
- NetdUtils.tetherInterface(mNetd, mIfaceName, ipv4Prefix);
+ NetdUtils.tetherInterface(mNetd, mIfaceName, PrefixUtils.asIpPrefix(mIpv4Address));
} catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
- mLog.e("Error Tethering: " + e);
+ mLog.e("Error Tethering", e);
mLastError = TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
return;
}
@@ -1084,7 +1208,7 @@ public class IpServer extends StateMachine {
if (DBG) Log.d(TAG, "Untethered (ifdown)" + mIfaceName);
break;
case CMD_IPV6_TETHER_UPDATE:
- updateUpstreamIPv6LinkProperties((LinkProperties) message.obj);
+ updateUpstreamIPv6LinkProperties((LinkProperties) message.obj, message.arg1);
sendLinkProperties();
break;
case CMD_IP_FORWARDING_ENABLE_ERROR:
@@ -1095,6 +1219,9 @@ public class IpServer extends StateMachine {
mLastError = TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
transitionTo(mInitialState);
break;
+ case CMD_NEW_PREFIX_REQUEST:
+ handleNewPrefixRequest((IpPrefix) message.obj);
+ break;
default:
return false;
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index 049a9f68bbd2..3c6e8d88ed13 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -37,6 +37,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.util.SharedLog;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Parcel;
import android.os.PersistableBundle;
@@ -45,13 +46,12 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
-import android.util.ArraySet;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.StateMachine;
import java.io.PrintWriter;
+import java.util.BitSet;
/**
* Re-check tethering provisioning for enabled downstream tether types.
@@ -73,39 +73,39 @@ public class EntitlementManager {
private final ComponentName mSilentProvisioningService;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
+ private static final int DUMP_TIMEOUT = 10_000;
- // The ArraySet contains enabled downstream types, ex:
+ // The BitSet is the bit map of each enabled downstream types, ex:
// {@link TetheringManager.TETHERING_WIFI}
// {@link TetheringManager.TETHERING_USB}
// {@link TetheringManager.TETHERING_BLUETOOTH}
- private final ArraySet<Integer> mCurrentTethers;
+ private final BitSet mCurrentDownstreams;
+ private final BitSet mExemptedDownstreams;
private final Context mContext;
- private final int mPermissionChangeMessageCode;
private final SharedLog mLog;
private final SparseIntArray mEntitlementCacheValue;
private final Handler mHandler;
- private final StateMachine mTetherMasterSM;
// Key: TetheringManager.TETHERING_*(downstream).
// Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
- private final SparseIntArray mCellularPermitted;
+ private final SparseIntArray mCurrentEntitlementResults;
+ private final Runnable mPermissionChangeCallback;
private PendingIntent mProvisioningRecheckAlarm;
- private boolean mCellularUpstreamPermitted = true;
+ private boolean mLastCellularUpstreamPermitted = true;
private boolean mUsingCellularAsUpstream = false;
private boolean mNeedReRunProvisioningUi = false;
private OnUiEntitlementFailedListener mListener;
private TetheringConfigurationFetcher mFetcher;
- public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
- int permissionChangeMessageCode) {
-
+ public EntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
mContext = ctx;
mLog = log.forSubComponent(TAG);
- mCurrentTethers = new ArraySet<Integer>();
- mCellularPermitted = new SparseIntArray();
+ mCurrentDownstreams = new BitSet();
+ mExemptedDownstreams = new BitSet();
+ mCurrentEntitlementResults = new SparseIntArray();
mEntitlementCacheValue = new SparseIntArray();
- mTetherMasterSM = tetherMasterSM;
- mPermissionChangeMessageCode = permissionChangeMessageCode;
- mHandler = tetherMasterSM.getHandler();
+ mPermissionChangeCallback = callback;
+ mHandler = h;
mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM),
null, mHandler);
mSilentProvisioningService = ComponentName.unflattenFromString(
@@ -144,13 +144,35 @@ public class EntitlementManager {
* Check if cellular upstream is permitted.
*/
public boolean isCellularUpstreamPermitted() {
- // If provisioning is required and EntitlementManager don't know any downstream,
- // cellular upstream should not be allowed.
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (mCurrentTethers.size() == 0 && isTetherProvisioningRequired(config)) {
- return false;
- }
- return mCellularUpstreamPermitted;
+
+ return isCellularUpstreamPermitted(config);
+ }
+
+ private boolean isCellularUpstreamPermitted(final TetheringConfiguration config) {
+ if (!isTetherProvisioningRequired(config)) return true;
+
+ // If provisioning is required and EntitlementManager doesn't know any downstreams, cellular
+ // upstream should not be enabled. Enable cellular upstream for exempted downstreams only
+ // when there is no non-exempted downstream.
+ if (mCurrentDownstreams.isEmpty()) return !mExemptedDownstreams.isEmpty();
+
+ return mCurrentEntitlementResults.indexOfValue(TETHER_ERROR_NO_ERROR) > -1;
+ }
+
+ /**
+ * Set exempted downstream type. If there is only exempted downstream type active,
+ * corresponding entitlement check will not be run and cellular upstream will be permitted
+ * by default. If a privileged app enables tethering without a provisioning check, and then
+ * another app enables tethering of the same type but does not disable the provisioning check,
+ * then the downstream immediately loses exempt status and a provisioning check is run.
+ * If any non-exempted downstream type is active, the cellular upstream will be gated by the
+ * result of entitlement check from non-exempted downstreams. If entitlement check is still
+ * in progress on non-exempt downstreams, ceullar upstream would default be disabled. When any
+ * non-exempted downstream gets positive entitlement result, ceullar upstream will be enabled.
+ */
+ public void setExemptedDownstreamType(final int type) {
+ mExemptedDownstreams.set(type, true);
}
/**
@@ -164,29 +186,24 @@ public class EntitlementManager {
public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
if (!isValidDownstreamType(downstreamType)) return;
- if (!mCurrentTethers.contains(downstreamType)) mCurrentTethers.add(downstreamType);
+ mCurrentDownstreams.set(downstreamType, true);
+
+ mExemptedDownstreams.set(downstreamType, false);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (isTetherProvisioningRequired(config)) {
- // If provisioning is required and the result is not available yet,
- // cellular upstream should not be allowed.
- if (mCellularPermitted.size() == 0) {
- mCellularUpstreamPermitted = false;
- }
- // If upstream is not cellular, provisioning app would not be launched
- // till upstream change to cellular.
- if (mUsingCellularAsUpstream) {
- if (showProvisioningUi) {
- runUiTetherProvisioning(downstreamType, config.activeDataSubId);
- } else {
- runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
- }
- mNeedReRunProvisioningUi = false;
+ if (!isTetherProvisioningRequired(config)) return;
+
+ // If upstream is not cellular, provisioning app would not be launched
+ // till upstream change to cellular.
+ if (mUsingCellularAsUpstream) {
+ if (showProvisioningUi) {
+ runUiTetherProvisioning(downstreamType, config.activeDataSubId);
} else {
- mNeedReRunProvisioningUi |= showProvisioningUi;
+ runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
}
+ mNeedReRunProvisioningUi = false;
} else {
- mCellularUpstreamPermitted = true;
+ mNeedReRunProvisioningUi |= showProvisioningUi;
}
}
@@ -195,14 +212,15 @@ public class EntitlementManager {
*
* @param type tethering type from TetheringManager.TETHERING_{@code *}
*/
- public void stopProvisioningIfNeeded(int type) {
- if (!isValidDownstreamType(type)) return;
+ public void stopProvisioningIfNeeded(int downstreamType) {
+ if (!isValidDownstreamType(downstreamType)) return;
- mCurrentTethers.remove(type);
+ mCurrentDownstreams.set(downstreamType, false);
// There are lurking bugs where the notion of "provisioning required" or
// "tethering supported" may change without without tethering being notified properly.
// Remove the mapping all the time no matter provisioning is required or not.
- removeDownstreamMapping(type);
+ removeDownstreamMapping(downstreamType);
+ mExemptedDownstreams.set(downstreamType, false);
}
/**
@@ -213,7 +231,7 @@ public class EntitlementManager {
public void notifyUpstream(boolean isCellular) {
if (DBG) {
mLog.i("notifyUpstream: " + isCellular
- + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted
+ + ", mLastCellularUpstreamPermitted: " + mLastCellularUpstreamPermitted
+ ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
}
mUsingCellularAsUpstream = isCellular;
@@ -231,7 +249,7 @@ public class EntitlementManager {
}
private void maybeRunProvisioning(final TetheringConfiguration config) {
- if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired(config)) {
+ if (mCurrentDownstreams.isEmpty() || !isTetherProvisioningRequired(config)) {
return;
}
@@ -239,8 +257,9 @@ public class EntitlementManager {
// are allowed. Therefore even if the silent check here ends in a failure and the UI later
// yields success, then the downstream that got a failure will re-evaluate as a result of
// the change and get the new correct value.
- for (Integer downstream : mCurrentTethers) {
- if (mCellularPermitted.indexOfKey(downstream) < 0) {
+ for (int downstream = mCurrentDownstreams.nextSetBit(0); downstream >= 0;
+ downstream = mCurrentDownstreams.nextSetBit(downstream + 1)) {
+ if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
if (mNeedReRunProvisioningUi) {
mNeedReRunProvisioningUi = false;
runUiTetherProvisioning(downstream, config.activeDataSubId);
@@ -286,7 +305,7 @@ public class EntitlementManager {
mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
}
mEntitlementCacheValue.clear();
- mCellularPermitted.clear();
+ mCurrentEntitlementResults.clear();
// TODO: refine provisioning check to isTetherProvisioningRequired() ??
if (!config.hasMobileHotspotProvisionApp()
@@ -410,26 +429,25 @@ public class EntitlementManager {
}
private void evaluateCellularPermission(final TetheringConfiguration config) {
- final boolean oldPermitted = mCellularUpstreamPermitted;
- mCellularUpstreamPermitted = (!isTetherProvisioningRequired(config)
- || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1);
+ final boolean permitted = isCellularUpstreamPermitted(config);
if (DBG) {
- mLog.i("Cellular permission change from " + oldPermitted
- + " to " + mCellularUpstreamPermitted);
+ mLog.i("Cellular permission change from " + mLastCellularUpstreamPermitted
+ + " to " + permitted);
}
- if (mCellularUpstreamPermitted != oldPermitted) {
- mLog.log("Cellular permission change: " + mCellularUpstreamPermitted);
- mTetherMasterSM.sendMessage(mPermissionChangeMessageCode);
+ if (mLastCellularUpstreamPermitted != permitted) {
+ mLog.log("Cellular permission change: " + permitted);
+ mPermissionChangeCallback.run();
}
// Only schedule periodic re-check when tether is provisioned
// and the result is ok.
- if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) {
+ if (permitted && mCurrentEntitlementResults.size() > 0) {
scheduleProvisioningRechecks(config);
} else {
cancelTetherProvisioningRechecks();
}
+ mLastCellularUpstreamPermitted = permitted;
}
/**
@@ -441,10 +459,10 @@ public class EntitlementManager {
*/
protected void addDownstreamMapping(int type, int resultCode) {
mLog.i("addDownstreamMapping: " + type + ", result: " + resultCode
- + " ,TetherTypeRequested: " + mCurrentTethers.contains(type));
- if (!mCurrentTethers.contains(type)) return;
+ + " ,TetherTypeRequested: " + mCurrentDownstreams.get(type));
+ if (!mCurrentDownstreams.get(type)) return;
- mCellularPermitted.put(type, resultCode);
+ mCurrentEntitlementResults.put(type, resultCode);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
evaluateCellularPermission(config);
}
@@ -455,7 +473,7 @@ public class EntitlementManager {
*/
protected void removeDownstreamMapping(int type) {
mLog.i("removeDownstreamMapping: " + type);
- mCellularPermitted.delete(type);
+ mCurrentEntitlementResults.delete(type);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
evaluateCellularPermission(config);
}
@@ -488,18 +506,33 @@ public class EntitlementManager {
* @param pw {@link PrintWriter} is used to print formatted
*/
public void dump(PrintWriter pw) {
- pw.print("mCellularUpstreamPermitted: ");
- pw.println(mCellularUpstreamPermitted);
- for (Integer type : mCurrentTethers) {
- pw.print("Type: ");
- pw.print(typeString(type));
- if (mCellularPermitted.indexOfKey(type) > -1) {
- pw.print(", Value: ");
- pw.println(errorString(mCellularPermitted.get(type)));
- } else {
- pw.println(", Value: empty");
+ final ConditionVariable mWaiting = new ConditionVariable();
+ mHandler.post(() -> {
+ pw.print("isCellularUpstreamPermitted: ");
+ pw.println(isCellularUpstreamPermitted());
+ for (int type = mCurrentDownstreams.nextSetBit(0); type >= 0;
+ type = mCurrentDownstreams.nextSetBit(type + 1)) {
+ pw.print("Type: ");
+ pw.print(typeString(type));
+ if (mCurrentEntitlementResults.indexOfKey(type) > -1) {
+ pw.print(", Value: ");
+ pw.println(errorString(mCurrentEntitlementResults.get(type)));
+ } else {
+ pw.println(", Value: empty");
+ }
}
+ mWaiting.open();
+ });
+ if (!mWaiting.block(DUMP_TIMEOUT)) {
+ pw.println("... dump timed out after " + DUMP_TIMEOUT + "ms");
+ }
+ pw.print("Exempted: [");
+ for (int type = mExemptedDownstreams.nextSetBit(0); type >= 0;
+ type = mExemptedDownstreams.nextSetBit(type + 1)) {
+ pw.print(typeString(type));
+ pw.print(", ");
}
+ pw.println("]");
}
private static String typeString(int type) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java
index d450c46de718..f3dcaa2529e7 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java
@@ -161,11 +161,28 @@ public class IPv6TetheringCoordinator {
private void updateIPv6TetheringInterfaces() {
for (IpServer ipServer : mNotifyList) {
final LinkProperties lp = getInterfaceIPv6LinkProperties(ipServer);
- ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
+ ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, getTtlAdjustment(), 0, lp);
break;
}
}
+ private int getTtlAdjustment() {
+ if (mUpstreamNetworkState == null || mUpstreamNetworkState.networkCapabilities == null) {
+ return 0;
+ }
+
+ // If upstream is cellular, set the TTL in Router Advertisements to "network-set TTL" - 1
+ // for carrier requirement.
+ if (mUpstreamNetworkState.networkCapabilities.hasTransport(
+ NetworkCapabilities.TRANSPORT_CELLULAR)) {
+ return -1;
+ }
+
+ // For other non-cellular upstream, set TTL as "network-set TTL" + 1 to preventing arbitrary
+ // distinction between tethered and untethered traffic.
+ return 1;
+ }
+
private LinkProperties getInterfaceIPv6LinkProperties(IpServer ipServer) {
final Downstream ds = findDownstream(ipServer);
if (ds == null) return null;
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
index c007c174fe4f..88c77b07e7e3 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
@@ -23,8 +23,11 @@ import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_TETHERING;
+import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.NetworkStatsManager;
@@ -115,11 +118,31 @@ public class OffloadController {
// includes upstream interfaces that have a quota set.
private HashMap<String, Long> mInterfaceQuotas = new HashMap<>();
+ // Tracking remaining alert quota. Unlike limit quota is subject to interface, the alert
+ // quota is interface independent and global for tether offload. Note that this is only
+ // accessed on the handler thread and in the constructor.
+ private long mRemainingAlertQuota = QUOTA_UNLIMITED;
+ // Runnable that used to schedule the next stats poll.
+ private final Runnable mScheduledPollingTask = () -> {
+ updateStatsForCurrentUpstream();
+ maybeSchedulePollingStats();
+ };
+
private int mNatUpdateCallbacksReceived;
private int mNatUpdateNetlinkErrors;
+ @NonNull
+ private final Dependencies mDeps;
+
+ // TODO: Put more parameters in constructor into dependency object.
+ interface Dependencies {
+ @NonNull
+ TetheringConfiguration getTetherConfig();
+ }
+
public OffloadController(Handler h, OffloadHardwareInterface hwi,
- ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log) {
+ ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log,
+ @NonNull Dependencies deps) {
mHandler = h;
mHwInterface = hwi;
mContentResolver = contentResolver;
@@ -135,6 +158,7 @@ public class OffloadController {
provider = null;
}
mStatsProvider = provider;
+ mDeps = deps;
}
/** Start hardware offload. */
@@ -240,6 +264,7 @@ public class OffloadController {
mLog.log("tethering offload started");
mNatUpdateCallbacksReceived = 0;
mNatUpdateNetlinkErrors = 0;
+ maybeSchedulePollingStats();
}
return isStarted;
}
@@ -255,6 +280,9 @@ public class OffloadController {
mHwInterface.stopOffloadControl();
mControlInitialized = false;
mConfigInitialized = false;
+ if (mHandler.hasCallbacks(mScheduledPollingTask)) {
+ mHandler.removeCallbacks(mScheduledPollingTask);
+ }
if (wasStarted) mLog.log("tethering offload stopped");
}
@@ -345,6 +373,11 @@ public class OffloadController {
@Override
public void onSetAlert(long quotaBytes) {
// TODO: Ask offload HAL to notify alert without stopping traffic.
+ // Post it to handler thread since it access remaining quota bytes.
+ mHandler.post(() -> {
+ updateAlertQuota(quotaBytes);
+ maybeSchedulePollingStats();
+ });
}
}
@@ -366,15 +399,70 @@ public class OffloadController {
// the stats for each interface, and does not observe partial writes where rxBytes is
// updated and txBytes is not.
ForwardedStats diff = mHwInterface.getForwardedStats(iface);
+ final long usedAlertQuota = diff.rxBytes + diff.txBytes;
ForwardedStats base = mForwardedStats.get(iface);
if (base != null) {
diff.add(base);
}
+
+ // Update remaining alert quota if it is still positive.
+ if (mRemainingAlertQuota > 0 && usedAlertQuota > 0) {
+ // Trim to zero if overshoot.
+ final long newQuota = Math.max(mRemainingAlertQuota - usedAlertQuota, 0);
+ updateAlertQuota(newQuota);
+ }
+
mForwardedStats.put(iface, diff);
// diff is a new object, just created by getForwardedStats(). Therefore, anyone reading from
// mForwardedStats (i.e., any caller of getTetherStats) will see the new stats immediately.
}
+ /**
+ * Update remaining alert quota, fire the {@link NetworkStatsProvider#notifyAlertReached()}
+ * callback when it reaches zero. This can be invoked either from service setting the alert, or
+ * {@code maybeUpdateStats} when updating stats. Note that this can be only called on
+ * handler thread.
+ *
+ * @param newQuota non-negative value to indicate the new quota, or
+ * {@link NetworkStatsProvider#QUOTA_UNLIMITED} to indicate there is no
+ * quota.
+ */
+ private void updateAlertQuota(long newQuota) {
+ if (newQuota < QUOTA_UNLIMITED) {
+ throw new IllegalArgumentException("invalid quota value " + newQuota);
+ }
+ if (mRemainingAlertQuota == newQuota) return;
+
+ mRemainingAlertQuota = newQuota;
+ if (mRemainingAlertQuota == 0) {
+ mLog.i("notifyAlertReached");
+ if (mStatsProvider != null) mStatsProvider.notifyAlertReached();
+ }
+ }
+
+ /**
+ * Schedule polling if needed, this will be stopped if offload has been
+ * stopped or remaining quota reaches zero or upstream is empty.
+ * Note that this can be only called on handler thread.
+ */
+ private void maybeSchedulePollingStats() {
+ if (!isPollingStatsNeeded()) return;
+
+ if (mHandler.hasCallbacks(mScheduledPollingTask)) {
+ mHandler.removeCallbacks(mScheduledPollingTask);
+ }
+ mHandler.postDelayed(mScheduledPollingTask,
+ mDeps.getTetherConfig().getOffloadPollInterval());
+ }
+
+ private boolean isPollingStatsNeeded() {
+ return started() && mRemainingAlertQuota > 0
+ && !TextUtils.isEmpty(currentUpstreamInterface())
+ && mDeps.getTetherConfig() != null
+ && mDeps.getTetherConfig().getOffloadPollInterval()
+ >= DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+ }
+
private boolean maybeUpdateDataLimit(String iface) {
// setDataLimit may only be called while offload is occurring on this upstream.
if (!started() || !TextUtils.equals(iface, currentUpstreamInterface())) {
@@ -414,6 +502,8 @@ public class OffloadController {
final String iface = currentUpstreamInterface();
if (!TextUtils.isEmpty(iface)) mForwardedStats.putIfAbsent(iface, EMPTY_STATS);
+ maybeSchedulePollingStats();
+
// TODO: examine return code and decide what to do if programming
// upstream parameters fails (probably just wait for a subsequent
// onOffloadEvent() callback to tell us offload is available again and
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index c4a1078d0be0..fe92204c25c8 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -66,6 +66,7 @@ public class OffloadHardwareInterface {
private final Handler mHandler;
private final SharedLog mLog;
+ private final Dependencies mDeps;
private IOffloadControl mOffloadControl;
private TetheringOffloadCallback mTetheringOffloadCallback;
private ControlCallback mControlCallback;
@@ -126,8 +127,76 @@ public class OffloadHardwareInterface {
}
public OffloadHardwareInterface(Handler h, SharedLog log) {
+ this(h, log, new Dependencies(log));
+ }
+
+ OffloadHardwareInterface(Handler h, SharedLog log, Dependencies deps) {
mHandler = h;
mLog = log.forSubComponent(TAG);
+ mDeps = deps;
+ }
+
+ /** Capture OffloadHardwareInterface dependencies, for injection. */
+ static class Dependencies {
+ private final SharedLog mLog;
+
+ Dependencies(SharedLog log) {
+ mLog = log;
+ }
+
+ public IOffloadConfig getOffloadConfig() {
+ try {
+ return IOffloadConfig.getService(true /*retry*/);
+ } catch (RemoteException | NoSuchElementException e) {
+ mLog.e("getIOffloadConfig error " + e);
+ return null;
+ }
+ }
+
+ public IOffloadControl getOffloadControl() {
+ try {
+ return IOffloadControl.getService(true /*retry*/);
+ } catch (RemoteException | NoSuchElementException e) {
+ mLog.e("tethering offload control not supported: " + e);
+ return null;
+ }
+ }
+
+ public NativeHandle createConntrackSocket(final int groups) {
+ final FileDescriptor fd;
+ try {
+ fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
+ } catch (ErrnoException e) {
+ mLog.e("Unable to create conntrack socket " + e);
+ return null;
+ }
+
+ final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
+ try {
+ Os.bind(fd, sockAddr);
+ } catch (ErrnoException | SocketException e) {
+ mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
+ try {
+ SocketUtils.closeSocket(fd);
+ } catch (IOException ie) {
+ // Nothing we can do here
+ }
+ return null;
+ }
+ try {
+ Os.connect(fd, sockAddr);
+ } catch (ErrnoException | SocketException e) {
+ mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
+ try {
+ SocketUtils.closeSocket(fd);
+ } catch (IOException ie) {
+ // Nothing we can do here
+ }
+ return null;
+ }
+
+ return new NativeHandle(fd, true);
+ }
}
/** Get default value indicating whether offload is supported. */
@@ -141,13 +210,7 @@ public class OffloadHardwareInterface {
* share them with offload management process.
*/
public boolean initOffloadConfig() {
- IOffloadConfig offloadConfig;
- try {
- offloadConfig = IOffloadConfig.getService(true /*retry*/);
- } catch (RemoteException | NoSuchElementException e) {
- mLog.e("getIOffloadConfig error " + e);
- return false;
- }
+ final IOffloadConfig offloadConfig = mDeps.getOffloadConfig();
if (offloadConfig == null) {
mLog.e("Could not find IOffloadConfig service");
return false;
@@ -159,11 +222,11 @@ public class OffloadHardwareInterface {
//
// h2 provides a file descriptor bound to the following netlink groups
// (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
- final NativeHandle h1 = createConntrackSocket(
+ final NativeHandle h1 = mDeps.createConntrackSocket(
NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
if (h1 == null) return false;
- final NativeHandle h2 = createConntrackSocket(
+ final NativeHandle h2 = mDeps.createConntrackSocket(
NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
if (h2 == null) {
closeFdInNativeHandle(h1);
@@ -198,53 +261,12 @@ public class OffloadHardwareInterface {
}
}
- private NativeHandle createConntrackSocket(final int groups) {
- FileDescriptor fd;
- try {
- fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
- } catch (ErrnoException e) {
- mLog.e("Unable to create conntrack socket " + e);
- return null;
- }
-
- final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
- try {
- Os.bind(fd, sockAddr);
- } catch (ErrnoException | SocketException e) {
- mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException ie) {
- // Nothing we can do here
- }
- return null;
- }
- try {
- Os.connect(fd, sockAddr);
- } catch (ErrnoException | SocketException e) {
- mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException ie) {
- // Nothing we can do here
- }
- return null;
- }
-
- return new NativeHandle(fd, true);
- }
-
/** Initialize the tethering offload HAL. */
public boolean initOffloadControl(ControlCallback controlCb) {
mControlCallback = controlCb;
if (mOffloadControl == null) {
- try {
- mOffloadControl = IOffloadControl.getService(true /*retry*/);
- } catch (RemoteException | NoSuchElementException e) {
- mLog.e("tethering offload control not supported: " + e);
- return false;
- }
+ mOffloadControl = mDeps.getOffloadControl();
if (mOffloadControl == null) {
mLog.e("tethering IOffloadControl.getService() returned null");
return false;
@@ -308,7 +330,6 @@ public class OffloadHardwareInterface {
return stats;
}
- mLog.log(logmsg + YIELDS + stats);
return stats;
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 44eacb410d10..3ce3b4506c3f 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -62,7 +62,6 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
-import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
@@ -110,8 +109,10 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -229,6 +230,7 @@ public class Tethering {
private final ConnectedClientsTracker mConnectedClientsTracker;
private final TetheringThreadExecutor mExecutor;
private final TetheringNotificationUpdater mNotificationUpdater;
+ private final UserManager mUserManager;
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
// All the usage of mTetheringEventCallback should run in the same thread.
private ITetheringEventCallback mTetheringEventCallback = null;
@@ -268,12 +270,15 @@ public class Tethering {
mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
mTetherMasterSM.start();
- final NetworkStatsManager statsManager =
- (NetworkStatsManager) mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
mHandler = mTetherMasterSM.getHandler();
- mOffloadController = new OffloadController(mHandler,
- mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(),
- statsManager, mLog);
+ mOffloadController = mDeps.getOffloadController(mHandler, mLog,
+ new OffloadController.Dependencies() {
+
+ @Override
+ public TetheringConfiguration getTetherConfig() {
+ return mConfig;
+ }
+ });
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
mForwardedDownstreams = new LinkedHashSet<>();
@@ -282,8 +287,9 @@ public class Tethering {
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
// EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
// permission is changed according to entitlement check result.
- mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog,
- TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED);
+ mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
+ () -> mTetherMasterSM.sendMessage(
+ TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
mLog.log("OBSERVED UiEnitlementFailed");
stopTethering(downstream);
@@ -302,23 +308,24 @@ public class Tethering {
mStateReceiver = new StateReceiver();
- final UserManager userManager = (UserManager) mContext.getSystemService(
- Context.USER_SERVICE);
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mTetheringRestriction = new UserRestrictionActionListener(
- userManager, this, mNotificationUpdater);
+ mUserManager, this, mNotificationUpdater);
mExecutor = new TetheringThreadExecutor(mHandler);
mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
mNetdCallback = new NetdCallback();
// Load tethering configuration.
updateConfiguration();
+
+ startStateMachineUpdaters();
}
/**
* Start to register callbacks.
* Call this function when tethering is ready to handle callback events.
*/
- public void startStateMachineUpdaters() {
+ private void startStateMachineUpdaters() {
try {
mNetd.registerUnsolicitedEventListener(mNetdCallback);
} catch (RemoteException e) {
@@ -513,8 +520,12 @@ public class Tethering {
}
mActiveTetheringRequests.put(request.tetheringType, request);
- mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
- request.showProvisioningUi);
+ if (request.exemptFromEntitlementCheck) {
+ mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);
+ } else {
+ mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
+ request.showProvisioningUi);
+ }
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
});
}
@@ -772,7 +783,7 @@ public class Tethering {
// TODO: Figure out how to update for local hotspot mode interfaces.
private void sendTetherStateChangedBroadcast() {
- if (!mDeps.isTetheringSupported()) return;
+ if (!isTetheringSupported()) return;
final ArrayList<String> availableList = new ArrayList<>();
final ArrayList<String> tetherList = new ArrayList<>();
@@ -1013,14 +1024,14 @@ public class Tethering {
@VisibleForTesting
protected static class UserRestrictionActionListener {
- private final UserManager mUserManager;
+ private final UserManager mUserMgr;
private final Tethering mWrapper;
private final TetheringNotificationUpdater mNotificationUpdater;
public boolean mDisallowTethering;
public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
@NonNull TetheringNotificationUpdater updater) {
- mUserManager = um;
+ mUserMgr = um;
mWrapper = wrapper;
mNotificationUpdater = updater;
mDisallowTethering = false;
@@ -1030,7 +1041,7 @@ public class Tethering {
// getUserRestrictions gets restriction for this process' user, which is the primary
// user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
// user. See UserManager.DISALLOW_CONFIG_TETHERING.
- final Bundle restrictions = mUserManager.getUserRestrictions();
+ final Bundle restrictions = mUserMgr.getUserRestrictions();
final boolean newlyDisallowed =
restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
final boolean prevDisallowed = mDisallowTethering;
@@ -1981,7 +1992,7 @@ public class Tethering {
mHandler.post(() -> {
mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
- parcel.tetheringSupported = mDeps.isTetheringSupported();
+ parcel.tetheringSupported = isTetheringSupported();
parcel.upstreamNetwork = mTetherUpstream;
parcel.config = mConfig.toStableParcelable();
parcel.states =
@@ -2104,6 +2115,20 @@ public class Tethering {
}
}
+ // if ro.tether.denied = true we default to no tethering
+ // gservices could set the secure setting to 1 though to enable it on a build where it
+ // had previously been turned off.
+ boolean isTetheringSupported() {
+ final int defaultVal =
+ SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
+ final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
+ final boolean tetherEnabledInSettings = tetherSupported
+ && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
+
+ return tetherEnabledInSettings && hasTetherableConfiguration();
+ }
+
void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
// Binder.java closes the resource for us.
@SuppressWarnings("resource")
@@ -2289,7 +2314,7 @@ public class Tethering {
final TetherState tetherState = new TetherState(
new IpServer(iface, mLooper, interfaceType, mLog, mNetd,
makeControlCallback(), mConfig.enableLegacyDhcpServer,
- mDeps.getIpServerDependencies()));
+ mConfig.enableBpfOffload, mDeps.getIpServerDependencies()));
mTetherStates.put(iface, tetherState);
tetherState.ipServer.start();
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index aeac437e24e3..48a600dfe6e1 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -73,11 +73,23 @@ public class TetheringConfiguration {
private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"};
/**
+ * Override enabling BPF offload configuration for tethering.
+ */
+ public static final String OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD =
+ "override_tether_enable_bpf_offload";
+
+ /**
* Use the old dnsmasq DHCP server for tethering instead of the framework implementation.
*/
public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
"tether_enable_legacy_dhcp_server";
+ /**
+ * Default value that used to periodic polls tether offload stats from tethering offload HAL
+ * to make the data warnings work.
+ */
+ public static final int DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS = 5000;
+
public final String[] tetherableUsbRegexs;
public final String[] tetherableWifiRegexs;
public final String[] tetherableWifiP2pRegexs;
@@ -89,6 +101,8 @@ public class TetheringConfiguration {
public final String[] legacyDhcpRanges;
public final String[] defaultIPv4DNS;
public final boolean enableLegacyDhcpServer;
+ // TODO: Add to TetheringConfigurationParcel if required.
+ public final boolean enableBpfOffload;
public final String[] provisioningApp;
public final String provisioningAppNoUi;
@@ -96,6 +110,8 @@ public class TetheringConfiguration {
public final int activeDataSubId;
+ private final int mOffloadPollInterval;
+
public TetheringConfiguration(Context ctx, SharedLog log, int id) {
final SharedLog configLog = log.forSubComponent("config");
@@ -116,11 +132,12 @@ public class TetheringConfiguration {
isDunRequired = checkDunRequired(ctx);
chooseUpstreamAutomatically = getResourceBoolean(
- res, R.bool.config_tether_upstream_automatic);
+ res, R.bool.config_tether_upstream_automatic, false /** defaultValue */);
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
legacyDhcpRanges = getLegacyDhcpRanges(res);
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
+ enableBpfOffload = getEnableBpfOffload(res);
enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
@@ -129,6 +146,10 @@ public class TetheringConfiguration {
R.integer.config_mobile_hotspot_provision_check_period,
0 /* No periodic re-check */);
+ mOffloadPollInterval = getResourceInteger(res,
+ R.integer.config_tether_offload_poll_interval,
+ DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+
configLog.log(toString());
}
@@ -189,10 +210,16 @@ public class TetheringConfiguration {
dumpStringArray(pw, "legacyDhcpRanges", legacyDhcpRanges);
dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
+ pw.print("offloadPollInterval: ");
+ pw.println(mOffloadPollInterval);
+
dumpStringArray(pw, "provisioningApp", provisioningApp);
pw.print("provisioningAppNoUi: ");
pw.println(provisioningAppNoUi);
+ pw.print("enableBpfOffload: ");
+ pw.println(enableBpfOffload);
+
pw.print("enableLegacyDhcpServer: ");
pw.println(enableLegacyDhcpServer);
}
@@ -208,10 +235,12 @@ public class TetheringConfiguration {
makeString(tetherableBluetoothRegexs)));
sj.add(String.format("isDunRequired:%s", isDunRequired));
sj.add(String.format("chooseUpstreamAutomatically:%s", chooseUpstreamAutomatically));
+ sj.add(String.format("offloadPollInterval:%d", mOffloadPollInterval));
sj.add(String.format("preferredUpstreamIfaceTypes:%s",
toIntArray(preferredUpstreamIfaceTypes)));
sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
+ sj.add(String.format("enableBpfOffload:%s", enableBpfOffload));
sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer));
return String.format("TetheringConfiguration{%s}", sj.toString());
}
@@ -246,6 +275,10 @@ public class TetheringConfiguration {
return (tm != null) ? tm.isTetheringApnRequired() : false;
}
+ public int getOffloadPollInterval() {
+ return mOffloadPollInterval;
+ }
+
private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
final int[] ifaceTypes = res.getIntArray(R.array.config_tether_upstream_types);
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
@@ -312,11 +345,11 @@ public class TetheringConfiguration {
}
}
- private static boolean getResourceBoolean(Resources res, int resId) {
+ private static boolean getResourceBoolean(Resources res, int resId, boolean defaultValue) {
try {
return res.getBoolean(resId);
} catch (Resources.NotFoundException e404) {
- return false;
+ return defaultValue;
}
}
@@ -337,14 +370,36 @@ public class TetheringConfiguration {
}
}
+ private boolean getEnableBpfOffload(final Resources res) {
+ // Get BPF offload config
+ // Priority 1: Device config
+ // Priority 2: Resource config
+ // Priority 3: Default value
+ final boolean defaultValue = getResourceBoolean(
+ res, R.bool.config_tether_enable_bpf_offload, true /** default value */);
+
+ return getDeviceConfigBoolean(OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD, defaultValue);
+ }
+
private boolean getEnableLegacyDhcpServer(final Resources res) {
- return getResourceBoolean(res, R.bool.config_tether_enable_legacy_dhcp_server)
- || getDeviceConfigBoolean(TETHER_ENABLE_LEGACY_DHCP_SERVER);
+ return getResourceBoolean(
+ res, R.bool.config_tether_enable_legacy_dhcp_server, false /** defaultValue */)
+ || getDeviceConfigBoolean(
+ TETHER_ENABLE_LEGACY_DHCP_SERVER, false /** defaultValue */);
+ }
+
+ private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
+ // Due to the limitation of static mock for testing, using #getDeviceConfigProperty instead
+ // of DeviceConfig#getBoolean. If using #getBoolean here, the test can't know that the
+ // returned boolean value comes from device config or default value (because of null
+ // property string). See the test case testBpfOffload{*} in TetheringConfigurationTest.java.
+ final String value = getDeviceConfigProperty(name);
+ return value != null ? Boolean.parseBoolean(value) : defaultValue;
}
@VisibleForTesting
- protected boolean getDeviceConfigBoolean(final String name) {
- return DeviceConfig.getBoolean(NAMESPACE_CONNECTIVITY, name, false /** defaultValue */);
+ protected String getDeviceConfigProperty(String name) {
+ return DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, name);
}
private Resources getResources(Context ctx, int subId) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
index 9b54b5ff2403..ce546c701a61 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
@@ -16,6 +16,7 @@
package com.android.networkstack.tethering;
+import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.INetd;
@@ -47,6 +48,19 @@ public abstract class TetheringDependencies {
}
/**
+ * Get a reference to the offload controller to be used by tethering.
+ */
+ @NonNull
+ public OffloadController getOffloadController(@NonNull Handler h,
+ @NonNull SharedLog log, @NonNull OffloadController.Dependencies deps) {
+ final NetworkStatsManager statsManager =
+ (NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE);
+ return new OffloadController(h, getOffloadHardwareInterface(h, log),
+ getContext().getContentResolver(), statsManager, log, deps);
+ }
+
+
+ /**
* Get a reference to the UpstreamNetworkMonitor to be used by tethering.
*/
public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, StateMachine target,
@@ -82,9 +96,9 @@ public abstract class TetheringDependencies {
/**
* Get a reference to the EntitlementManager to be used by tethering.
*/
- public EntitlementManager getEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, int what) {
- return new EntitlementManager(ctx, target, log, what);
+ public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ return new EntitlementManager(ctx, h, log, callback);
}
/**
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
index c82e2be72ad2..c11e86258d3c 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
@@ -16,6 +16,8 @@
package com.android.networkstack.tethering;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
@@ -38,15 +40,12 @@ import android.net.TetheringRequestParcel;
import android.net.dhcp.DhcpServerCallbacks;
import android.net.dhcp.DhcpServingParamsParcel;
import android.net.ip.IpServer;
-import android.net.util.SharedLog;
import android.os.Binder;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.os.SystemProperties;
-import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
@@ -66,21 +65,14 @@ import java.io.PrintWriter;
public class TetheringService extends Service {
private static final String TAG = TetheringService.class.getSimpleName();
- private final SharedLog mLog = new SharedLog(TAG);
private TetheringConnector mConnector;
- private Context mContext;
- private TetheringDependencies mDeps;
- private Tethering mTethering;
- private UserManager mUserManager;
@Override
public void onCreate() {
- mLog.mark("onCreate");
- mDeps = getTetheringDependencies();
- mContext = mDeps.getContext();
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mTethering = makeTethering(mDeps);
- mTethering.startStateMachineUpdaters();
+ final TetheringDependencies deps = makeTetheringDependencies();
+ // The Tethering object needs a fully functional context to start, so this can't be done
+ // in the constructor.
+ mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
}
/**
@@ -92,21 +84,10 @@ public class TetheringService extends Service {
return new Tethering(deps);
}
- /**
- * Create a binder connector for the system server to communicate with the tethering.
- */
- private synchronized IBinder makeConnector() {
- if (mConnector == null) {
- mConnector = new TetheringConnector(mTethering, TetheringService.this);
- }
- return mConnector;
- }
-
@NonNull
@Override
public IBinder onBind(Intent intent) {
- mLog.mark("onBind");
- return makeConnector();
+ return mConnector;
}
private static class TetheringConnector extends ITetheringConnector.Stub {
@@ -151,7 +132,12 @@ public class TetheringService extends Service {
@Override
public void startTethering(TetheringRequestParcel request, String callerPkg,
String callingAttributionTag, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
+ if (checkAndNotifyCommonError(callerPkg,
+ callingAttributionTag,
+ request.exemptFromEntitlementCheck /* onlyAllowPrivileged */,
+ listener)) {
+ return;
+ }
mTethering.startTethering(request, listener);
}
@@ -179,7 +165,7 @@ public class TetheringService extends Service {
public void registerTetheringEventCallback(ITetheringEventCallback callback,
String callerPkg) {
try {
- if (!mService.hasTetherAccessPermission()) {
+ if (!hasTetherAccessPermission()) {
callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
return;
}
@@ -191,7 +177,7 @@ public class TetheringService extends Service {
public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
String callerPkg) {
try {
- if (!mService.hasTetherAccessPermission()) {
+ if (!hasTetherAccessPermission()) {
callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
return;
}
@@ -226,14 +212,22 @@ public class TetheringService extends Service {
mTethering.dump(fd, writer, args);
}
- private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag,
- IIntResultListener listener) {
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final IIntResultListener listener) {
+ return checkAndNotifyCommonError(callerPkg, callingAttributionTag,
+ false /* onlyAllowPrivileged */, listener);
+ }
+
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final boolean onlyAllowPrivileged,
+ final IIntResultListener listener) {
try {
- if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) {
+ if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
+ onlyAllowPrivileged)) {
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
return true;
}
- if (!mService.isTetheringSupported()) {
+ if (!mTethering.isTetheringSupported()) {
listener.onResult(TETHER_ERROR_UNSUPPORTED);
return true;
}
@@ -244,13 +238,14 @@ public class TetheringService extends Service {
return false;
}
- private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag,
- ResultReceiver receiver) {
- if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) {
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final ResultReceiver receiver) {
+ if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
+ false /* onlyAllowPrivileged */)) {
receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
return true;
}
- if (!mService.isTetheringSupported()) {
+ if (!mTethering.isTetheringSupported()) {
receiver.send(TETHER_ERROR_UNSUPPORTED, null);
return true;
}
@@ -258,40 +253,31 @@ public class TetheringService extends Service {
return false;
}
- }
-
- // if ro.tether.denied = true we default to no tethering
- // gservices could set the secure setting to 1 though to enable it on a build where it
- // had previously been turned off.
- private boolean isTetheringSupported() {
- final int defaultVal =
- SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
- final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
- final boolean tetherEnabledInSettings = tetherSupported
- && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
-
- return tetherEnabledInSettings && mTethering.hasTetherableConfiguration();
- }
-
- private boolean hasTetherChangePermission(String callerPkg, String callingAttributionTag) {
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
- return true;
+ private boolean hasTetherPrivilegedPermission() {
+ return mService.checkCallingOrSelfPermission(TETHER_PRIVILEGED) == PERMISSION_GRANTED;
}
- if (mTethering.isTetherProvisioningRequired()) return false;
+ private boolean hasTetherChangePermission(final String callerPkg,
+ final String callingAttributionTag, final boolean onlyAllowPrivileged) {
+ if (hasTetherPrivilegedPermission()) return true;
+ if (onlyAllowPrivileged || mTethering.isTetherProvisioningRequired()) return false;
- int uid = Binder.getCallingUid();
- // If callerPkg's uid is not same as Binder.getCallingUid(),
- // checkAndNoteWriteSettingsOperation will return false and the operation will be denied.
- if (checkAndNoteWriteSettingsOperation(mContext, uid, callerPkg,
- callingAttributionTag, false /* throwException */)) {
- return true;
+ int uid = Binder.getCallingUid();
+
+ // If callerPkg's uid is not same as Binder.getCallingUid(),
+ // checkAndNoteWriteSettingsOperation will return false and the operation will be
+ // denied.
+ return mService.checkAndNoteWriteSettingsOperation(mService, uid, callerPkg,
+ callingAttributionTag, false /* throwException */);
}
- return false;
+ private boolean hasTetherAccessPermission() {
+ if (hasTetherPrivilegedPermission()) return true;
+
+ return mService.checkCallingOrSelfPermission(
+ ACCESS_NETWORK_STATE) == PERMISSION_GRANTED;
+ }
}
/**
@@ -300,114 +286,91 @@ public class TetheringService extends Service {
*
* @return {@code true} iff the package is allowed to write settings.
*/
- // TODO: Remove method and replace with direct call once R code is pushed to AOSP
- private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
+ @VisibleForTesting
+ boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
@NonNull String callingPackage, @Nullable String callingAttributionTag,
boolean throwException) {
return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage,
throwException);
}
- private boolean hasTetherAccessPermission() {
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
- return true;
- }
-
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE) == PERMISSION_GRANTED) {
- return true;
- }
-
- return false;
- }
-
-
/**
* An injection method for testing.
*/
@VisibleForTesting
- public TetheringDependencies getTetheringDependencies() {
- if (mDeps == null) {
- mDeps = new TetheringDependencies() {
- @Override
- public NetworkRequest getDefaultNetworkRequest() {
- // TODO: b/147280869, add a proper system API to replace this.
- final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
- .clearCapabilities()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .build();
- return trackDefaultRequest;
- }
-
- @Override
- public Looper getTetheringLooper() {
- final HandlerThread tetherThread = new HandlerThread("android.tethering");
- tetherThread.start();
- return tetherThread.getLooper();
- }
+ public TetheringDependencies makeTetheringDependencies() {
+ return new TetheringDependencies() {
+ @Override
+ public NetworkRequest getDefaultNetworkRequest() {
+ // TODO: b/147280869, add a proper system API to replace this.
+ final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
+ .clearCapabilities()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+ return trackDefaultRequest;
+ }
- @Override
- public boolean isTetheringSupported() {
- return TetheringService.this.isTetheringSupported();
- }
+ @Override
+ public Looper getTetheringLooper() {
+ final HandlerThread tetherThread = new HandlerThread("android.tethering");
+ tetherThread.start();
+ return tetherThread.getLooper();
+ }
- @Override
- public Context getContext() {
- return TetheringService.this;
- }
+ @Override
+ public Context getContext() {
+ return TetheringService.this;
+ }
- @Override
- public IpServer.Dependencies getIpServerDependencies() {
- return new IpServer.Dependencies() {
- @Override
- public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
- DhcpServerCallbacks cb) {
+ @Override
+ public IpServer.Dependencies getIpServerDependencies() {
+ return new IpServer.Dependencies() {
+ @Override
+ public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
+ DhcpServerCallbacks cb) {
+ try {
+ final INetworkStackConnector service = getNetworkStackConnector();
+ if (service == null) return;
+
+ service.makeDhcpServer(ifName, params, cb);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Fail to make dhcp server");
try {
- final INetworkStackConnector service = getNetworkStackConnector();
- if (service == null) return;
-
- service.makeDhcpServer(ifName, params, cb);
- } catch (RemoteException e) {
- Log.e(TAG, "Fail to make dhcp server");
- try {
- cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
- } catch (RemoteException re) { }
- }
+ cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
+ } catch (RemoteException re) { }
}
- };
- }
+ }
+ };
+ }
- // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
- // networkStackClient.
- static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
- private INetworkStackConnector getNetworkStackConnector() {
- IBinder connector;
- try {
- final long before = System.currentTimeMillis();
- while ((connector = NetworkStack.getService()) == null) {
- if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
- Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
- return null;
- }
- Thread.sleep(200);
+ // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
+ // networkStackClient.
+ static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
+ private INetworkStackConnector getNetworkStackConnector() {
+ IBinder connector;
+ try {
+ final long before = System.currentTimeMillis();
+ while ((connector = NetworkStack.getService()) == null) {
+ if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
+ Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
+ return null;
}
- } catch (InterruptedException e) {
- Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
- return null;
+ Thread.sleep(200);
}
- return INetworkStackConnector.Stub.asInterface(connector);
+ } catch (InterruptedException e) {
+ Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
+ return null;
}
+ return INetworkStackConnector.Stub.asInterface(connector);
+ }
- @Override
- public BluetoothAdapter getBluetoothAdapter() {
- return BluetoothAdapter.getDefaultAdapter();
- }
- };
- }
- return mDeps;
+ @Override
+ public BluetoothAdapter getBluetoothAdapter() {
+ return BluetoothAdapter.getDefaultAdapter();
+ }
+ };
}
}
diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp
index 3305ed084481..ed69b7d63cb4 100644
--- a/packages/Tethering/tests/integration/Android.bp
+++ b/packages/Tethering/tests/integration/Android.bp
@@ -63,7 +63,6 @@ android_test {
// NetworkStackTests.
android_test {
name: "TetheringCoverageTests",
- certificate: "platform",
platform_apis: true,
test_suites: ["device-tests", "mts"],
test_config: "AndroidTest_Coverage.xml",
diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp
index 9b7d68309fbf..d1e8f5fc777d 100644
--- a/packages/Tethering/tests/unit/Android.bp
+++ b/packages/Tethering/tests/unit/Android.bp
@@ -82,7 +82,7 @@ android_library {
android_test {
name: "TetheringTests",
- certificate: "platform",
+ platform_apis: true,
test_suites: [
"device-tests",
"mts",
diff --git a/packages/Tethering/tests/unit/AndroidManifest.xml b/packages/Tethering/tests/unit/AndroidManifest.xml
index 31eaabff5274..355342f64371 100644
--- a/packages/Tethering/tests/unit/AndroidManifest.xml
+++ b/packages/Tethering/tests/unit/AndroidManifest.xml
@@ -16,9 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack.tethering.tests.unit">
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/>
-
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<service
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index f9be7b9d3664..307ebf17d229 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -17,7 +17,9 @@
package android.net.ip;
import static android.net.INetd.IF_STATE_UP;
+import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
+import static android.net.TetheringManager.TETHERING_NCM;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
@@ -38,6 +40,7 @@ import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -67,10 +70,12 @@ import android.net.MacAddress;
import android.net.RouteInfo;
import android.net.TetherOffloadRuleParcel;
import android.net.dhcp.DhcpServingParamsParcel;
+import android.net.dhcp.IDhcpEventCallbacks;
import android.net.dhcp.IDhcpServer;
import android.net.dhcp.IDhcpServerCallbacks;
import android.net.ip.IpNeighborMonitor.NeighborEvent;
import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
+import android.net.ip.RouterAdvertisementDaemon.RaParams;
import android.net.util.InterfaceParams;
import android.net.util.InterfaceSet;
import android.net.util.SharedLog;
@@ -94,6 +99,7 @@ import org.mockito.MockitoAnnotations;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;
+import java.util.List;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -106,6 +112,7 @@ public class IpServerTest {
private static final String BLUETOOTH_IFACE_ADDR = "192.168.42.1";
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
private static final int DHCP_LEASE_TIME_SECS = 3600;
+ private static final boolean DEFAULT_USING_BPF_OFFLOAD = true;
private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
IFACE_NAME, 42 /* index */, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
@@ -130,10 +137,11 @@ public class IpServerTest {
private NeighborEventConsumer mNeighborEventConsumer;
private void initStateMachine(int interfaceType) throws Exception {
- initStateMachine(interfaceType, false /* usingLegacyDhcp */);
+ initStateMachine(interfaceType, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
}
- private void initStateMachine(int interfaceType, boolean usingLegacyDhcp) throws Exception {
+ private void initStateMachine(int interfaceType, boolean usingLegacyDhcp,
+ boolean usingBpfOffload) throws Exception {
doAnswer(inv -> {
final IDhcpServerCallbacks cb = inv.getArgument(2);
new Thread(() -> {
@@ -165,7 +173,7 @@ public class IpServerTest {
mIpServer = new IpServer(
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd,
- mCallback, usingLegacyDhcp, mDependencies);
+ mCallback, usingLegacyDhcp, usingBpfOffload, mDependencies);
mIpServer.start();
mNeighborEventConsumer = neighborCaptor.getValue();
@@ -179,17 +187,18 @@ public class IpServerTest {
private void initTetheredStateMachine(int interfaceType, String upstreamIface)
throws Exception {
- initTetheredStateMachine(interfaceType, upstreamIface, false);
+ initTetheredStateMachine(interfaceType, upstreamIface, false,
+ DEFAULT_USING_BPF_OFFLOAD);
}
private void initTetheredStateMachine(int interfaceType, String upstreamIface,
- boolean usingLegacyDhcp) throws Exception {
- initStateMachine(interfaceType, usingLegacyDhcp);
+ boolean usingLegacyDhcp, boolean usingBpfOffload) throws Exception {
+ initStateMachine(interfaceType, usingLegacyDhcp, usingBpfOffload);
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
if (upstreamIface != null) {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(upstreamIface);
- dispatchTetherConnectionChanged(upstreamIface, lp);
+ dispatchTetherConnectionChanged(upstreamIface, lp, 0);
}
reset(mNetd, mCallback);
}
@@ -204,7 +213,8 @@ public class IpServerTest {
when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
.thenReturn(mIpNeighborMonitor);
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
- mNetd, mCallback, false /* usingLegacyDhcp */, mDependencies);
+ mNetd, mCallback, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD,
+ mDependencies);
mIpServer.start();
mLooper.dispatchAll();
verify(mCallback).updateInterfaceState(
@@ -493,8 +503,62 @@ public class IpServerTest {
}
@Test
+ public void startsDhcpServerOnNcm() throws Exception {
+ initStateMachine(TETHERING_NCM);
+ dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE);
+
+ assertDhcpStarted(new IpPrefix("192.168.42.0/24"));
+ }
+
+ @Test
+ public void testOnNewPrefixRequest() throws Exception {
+ initStateMachine(TETHERING_NCM);
+ dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
+
+ final IDhcpEventCallbacks eventCallbacks;
+ final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
+ ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
+ verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
+ any(), dhcpEventCbsCaptor.capture());
+ eventCallbacks = dhcpEventCbsCaptor.getValue();
+ assertDhcpStarted(new IpPrefix("192.168.42.0/24"));
+
+ // Simulate the DHCP server receives DHCPDECLINE on MirrorLink and then signals
+ // onNewPrefixRequest callback.
+ eventCallbacks.onNewPrefixRequest(new IpPrefix("192.168.42.0/24"));
+ mLooper.dispatchAll();
+
+ final ArgumentCaptor<LinkProperties> lpCaptor =
+ ArgumentCaptor.forClass(LinkProperties.class);
+ InOrder inOrder = inOrder(mNetd, mCallback);
+ inOrder.verify(mCallback).updateInterfaceState(
+ mIpServer, STATE_LOCAL_ONLY, TETHER_ERROR_NO_ERROR);
+ inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture());
+ inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
+ // One for ipv4 route, one for ipv6 link local route.
+ inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
+ any(), any());
+ inOrder.verify(mNetd).tetherApplyDnsInterfaces();
+ inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture());
+ verifyNoMoreInteractions(mCallback);
+
+ final LinkProperties linkProperties = lpCaptor.getValue();
+ final List<LinkAddress> linkAddresses = linkProperties.getLinkAddresses();
+ assertEquals(1, linkProperties.getLinkAddresses().size());
+ assertEquals(1, linkProperties.getRoutes().size());
+ final IpPrefix prefix = new IpPrefix(linkAddresses.get(0).getAddress(),
+ linkAddresses.get(0).getPrefixLength());
+ assertNotEquals(prefix, new IpPrefix("192.168.42.0/24"));
+
+ verify(mDhcpServer).updateParams(mDhcpParamsCaptor.capture(), any());
+ assertDhcpServingParams(mDhcpParamsCaptor.getValue(), prefix);
+ }
+
+ @Test
public void doesNotStartDhcpServerIfDisabled() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */);
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */,
+ DEFAULT_USING_BPF_OFFLOAD);
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
verify(mDependencies, never()).makeDhcpServer(any(), any(), any());
@@ -577,7 +641,8 @@ public class IpServerTest {
@Test
public void addRemoveipv6ForwardingRules() throws Exception {
- initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */);
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+ DEFAULT_USING_BPF_OFFLOAD);
final int myIfindex = TEST_IFACE_PARAMS.index;
final int notMyIfindex = myIfindex - 1;
@@ -631,7 +696,7 @@ public class IpServerTest {
InOrder inOrder = inOrder(mNetd);
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(UPSTREAM_IFACE2);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighA, macA));
inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX2, neighB, macB));
@@ -639,7 +704,7 @@ public class IpServerTest {
reset(mNetd);
// When the upstream is lost, rules are removed.
- dispatchTetherConnectionChanged(null, null);
+ dispatchTetherConnectionChanged(null, null, 0);
verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighA, macA));
verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX2, neighB, macB));
reset(mNetd);
@@ -652,19 +717,19 @@ public class IpServerTest {
// Rules can be added again once upstream IPv6 connectivity is available.
lp.setInterfaceName(UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighB, macB));
verify(mNetd, never()).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
// If upstream IPv6 connectivity is lost, rules are removed.
reset(mNetd);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, null);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
// When the interface goes down, rules are removed.
lp.setInterfaceName(UPSTREAM_IFACE);
- dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neighA, macA));
@@ -678,19 +743,116 @@ public class IpServerTest {
reset(mNetd);
}
- private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
- verify(mDependencies, times(1)).makeDhcpServer(eq(IFACE_NAME), any(), any());
- verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
- any(), any());
- final DhcpServingParamsParcel params = mDhcpParamsCaptor.getValue();
+ @Test
+ public void enableDisableUsingBpfOffload() throws Exception {
+ final int myIfindex = TEST_IFACE_PARAMS.index;
+ final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
+ final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
+ final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
+
+ reset(mNetd);
+
+ // Expect that rules can be only added/removed when the BPF offload config is enabled.
+ // Note that the usingBpfOffload false case is not a realistic test case. Because IP
+ // neighbor monitor doesn't start if BPF offload is disabled, there should have no
+ // neighbor event listening. This is used for testing the protection check just in case.
+ // TODO: Perhaps remove this test once we don't need this check anymore.
+ for (boolean usingBpfOffload : new boolean[]{true, false}) {
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+ usingBpfOffload);
+
+ // A neighbor is added.
+ recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
+ if (usingBpfOffload) {
+ verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neigh, macA));
+ } else {
+ verify(mNetd, never()).tetherOffloadRuleAdd(any());
+ }
+ reset(mNetd);
+
+ // A neighbor is deleted.
+ recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
+ if (usingBpfOffload) {
+ verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neigh, macNull));
+ } else {
+ verify(mNetd, never()).tetherOffloadRuleRemove(any());
+ }
+ reset(mNetd);
+ }
+ }
+
+ @Test
+ public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+ false /* usingBpfOffload */);
+
+ // IP neighbor monitor doesn't start if BPF offload is disabled.
+ verify(mIpNeighborMonitor, never()).start();
+ }
+
+ private LinkProperties buildIpv6OnlyLinkProperties(final String iface) {
+ final LinkProperties linkProp = new LinkProperties();
+ linkProp.setInterfaceName(iface);
+ linkProp.addLinkAddress(new LinkAddress("2001:db8::1/64"));
+ linkProp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, iface, RTN_UNICAST));
+ final InetAddress dns = InetAddresses.parseNumericAddress("2001:4860:4860::8888");
+ linkProp.addDnsServer(dns);
+
+ return linkProp;
+ }
+
+ @Test
+ public void testAdjustTtlValue() throws Exception {
+ final ArgumentCaptor<RaParams> raParamsCaptor =
+ ArgumentCaptor.forClass(RaParams.class);
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
+ verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
+ final RaParams noV6Params = raParamsCaptor.getValue();
+ assertEquals(65, noV6Params.hopLimit);
+ reset(mRaDaemon);
+
+ when(mNetd.getProcSysNet(
+ INetd.IPV6, INetd.CONF, UPSTREAM_IFACE, "hop_limit")).thenReturn("64");
+ final LinkProperties lp = buildIpv6OnlyLinkProperties(UPSTREAM_IFACE);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, 1);
+ verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
+ final RaParams nonCellularParams = raParamsCaptor.getValue();
+ assertEquals(65, nonCellularParams.hopLimit);
+ reset(mRaDaemon);
+
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
+ verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
+ final RaParams noUpstream = raParamsCaptor.getValue();
+ assertEquals(65, nonCellularParams.hopLimit);
+ reset(mRaDaemon);
+
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
+ verify(mRaDaemon).buildNewRa(any(), raParamsCaptor.capture());
+ final RaParams cellularParams = raParamsCaptor.getValue();
+ assertEquals(63, cellularParams.hopLimit);
+ reset(mRaDaemon);
+ }
+
+ private void assertDhcpServingParams(final DhcpServingParamsParcel params,
+ final IpPrefix prefix) {
// Last address byte is random
- assertTrue(expectedPrefix.contains(intToInet4AddressHTH(params.serverAddr)));
- assertEquals(expectedPrefix.getPrefixLength(), params.serverAddrPrefixLength);
+ assertTrue(prefix.contains(intToInet4AddressHTH(params.serverAddr)));
+ assertEquals(prefix.getPrefixLength(), params.serverAddrPrefixLength);
assertEquals(1, params.defaultRouters.length);
assertEquals(params.serverAddr, params.defaultRouters[0]);
assertEquals(1, params.dnsServers.length);
assertEquals(params.serverAddr, params.dnsServers[0]);
assertEquals(DHCP_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
+ if (mIpServer.interfaceType() == TETHERING_NCM) {
+ assertTrue(params.changePrefixOnDecline);
+ }
+ }
+
+ private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
+ verify(mDependencies, times(1)).makeDhcpServer(eq(IFACE_NAME), any(), any());
+ verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
+ any(), any());
+ assertDhcpServingParams(mDhcpParamsCaptor.getValue(), expectedPrefix);
}
/**
@@ -721,9 +883,10 @@ public class IpServerTest {
* @param upstreamIface String name of upstream interface (or null)
* @param v6lp IPv6 LinkProperties of the upstream interface, or null for an IPv4-only upstream.
*/
- private void dispatchTetherConnectionChanged(String upstreamIface, LinkProperties v6lp) {
+ private void dispatchTetherConnectionChanged(String upstreamIface, LinkProperties v6lp,
+ int ttlAdjustment) {
dispatchTetherConnectionChanged(upstreamIface);
- mIpServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, v6lp);
+ mIpServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, ttlAdjustment, 0, v6lp);
mLooper.dispatchAll();
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
index 8bd0edc2490d..72fa916b9e42 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
@@ -37,6 +37,8 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -45,7 +47,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.net.util.SharedLog;
import android.os.Bundle;
-import android.os.Message;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
import android.os.SystemProperties;
@@ -56,26 +58,22 @@ import android.telephony.CarrierConfigManager;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
import com.android.internal.util.test.BroadcastInterceptingContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
-import java.util.ArrayList;
-
@RunWith(AndroidJUnit4.class)
@SmallTest
public final class EntitlementManagerTest {
- private static final int EVENT_EM_UPDATE = 1;
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
@@ -90,8 +88,8 @@ public final class EntitlementManagerTest {
private final PersistableBundle mCarrierConfig = new PersistableBundle();
private final TestLooper mLooper = new TestLooper();
private Context mMockContext;
+ private Runnable mPermissionChangeCallback;
- private TestStateMachine mSM;
private WrappedEntitlementManager mEnMgr;
private TetheringConfiguration mConfig;
private MockitoSession mMockingSession;
@@ -112,9 +110,9 @@ public final class EntitlementManagerTest {
public int uiProvisionCount = 0;
public int silentProvisionCount = 0;
- public WrappedEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, int what) {
- super(ctx, target, log, what);
+ public WrappedEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ super(ctx, h, log, callback);
}
public void reset() {
@@ -149,9 +147,8 @@ public final class EntitlementManagerTest {
doReturn(false).when(
() -> SystemProperties.getBoolean(
eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY), anyBoolean()));
- doReturn(false).when(
- () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+ doReturn(null).when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY), anyString()));
when(mResources.getStringArray(R.array.config_tether_dhcp_range))
.thenReturn(new String[0]);
@@ -169,8 +166,9 @@ public final class EntitlementManagerTest {
when(mLog.forSubComponent(anyString())).thenReturn(mLog);
mMockContext = new MockContext(mContext);
- mSM = new TestStateMachine();
- mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE);
+ mPermissionChangeCallback = spy(() -> { });
+ mEnMgr = new WrappedEntitlementManager(mMockContext, new Handler(mLooper.getLooper()), mLog,
+ mPermissionChangeCallback);
mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
mEnMgr.setTetheringConfigurationFetcher(() -> {
@@ -180,10 +178,6 @@ public final class EntitlementManagerTest {
@After
public void tearDown() throws Exception {
- if (mSM != null) {
- mSM.quit();
- mSM = null;
- }
mMockingSession.finishMocking();
}
@@ -350,68 +344,105 @@ public final class EntitlementManagerTest {
mEnMgr.reset();
}
+ private void assertPermissionChangeCallback(InOrder inOrder) {
+ inOrder.verify(mPermissionChangeCallback, times(1)).run();
+ }
+
+ private void assertNoPermissionChange(InOrder inOrder) {
+ inOrder.verifyNoMoreInteractions();
+ }
+
@Test
public void verifyPermissionResult() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: false -> true
+ assertPermissionChangeCallback(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
}
@Test
public void verifyPermissionIfAllNotApproved() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
}
@Test
public void verifyPermissionIfAnyApproved() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mLooper.dispatchAll();
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
mLooper.dispatchAll();
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
}
@Test
public void verifyPermissionWhenProvisioningNotStarted() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ assertNoPermissionChange(inOrder);
setupForRequiredProvisioning();
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ assertNoPermissionChange(inOrder);
}
@Test
public void testRunTetherProvisioning() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
// 1. start ui provisioning, upstream is mobile
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
@@ -421,16 +452,22 @@ public final class EntitlementManagerTest {
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 2. start no-ui provisioning
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(1, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 3. tear down mobile, then start ui provisioning
mEnMgr.notifyUpstream(false);
mLooper.dispatchAll();
@@ -438,44 +475,58 @@ public final class EntitlementManagerTest {
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
+
// 4. switch upstream back to mobile
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.notifyUpstream(true);
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 5. tear down mobile, then switch SIM
mEnMgr.notifyUpstream(false);
mLooper.dispatchAll();
mEnMgr.reevaluateSimCardProvisioning(mConfig);
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
+
// 6. switch upstream back to mobile again
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.notifyUpstream(true);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(3, mEnMgr.silentProvisionCount);
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 7. start ui provisioning, upstream is mobile, downstream is ethernet
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_ETHERNET, true);
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: false -> true
+ assertPermissionChangeCallback(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 8. downstream is invalid
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI_P2P, true);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
}
@@ -492,31 +543,32 @@ public final class EntitlementManagerTest {
verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI);
}
- public class TestStateMachine extends StateMachine {
- public final ArrayList<Message> messages = new ArrayList<>();
- private final State
- mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState();
+ @Test
+ public void testsetExemptedDownstreamType() throws Exception {
+ setupForRequiredProvisioning();
+ // Cellular upstream is not permitted when no entitlement result.
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
- class LoggingState extends State {
- @Override public void enter() {
- messages.clear();
- }
+ // If there is exempted downstream and no other non-exempted downstreams, cellular is
+ // permitted.
+ mEnMgr.setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
- @Override public void exit() {
- messages.clear();
- }
+ // If second downstream run entitlement check fail, cellular upstream is not permitted.
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
+ mEnMgr.notifyUpstream(true);
+ mLooper.dispatchAll();
+ mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
- @Override public boolean processMessage(Message msg) {
- messages.add(msg);
- return false;
- }
- }
+ // When second downstream is down, exempted downstream can use cellular upstream.
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ verify(mEntitlementFailedListener).onUiEntitlementFailed(TETHERING_USB);
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_USB);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
- public TestStateMachine() {
- super("EntitlementManagerTest.TestStateMachine", mLooper.getLooper());
- addState(mLoggingState);
- setInitialState(mLoggingState);
- super.start();
- }
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
}
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java
index 820f25514532..f2b5314e5a17 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java
@@ -128,7 +128,7 @@ public class IPv6TetheringCoordinatorTest {
final UpstreamNetworkState mobileUpstream = createDualStackUpstream(TRANSPORT_CELLULAR);
final ArgumentCaptor<LinkProperties> lp = ArgumentCaptor.forClass(LinkProperties.class);
mIPv6TetheringCoordinator.updateUpstreamNetworkState(mobileUpstream);
- verify(firstServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(0), eq(0),
+ verify(firstServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(-1), eq(0),
lp.capture());
final LinkProperties v6OnlyLink = lp.getValue();
assertOnlyOneV6AddressAndNoV4(v6OnlyLink);
@@ -140,7 +140,7 @@ public class IPv6TetheringCoordinatorTest {
mNotifyList.remove(firstServer);
mIPv6TetheringCoordinator.removeActiveDownstream(firstServer);
verify(firstServer).sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
- verify(secondServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(0), eq(0),
+ verify(secondServer).sendMessage(eq(IpServer.CMD_IPV6_TETHER_UPDATE), eq(-1), eq(0),
lp.capture());
final LinkProperties localOnlyLink = lp.getValue();
assertNotNull(localOnlyLink);
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java
index 1c81c1247ded..071a290e657b 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java
@@ -15,13 +15,20 @@
*/
package com.android.networkstack.tethering;
+import static android.Manifest.permission.WRITE_SETTINGS;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import static org.mockito.Mockito.mock;
+import android.content.Context;
import android.content.Intent;
import android.net.ITetheringConnector;
import android.os.Binder;
import android.os.IBinder;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
public class MockTetheringService extends TetheringService {
private final Tethering mTethering = mock(Tethering.class);
@@ -35,6 +42,15 @@ public class MockTetheringService extends TetheringService {
return mTethering;
}
+ @Override
+ boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
+ @NonNull String callingPackage, @Nullable String callingAttributionTag,
+ boolean throwException) {
+ // Test this does not verify the calling package / UID, as calling package could be shell
+ // and not match the UID.
+ return context.checkCallingOrSelfPermission(WRITE_SETTINGS) == PERMISSION_GRANTED;
+ }
+
public Tethering getTethering() {
return mTethering;
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
index 65797200fa92..b291438937c7 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
@@ -29,15 +29,15 @@ import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
import static com.android.testutils.MiscAssertsKt.assertContainsAll;
import static com.android.testutils.MiscAssertsKt.assertThrows;
-import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals;
+import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
@@ -63,10 +63,10 @@ import android.net.LinkProperties;
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
import android.net.RouteInfo;
-import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.os.Handler;
-import android.os.Looper;
+import android.os.test.TestLooper;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.test.mock.MockContentResolver;
@@ -75,7 +75,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.TestableNetworkStatsProviderCbBinder;
import org.junit.After;
import org.junit.Before;
@@ -109,13 +109,22 @@ public class OffloadControllerTest {
@Mock private ApplicationInfo mApplicationInfo;
@Mock private Context mContext;
@Mock private NetworkStatsManager mStatsManager;
- @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb;
+ @Mock private TetheringConfiguration mTetherConfig;
+ // Late init since methods must be called by the thread that created this object.
+ private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
ArgumentCaptor.forClass(ArrayList.class);
private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
private MockContentResolver mContentResolver;
+ private final TestLooper mTestLooper = new TestLooper();
+ private OffloadController.Dependencies mDeps = new OffloadController.Dependencies() {
+ @Override
+ public TetheringConfiguration getTetherConfig() {
+ return mTetherConfig;
+ }
+ };
@Before public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -125,6 +134,7 @@ public class OffloadControllerTest {
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
FakeSettingsProvider.clearSettingsProvider();
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(-1); // Disabled.
}
@After public void tearDown() throws Exception {
@@ -144,13 +154,17 @@ public class OffloadControllerTest {
Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
}
+ private void setOffloadPollInterval(int interval) {
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(interval);
+ }
+
private void waitForIdle() {
- HandlerUtilsKt.waitForIdle(new Handler(Looper.getMainLooper()), WAIT_FOR_IDLE_TIMEOUT);
+ mTestLooper.dispatchAll();
}
private OffloadController makeOffloadController() throws Exception {
- OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()),
- mHardware, mContentResolver, mStatsManager, new SharedLog("test"));
+ OffloadController offload = new OffloadController(new Handler(mTestLooper.getLooper()),
+ mHardware, mContentResolver, mStatsManager, new SharedLog("test"), mDeps);
final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
tetherStatsProviderCaptor =
ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
@@ -158,6 +172,7 @@ public class OffloadControllerTest {
tetherStatsProviderCaptor.capture());
mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
assertNotNull(mTetherStatsProvider);
+ mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder();
mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
return offload;
}
@@ -346,9 +361,9 @@ public class OffloadControllerTest {
stacked.setInterfaceName("stacked");
stacked.addLinkAddress(new LinkAddress("192.0.2.129/25"));
stacked.addRoute(new RouteInfo(null, InetAddress.getByName("192.0.2.254"), null,
- RTN_UNICAST));
+ RTN_UNICAST));
stacked.addRoute(new RouteInfo(null, InetAddress.getByName("fe80::bad:f00"), null,
- RTN_UNICAST));
+ RTN_UNICAST));
assertTrue(lp.addStackedLink(stacked));
offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes().
@@ -453,20 +468,12 @@ public class OffloadControllerTest {
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
- assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats));
- assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats));
-
- final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass(
- NetworkStats.class);
- final ArgumentCaptor<NetworkStats> uidStatsCaptor = ArgumentCaptor.forClass(
- NetworkStats.class);
+ assertNetworkStatsEquals(expectedIfaceStats, ifaceStats);
+ assertNetworkStatsEquals(expectedUidStats, uidStats);
// Force pushing stats update to verify the stats reported.
mTetherStatsProvider.pushTetherStats();
- verify(mTetherStatsProviderCb, times(1))
- .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
- assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue()));
- assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue()));
+ mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats);
when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
new ForwardedStats(100000, 100000));
@@ -492,11 +499,10 @@ public class OffloadControllerTest {
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
- assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu));
- assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu));
+ assertNetworkStatsEquals(expectedIfaceStatsAccu, ifaceStatsAccu);
+ assertNetworkStatsEquals(expectedUidStatsAccu, uidStatsAccu);
// Verify that only diff of stats is reported.
- reset(mTetherStatsProviderCb);
mTetherStatsProvider.pushTetherStats();
final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
.addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
@@ -505,10 +511,8 @@ public class OffloadControllerTest {
final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
- verify(mTetherStatsProviderCb, times(1))
- .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
- assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue()));
- assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue()));
+ mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStatsDiff,
+ expectedUidStatsDiff);
}
@Test
@@ -585,7 +589,7 @@ public class OffloadControllerTest {
OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
callback.onStoppedLimitReached();
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
}
@Test
@@ -689,8 +693,8 @@ public class OffloadControllerTest {
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
// TODO: verify the exact stats reported.
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
- verifyNoMoreInteractions(mTetherStatsProviderCb);
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
+ mTetherStatsProviderCb.assertNoCallback();
verifyNoMoreInteractions(mHardware);
}
@@ -754,8 +758,8 @@ public class OffloadControllerTest {
// Verify forwarded stats behaviour.
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
- verifyNoMoreInteractions(mTetherStatsProviderCb);
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
+ mTetherStatsProviderCb.assertNoCallback();
// TODO: verify local prefixes and downstreams are also pushed to the HAL.
verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
@@ -774,4 +778,50 @@ public class OffloadControllerTest {
verifyNoMoreInteractions(mHardware);
}
+ @Test
+ public void testOnSetAlert() throws Exception {
+ setupFunctioningHardwareInterface();
+ enableOffload();
+ setOffloadPollInterval(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ final OffloadController offload = makeOffloadController();
+ offload.start();
+
+ // Initialize with fake eth upstream.
+ final String ethernetIface = "eth1";
+ InOrder inOrder = inOrder(mHardware);
+ final LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(ethernetIface);
+ offload.setUpstreamLinkProperties(lp);
+ // Previous upstream was null, so no stats are fetched.
+ inOrder.verify(mHardware, never()).getForwardedStats(any());
+
+ // Verify that set quota to 0 will immediately triggers an callback.
+ mTetherStatsProvider.onSetAlert(0);
+ waitForIdle();
+ mTetherStatsProviderCb.expectNotifyAlertReached();
+
+ // Verify that notifyAlertReached never fired if quota is not yet reached.
+ when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
+ new ForwardedStats(0, 0));
+ mTetherStatsProvider.onSetAlert(100);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.assertNoCallback();
+
+ // Verify that notifyAlertReached fired when quota is reached.
+ when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
+ new ForwardedStats(50, 50));
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.expectNotifyAlertReached();
+
+ // Verify that set quota with UNLIMITED won't trigger any callback, and won't fetch
+ // any stats since the polling is stopped.
+ reset(mHardware);
+ mTetherStatsProvider.onSetAlert(NetworkStatsProvider.QUOTA_UNLIMITED);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.assertNoCallback();
+ verify(mHardware, never()).getForwardedStats(any());
+ }
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
new file mode 100644
index 000000000000..f8ff1cb29c23
--- /dev/null
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.tethering;
+
+import static android.net.util.TetheringUtils.uint16;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
+import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
+import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.test.TestLooper;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class OffloadHardwareInterfaceTest {
+ private static final String RMNET0 = "test_rmnet_data0";
+
+ private final TestLooper mTestLooper = new TestLooper();
+
+ private OffloadHardwareInterface mOffloadHw;
+ private ITetheringOffloadCallback mTetheringOffloadCallback;
+ private OffloadHardwareInterface.ControlCallback mControlCallback;
+
+ @Mock private IOffloadConfig mIOffloadConfig;
+ @Mock private IOffloadControl mIOffloadControl;
+ @Mock private NativeHandle mNativeHandle;
+
+ class MyDependencies extends OffloadHardwareInterface.Dependencies {
+ MyDependencies(SharedLog log) {
+ super(log);
+ }
+
+ @Override
+ public IOffloadConfig getOffloadConfig() {
+ return mIOffloadConfig;
+ }
+
+ @Override
+ public IOffloadControl getOffloadControl() {
+ return mIOffloadControl;
+ }
+
+ @Override
+ public NativeHandle createConntrackSocket(final int groups) {
+ return mNativeHandle;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ final SharedLog log = new SharedLog("test");
+ mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
+ new MyDependencies(log));
+ mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
+ }
+
+ private void startOffloadHardwareInterface() throws Exception {
+ mOffloadHw.initOffloadConfig();
+ mOffloadHw.initOffloadControl(mControlCallback);
+ final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
+ ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
+ verify(mIOffloadControl).initOffload(mOffloadCallbackCaptor.capture(), any());
+ mTetheringOffloadCallback = mOffloadCallbackCaptor.getValue();
+ }
+
+ @Test
+ public void testGetForwardedStats() throws Exception {
+ startOffloadHardwareInterface();
+ final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
+ verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
+ assertNotNull(stats);
+ }
+
+ @Test
+ public void testSetLocalPrefixes() throws Exception {
+ startOffloadHardwareInterface();
+ final ArrayList<String> localPrefixes = new ArrayList<>();
+ localPrefixes.add("127.0.0.0/8");
+ localPrefixes.add("fe80::/64");
+ mOffloadHw.setLocalPrefixes(localPrefixes);
+ verify(mIOffloadControl).setLocalPrefixes(eq(localPrefixes), any());
+ }
+
+ @Test
+ public void testSetDataLimit() throws Exception {
+ startOffloadHardwareInterface();
+ final long limit = 12345;
+ mOffloadHw.setDataLimit(RMNET0, limit);
+ verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
+ }
+
+ @Test
+ public void testSetUpstreamParameters() throws Exception {
+ startOffloadHardwareInterface();
+ final String v4addr = "192.168.10.1";
+ final String v4gateway = "192.168.10.255";
+ final ArrayList<String> v6gws = new ArrayList<>(0);
+ v6gws.add("2001:db8::1");
+ mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws);
+ verify(mIOffloadControl).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
+ eq(v6gws), any());
+
+ final ArgumentCaptor<ArrayList<String>> mArrayListCaptor =
+ ArgumentCaptor.forClass(ArrayList.class);
+ mOffloadHw.setUpstreamParameters(null, null, null, null);
+ verify(mIOffloadControl).setUpstreamParameters(eq(""), eq(""), eq(""),
+ mArrayListCaptor.capture(), any());
+ assertEquals(mArrayListCaptor.getValue().size(), 0);
+ }
+
+ @Test
+ public void testUpdateDownstreamPrefix() throws Exception {
+ startOffloadHardwareInterface();
+ final String ifName = "wlan1";
+ final String prefix = "192.168.43.0/24";
+ mOffloadHw.addDownstreamPrefix(ifName, prefix);
+ verify(mIOffloadControl).addDownstream(eq(ifName), eq(prefix), any());
+
+ mOffloadHw.removeDownstreamPrefix(ifName, prefix);
+ verify(mIOffloadControl).removeDownstream(eq(ifName), eq(prefix), any());
+ }
+
+ @Test
+ public void testTetheringOffloadCallback() throws Exception {
+ startOffloadHardwareInterface();
+
+ mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onStarted();
+
+ mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onStoppedError();
+
+ mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onStoppedUnsupported();
+
+ mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onSupportAvailable();
+
+ mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onStoppedLimitReached();
+
+ final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
+ mTetheringOffloadCallback.updateTimeout(tcpParams);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
+ eq(tcpParams.src.addr),
+ eq(uint16(tcpParams.src.port)),
+ eq(tcpParams.dst.addr),
+ eq(uint16(tcpParams.dst.port)));
+
+ final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
+ mTetheringOffloadCallback.updateTimeout(udpParams);
+ mTestLooper.dispatchAll();
+ verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
+ eq(udpParams.src.addr),
+ eq(uint16(udpParams.src.port)),
+ eq(udpParams.dst.addr),
+ eq(uint16(udpParams.dst.port)));
+ }
+
+ private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
+ final NatTimeoutUpdate params = new NatTimeoutUpdate();
+ params.proto = proto;
+ params.src.addr = "192.168.43.200";
+ params.src.port = 100;
+ params.dst.addr = "172.50.46.169";
+ params.dst.port = 150;
+ return params;
+ }
+}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index 07ddea43f4e8..1999ad786ed4 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -30,7 +30,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
@@ -109,12 +108,14 @@ public class TetheringConfigurationTest {
.mockStatic(DeviceConfig.class)
.strictness(Strictness.WARN)
.startMocking();
- doReturn(false).when(
- () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+ doReturn(null).when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+ eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
when(mResources.getStringArray(R.array.config_tether_dhcp_range)).thenReturn(
new String[0]);
+ when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
+ TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
when(mResources.getStringArray(R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
.thenReturn(new String[]{ "test_wlan\\d" });
@@ -125,6 +126,8 @@ public class TetheringConfigurationTest {
.thenReturn(new String[0]);
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
+ initializeBpfOffloadConfiguration(true, null /* unset */);
+
mHasTelephonyManager = true;
mMockContext = new MockContext(mContext);
mEnableLegacyDhcpServer = false;
@@ -276,13 +279,57 @@ public class TetheringConfigurationTest {
assertFalse(upstreamIterator.hasNext());
}
+ private void initializeBpfOffloadConfiguration(
+ final boolean fromRes, final String fromDevConfig) {
+ when(mResources.getBoolean(R.bool.config_tether_enable_bpf_offload)).thenReturn(fromRes);
+ doReturn(fromDevConfig).when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+ eq(TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD)));
+ }
+
+ @Test
+ public void testBpfOffloadEnabledByResource() {
+ initializeBpfOffloadConfiguration(true, null /* unset */);
+ final TetheringConfiguration enableByRes =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertTrue(enableByRes.enableBpfOffload);
+ }
+
+ @Test
+ public void testBpfOffloadEnabledByDeviceConfigOverride() {
+ for (boolean res : new boolean[]{true, false}) {
+ initializeBpfOffloadConfiguration(res, "true");
+ final TetheringConfiguration enableByDevConOverride =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertTrue(enableByDevConOverride.enableBpfOffload);
+ }
+ }
+
+ @Test
+ public void testBpfOffloadDisabledByResource() {
+ initializeBpfOffloadConfiguration(false, null /* unset */);
+ final TetheringConfiguration disableByRes =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertFalse(disableByRes.enableBpfOffload);
+ }
+
+ @Test
+ public void testBpfOffloadDisabledByDeviceConfigOverride() {
+ for (boolean res : new boolean[]{true, false}) {
+ initializeBpfOffloadConfiguration(res, "false");
+ final TetheringConfiguration disableByDevConOverride =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertFalse(disableByDevConOverride.enableBpfOffload);
+ }
+ }
+
@Test
public void testNewDhcpServerDisabled() {
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
true);
- doReturn(false).when(
- () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+ doReturn("false").when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+ eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
final TetheringConfiguration enableByRes =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -290,9 +337,9 @@ public class TetheringConfigurationTest {
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
- doReturn(true).when(
- () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+ doReturn("true").when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+ eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
final TetheringConfiguration enableByDevConfig =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -303,9 +350,9 @@ public class TetheringConfigurationTest {
public void testNewDhcpServerEnabled() {
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
- doReturn(false).when(
- () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+ doReturn("false").when(
+ () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+ eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
final TetheringConfiguration cfg =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -314,6 +361,23 @@ public class TetheringConfigurationTest {
}
@Test
+ public void testOffloadIntervalByResource() {
+ final TetheringConfiguration intervalByDefault =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertEquals(TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS,
+ intervalByDefault.getOffloadPollInterval());
+
+ final int[] testOverrides = {0, 3000, -1};
+ for (final int override : testOverrides) {
+ when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
+ override);
+ final TetheringConfiguration overrideByRes =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertEquals(override, overrideByRes.getOffloadPollInterval());
+ }
+ }
+
+ @Test
public void testGetResourcesBySubId() {
setUpResourceForSubId();
final TetheringConfiguration cfg = new TetheringConfiguration(
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
index 7df9fc685053..cf060ba95d25 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
@@ -16,20 +16,29 @@
package com.android.networkstack.tethering;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
+import static android.Manifest.permission.WRITE_SETTINGS;
import static android.net.TetheringManager.TETHERING_WIFI;
+import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
+import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.app.UiAutomation;
import android.content.Intent;
import android.net.IIntResultListener;
import android.net.ITetheringConnector;
import android.net.ITetheringEventCallback;
import android.net.TetheringRequestParcel;
+import android.os.Bundle;
+import android.os.Handler;
import android.os.ResultReceiver;
import androidx.test.InstrumentationRegistry;
@@ -51,13 +60,14 @@ import org.mockito.MockitoAnnotations;
@SmallTest
public final class TetheringServiceTest {
private static final String TEST_IFACE_NAME = "test_wlan0";
- private static final String TEST_CALLER_PKG = "test_pkg";
+ private static final String TEST_CALLER_PKG = "com.android.shell";
private static final String TEST_ATTRIBUTION_TAG = null;
@Mock private ITetheringEventCallback mITetheringEventCallback;
@Rule public ServiceTestRule mServiceTestRule;
private Tethering mTethering;
private Intent mMockServiceIntent;
private ITetheringConnector mTetheringConnector;
+ private UiAutomation mUiAutomation;
private class TestTetheringResult extends IIntResultListener.Stub {
private int mResult = -1; // Default value that does not match any result code.
@@ -71,9 +81,26 @@ public final class TetheringServiceTest {
}
}
+ private class MyResultReceiver extends ResultReceiver {
+ MyResultReceiver(Handler handler) {
+ super(handler);
+ }
+ private int mResult = -1; // Default value that does not match any result code.
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mResult = resultCode;
+ }
+
+ public void assertResult(int expected) {
+ assertEquals(expected, mResult);
+ }
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mUiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
mServiceTestRule = new ServiceTestRule();
mMockServiceIntent = new Intent(
InstrumentationRegistry.getTargetContext(),
@@ -83,116 +110,364 @@ public final class TetheringServiceTest {
mTetheringConnector = mockConnector.getTetheringConnector();
final MockTetheringService service = mockConnector.getService();
mTethering = service.getTethering();
- verify(mTethering).startStateMachineUpdaters();
- when(mTethering.hasTetherableConfiguration()).thenReturn(true);
}
@After
public void tearDown() throws Exception {
mServiceTestRule.unbindService();
+ mUiAutomation.dropShellPermissionIdentity();
}
- @Test
- public void testTether() throws Exception {
+ private interface TestTetheringCall {
+ void runTetheringCall(TestTetheringResult result) throws Exception;
+ }
+
+ private void runAsNoPermission(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, new String[0]);
+ }
+
+ private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, TETHER_PRIVILEGED);
+ }
+
+ private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, ACCESS_NETWORK_STATE);
+ }
+
+ private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
+ runTetheringCall(test, WRITE_SETTINGS);
+ }
+
+ private void runTetheringCall(final TestTetheringCall test, String... permissions)
+ throws Exception {
+ if (permissions.length > 0) mUiAutomation.adoptShellPermissionIdentity(permissions);
+ try {
+ when(mTethering.isTetheringSupported()).thenReturn(true);
+ test.runTetheringCall(new TestTetheringResult());
+ } finally {
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ private void verifyNoMoreInteractionsForTethering() {
+ verifyNoMoreInteractions(mTethering);
+ verifyNoMoreInteractions(mITetheringEventCallback);
+ reset(mTethering, mITetheringEventCallback);
+ }
+
+ private void runTether(final TestTetheringResult result) throws Exception {
when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).hasTetherableConfiguration();
+ verify(mTethering).isTetheringSupported();
verify(mTethering).tether(TEST_IFACE_NAME);
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
- public void testUntether() throws Exception {
+ public void testTether() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runTether(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runTether(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runUnTether(final TestTetheringResult result) throws Exception {
when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
result);
- verify(mTethering).hasTetherableConfiguration();
+ verify(mTethering).isTetheringSupported();
verify(mTethering).untether(TEST_IFACE_NAME);
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
- public void testSetUsbTethering() throws Exception {
+ public void testUntether() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runUnTether(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runUnTether(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runSetUsbTethering(final TestTetheringResult result) throws Exception {
when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR);
- final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).hasTetherableConfiguration();
+ verify(mTethering).isTetheringSupported();
verify(mTethering).setUsbTethering(true /* enable */);
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
+ public void testSetUsbTethering() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runSetUsbTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runSetUsbTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ }
+
+ private void runStartTethering(final TestTetheringResult result,
+ final TetheringRequestParcel request) throws Exception {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetheringSupported();
+ verify(mTethering).startTethering(eq(request), eq(result));
+ }
+
+ @Test
public void testStartTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
final TetheringRequestParcel request = new TetheringRequestParcel();
request.tetheringType = TETHERING_WIFI;
- mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).hasTetherableConfiguration();
- verify(mTethering).startTethering(eq(request), eq(result));
- verifyNoMoreInteractions(mTethering);
+
+ runAsNoPermission((result) -> {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStartTethering(result, request);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStartTethering(result, request);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
}
@Test
- public void testStopTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
- mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
- result);
- verify(mTethering).hasTetherableConfiguration();
+ public void testStartTetheringWithExemptFromEntitlementCheck() throws Exception {
+ final TetheringRequestParcel request = new TetheringRequestParcel();
+ request.tetheringType = TETHERING_WIFI;
+ request.exemptFromEntitlementCheck = true;
+
+ runAsTetherPrivileged((result) -> {
+ runStartTethering(result, request);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runStopTethering(final TestTetheringResult result) throws Exception {
+ mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetheringSupported();
verify(mTethering).stopTethering(TETHERING_WIFI);
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
- public void testRequestLatestTetheringEntitlementResult() throws Exception {
- final ResultReceiver result = new ResultReceiver(null);
+ public void testStopTethering() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
+ TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStopTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStopTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runRequestLatestTetheringEntitlementResult() throws Exception {
+ final MyResultReceiver result = new MyResultReceiver(null);
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
- verify(mTethering).hasTetherableConfiguration();
+ verify(mTethering).isTetheringSupported();
verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
eq(result), eq(true) /* showEntitlementUi */);
- verifyNoMoreInteractions(mTethering);
}
@Test
- public void testRegisterTetheringEventCallback() throws Exception {
+ public void testRequestLatestTetheringEntitlementResult() throws Exception {
+ // Run as no permission.
+ final MyResultReceiver result = new MyResultReceiver(null);
+ mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
+ true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractions(mTethering);
+
+ runAsTetherPrivileged((none) -> {
+ runRequestLatestTetheringEntitlementResult();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((none) -> {
+ runRequestLatestTetheringEntitlementResult();
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runRegisterTetheringEventCallback() throws Exception {
mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
TEST_CALLER_PKG);
verify(mTethering).registerTetheringEventCallback(eq(mITetheringEventCallback));
- verifyNoMoreInteractions(mTethering);
}
@Test
- public void testUnregisterTetheringEventCallback() throws Exception {
+ public void testRegisterTetheringEventCallback() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.registerTetheringEventCallback(mITetheringEventCallback,
+ TEST_CALLER_PKG);
+ verify(mITetheringEventCallback).onCallbackStopped(
+ TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((none) -> {
+ runRegisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsAccessNetworkState((none) -> {
+ runRegisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runUnregisterTetheringEventCallback() throws Exception {
mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
TEST_CALLER_PKG);
- verify(mTethering).unregisterTetheringEventCallback(
- eq(mITetheringEventCallback));
- verifyNoMoreInteractions(mTethering);
+ verify(mTethering).unregisterTetheringEventCallback(eq(mITetheringEventCallback));
}
@Test
- public void testStopAllTethering() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
+ public void testUnregisterTetheringEventCallback() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.unregisterTetheringEventCallback(mITetheringEventCallback,
+ TEST_CALLER_PKG);
+ verify(mITetheringEventCallback).onCallbackStopped(
+ TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((none) -> {
+ runUnregisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsAccessNetworkState((none) -> {
+ runUnregisterTetheringEventCallback();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runStopAllTethering(final TestTetheringResult result) throws Exception {
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).hasTetherableConfiguration();
+ verify(mTethering).isTetheringSupported();
verify(mTethering).untetherAll();
- verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR);
}
@Test
- public void testIsTetheringSupported() throws Exception {
- final TestTetheringResult result = new TestTetheringResult();
+ public void testStopAllTethering() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runStopAllTethering(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runStopAllTethering(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
+
+ private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
- verify(mTethering).hasTetherableConfiguration();
- verifyNoMoreInteractions(mTethering);
+ verify(mTethering).isTetheringSupported();
result.assertResult(TETHER_ERROR_NO_ERROR);
}
+
+ @Test
+ public void testIsTetheringSupported() throws Exception {
+ runAsNoPermission((result) -> {
+ mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
+ result);
+ verify(mTethering).isTetherProvisioningRequired();
+ result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsTetherPrivileged((result) -> {
+ runIsTetheringSupported(result);
+ verifyNoMoreInteractionsForTethering();
+ });
+
+ runAsWriteSettings((result) -> {
+ runIsTetheringSupported(result);
+ verify(mTethering).isTetherProvisioningRequired();
+ verifyNoMoreInteractionsForTethering();
+ });
+ }
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 4471f649691f..7734a3c61eaf 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -57,6 +57,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
@@ -150,6 +151,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.util.ArrayList;
@@ -170,6 +173,8 @@ public class TetheringTest {
private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
private static final String TEST_NCM_IFNAME = "test_ncm0";
private static final String TETHERING_NAME = "Tethering";
+ private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
+ private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
@@ -212,6 +217,9 @@ public class TetheringTest {
private Tethering mTethering;
private PhoneStateListener mPhoneStateListener;
private InterfaceConfigurationParcel mInterfaceConfiguration;
+ private TetheringConfiguration mConfig;
+ private EntitlementManager mEntitleMgr;
+ private OffloadController mOffloadCtrl;
private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base) {
@@ -297,14 +305,15 @@ public class TetheringTest {
}
}
- private class MockTetheringConfiguration extends TetheringConfiguration {
- MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
+ // MyTetheringConfiguration is used to override static method for testing.
+ private class MyTetheringConfiguration extends TetheringConfiguration {
+ MyTetheringConfiguration(Context ctx, SharedLog log, int id) {
super(ctx, log, id);
}
@Override
- protected boolean getDeviceConfigBoolean(final String name) {
- return false;
+ protected String getDeviceConfigProperty(final String name) {
+ return null;
}
@Override
@@ -328,6 +337,15 @@ public class TetheringTest {
}
@Override
+ public OffloadController getOffloadController(Handler h, SharedLog log,
+ OffloadController.Dependencies deps) {
+ mOffloadCtrl = spy(super.getOffloadController(h, log, deps));
+ // Return real object here instead of mock because
+ // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
+ return mOffloadCtrl;
+ }
+
+ @Override
public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
StateMachine target, SharedLog log, int what) {
mUpstreamNetworkMonitorMasterSM = target;
@@ -352,6 +370,13 @@ public class TetheringTest {
}
@Override
+ public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback));
+ return mEntitleMgr;
+ }
+
+ @Override
public boolean isTetheringSupported() {
return true;
}
@@ -359,7 +384,8 @@ public class TetheringTest {
@Override
public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
int subId) {
- return new MockTetheringConfiguration(ctx, log, subId);
+ mConfig = spy(new MyTetheringConfiguration(ctx, log, subId));
+ return mConfig;
}
@Override
@@ -459,18 +485,6 @@ public class TetheringTest {
MockitoAnnotations.initMocks(this);
when(mResources.getStringArray(R.array.config_tether_dhcp_range))
.thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_usb_regexs))
- .thenReturn(new String[] { "test_rndis\\d" });
- when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
- .thenReturn(new String[]{ "test_wlan\\d" });
- when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
- .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
- when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
- .thenReturn(new String[0]);
- when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
- .thenReturn(new String[] { "test_ncm\\d" });
- when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
- when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false);
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
when(mNetd.interfaceGetList())
@@ -489,6 +503,7 @@ public class TetheringTest {
mServiceContext = new TestContext(mContext);
mContentResolver = new MockContentResolver(mServiceContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ setTetheringSupported(true /* supported */);
mIntents = new Vector<>();
mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -499,7 +514,6 @@ public class TetheringTest {
mServiceContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(ACTION_TETHER_STATE_CHANGED));
mTethering = makeTethering();
- mTethering.startStateMachineUpdaters();
verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
verify(mNetd).registerUnsolicitedEventListener(any());
final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -510,22 +524,47 @@ public class TetheringTest {
mPhoneStateListener = phoneListenerCaptor.getValue();
}
+ private void setTetheringSupported(final boolean supported) {
+ Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
+ supported ? 1 : 0);
+ when(mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
+ // Setup tetherable configuration.
+ when(mResources.getStringArray(R.array.config_tether_usb_regexs))
+ .thenReturn(new String[] { "test_rndis\\d" });
+ when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
+ .thenReturn(new String[]{ "test_wlan\\d" });
+ when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
+ .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
+ when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
+ .thenReturn(new String[0]);
+ when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
+ .thenReturn(new String[] { "test_ncm\\d" });
+ when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
+ when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
+ }
+
+ private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
+ when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
+ when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+ }
+
private Tethering makeTethering() {
mTetheringDependencies.reset();
return new Tethering(mTetheringDependencies);
}
private TetheringRequestParcel createTetheringRequestParcel(final int type) {
- return createTetheringRequestParcel(type, null, null);
+ return createTetheringRequestParcel(type, null, null, false);
}
private TetheringRequestParcel createTetheringRequestParcel(final int type,
- final LinkAddress serverAddr, final LinkAddress clientAddr) {
+ final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt) {
final TetheringRequestParcel request = new TetheringRequestParcel();
request.tetheringType = type;
request.localIPv4Address = serverAddr;
request.staticClientAddress = clientAddr;
- request.exemptFromEntitlementCheck = false;
+ request.exemptFromEntitlementCheck = exempt;
request.showProvisioningUi = false;
return request;
@@ -646,9 +685,7 @@ public class TetheringTest {
}
private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
- when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
- .thenReturn(upstreamState);
+ initTetheringUpstream(upstreamState);
// Emulate pressing the USB tethering button in Settings UI.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
@@ -674,7 +711,7 @@ public class TetheringTest {
verify(mNetd, times(1)).interfaceGetList();
// UpstreamNetworkMonitor should receive selected upstream
- verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
+ verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
}
@@ -846,8 +883,7 @@ public class TetheringTest {
// Then 464xlat comes up
upstreamState = buildMobile464xlatUpstreamState();
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
- .thenReturn(upstreamState);
+ initTetheringUpstream(upstreamState);
// Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
@@ -1318,9 +1354,7 @@ public class TetheringTest {
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
// 2. Enable wifi tethering.
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
- when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
- .thenReturn(upstreamState);
+ initTetheringUpstream(upstreamState);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
mLooper.dispatchAll();
@@ -1636,7 +1670,7 @@ public class TetheringTest {
// Enable USB tethering and check that Tethering starts USB.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null), firstResult);
+ null, null, false), firstResult);
mLooper.dispatchAll();
firstResult.assertHasResult();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
@@ -1644,7 +1678,7 @@ public class TetheringTest {
// Enable USB tethering again with the same request and expect no change to USB.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null), secondResult);
+ null, null, false), secondResult);
mLooper.dispatchAll();
secondResult.assertHasResult();
verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
@@ -1653,7 +1687,7 @@ public class TetheringTest {
// Enable USB tethering with a different request and expect that USB is stopped and
// started.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr), thirdResult);
+ serverLinkAddr, clientLinkAddr, false), thirdResult);
mLooper.dispatchAll();
thirdResult.assertHasResult();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
@@ -1677,7 +1711,7 @@ public class TetheringTest {
final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr), null);
+ serverLinkAddr, clientLinkAddr, false), null);
mLooper.dispatchAll();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
@@ -1697,7 +1731,7 @@ public class TetheringTest {
final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+ initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true);
verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
@@ -1709,7 +1743,7 @@ public class TetheringTest {
final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
- when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+ initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true);
stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
@@ -1726,6 +1760,82 @@ public class TetheringTest {
verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
}
+ @Test
+ public void testDumpTetheringLog() throws Exception {
+ final FileDescriptor mockFd = mock(FileDescriptor.class);
+ final PrintWriter mockPw = mock(PrintWriter.class);
+ runUsbTethering(null);
+ mLooper.startAutoDispatch();
+ mTethering.dump(mockFd, mockPw, new String[0]);
+ verify(mConfig).dump(any());
+ verify(mEntitleMgr).dump(any());
+ verify(mOffloadCtrl).dump(any());
+ mLooper.stopAutoDispatch();
+ }
+
+ @Test
+ public void testExemptFromEntitlementCheck() throws Exception {
+ setupForRequiredProvisioning();
+ final TetheringRequestParcel wifiNotExemptRequest =
+ createTetheringRequestParcel(TETHERING_WIFI, null, null, false);
+ mTethering.startTethering(wifiNotExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
+ assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+
+ setupForRequiredProvisioning();
+ final TetheringRequestParcel wifiExemptRequest =
+ createTetheringRequestParcel(TETHERING_WIFI, null, null, true);
+ mTethering.startTethering(wifiExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+
+ // If one app enables tethering without provisioning check first, then another app enables
+ // tethering of the same type but does not disable the provisioning check.
+ setupForRequiredProvisioning();
+ mTethering.startTethering(wifiExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
+ reset(mEntitleMgr);
+ setupForRequiredProvisioning();
+ mTethering.startTethering(wifiNotExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
+ assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+ }
+
+ private void setupForRequiredProvisioning() {
+ // Produce some acceptable looking provision app setting if requested.
+ when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
+ .thenReturn(PROVISIONING_APP_NAME);
+ when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
+ .thenReturn(PROVISIONING_NO_UI_APP_NAME);
+ // Act like the CarrierConfigManager is present and ready unless told otherwise.
+ when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+ .thenReturn(mCarrierConfigManager);
+ when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ sendConfigurationChanged();
+ }
// TODO: Test that a request for hotspot mode doesn't interfere with an
// already operating tethering mode interface.
}
diff --git a/services/Android.bp b/services/Android.bp
index b4d8393683ba..0d221b930f5d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -122,13 +122,13 @@ droidstubs {
removed_api_file: "api/removed.txt",
},
last_released: {
- api_file: ":last-released-system-server-api",
+ api_file: ":android.api.system-server.latest",
removed_api_file: "api/removed.txt",
baseline_file: ":system-server-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-system-server-api",
+ new_since: ":android.api.system-server.latest",
baseline_file: "api/lint-baseline.txt",
},
},
diff --git a/services/core/Android.bp b/services/core/Android.bp
index a2f73a6730b5..74fddb2b630e 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -28,7 +28,7 @@ java_library_static {
"android.hardware.power-V1.0-java",
"android.hardware.tv.cec-V1.0-java",
"android.hardware.vibrator-java",
- "android.net.ipsec.ike.stubs.module_libs_api",
+ "android.net.ipsec.ike.stubs.module_lib",
"app-compat-annotations",
"framework-tethering-stubs-module_libs_api",
],
@@ -53,8 +53,8 @@ java_library_static {
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
- "dnsresolver_aidl_interface-V4-java",
- "netd_event_listener_interface-java",
+ "dnsresolver_aidl_interface-java",
+ "netd_aidl_interfaces-platform-java",
],
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 58e06e00ef2d..4b66cea88ed0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2732,7 +2732,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// the Messenger, but if this ever changes, not making a defensive copy
// here will give attack vectors to clients using this code path.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork();
+ networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
}
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
break;
@@ -3079,30 +3079,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void notifyDataStallSuspected(DataStallReportParcelable p) {
- final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED,
- p.detectionMethod, mNetId, p.timestampMillis);
-
- final PersistableBundle extras = new PersistableBundle();
- switch (p.detectionMethod) {
- case DETECTION_METHOD_DNS_EVENTS:
- extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
- break;
- case DETECTION_METHOD_TCP_METRICS:
- extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
- extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
- p.tcpMetricsCollectionPeriodMillis);
- break;
- default:
- log("Unknown data stall detection method, ignoring: " + p.detectionMethod);
- return;
- }
- msg.setData(new Bundle(extras));
-
- // NetworkStateTrackerHandler currently doesn't take any actions based on data
- // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
- // the cost of going through two handlers.
- mConnectivityDiagnosticsHandler.sendMessage(msg);
+ ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
}
@Override
@@ -3116,6 +3093,37 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
+ log("Data stall detected with methods: " + p.detectionMethod);
+
+ final PersistableBundle extras = new PersistableBundle();
+ int detectionMethod = 0;
+ if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
+ extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
+ detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
+ }
+ if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
+ extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
+ extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
+ p.tcpMetricsCollectionPeriodMillis);
+ detectionMethod |= DETECTION_METHOD_TCP_METRICS;
+ }
+
+ final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
+ ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
+ p.timestampMillis);
+ msg.setData(new Bundle(extras));
+
+ // NetworkStateTrackerHandler currently doesn't take any actions based on data
+ // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
+ // the cost of going through two handlers.
+ mConnectivityDiagnosticsHandler.sendMessage(msg);
+ }
+
+ private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
+ return (p.detectionMethod & detectionMethod) != 0;
+ }
+
private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
return isPrivateDnsValidationRequired(nai.networkCapabilities);
}
@@ -5855,7 +5863,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
// sees capabilities that may be malicious, which might prevent mistakes in the future.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork();
+ networkCapabilities.restrictCapabilitesForTestNetwork(Binder.getCallingUid());
} else {
enforceNetworkFactoryPermission();
}
@@ -5868,7 +5876,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, mNMS, providerId);
+ this, mNetd, mDnsResolver, mNMS, providerId, Binder.getCallingUid());
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
@@ -5969,7 +5977,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Start or stop DNS64 detection and 464xlat according to network state.
networkAgent.clatd.update();
notifyIfacesChangedForNetworkStats();
- networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
+ networkAgent.networkMonitor().notifyLinkPropertiesChanged(
+ new LinkProperties(newLp, true /* parcelSensitiveFields */));
if (networkAgent.everConnected) {
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
}
@@ -7123,6 +7132,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
if (!createNativeNetwork(networkAgent)) return;
+ if (networkAgent.isVPN()) {
+ // Initialize the VPN capabilities to their starting values according to the
+ // underlying networks. This will avoid a spurious callback to
+ // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
+ // the VPN would switch from its default, blank capabilities to those
+ // that reflect the capabilities of its underlying networks.
+ updateAllVpnsCapabilities();
+ }
networkAgent.created = true;
}
@@ -7149,7 +7166,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkAgent.networkMonitor().setAcceptPartialConnectivity();
}
networkAgent.networkMonitor().notifyNetworkConnected(
- networkAgent.linkProperties, networkAgent.networkCapabilities);
+ new LinkProperties(networkAgent.linkProperties,
+ true /* parcelSensitiveFields */),
+ networkAgent.networkCapabilities);
scheduleUnvalidatedPrompt(networkAgent);
// Whether a particular NetworkRequest listen should cause signal strength thresholds to
@@ -8147,4 +8166,41 @@ public class ConnectivityService extends IConnectivityManager.Stub
0,
callback));
}
+
+ @Override
+ public void simulateDataStall(int detectionMethod, long timestampMillis,
+ @NonNull Network network, @NonNull PersistableBundle extras) {
+ enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
+ android.Manifest.permission.NETWORK_STACK);
+ final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
+ if (!nc.hasTransport(TRANSPORT_TEST)) {
+ throw new SecurityException("Data Stall simluation is only possible for test networks");
+ }
+
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai == null || nai.creatorUid != Binder.getCallingUid()) {
+ throw new SecurityException("Data Stall simulation is only possible for network "
+ + "creators");
+ }
+
+ // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
+ // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
+ // Data Stall information as a DataStallReportParcelable and passing to
+ // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
+ // still passed to ConnectivityDiagnostics (with new detection methods masked).
+ final DataStallReportParcelable p = new DataStallReportParcelable();
+ p.timestampMillis = timestampMillis;
+ p.detectionMethod = detectionMethod;
+
+ if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
+ p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
+ }
+ if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
+ p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
+ p.tcpMetricsCollectionPeriodMillis = extras.getInt(
+ KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
+ }
+
+ notifyDataStallSuspected(p, network.netId);
+ }
}
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 0ea73460e105..d6bd5a1d7c4c 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -317,39 +317,34 @@ class TestNetworkService extends ITestNetworkManager.Stub {
"Cannot create network for non ipsec, non-testtun interface");
}
- // Setup needs to be done with NETWORK_STACK privileges.
- int callingUid = Binder.getCallingUid();
- Binder.withCleanCallingIdentity(
- () -> {
- try {
- mNMS.setInterfaceUp(iface);
-
- // Synchronize all accesses to mTestNetworkTracker to prevent the case
- // where:
- // 1. TestNetworkAgent successfully binds to death of binder
- // 2. Before it is added to the mTestNetworkTracker, binder dies,
- // binderDied() is called (on a different thread)
- // 3. This thread is pre-empted, put() is called after remove()
- synchronized (mTestNetworkTracker) {
- TestNetworkAgent agent =
- registerTestNetworkAgent(
- mHandler.getLooper(),
- mContext,
- iface,
- lp,
- isMetered,
- callingUid,
- administratorUids,
- binder);
-
- mTestNetworkTracker.put(agent.getNetwork().netId, agent);
- }
- } catch (SocketException e) {
- throw new UncheckedIOException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- });
+ try {
+ // This requires NETWORK_STACK privileges.
+ Binder.withCleanCallingIdentity(() -> mNMS.setInterfaceUp(iface));
+
+ // Synchronize all accesses to mTestNetworkTracker to prevent the case where:
+ // 1. TestNetworkAgent successfully binds to death of binder
+ // 2. Before it is added to the mTestNetworkTracker, binder dies, binderDied() is called
+ // (on a different thread)
+ // 3. This thread is pre-empted, put() is called after remove()
+ synchronized (mTestNetworkTracker) {
+ TestNetworkAgent agent =
+ registerTestNetworkAgent(
+ mHandler.getLooper(),
+ mContext,
+ iface,
+ lp,
+ isMetered,
+ Binder.getCallingUid(),
+ administratorUids,
+ binder);
+
+ mTestNetworkTracker.put(agent.getNetwork().netId, agent);
+ }
+ } catch (SocketException e) {
+ throw new UncheckedIOException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/** Teardown a test network */
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0ba41736ce15..0ba6a5536cbf 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -842,6 +842,15 @@ public final class ActiveServices {
}
}
+ void killMisbehavingService(ServiceRecord r,
+ int appUid, int appPid, String localPackageName) {
+ synchronized (mAm) {
+ stopServiceLocked(r);
+ mAm.crashApplication(appUid, appPid, localPackageName, -1,
+ "Bad notification for startForeground", true /*force*/);
+ }
+ }
+
IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(),
@@ -3946,7 +3955,7 @@ public final class ActiveServices {
void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId,
"Context.startForegroundService() did not then call Service.startForeground(): "
- + serviceRecord);
+ + serviceRecord, false /*force*/);
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b001e62a4684..166c4f3c749b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -456,6 +456,8 @@ public class ActivityManagerService extends IActivityManager.Stub
static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
+ static final String SYSTEM_USER_HOME_NEEDED = "ro.system_user_home_needed";
+
public static final String ANR_TRACE_DIR = "/data/anr";
// Maximum number of receivers an app can register.
@@ -3595,7 +3597,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void crashApplication(int uid, int initialPid, String packageName, int userId,
- String message) {
+ String message, boolean force) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: crashApplication() from pid="
@@ -3607,7 +3609,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
synchronized(this) {
- mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
+ mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
+ message, force);
}
}
@@ -4786,7 +4789,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
- private final boolean attachApplicationLocked(IApplicationThread thread,
+ private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// Find the application record that is being attached... either via
@@ -5209,6 +5212,9 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
+ if (thread == null) {
+ throw new SecurityException("Invalid application interface");
+ }
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
@@ -9111,7 +9117,8 @@ public class ActivityManagerService extends IActivityManager.Stub
// to handle home activity in this case.
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
+ Settings.Secure.USER_SETUP_COMPLETE, 0) != 0
+ || SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) {
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
@@ -12850,7 +12857,9 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.print(" unmapped + ");
pw.print(stringifyKBSize(ionPool));
pw.println(" pools)");
- kernelUsed += ionUnmapped;
+ // Note: mapped ION memory is not accounted in PSS due to VM_PFNMAP flag being
+ // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
+ kernelUsed += ionHeap;
}
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
@@ -13587,7 +13596,9 @@ public class ActivityManagerService extends IActivityManager.Stub
memInfoBuilder.append(" ION: ");
memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool));
memInfoBuilder.append("\n");
- kernelUsed += ionUnmapped;
+ // Note: mapped ION memory is not accounted in PSS due to VM_PFNMAP flag being
+ // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
+ kernelUsed += ionHeap;
}
memInfoBuilder.append(" Used RAM: ");
memInfoBuilder.append(stringifyKBSize(
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 5078b8a14eb2..5ab18d95b84d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1058,7 +1058,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
} catch (NumberFormatException e) {
packageName = arg;
}
- mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
+ mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false);
return 0;
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index a4c695067139..bbd2d34e92a6 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -314,20 +314,24 @@ class AppErrors {
}
void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
- app.setCrashing(false);
- app.crashingReport = null;
- app.setNotResponding(false);
- app.notRespondingReport = null;
if (app.anrDialog == fromDialog) {
app.anrDialog = null;
}
if (app.waitDialog == fromDialog) {
app.waitDialog = null;
}
+ killAppImmediateLocked(app, "user-terminated", "user request after error");
+ }
+
+ private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) {
+ app.setCrashing(false);
+ app.crashingReport = null;
+ app.setNotResponding(false);
+ app.notRespondingReport = null;
if (app.pid > 0 && app.pid != MY_PID) {
- handleAppCrashLocked(app, "user-terminated" /*reason*/,
+ handleAppCrashLocked(app, reason,
null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
- app.kill("user request after error", true);
+ app.kill(killReason, true);
}
}
@@ -341,7 +345,7 @@ class AppErrors {
* @param message
*/
void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
- String message) {
+ String message, boolean force) {
ProcessRecord proc = null;
// Figure out which process to kill. We don't trust that initialPid
@@ -374,6 +378,14 @@ class AppErrors {
}
proc.scheduleCrash(message);
+ if (force) {
+ // If the app is responsive, the scheduled crash will happen as expected
+ // and then the delayed summary kill will be a no-op.
+ final ProcessRecord p = proc;
+ mService.mHandler.postDelayed(
+ () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
+ 5000L);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dee8e3b285a7..c408695bcb66 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -798,6 +798,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
final Notification _foregroundNoti = foregroundNoti;
+ final ServiceRecord record = this;
ams.mHandler.post(new Runnable() {
public void run() {
NotificationManagerInternal nm = LocalServices.getService(
@@ -896,10 +897,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
Slog.w(TAG, "Error showing notification for service", e);
// If it gave us a garbage notification, it doesn't
// get to be foreground.
- ams.setServiceForeground(instanceName, ServiceRecord.this,
- 0, null, 0, 0);
- ams.crashApplication(appUid, appPid, localPackageName, -1,
- "Bad notification for startForeground: " + e);
+ ams.mServices.killMisbehavingService(record,
+ appUid, appPid, localPackageName);
}
}
});
diff --git a/services/core/java/com/android/server/compat/OWNERS b/services/core/java/com/android/server/compat/OWNERS
index 2b7cdb0cbce9..cfd0a4b079ad 100644
--- a/services/core/java/com/android/server/compat/OWNERS
+++ b/services/core/java/com/android/server/compat/OWNERS
@@ -2,6 +2,5 @@
platform-compat-eng+reviews@google.com
andreionea@google.com
-atrost@google.com
mathewi@google.com
satayev@google.com
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 34d0bed9a802..3091a7178377 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -198,6 +198,9 @@ public class Nat464Xlat extends BaseNetworkObserver {
if (mPrefixDiscoveryRunning && !isPrefixDiscoveryNeeded()) {
stopPrefixDiscovery();
}
+ if (!mPrefixDiscoveryRunning) {
+ setPrefix64(mNat64PrefixInUse);
+ }
}
/**
@@ -221,6 +224,10 @@ public class Nat464Xlat extends BaseNetworkObserver {
mIface = null;
mBaseIface = null;
+ if (!mPrefixDiscoveryRunning) {
+ setPrefix64(null);
+ }
+
if (isPrefixDiscoveryNeeded()) {
if (!mPrefixDiscoveryRunning) {
startPrefixDiscovery();
@@ -308,6 +315,16 @@ public class Nat464Xlat extends BaseNetworkObserver {
return requiresClat(mNetwork) && mNat64PrefixFromRa == null;
}
+ private void setPrefix64(IpPrefix prefix) {
+ final String prefixString = (prefix != null) ? prefix.toString() : "";
+ try {
+ mDnsResolver.setPrefix64(getNetId(), prefixString);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Slog.e(TAG, "Error setting NAT64 prefix on netId " + getNetId() + " to "
+ + prefix + ": " + e);
+ }
+ }
+
private void maybeHandleNat64PrefixChange() {
final IpPrefix newPrefix = selectNat64Prefix();
if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 2d1f553ab8cd..a9f62d91592d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -168,6 +168,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// Obtained by ConnectivityService and merged into NetworkAgent-provided information.
public CaptivePortalData captivePortalData;
+ // The UID of the remote entity that created this Network.
+ public final int creatorUid;
+
// Networks are lingered when they become unneeded as a result of their NetworkRequests being
// satisfied by a higher-scoring network. so as to allow communication to wrap up before the
// network is taken down. This usually only happens to the default network. Lingering ends with
@@ -268,7 +271,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
- IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
+ IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
+ int creatorUid) {
this.messenger = messenger;
asyncChannel = ac;
network = net;
@@ -282,6 +286,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
mHandler = handler;
networkAgentConfig = config;
this.factorySerialNumber = factorySerialNumber;
+ this.creatorUid = creatorUid;
}
/**
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 120e744a9740..730da28ba8a2 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -64,6 +65,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkProvider;
+import android.net.NetworkRequest;
import android.net.RouteInfo;
import android.net.UidRange;
import android.net.VpnManager;
@@ -317,8 +319,7 @@ public class Vpn {
*
* @param defaultNetwork underlying network for VPNs following platform's default
*/
- public synchronized NetworkCapabilities updateCapabilities(
- @Nullable Network defaultNetwork) {
+ public synchronized NetworkCapabilities updateCapabilities(@Nullable Network defaultNetwork) {
if (mConfig == null) {
// VPN is not running.
return null;
@@ -350,11 +351,10 @@ public class Vpn {
int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN };
int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- // VPN's meteredness is OR'd with isAlwaysMetered and meteredness of its underlying
- // networks.
- boolean metered = isAlwaysMetered;
- boolean roaming = false;
- boolean congested = false;
+ boolean metered = isAlwaysMetered; // metered if any underlying is metered, or alwaysMetered
+ boolean roaming = false; // roaming if any underlying is roaming
+ boolean congested = false; // congested if any underlying is congested
+ boolean suspended = true; // suspended if all underlying are suspended
boolean hadUnderlyingNetworks = false;
if (null != underlyingNetworks) {
@@ -367,15 +367,24 @@ public class Vpn {
transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType);
}
- // When we have multiple networks, we have to assume the
- // worst-case link speed and restrictions.
+ // Merge capabilities of this underlying network. For bandwidth, assume the
+ // worst case.
downKbps = NetworkCapabilities.minBandwidth(downKbps,
underlyingCaps.getLinkDownstreamBandwidthKbps());
upKbps = NetworkCapabilities.minBandwidth(upKbps,
underlyingCaps.getLinkUpstreamBandwidthKbps());
+ // If this underlying network is metered, the VPN is metered (it may cost money
+ // to send packets on this network).
metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
+ // If this underlying network is roaming, the VPN is roaming (the billing structure
+ // is different than the usual, local one).
roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+ // If this underlying network is congested, the VPN is congested (the current
+ // condition of the network affects the performance of this network).
congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
+ // If this network is not suspended, the VPN is not suspended (the VPN
+ // is able to transfer some data).
+ suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
}
}
if (!hadUnderlyingNetworks) {
@@ -383,6 +392,7 @@ public class Vpn {
metered = true;
roaming = false;
congested = false;
+ suspended = false;
}
caps.setTransportTypes(transportTypes);
@@ -391,6 +401,7 @@ public class Vpn {
caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
+ caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
}
/**
@@ -1955,6 +1966,7 @@ public class Vpn {
profile.ipsecCaCert = caCert;
// Start VPN profile
+ profile.setAllowedAlgorithms(Ikev2VpnProfile.DEFAULT_ALGORITHMS);
startVpnProfilePrivileged(profile, VpnConfig.LEGACY_VPN, keyStore);
return;
case VpnProfile.TYPE_IKEV2_IPSEC_PSK:
@@ -1963,6 +1975,7 @@ public class Vpn {
Ikev2VpnProfile.encodeForIpsecSecret(profile.ipsecSecret.getBytes());
// Start VPN profile
+ profile.setAllowedAlgorithms(Ikev2VpnProfile.DEFAULT_ALGORITHMS);
startVpnProfilePrivileged(profile, VpnConfig.LEGACY_VPN, keyStore);
return;
case VpnProfile.TYPE_L2TP_IPSEC_PSK:
@@ -2213,12 +2226,27 @@ public class Vpn {
@Override
public void run() {
- // Explicitly use only the network that ConnectivityService thinks is the "best." In
- // other words, only ever use the currently selected default network. This does mean
- // that in both onLost() and onConnected(), any old sessions MUST be torn down. This
- // does NOT include VPNs.
+ // Unless the profile is restricted to test networks, explicitly use only the network
+ // that ConnectivityService thinks is the "best." In other words, only ever use the
+ // currently selected default network. This does mean that in both onLost() and
+ // onConnected(), any old sessions MUST be torn down. This does NOT include VPNs.
+ //
+ // When restricted to test networks, select any network with TRANSPORT_TEST. Since the
+ // creator of the profile and the test network creator both have MANAGE_TEST_NETWORKS,
+ // this is considered safe.
final ConnectivityManager cm = ConnectivityManager.from(mContext);
- cm.requestNetwork(cm.getDefaultRequest(), mNetworkCallback);
+ final NetworkRequest req;
+
+ if (mProfile.isRestrictedToTestNetworks()) {
+ req = new NetworkRequest.Builder()
+ .clearCapabilities()
+ .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+ .build();
+ } else {
+ req = cm.getDefaultRequest();
+ }
+
+ cm.requestNetwork(req, mNetworkCallback);
}
private boolean isActiveNetwork(@Nullable Network network) {
@@ -2359,7 +2387,7 @@ public class Vpn {
final IkeSessionParams ikeSessionParams =
VpnIkev2Utils.buildIkeSessionParams(mContext, mProfile, network);
final ChildSessionParams childSessionParams =
- VpnIkev2Utils.buildChildSessionParams();
+ VpnIkev2Utils.buildChildSessionParams(mProfile.getAllowedAlgorithms());
// TODO: Remove the need for adding two unused addresses with
// IPsec tunnels.
@@ -2856,6 +2884,11 @@ public class Vpn {
verifyCallingUidAndPackage(packageName);
enforceNotRestrictedUser();
+ if (profile.isRestrictedToTestNetworks) {
+ mContext.enforceCallingPermission(Manifest.permission.MANAGE_TEST_NETWORKS,
+ "Test-mode profiles require the MANAGE_TEST_NETWORKS permission");
+ }
+
final byte[] encodedProfile = profile.encode();
if (encodedProfile.length > MAX_VPN_PROFILE_SIZE_BYTES) {
throw new IllegalArgumentException("Profile too big");
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 3da304c07910..103f659cc258 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -17,14 +17,12 @@
package com.android.server.connectivity;
import static android.net.ConnectivityManager.NetworkCallback;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96;
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192;
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256;
@@ -39,6 +37,7 @@ import android.content.Context;
import android.net.Ikev2VpnProfile;
import android.net.InetAddresses;
import android.net.IpPrefix;
+import android.net.IpSecAlgorithm;
import android.net.IpSecTransform;
import android.net.Network;
import android.net.RouteInfo;
@@ -83,6 +82,14 @@ import java.util.List;
* @hide
*/
public class VpnIkev2Utils {
+ private static final String TAG = VpnIkev2Utils.class.getSimpleName();
+
+ // TODO: Use IKE library exposed constants when @SystemApi is updated.
+ /** IANA-defined 3072 group for use in IKEv2 */
+ private static final int DH_GROUP_3072_BIT_MODP = 15;
+ /** IANA-defined 4096 group for use in IKEv2 */
+ private static final int DH_GROUP_4096_BIT_MODP = 16;
+
static IkeSessionParams buildIkeSessionParams(
@NonNull Context context, @NonNull Ikev2VpnProfile profile, @NonNull Network network) {
final IkeIdentification localId = parseIkeIdentification(profile.getUserIdentity());
@@ -103,11 +110,11 @@ public class VpnIkev2Utils {
return ikeOptionsBuilder.build();
}
- static ChildSessionParams buildChildSessionParams() {
+ static ChildSessionParams buildChildSessionParams(List<String> allowedAlgorithms) {
final TunnelModeChildSessionParams.Builder childOptionsBuilder =
new TunnelModeChildSessionParams.Builder();
- for (final ChildSaProposal childProposal : getChildSaProposals()) {
+ for (final ChildSaProposal childProposal : getChildSaProposals(allowedAlgorithms)) {
childOptionsBuilder.addSaProposal(childProposal);
}
@@ -144,7 +151,7 @@ public class VpnIkev2Utils {
}
private static List<IkeSaProposal> getIkeSaProposals() {
- // TODO: filter this based on allowedAlgorithms
+ // TODO: Add ability to filter this when IKEv2 API is made Public API
final List<IkeSaProposal> proposals = new ArrayList<>();
// Encryption Algorithms: Currently only AES_CBC is supported.
@@ -160,7 +167,6 @@ public class VpnIkev2Utils {
normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_AES_XCBC_96);
- normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
// Add AEAD options
final IkeSaProposal.Builder aeadBuilder = new IkeSaProposal.Builder();
@@ -176,8 +182,9 @@ public class VpnIkev2Utils {
// Add dh, prf for both builders
for (final IkeSaProposal.Builder builder : Arrays.asList(normalModeBuilder, aeadBuilder)) {
+ builder.addDhGroup(DH_GROUP_4096_BIT_MODP);
+ builder.addDhGroup(DH_GROUP_3072_BIT_MODP);
builder.addDhGroup(DH_GROUP_2048_BIT_MODP);
- builder.addDhGroup(DH_GROUP_1024_BIT_MODP);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
}
@@ -187,38 +194,59 @@ public class VpnIkev2Utils {
return proposals;
}
- private static List<ChildSaProposal> getChildSaProposals() {
- // TODO: filter this based on allowedAlgorithms
+ /** Builds a child SA proposal based on the allowed IPsec algorithms */
+ private static List<ChildSaProposal> getChildSaProposals(List<String> allowedAlgorithms) {
final List<ChildSaProposal> proposals = new ArrayList<>();
// Add non-AEAD options
- final ChildSaProposal.Builder normalModeBuilder = new ChildSaProposal.Builder();
-
- // Encryption Algorithms: Currently only AES_CBC is supported.
- normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256);
- normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192);
- normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128);
+ if (Ikev2VpnProfile.hasNormalModeAlgorithms(allowedAlgorithms)) {
+ final ChildSaProposal.Builder normalModeBuilder = new ChildSaProposal.Builder();
+
+ // Encryption Algorithms:
+ // AES-CBC is currently the only supported encryption algorithm.
+ normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256);
+ normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192);
+ normalModeBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128);
+
+ // Authentication/Integrity Algorithms:
+ // Guaranteed by Ikev2VpnProfile constructor to contain at least one of these.
+ if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_HMAC_SHA512)) {
+ normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+ }
+ if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_HMAC_SHA384)) {
+ normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
+ }
+ if (allowedAlgorithms.contains(IpSecAlgorithm.AUTH_HMAC_SHA256)) {
+ normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
+ }
- // Authentication/Integrity Algorithms
- normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
- normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
- normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
- normalModeBuilder.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+ ChildSaProposal proposal = normalModeBuilder.build();
+ if (proposal.getIntegrityAlgorithms().isEmpty()) {
+ // Should be impossible; Verified in Ikev2VpnProfile.
+ Log.wtf(TAG, "Missing integrity algorithm when buildling Child SA proposal");
+ } else {
+ proposals.add(normalModeBuilder.build());
+ }
+ }
// Add AEAD options
- final ChildSaProposal.Builder aeadBuilder = new ChildSaProposal.Builder();
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_192);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128);
- aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128);
+ if (Ikev2VpnProfile.hasAeadAlgorithms(allowedAlgorithms)) {
+ final ChildSaProposal.Builder aeadBuilder = new ChildSaProposal.Builder();
+
+ // AES-GCM is currently the only supported AEAD algorithm
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_192);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_192);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_128);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128);
+ aeadBuilder.addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128);
+
+ proposals.add(aeadBuilder.build());
+ }
- proposals.add(normalModeBuilder.build());
- proposals.add(aeadBuilder.build());
return proposals;
}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 3006ef41931f..d7bf37db6afd 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -306,49 +306,6 @@ final class Constants {
static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "persist.sys.hdmi.addr.playback";
static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv";
-
- // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event.
- // True by default.
- static final String PROPERTY_WAKE_ON_HOTPLUG = "ro.hdmi.wake_on_hotplug";
-
- // TODO(OEM): Set this to true to enable 'Set Menu Language' feature. False by default.
- static final String PROPERTY_SET_MENU_LANGUAGE = "ro.hdmi.set_menu_language";
-
- /**
- * Property to save the ARC port id on system audio device.
- * <p>When ARC is initiated, this port will be used to turn on ARC.
- */
- static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT =
- "ro.hdmi.property_sytem_audio_device_arc_port";
-
- /**
- * Property to disable muting logic in System Audio Control handling. Default is true.
- *
- * <p>True means enabling muting logic.
- * <p>False means never mute device.
- */
- static final String PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE =
- "ro.hdmi.property_system_audio_mode_muting_enable";
-
- /**
- * When set to true the HdmiControlService will never request a Logical Address for the
- * playback device type. Default is false.
- *
- * <p> This is useful when HDMI CEC multiple device types is not supported by the cec driver
- */
- static final String PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS =
- "ro.hdmi.property_hdmi_cec_never_claim_playback_logical_address";
-
- /**
- * A comma separated list of logical addresses that HdmiControlService
- * will never assign local CEC devices to.
- *
- * <p> This is useful when HDMI CEC hardware module can't assign multiple logical addresses
- * in the range same range of 0-7 or 8-15.
- */
- static final String PROPERTY_HDMI_CEC_NEVER_ASSIGN_LOGICAL_ADDRESSES =
- "ro.hdmi.property_hdmi_cec_never_assign_logical_addresses";
-
// Set to false to allow playback device to go to suspend mode even
// when it's an active source. True by default.
static final String PROPERTY_KEEP_AWAKE = "persist.sys.hdmi.keep_awake";
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 9e2fd4e9e91e..496273b6bf0e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -35,6 +35,7 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager.TvInputCallback;
import android.os.SystemProperties;
import android.provider.Settings.Global;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import android.util.SparseArray;
@@ -90,8 +91,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
// If the current device uses TvInput for ARC. We assume all other inputs also use TvInput
// when ARC is using TvInput.
- private boolean mArcIntentUsed = SystemProperties
- .get(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT, "0").contains("tvinput");
+ private boolean mArcIntentUsed = HdmiProperties.arc_port().orElse("0").contains("tvinput");
// Keeps the mapping (HDMI port ID to TV input URI) to keep track of the TV inputs ready to
// accept input switching request from HDMI devices.
@@ -823,7 +823,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
private void enableAudioReturnChannel(boolean enabled) {
assertRunOnServiceThread();
mService.enableAudioReturnChannel(
- SystemProperties.getInt(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT, 0),
+ Integer.parseInt(HdmiProperties.arc_port().orElse("0")),
enabled);
}
@@ -895,9 +895,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
boolean currentMuteStatus =
mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
if (currentMuteStatus == newSystemAudioMode) {
- if (mService.readBooleanSystemProperty(
- Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, true)
- || newSystemAudioMode) {
+ if (HdmiProperties.system_audio_mode_muting().orElse(true) || newSystemAudioMode) {
mService.getAudioManager()
.adjustStreamVolume(
AudioManager.STREAM_MUSIC,
@@ -1133,7 +1131,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
if (portId == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) {
switchToHomeTvInput();
} else if (portId == Constants.CEC_SWITCH_ARC) {
- switchToTvInput(SystemProperties.get(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT));
+ switchToTvInput(HdmiProperties.arc_port().orElse("0"));
setLocalActivePort(portId);
return;
} else {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 560f7a03b20f..603dfafc6ff5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -24,6 +24,7 @@ import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemProperties;
import android.provider.Settings.Global;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -43,11 +44,10 @@ import java.util.Locale;
public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
private static final String TAG = "HdmiCecLocalDevicePlayback";
- private static final boolean WAKE_ON_HOTPLUG =
- SystemProperties.getBoolean(Constants.PROPERTY_WAKE_ON_HOTPLUG, true);
+ private static final boolean WAKE_ON_HOTPLUG = false;
private static final boolean SET_MENU_LANGUAGE =
- SystemProperties.getBoolean(Constants.PROPERTY_SET_MENU_LANGUAGE, false);
+ HdmiProperties.set_menu_language_enabled().orElse(false);
// Used to keep the device awake while it is the active source. For devices that
// cannot wake up via CEC commands, this address the inconvenience of having to
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index ae008b4bfa7a..eb6612fffc0c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -16,12 +16,10 @@
package com.android.server.hdmi;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
-
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.SystemProperties;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -44,8 +42,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
// Device has cec switch functionality or not.
// Default is false.
- protected boolean mIsSwitchDevice = SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ protected boolean mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
// Routing port number used for Routing Control.
// This records the default routing port or the previous valid routing port.
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 6a0cc2661f3d..51d363a41116 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -19,7 +19,6 @@ package com.android.server.hdmi;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
@@ -2520,8 +2519,7 @@ public class HdmiControlService extends SystemService {
}
boolean isSwitchDevice() {
- return SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ return HdmiProperties.is_switch().orElse(false);
}
boolean isTvDeviceEnabled() {
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 75ffe35674d1..3dac106418c5 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -385,11 +385,10 @@ public class NetworkStatsFactory {
// Migrate data usage over a VPN to the TUN network.
for (VpnInfo info : vpnArray) {
delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
+ // Filter out debug entries as that may lead to over counting.
+ delta.filterDebugEntries();
}
- // Filter out debug entries as that may lead to over counting.
- delta.filterDebugEntries();
-
// Update mTunAnd464xlatAdjustedStats with migrated delta.
mTunAnd464xlatAdjustedStats.combineAllValues(delta);
mTunAnd464xlatAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 26808587437c..5d1cc2a5c24a 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
-import static android.net.NetworkTemplate.getCollapsedRatType;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.os.Trace.TRACE_TAG_NETWORK;
@@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
-import static android.telephony.PhoneStateListener.LISTEN_NONE;
-import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -123,7 +119,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
-import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
@@ -133,9 +128,7 @@ import android.provider.Settings.Global;
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -166,6 +159,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -184,6 +178,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// Perform polling, persist network, and register the global alert again.
private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
private static final int MSG_UPDATE_IFACES = 3;
+ // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
+ // deadlock.
+ private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
/** Flags to control detail level of poll event. */
private static final int FLAG_PERSIST_NETWORK = 0x1;
@@ -206,7 +203,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final NetworkStatsFactory mStatsFactory;
private final AlarmManager mAlarmManager;
private final Clock mClock;
- private final TelephonyManager mTeleManager;
private final NetworkStatsSettings mSettings;
private final NetworkStatsObservers mStatsObservers;
@@ -231,12 +227,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static final String PREFIX_UID_TAG = "uid_tag";
/**
- * Virtual network interface for video telephony. This is for VT data usage counting purpose.
- */
- // TODO: Remove this after no one is using it.
- public static final String VT_INTERFACE = NetworkStats.IFACE_VT;
-
- /**
* Settings that can be changed externally.
*/
public interface NetworkStatsSettings {
@@ -308,8 +298,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
new DropBoxNonMonotonicObserver();
private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
- private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
- new RemoteCallbackList<>();
+ private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
+ new CopyOnWriteArrayList<>();
/** Semaphore used to wait for stats provider to respond to request stats update. */
private final Semaphore mStatsProviderSem = new Semaphore(0, true);
@@ -352,6 +342,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@NonNull
private final Dependencies mDeps;
+ @NonNull
+ private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
+
private static @NonNull File getDefaultSystemDir() {
return new File(Environment.getDataDirectory(), "system");
}
@@ -390,6 +383,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
registerGlobalAlert();
break;
}
+ case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
+ final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
+ updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
+ READ_NETWORK_USAGE_HISTORY);
+ break;
+ }
}
}
}
@@ -401,8 +401,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
PowerManager.WakeLock wakeLock =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
- wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
+ final NetworkStatsService service = new NetworkStatsService(context, networkManager,
+ alarmManager, wakeLock, getDefaultClock(),
new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
new Dependencies());
@@ -416,16 +416,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@VisibleForTesting
NetworkStatsService(Context context, INetworkManagementService networkManager,
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
- TelephonyManager teleManager, NetworkStatsSettings settings,
- NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
- File baseDir, @NonNull Dependencies deps) {
+ NetworkStatsSettings settings, NetworkStatsFactory factory,
+ NetworkStatsObservers statsObservers, File systemDir, File baseDir,
+ @NonNull Dependencies deps) {
mContext = Objects.requireNonNull(context, "missing Context");
mNetworkManager = Objects.requireNonNull(networkManager,
- "missing INetworkManagementService");
+ "missing INetworkManagementService");
mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
mClock = Objects.requireNonNull(clock, "missing Clock");
mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
- mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager");
mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
mStatsFactory = Objects.requireNonNull(factory, "missing factory");
mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
@@ -437,7 +436,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final HandlerThread handlerThread = mDeps.makeHandlerThread();
handlerThread.start();
mHandler = new NetworkStatsHandler(handlerThread.getLooper());
- mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler));
+ mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
+ new HandlerExecutor(mHandler), this);
}
/**
@@ -453,6 +453,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public HandlerThread makeHandlerThread() {
return new HandlerThread(TAG);
}
+
+ /**
+ * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
+ * event in NetworkStatsService.
+ */
+ @NonNull
+ public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
+ @NonNull Executor executor, @NonNull NetworkStatsService service) {
+ // TODO: Update RatType passively in NSS, instead of querying into the monitor
+ // when forceUpdateIface.
+ return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) ->
+ service.handleOnCollapsedRatTypeChanged());
+ }
}
private void registerLocalService() {
@@ -517,11 +530,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
mSettings.getPollInterval(), pollIntent);
- // TODO: 1. listen to changes from all subscriptions.
- // 2. listen to settings changed to support dynamically enable/disable.
+ // TODO: listen to settings changed to support dynamically enable/disable.
// watch for networkType changes
if (!mSettings.getCombineSubtypeEnabled()) {
- mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE);
+ mNetworkStatsSubscriptionsMonitor.start();
}
registerGlobalAlert();
@@ -544,7 +556,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext.unregisterReceiver(mUserReceiver);
mContext.unregisterReceiver(mShutdownReceiver);
- mTeleManager.listen(mPhoneListener, LISTEN_NONE);
+ if (!mSettings.getCombineSubtypeEnabled()) {
+ mNetworkStatsSubscriptionsMonitor.stop();
+ }
final long currentTime = mClock.millis();
@@ -1197,35 +1211,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
};
/**
- * Receiver that watches for {@link TelephonyManager} changes, such as
- * transitioning between Radio Access Technology(RAT) types.
+ * Handle collapsed RAT type changed event.
*/
- @NonNull
- private final NetworkTypeListener mPhoneListener;
-
- class NetworkTypeListener extends PhoneStateListener {
- private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN;
-
- NetworkTypeListener(@NonNull Executor executor) {
- super(executor);
- }
-
- @Override
- public void onServiceStateChanged(@NonNull ServiceState ss) {
- final int networkType = ss.getDataNetworkType();
- final int collapsedRatType = getCollapsedRatType(networkType);
- if (collapsedRatType == mLastCollapsedRatType) return;
-
- if (LOGD) {
- Log.d(TAG, "subtype changed for mobile: "
- + mLastCollapsedRatType + " -> " + collapsedRatType);
- }
- // Protect service from frequently updating. Remove pending messages if any.
- mHandler.removeMessages(MSG_UPDATE_IFACES);
- mLastCollapsedRatType = collapsedRatType;
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
- }
+ @VisibleForTesting
+ public void handleOnCollapsedRatTypeChanged() {
+ // Protect service from frequently updating. Remove pending messages if any.
+ mHandler.removeMessages(MSG_UPDATE_IFACES);
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
}
private void updateIfaces(
@@ -1352,8 +1345,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return 0;
}
- // TODO: return different subType for different subscriptions.
- return mPhoneListener.mLastCollapsedRatType;
+ return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
}
private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
@@ -1463,10 +1455,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
// Request asynchronous stats update from all providers for next poll. And wait a bit of
- // time to allow providers report-in given that normally binder call should be fast.
+ // time to allow providers report-in given that normally binder call should be fast. Note
+ // that size of list might be changed because addition/removing at the same time. For
+ // addition, the stats of the missed provider can only be collected in next poll;
+ // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
+ // once that happened.
// TODO: request with a valid token.
Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
- final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
+ final int registeredCallbackCount = mStatsProviderCbList.size();
mStatsProviderSem.drainPermits();
invokeForAllStatsProviderCallbacks(
(cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
@@ -1520,10 +1516,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
// finally, dispatch updated event to any listeners
- final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
- updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
- READ_NETWORK_USAGE_HISTORY);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
Trace.traceEnd(TRACE_TAG_NETWORK);
}
@@ -1643,7 +1636,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
- Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
+ if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
}
}
@@ -1934,7 +1927,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
tag, provider, mStatsProviderSem, mAlertObserver,
mStatsProviderCbList);
- mStatsProviderCbList.register(callback);
+ mStatsProviderCbList.add(callback);
Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
+ getCallingUid() + "/" + getCallingPid());
return callback;
@@ -1958,20 +1951,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void invokeForAllStatsProviderCallbacks(
@NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
- synchronized (mStatsLock) {
- final int length = mStatsProviderCbList.beginBroadcast();
+ for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
try {
- for (int i = 0; i < length; i++) {
- final NetworkStatsProviderCallbackImpl cb =
- mStatsProviderCbList.getBroadcastItem(i);
- try {
- task.accept(cb);
- } catch (RemoteException e) {
- Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
- }
- }
- } finally {
- mStatsProviderCbList.finishBroadcast();
+ task.accept(cb);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
}
}
}
@@ -1983,7 +1967,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@NonNull final INetworkStatsProvider mProvider;
@NonNull private final Semaphore mSemaphore;
@NonNull final INetworkManagementEventObserver mAlertObserver;
- @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
+ @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
@NonNull private final Object mProviderStatsLock = new Object();
@@ -1997,7 +1981,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@NonNull String tag, @NonNull INetworkStatsProvider provider,
@NonNull Semaphore semaphore,
@NonNull INetworkManagementEventObserver alertObserver,
- @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList)
+ @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList)
throws RemoteException {
mTag = tag;
mProvider = provider;
@@ -2054,13 +2038,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public void binderDied() {
Log.d(TAG, mTag + ": binderDied");
- mStatsProviderCbList.unregister(this);
+ mStatsProviderCbList.remove(this);
}
@Override
public void unregister() {
Log.d(TAG, mTag + ": unregister");
- mStatsProviderCbList.unregister(this);
+ mStatsProviderCbList.remove(this);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a2f191444b63..2d39e9169245 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -920,7 +920,7 @@ public class NotificationManagerService extends SystemService {
() -> mAm.crashApplication(uid, initialPid, pkg, -1,
"Bad notification(tag=" + tag + ", id=" + id + ") posted from package "
+ pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): "
- + message));
+ + message, true /* force */));
}
}
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 341a88dd0a87..4bb17a2c298e 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -33,9 +33,9 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
+import android.os.Binder;
import android.os.Environment;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.sysprop.ApexProperties;
import android.util.Slog;
@@ -73,12 +73,7 @@ abstract class ApexManager {
*/
static ApexManager create(Context systemContext) {
if (ApexProperties.updatable().orElse(false)) {
- try {
- return new ApexManagerImpl(systemContext, IApexService.Stub.asInterface(
- ServiceManager.getServiceOrThrow("apexservice")));
- } catch (ServiceManager.ServiceNotFoundException e) {
- throw new IllegalStateException("Required service apexservice not available");
- }
+ return new ApexManagerImpl(systemContext);
} else {
return new ApexManagerFlattenedApex();
}
@@ -247,8 +242,7 @@ abstract class ApexManager {
* APEX packages.
*/
@VisibleForTesting
- static class ApexManagerImpl extends ApexManager {
- private final IApexService mApexService;
+ protected static class ApexManagerImpl extends ApexManager {
private final Context mContext;
private final Object mLock = new Object();
/**
@@ -261,9 +255,8 @@ abstract class ApexManager {
@GuardedBy("mLock")
private List<PackageInfo> mAllPackagesCache;
- ApexManagerImpl(Context context, IApexService apexService) {
+ ApexManagerImpl(Context context) {
mContext = context;
- mApexService = apexService;
}
/**
@@ -286,10 +279,23 @@ abstract class ApexManager {
return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ /**
+ * Retrieve the service from ServiceManager. If the service is not running, it will be
+ * started, and this function will block until it is ready.
+ */
+ @VisibleForTesting
+ protected IApexService waitForApexService() {
+ try {
+ return IApexService.Stub.asInterface(Binder.waitForService("apexservice"));
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Required service apexservice not available");
+ }
+ }
+
@Override
List<ActiveApexInfo> getActiveApexInfos() {
try {
- return Arrays.stream(mApexService.getActivePackages())
+ return Arrays.stream(waitForApexService().getActivePackages())
.map(apexInfo -> new ActiveApexInfo(
new File(
Environment.getApexDirectory() + File.separator
@@ -324,7 +330,7 @@ abstract class ApexManager {
mAllPackagesCache = new ArrayList<>();
HashSet<String> activePackagesSet = new HashSet<>();
HashSet<String> factoryPackagesSet = new HashSet<>();
- final ApexInfo[] allPkgs = mApexService.getAllPackages();
+ final ApexInfo[] allPkgs = waitForApexService().getAllPackages();
for (ApexInfo ai : allPkgs) {
// If the device is using flattened APEX, don't report any APEX
// packages since they won't be managed or updated by PackageManager.
@@ -431,7 +437,8 @@ abstract class ApexManager {
@Override
@Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) {
try {
- ApexSessionInfo apexSessionInfo = mApexService.getStagedSessionInfo(sessionId);
+ ApexSessionInfo apexSessionInfo =
+ waitForApexService().getStagedSessionInfo(sessionId);
if (apexSessionInfo.isUnknown) {
return null;
}
@@ -450,7 +457,7 @@ abstract class ApexManager {
ApexSessionParams params = new ApexSessionParams();
params.sessionId = sessionId;
params.childSessionIds = childSessionIds;
- mApexService.submitStagedSession(params, apexInfoList);
+ waitForApexService().submitStagedSession(params, apexInfoList);
return apexInfoList;
} catch (RemoteException re) {
Slog.e(TAG, "Unable to contact apexservice", re);
@@ -465,7 +472,7 @@ abstract class ApexManager {
@Override
void markStagedSessionReady(int sessionId) throws PackageManagerException {
try {
- mApexService.markStagedSessionReady(sessionId);
+ waitForApexService().markStagedSessionReady(sessionId);
} catch (RemoteException re) {
Slog.e(TAG, "Unable to contact apexservice", re);
throw new RuntimeException(re);
@@ -479,7 +486,7 @@ abstract class ApexManager {
@Override
void markStagedSessionSuccessful(int sessionId) {
try {
- mApexService.markStagedSessionSuccessful(sessionId);
+ waitForApexService().markStagedSessionSuccessful(sessionId);
} catch (RemoteException re) {
Slog.e(TAG, "Unable to contact apexservice", re);
throw new RuntimeException(re);
@@ -498,7 +505,7 @@ abstract class ApexManager {
@Override
boolean revertActiveSessions() {
try {
- mApexService.revertActiveSessions();
+ waitForApexService().revertActiveSessions();
return true;
} catch (RemoteException re) {
Slog.e(TAG, "Unable to contact apexservice", re);
@@ -512,7 +519,7 @@ abstract class ApexManager {
@Override
boolean abortStagedSession(int sessionId) throws PackageManagerException {
try {
- mApexService.abortStagedSession(sessionId);
+ waitForApexService().abortStagedSession(sessionId);
return true;
} catch (RemoteException re) {
Slog.e(TAG, "Unable to contact apexservice", re);
@@ -527,7 +534,7 @@ abstract class ApexManager {
@Override
boolean uninstallApex(String apexPackagePath) {
try {
- mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
+ waitForApexService().unstagePackages(Collections.singletonList(apexPackagePath));
return true;
} catch (Exception e) {
return false;
@@ -578,7 +585,7 @@ abstract class ApexManager {
ipw.increaseIndent();
ipw.println("APEX session state:");
ipw.increaseIndent();
- final ApexSessionInfo[] sessions = mApexService.getSessions();
+ final ApexSessionInfo[] sessions = waitForApexService().getSessions();
for (ApexSessionInfo si : sessions) {
ipw.println("Session ID: " + si.sessionId);
ipw.increaseIndent();
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 0d7494cfbeab..6fdde7a196cc 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -30,7 +30,7 @@ per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.
per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com
per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com
per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
-per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
+per-file UserManagerService.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com
per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e82102f3379d..50bbfa96bfab 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3004,8 +3004,7 @@ public class PackageManagerService extends IPackageManager.Stub
mWellbeingPackage = getWellbeingPackageName();
mDocumenterPackage = getDocumenterPackageName();
- mConfiguratorPackage =
- mContext.getString(R.string.config_deviceConfiguratorPackageName);
+ mConfiguratorPackage = getDeviceConfiguratorPackageName();
mAppPredictionServicePackage = getAppPredictionServicePackageName();
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
mTelephonyPackages = getTelephonyPackageNames();
@@ -20537,7 +20536,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getSystemTextClassifierPackageName() {
- return mContext.getString(R.string.config_defaultTextClassifierPackage);
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_defaultTextClassifierPackage));
}
@Override
@@ -20547,7 +20547,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (flattenedComponentName != null) {
ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
if (componentName != null && componentName.getPackageName() != null) {
- return componentName.getPackageName();
+ return ensureSystemPackageName(componentName.getPackageName());
}
}
return null;
@@ -20572,9 +20572,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ @Nullable
+ private String getDeviceConfiguratorPackageName() {
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_deviceConfiguratorPackageName));
+ }
+
@Override
public String getWellbeingPackageName() {
- return mContext.getString(R.string.config_defaultWellbeingPackage);
+ return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
}
@Override
@@ -20589,7 +20595,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (appPredictionServiceComponentName == null) {
return null;
}
- return appPredictionServiceComponentName.getPackageName();
+ return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
}
@Override
@@ -20606,11 +20612,33 @@ public class PackageManagerService extends IPackageManager.Stub
if (systemCaptionsServiceComponentName == null) {
return null;
}
- return systemCaptionsServiceComponentName.getPackageName();
+ return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
}
public String getIncidentReportApproverPackageName() {
- return mContext.getString(R.string.config_incidentReportApproverPackage);
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_incidentReportApproverPackage));
+ }
+
+ @Nullable
+ private String ensureSystemPackageName(@Nullable String packageName) {
+ if (packageName == null) {
+ return null;
+ }
+ long token = Binder.clearCallingIdentity();
+ try {
+ if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
+ PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
+ if (packageInfo != null) {
+ EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
+ "");
+ }
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return packageName;
}
@Override
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index f78d2639df1a..add0b01f1879 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -19,8 +19,6 @@ package com.android.server.policy.keyguard;
import android.app.ActivityManager;
import android.content.Context;
import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.security.keystore.IKeystoreService;
import android.util.Slog;
import com.android.internal.policy.IKeyguardService;
@@ -53,16 +51,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
private final LockPatternUtils mLockPatternUtils;
private final StateCallback mCallback;
- IKeystoreService mKeystoreService;
-
public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
mLockPatternUtils = new LockPatternUtils(context);
mCurrentUserId = ActivityManager.getCurrentUser();
mCallback = callback;
- mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
- .getService("android.security.keystore"));
-
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -95,23 +88,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
mIsShowing = showing;
mCallback.onShowingChanged();
- int retry = 2;
- while (retry > 0) {
- try {
- mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
- break;
- } catch (RemoteException e) {
- if (retry == 2) {
- Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died"
- + " -> refreshing service token and retrying");
- mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
- .getService("android.security.keystore"));
- } else {
- Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e);
- }
- --retry;
- }
- }
}
@Override // Binder interface
@@ -123,10 +99,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
mCurrentUserId = userId;
}
- private synchronized int getCurrentUser() {
- return mCurrentUserId;
- }
-
@Override // Binder interface
public void onInputRestrictedStateChanged(boolean inputRestricted) {
mInputRestricted = inputRestricted;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 7408dd40b5ca..5f5cd3c46117 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,6 +53,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.security.KeyStore;
import android.service.trust.TrustAgentService;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -135,6 +136,33 @@ public class TrustManagerService extends SystemService {
@GuardedBy("mUserIsTrusted")
private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
+ /**
+ * Stores the locked state for users on the device. There are three different type of users
+ * which are handled slightly differently:
+ * <ul>
+ * <li> Users with real keyguard
+ * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their
+ * locked state is derived by a combination of user secure state, keyguard state, trust agent
+ * decision and biometric authentication result. These are updated via
+ * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}.
+ * <li> Managed profiles with unified challenge
+ * Managed profile with unified challenge always shares the same locked state as their parent,
+ * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead,
+ * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and
+ * queries its locked state instead.
+ * <li> Managed profiles with separate challenge
+ * Locked state for profile with separate challenge is determined by other parts of the
+ * framework (mostly PowerManager) and pushed to TrustManagerService via
+ * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when
+ * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to
+ * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}.
+ * </ul>
+ * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to
+ * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying
+ * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice.
+ * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different
+ * side-effects: one notifies trust agents while the other sends out a broadcast.
+ */
@GuardedBy("mDeviceLockedForUser")
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
@@ -601,6 +629,10 @@ public class TrustManagerService extends SystemService {
}
}
+ /**
+ * Update the user's locked state. Only applicable to users with a real keyguard
+ * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles.
+ */
private void refreshDeviceLockedForUser(int userId) {
if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
@@ -661,6 +693,15 @@ public class TrustManagerService extends SystemService {
}
if (changed) {
dispatchDeviceLocked(userId, locked);
+
+ KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
+ // Also update the user's profiles who have unified challenge, since they
+ // share the same unlocked state (see {@link #isDeviceLocked(int)})
+ for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
+ if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
+ KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked);
+ }
+ }
}
}
@@ -1194,6 +1235,10 @@ public class TrustManagerService extends SystemService {
return "0x" + Integer.toHexString(i);
}
+ /**
+ * Changes the lock status for the given user. This is only applicable to managed profiles,
+ * other users should be handled by Keyguard.
+ */
@Override
public void setDeviceLockedForUser(int userId, boolean locked) {
enforceReportPermission();
@@ -1204,6 +1249,9 @@ public class TrustManagerService extends SystemService {
synchronized (mDeviceLockedForUser) {
mDeviceLockedForUser.put(userId, locked);
}
+
+ KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
+
if (locked) {
try {
ActivityManager.getService().notifyLockedProfile(userId);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 848971d3b044..1592f239fd2e 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4268,6 +4268,11 @@ class ActivityStack extends ConfigurationContainer {
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
Intent resultData) {
+ if (!srec.attachedToProcess()) {
+ // Nothing to do if the caller is not attached, because this method should be called
+ // from an alive activity.
+ return false;
+ }
final TaskRecord task = srec.getTaskRecord();
final ArrayList<ActivityRecord> activities = task.mActivities;
final int start = activities.indexOf(srec);
@@ -4321,14 +4326,14 @@ class ActivityStack extends ConfigurationContainer {
}
if (parent != null && foundParentInTask) {
+ final int callingUid = srec.info.applicationInfo.uid;
final int parentLaunchMode = parent.info.launchMode;
final int destIntentFlags = destIntent.getFlags();
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
- parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
- srec.packageName);
+ parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -4341,10 +4346,10 @@ class ActivityStack extends ConfigurationContainer {
.setActivityInfo(aInfo)
.setResultTo(parent.appToken)
.setCallingPid(-1)
- .setCallingUid(parent.launchedFromUid)
- .setCallingPackage(parent.launchedFromPackage)
+ .setCallingUid(callingUid)
+ .setCallingPackage(srec.packageName)
.setRealCallingPid(-1)
- .setRealCallingUid(parent.launchedFromUid)
+ .setRealCallingUid(callingUid)
.setComponentSpecified(true)
.execute();
foundParentInTask = res == ActivityManager.START_SUCCESS;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5b697ee89602..f37698de34d5 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2763,6 +2763,11 @@ class ActivityStarter {
return mRequest.intent;
}
+ @VisibleForTesting
+ int getCallingUid() {
+ return mRequest.callingUid;
+ }
+
ActivityStarter setReason(String reason) {
mRequest.reason = reason;
return this;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 72fc18937ece..9d56263740ed 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -28,12 +28,14 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Process;
import android.os.SystemClock;
+import android.os.UserManagerInternal;
import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.AtomicFile;
+import com.android.server.LocalServices;
import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto;
import java.io.File;
@@ -73,6 +75,7 @@ class TaskSnapshotPersister {
private boolean mStarted;
private final Object mLock = new Object();
private final DirectoryResolver mDirectoryResolver;
+ private final UserManagerInternal mUserManagerInternal;
private final float mReducedScale;
/**
@@ -84,6 +87,7 @@ class TaskSnapshotPersister {
TaskSnapshotPersister(WindowManagerService service, DirectoryResolver resolver) {
mDirectoryResolver = resolver;
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
if (service.mLowRamTaskSnapshotsAndRecents) {
// Use very low res snapshots if we are using Go version of recents.
mReducedScale = LOW_RAM_RECENTS_REDUCED_SCALE;
@@ -172,7 +176,7 @@ class TaskSnapshotPersister {
return;
}
}
- SystemClock.sleep(100);
+ SystemClock.sleep(DELAY_MS);
}
}
@@ -218,7 +222,7 @@ class TaskSnapshotPersister {
private boolean createDirectory(int userId) {
final File dir = getDirectory(userId);
- return dir.exists() || dir.mkdirs();
+ return dir.exists() || dir.mkdir();
}
private void deleteSnapshot(int taskId, int userId) {
@@ -243,18 +247,26 @@ class TaskSnapshotPersister {
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
WriteQueueItem next;
+ boolean isReadyToWrite = false;
synchronized (mLock) {
if (mPaused) {
next = null;
} else {
next = mWriteQueue.poll();
if (next != null) {
- next.onDequeuedLocked();
+ if (next.isReady()) {
+ isReadyToWrite = true;
+ next.onDequeuedLocked();
+ } else {
+ mWriteQueue.addLast(next);
+ }
}
}
}
if (next != null) {
- next.write();
+ if (isReadyToWrite) {
+ next.write();
+ }
SystemClock.sleep(DELAY_MS);
}
synchronized (mLock) {
@@ -274,6 +286,13 @@ class TaskSnapshotPersister {
};
private abstract class WriteQueueItem {
+ /**
+ * @return {@code true} if item is ready to have {@link WriteQueueItem#write} called
+ */
+ boolean isReady() {
+ return true;
+ }
+
abstract void write();
/**
@@ -313,6 +332,11 @@ class TaskSnapshotPersister {
}
@Override
+ boolean isReady() {
+ return mUserManagerInternal.isUserUnlocked(mUserId);
+ }
+
+ @Override
void write() {
if (!createDirectory(mUserId)) {
Slog.e(TAG, "Unable to create snapshot directory for user dir="
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e1f85446de7b..404863af800f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7717,14 +7717,19 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void syncInputTransactions() {
- waitForAnimationsToComplete();
+ long token = Binder.clearCallingIdentity();
+ try {
+ waitForAnimationsToComplete();
- synchronized (mGlobalLock) {
- mWindowPlacerLocked.performSurfacePlacementIfScheduled();
- mRoot.forAllDisplays(displayContent ->
+ synchronized (mGlobalLock) {
+ mWindowPlacerLocked.performSurfacePlacementIfScheduled();
+ mRoot.forAllDisplays(displayContent ->
displayContent.getInputMonitor().updateInputWindowsImmediately());
+ }
+ new SurfaceControl.Transaction().syncInputWindows().apply(true);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- new SurfaceControl.Transaction().syncInputWindows().apply(true);
}
private void waitForAnimationsToComplete() {
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index e79612fbf3d3..a99c0a3fa23e 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -40,6 +40,7 @@
#include <linux/rtc.h>
#include <array>
+#include <limits>
#include <memory>
namespace android {
@@ -213,22 +214,20 @@ int AlarmImpl::waitForAlarm()
static jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis)
{
AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
- struct timeval tv;
- int ret;
- if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+ if (millis <= 0 || millis / 1000LL >= std::numeric_limits<time_t>::max()) {
return -1;
}
- tv.tv_sec = (time_t) (millis / 1000LL);
- tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
-
- ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+ struct timeval tv;
+ tv.tv_sec = (millis / 1000LL);
+ tv.tv_usec = ((millis % 1000LL) * 1000LL);
- ret = impl->setTime(&tv);
+ ALOGD("Setting time of day to sec=%ld", tv.tv_sec);
- if(ret < 0) {
- ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+ int ret = impl->setTime(&tv);
+ if (ret < 0) {
+ ALOGW("Unable to set rtc to %ld: %s", tv.tv_sec, strerror(errno));
ret = -1;
}
return ret;
diff --git a/services/core/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp
index aef0b25503c8..c9459994a658 100644
--- a/services/core/jni/com_android_server_SerialService.cpp
+++ b/services/core/jni/com_android_server_SerialService.cpp
@@ -48,6 +48,7 @@ static jobject android_server_SerialService_open(JNIEnv *env, jobject /* thiz */
jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
if (fileDescriptor == NULL) {
+ close(fd);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,
diff --git a/services/core/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp
index ff1ec04cb23e..72dce4dca0da 100644
--- a/services/core/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp
@@ -19,6 +19,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "MtpDescriptors.h"
@@ -88,6 +89,7 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec
}
jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
if (fileDescriptor == NULL) {
+ close(fd);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,
@@ -120,35 +122,30 @@ static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv* /* env */, jobj
}
static jobject android_server_UsbDeviceManager_openControl(JNIEnv *env, jobject /* thiz */, jstring jFunction) {
- const char *function = env->GetStringUTFChars(jFunction, NULL);
+ ScopedUtfChars function(env, jFunction);
bool ptp = false;
int fd = -1;
- if (!strcmp(function, "ptp")) {
+ if (!strcmp(function.c_str(), "ptp")) {
ptp = true;
}
- if (!strcmp(function, "mtp") || ptp) {
+ if (!strcmp(function.c_str(), "mtp") || ptp) {
fd = TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP0 : FFS_MTP_EP0, O_RDWR));
if (fd < 0) {
- ALOGE("could not open control for %s %s", function, strerror(errno));
- goto error;
+ ALOGE("could not open control for %s %s", function.c_str(), strerror(errno));
+ return NULL;
}
if (!writeDescriptors(fd, ptp)) {
- goto error;
+ close(fd);
+ return NULL;
}
}
- if (function != NULL) {
- env->ReleaseStringUTFChars(jFunction, function);
- }
- return jniCreateFileDescriptor(env, fd);
-error:
- if (fd != -1) {
+ jobject jifd = jniCreateFileDescriptor(env, fd);
+ if (jifd == NULL) {
+ // OutOfMemoryError will be pending.
close(fd);
}
- if (function != NULL) {
- env->ReleaseStringUTFChars(jFunction, function);
- }
- return NULL;
+ return jifd;
}
static const JNINativeMethod method_table[] = {
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index 24f2014afa30..a40bcd0d7c07 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -134,6 +134,7 @@ static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject /*
jobject fileDescriptor = jniCreateFileDescriptor(env, newFD);
if (fileDescriptor == NULL) {
+ close(newFD);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,
diff --git a/services/core/jni/com_android_server_UsbMidiDevice.cpp b/services/core/jni/com_android_server_UsbMidiDevice.cpp
index 79d935fe610c..8ac2c4f37ecd 100644
--- a/services/core/jni/com_android_server_UsbMidiDevice.cpp
+++ b/services/core/jni/com_android_server_UsbMidiDevice.cpp
@@ -20,6 +20,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
@@ -99,24 +100,45 @@ android_server_UsbMidiDevice_open(JNIEnv *env, jobject thiz, jint card, jint dev
int fd = open(path, O_RDWR);
if (fd < 0) {
ALOGE("open failed on %s for index %d", path, i);
- return NULL;
+ goto release_fds;
}
-
- jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
- env->SetObjectArrayElement(fds, i, fileDescriptor);
- env->DeleteLocalRef(fileDescriptor);
+ ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, fd));
+ if (jifd.get() == NULL) {
+ goto release_fds;
+ }
+ env->SetObjectArrayElement(fds, i, jifd.get());
}
// create a pipe to use for unblocking our input thread
- int pipeFD[2];
- pipe(pipeFD);
- jobject fileDescriptor = jniCreateFileDescriptor(env, pipeFD[0]);
- env->SetObjectArrayElement(fds, subdevice_count, fileDescriptor);
- env->DeleteLocalRef(fileDescriptor);
- // store our end of the pipe in mPipeFD
- env->SetIntField(thiz, sPipeFDField, pipeFD[1]);
+ {
+ int pipeFD[2];
+ if (pipe(pipeFD) == -1) {
+ ALOGE("pipe() failed, errno = %d", errno);
+ goto release_fds;
+ }
+ ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, pipeFD[0]));
+ if (jifd.get() == NULL) {
+ close(pipeFD[0]);
+ close(pipeFD[1]);
+ goto release_fds;
+ }
+ env->SetObjectArrayElement(fds, subdevice_count, jifd.get());
+ // store our end of the pipe in mPipeFD
+ env->SetIntField(thiz, sPipeFDField, pipeFD[1]);
+ }
return fds;
+
+release_fds:
+ for (int i = 0; i < subdevice_count + 1; ++i) {
+ ScopedLocalRef<jobject> jifd(env, env->GetObjectArrayElement(fds, i));
+ if (jifd.get() == NULL) {
+ break;
+ }
+ int fd = jniGetFDFromFileDescriptor(env, jifd.get());
+ close(fd);
+ }
+ return NULL;
}
static void
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0167a3b0aebe..23b1512081da 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -165,6 +165,8 @@ import com.android.server.wm.ActivityTaskManagerService;
import com.android.server.wm.WindowManagerGlobalLock;
import com.android.server.wm.WindowManagerService;
+import libcore.timezone.ZoneInfoDb;
+
import dalvik.system.VMRuntime;
import java.io.File;
@@ -395,8 +397,9 @@ public final class SystemServer {
// Default the timezone property to GMT if not set.
//
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
- if (timezoneProperty == null || timezoneProperty.isEmpty()) {
- Slog.w(TAG, "Timezone not set; setting to GMT.");
+ if (!isValidTimeZoneId(timezoneProperty)) {
+ Slog.w(TAG, "persist.sys.timezone is not valid (" + timezoneProperty
+ + "); setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
@@ -564,6 +567,12 @@ public final class SystemServer {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
+ private static boolean isValidTimeZoneId(String timezoneProperty) {
+ return timezoneProperty != null
+ && !timezoneProperty.isEmpty()
+ && ZoneInfoDb.getInstance().hasTimeZone(timezoneProperty);
+ }
+
private boolean isFirstBootOrUpgrade() {
return mPackageManagerService.isFirstBoot() || mPackageManagerService.isDeviceUpgrading();
}
diff --git a/services/net/Android.bp b/services/net/Android.bp
index bb5409b3e032..8b444b0fed41 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -12,8 +12,7 @@ java_library_static {
":services.net-sources",
],
static_libs: [
- "dnsresolver_aidl_interface-V4-java",
- "netd_aidl_interface-V3-java",
+ "netd_aidl_interfaces-platform-java",
"netlink-client",
"networkstack-client",
"net-utils-services-common",
@@ -44,7 +43,8 @@ java_library {
"framework-wifi-util-lib",
],
static_libs: [
- "dnsresolver_aidl_interface-V2-java",
+ // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
+ // classes generated by netd_aidl_interfaces-platform-java above.
"netd_aidl_interface-V3-java",
"netlink-client",
"networkstack-client",
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 163832983b5b..3465ea99bdae 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -73,7 +73,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
private static final int HDMI_3_PHYSICAL_ADDRESS = 0x2300;
private int mInvokeDeviceEventState;
private HdmiDeviceInfo mDeviceInfo;
- private boolean mMutingEnabled;
private boolean mArcSupport;
private HdmiPortInfo[] mHdmiPortInfo;
@@ -154,8 +153,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
@Override
boolean readBooleanSystemProperty(String key, boolean defVal) {
switch (key) {
- case Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE:
- return mMutingEnabled;
case Constants.PROPERTY_ARC_SUPPORT:
return mArcSupport;
default:
@@ -209,7 +206,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
mNativeWrapper.clearResultMessages();
- mMutingEnabled = true;
mArcSupport = true;
mInvokeDeviceEventState = 0;
mDeviceInfo = null;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 30d103576c99..c08671825b09 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -21,8 +21,10 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -68,7 +70,9 @@ public class ApexManagerTest {
@Before
public void setUp() throws RemoteException {
mContext = InstrumentationRegistry.getInstrumentation().getContext();
- mApexManager = new ApexManager.ApexManagerImpl(mContext, mApexService);
+ ApexManager.ApexManagerImpl managerImpl = spy(new ApexManager.ApexManagerImpl(mContext));
+ doReturn(mApexService).when(managerImpl).waitForApexService();
+ mApexManager = managerImpl;
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index bde0ef6aa39e..ff27b9bb1c9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -28,7 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
@@ -54,8 +54,11 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import android.app.ActivityManager;
+import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -82,8 +85,9 @@ public class ActivityStackTests extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
- mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
- true /* onTop */));
+ mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
+ true /* onTop */);
+ spyOn(mStack);
mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
}
@@ -1078,6 +1082,37 @@ public class ActivityStackTests extends ActivityTestsBase {
assertTrue(listener.mChanged);
}
+ @Test
+ public void testNavigateUpTo() {
+ final ActivityStartController controller = mock(ActivityStartController.class);
+ final ActivityStarter starter = new ActivityStarter(controller,
+ mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ doReturn(controller).when(mService).getActivityStartController();
+ spyOn(starter);
+ doReturn(ActivityManager.START_SUCCESS).when(starter).execute();
+
+ final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
+ .setUid(firstActivity.getUid() + 1).build();
+ doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString());
+
+ final IApplicationThread thread = secondActivity.app.getThread();
+ secondActivity.app.setThread(null);
+ // This should do nothing from a non-attached caller.
+ assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+
+ secondActivity.app.setThread(thread);
+ assertTrue(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+ // The firstActivity uses default launch mode, so the activities between it and itself will
+ // be finished.
+ assertTrue(secondActivity.finishing);
+ assertTrue(firstActivity.finishing);
+ // The calling uid of the new activity should be the current real caller.
+ assertEquals(secondActivity.getUid(), starter.getCallingUid());
+ }
+
private void verifyShouldSleepActivities(boolean focusedStack,
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
final ActivityDisplay display = mock(ActivityDisplay.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 84bdecb86826..f94f00203521 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -290,6 +290,7 @@ class ActivityTestsBase {
aInfo.applicationInfo.packageName = mComponent.getPackageName();
aInfo.applicationInfo.uid = mUid;
aInfo.packageName = mComponent.getPackageName();
+ aInfo.name = mComponent.getClassName();
if (mTargetActivity != null) {
aInfo.targetActivity = mTargetActivity;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index e004cd3fb0c4..f25110f549df 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -23,6 +23,9 @@ import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.app.ActivityManager.TaskSnapshot;
import android.content.ComponentName;
import android.graphics.Canvas;
@@ -32,9 +35,14 @@ import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.UserManager;
+import android.os.UserManagerInternal;
+
+import com.android.server.LocalServices;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.BeforeClass;
import java.io.File;
@@ -50,10 +58,26 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
TaskSnapshotLoader mLoader;
int mTestUserId;
+ @BeforeClass
+ public static void setUpOnce() {
+ final UserManagerInternal userManager = mock(UserManagerInternal.class);
+ LocalServices.addService(UserManagerInternal.class, userManager);
+ }
+
+ @AfterClass
+ public static void tearDownOnce() {
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
+ }
+
@Before
public void setUp() {
final UserManager um = UserManager.get(getInstrumentation().getTargetContext());
mTestUserId = um.getUserHandle();
+
+ final UserManagerInternal userManagerInternal =
+ LocalServices.getService(UserManagerInternal.class);
+ when(userManagerInternal.isUserUnlocked(mTestUserId)).thenReturn(true);
+
mPersister = new TaskSnapshotPersister(mWm, userId -> FILES_DIR);
mLoader = new TaskSnapshotLoader(mPersister);
mPersister.start();
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 4e14fd3d59a1..d9605522b3b0 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -106,6 +106,7 @@ public abstract class Conference extends Conferenceable {
private int mCallerDisplayNamePresentation;
private int mCallDirection;
private boolean mRingbackRequested = false;
+ private boolean mIsMultiparty = true;
private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
@Override
@@ -998,8 +999,8 @@ public abstract class Conference extends Conferenceable {
public void onExtrasChanged(Bundle extras) {}
/**
- * Set whether Telecom should treat this {@link Conference} as a conference call or if it
- * should treat it as a single-party call.
+ * Set whether Telecom should treat this {@link Conference} as a multiparty conference call or
+ * if it should treat it as a single-party call.
* This method is used as part of a workaround regarding IMS conference calls and user
* expectation. In IMS, once a conference is formed, the UE is connected to an IMS conference
* server. If all participants of the conference drop out of the conference except for one, the
@@ -1020,6 +1021,7 @@ public abstract class Conference extends Conferenceable {
@TestApi
@RequiresPermission(MODIFY_PHONE_STATE)
public void setConferenceState(boolean isConference) {
+ mIsMultiparty = isConference;
for (Listener l : mListeners) {
l.onConferenceStateChanged(this, isConference);
}
@@ -1043,6 +1045,20 @@ public abstract class Conference extends Conferenceable {
}
}
+ /**
+ * Determines if the {@link Conference} is considered "multiparty" or not. By default all
+ * conferences are considered multiparty. A multiparty conference is one where there are
+ * multiple conference participants (other than the host) in the conference.
+ * This is tied to {@link #setConferenceState(boolean)}, which is used for some use cases to
+ * have a conference appear as if it is a standalone call, in which case the conference will
+ * no longer be multiparty.
+ * @return {@code true} if conference is treated as a conference (i.e. it is multiparty),
+ * {@code false} if it should emulate a standalone call (i.e. not multiparty).
+ * @hide
+ */
+ public boolean isMultiparty() {
+ return mIsMultiparty;
+ }
/**
* Sets the address of this {@link Conference}. Used when {@link #setConferenceState(boolean)}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 73296986d82e..1b60e4820ad0 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2505,6 +2505,11 @@ public abstract class ConnectionService extends Service {
mAdapter.addConferenceCall(id, parcelableConference);
mAdapter.setVideoProvider(id, conference.getVideoProvider());
mAdapter.setVideoState(id, conference.getVideoState());
+ // In some instances a conference can start its life as a standalone call with just a
+ // single participant; ensure we signal to Telecom in this case.
+ if (!conference.isMultiparty()) {
+ mAdapter.setConferenceState(id, conference.isMultiparty());
+ }
// Go through any child calls and set the parent.
for (Connection connection : conference.getConnections()) {
diff --git a/telecomm/java/android/telecom/GatewayInfo.java b/telecomm/java/android/telecom/GatewayInfo.java
index 0faa4fd2027a..31c24d54918a 100644
--- a/telecomm/java/android/telecom/GatewayInfo.java
+++ b/telecomm/java/android/telecom/GatewayInfo.java
@@ -111,7 +111,7 @@ public class GatewayInfo implements Parcelable {
@Override
public void writeToParcel(Parcel destination, int flags) {
destination.writeString(mGatewayProviderPackageName);
- mGatewayAddress.writeToParcel(destination, 0);
- mOriginalAddress.writeToParcel(destination, 0);
+ Uri.writeToParcel(destination, mGatewayAddress);
+ Uri.writeToParcel(destination, mOriginalAddress);
}
}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 415a817b58d5..182dc8bb8325 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -629,7 +629,7 @@ public final class ParcelableCall implements Parcelable {
int capabilities = source.readInt();
int properties = source.readInt();
long connectTimeMillis = source.readLong();
- Uri handle = source.readParcelable(classLoader);
+ Uri handle = Uri.CREATOR.createFromParcel(source);
int handlePresentation = source.readInt();
String callerDisplayName = source.readString();
int callerDisplayNamePresentation = source.readInt();
@@ -711,7 +711,7 @@ public final class ParcelableCall implements Parcelable {
destination.writeInt(mCapabilities);
destination.writeInt(mProperties);
destination.writeLong(mConnectTimeMillis);
- destination.writeParcelable(mHandle, 0);
+ Uri.writeToParcel(destination, mHandle);
destination.writeInt(mHandlePresentation);
destination.writeString(mCallerDisplayName);
destination.writeInt(mCallerDisplayNamePresentation);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 8d53158b9f32..ce71511c0361 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -398,7 +398,7 @@ public class TelecomManager {
* Optional extra for communicating the call network technology used by a
* {@link android.telecom.Connection} to Telecom and InCallUI.
*
- * @see {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}.
+ * {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}.
*/
public static final String EXTRA_CALL_NETWORK_TYPE =
"android.telecom.extra.CALL_NETWORK_TYPE";
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
deleted file mode 100644
index 892bd03a562e..000000000000
--- a/telephony/api/system-current.txt
+++ /dev/null
@@ -1,2140 +0,0 @@
-// Signature format: 2.0
-package android.telephony {
-
- public final class AccessNetworkConstants {
- field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
- }
-
- public static final class AccessNetworkConstants.NgranBands {
- method public static int getFrequencyRangeGroup(int);
- field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1
- field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2
- field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
- }
-
- public final class BarringInfo implements android.os.Parcelable {
- ctor public BarringInfo();
- method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
- }
-
- public final class CallAttributes implements android.os.Parcelable {
- ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
- method public int describeContents();
- method @NonNull public android.telephony.CallQuality getCallQuality();
- method public int getNetworkType();
- method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
- }
-
- public final class CallQuality implements android.os.Parcelable {
- ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
- ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
- method public int describeContents();
- method public int getAverageRelativeJitter();
- method public int getAverageRoundTripTime();
- method public int getCallDuration();
- method public int getCodecType();
- method public int getDownlinkCallQualityLevel();
- method public int getMaxRelativeJitter();
- method public int getNumRtpPacketsNotReceived();
- method public int getNumRtpPacketsReceived();
- method public int getNumRtpPacketsTransmitted();
- method public int getNumRtpPacketsTransmittedLost();
- method public int getUplinkCallQualityLevel();
- method public boolean isIncomingSilenceDetected();
- method public boolean isOutgoingSilenceDetected();
- method public boolean isRtpInactivityDetected();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_QUALITY_BAD = 4; // 0x4
- field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
- field public static final int CALL_QUALITY_FAIR = 2; // 0x2
- field public static final int CALL_QUALITY_GOOD = 1; // 0x1
- field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
- field public static final int CALL_QUALITY_POOR = 3; // 0x3
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
- }
-
- public class CarrierConfigManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
- method @NonNull public static android.os.PersistableBundle getDefaultConfig();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String);
- field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
- field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
- }
-
- public static final class CarrierConfigManager.Wifi {
- field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count";
- field public static final String KEY_PREFIX = "wifi.";
- }
-
- public final class CarrierRestrictionRules implements android.os.Parcelable {
- method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
- method public int describeContents();
- method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers();
- method public int getDefaultCarrierRestriction();
- method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
- method public int getMultiSimPolicy();
- method public boolean isAllCarriersAllowed();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
- field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierRestrictionRules> CREATOR;
- field public static final int MULTISIM_POLICY_NONE = 0; // 0x0
- field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1
- }
-
- public static final class CarrierRestrictionRules.Builder {
- ctor public CarrierRestrictionRules.Builder();
- method @NonNull public android.telephony.CarrierRestrictionRules build();
- method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
- method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
- method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int);
- method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
- method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
- }
-
- public class CbGeoUtils {
- }
-
- public static class CbGeoUtils.Circle implements android.telephony.CbGeoUtils.Geometry {
- ctor public CbGeoUtils.Circle(@NonNull android.telephony.CbGeoUtils.LatLng, double);
- method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
- method @NonNull public android.telephony.CbGeoUtils.LatLng getCenter();
- method public double getRadius();
- }
-
- public static interface CbGeoUtils.Geometry {
- method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
- }
-
- public static class CbGeoUtils.LatLng {
- ctor public CbGeoUtils.LatLng(double, double);
- method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng);
- method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng);
- field public final double lat;
- field public final double lng;
- }
-
- public static class CbGeoUtils.Polygon implements android.telephony.CbGeoUtils.Geometry {
- ctor public CbGeoUtils.Polygon(@NonNull java.util.List<android.telephony.CbGeoUtils.LatLng>);
- method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
- method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices();
- }
-
- public abstract class CellBroadcastService extends android.app.Service {
- ctor public CellBroadcastService();
- method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
- method public android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
- method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
- method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
- field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
- }
-
- public abstract class CellIdentity implements android.os.Parcelable {
- method @NonNull public abstract android.telephony.CellLocation asCellLocation();
- method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
- }
-
- public final class CellIdentityCdma extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
- }
-
- public final class CellIdentityGsm extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo();
- }
-
- public final class CellIdentityLte extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo();
- }
-
- public final class CellIdentityNr extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.CellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo();
- }
-
- public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo();
- }
-
- public final class CellIdentityWcdma extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo();
- }
-
- public final class DataFailCause {
- field @Deprecated public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be
- }
-
- public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
- }
-
- public final class DisconnectCause {
- field public static final int ALREADY_DIALING = 72; // 0x48
- field public static final int ANSWERED_ELSEWHERE = 52; // 0x34
- field public static final int BUSY = 4; // 0x4
- field public static final int CALLING_DISABLED = 74; // 0x4a
- field public static final int CALL_BARRED = 20; // 0x14
- field public static final int CALL_PULLED = 51; // 0x33
- field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49
- field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
- field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
- field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31
- field public static final int CDMA_DROP = 27; // 0x1b
- field public static final int CDMA_INTERCEPT = 28; // 0x1c
- field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
- field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
- field public static final int CDMA_PREEMPTED = 33; // 0x21
- field public static final int CDMA_REORDER = 29; // 0x1d
- field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
- field public static final int CDMA_SO_REJECT = 30; // 0x1e
- field public static final int CONGESTION = 5; // 0x5
- field public static final int CS_RESTRICTED = 22; // 0x16
- field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
- field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
- field public static final int DATA_DISABLED = 54; // 0x36
- field public static final int DATA_LIMIT_REACHED = 55; // 0x37
- field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39
- field public static final int DIALED_MMI = 39; // 0x27
- field public static final int DIAL_LOW_BATTERY = 62; // 0x3e
- field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30
- field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42
- field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f
- field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e
- field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45
- field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
- field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
- field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
- field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
- field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
- field public static final int ERROR_UNSPECIFIED = 36; // 0x24
- field public static final int FDN_BLOCKED = 21; // 0x15
- field public static final int ICC_ERROR = 19; // 0x13
- field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a
- field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c
- field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d
- field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47
- field public static final int INCOMING_AUTO_REJECTED = 81; // 0x51
- field public static final int INCOMING_MISSED = 1; // 0x1
- field public static final int INCOMING_REJECTED = 16; // 0x10
- field public static final int INVALID_CREDENTIALS = 10; // 0xa
- field public static final int INVALID_NUMBER = 7; // 0x7
- field public static final int LIMIT_EXCEEDED = 15; // 0xf
- field public static final int LOCAL = 3; // 0x3
- field public static final int LOST_SIGNAL = 14; // 0xe
- field public static final int LOW_BATTERY = 61; // 0x3d
- field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
- field public static final int MMI = 6; // 0x6
- field public static final int NORMAL = 2; // 0x2
- field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
- field public static final int NOT_DISCONNECTED = 0; // 0x0
- field public static final int NOT_VALID = -1; // 0xffffffff
- field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
- field public static final int NUMBER_UNREACHABLE = 8; // 0x8
- field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
- field public static final int OUTGOING_CANCELED = 44; // 0x2c
- field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50
- field public static final int OUTGOING_FAILURE = 43; // 0x2b
- field public static final int OUT_OF_NETWORK = 11; // 0xb
- field public static final int OUT_OF_SERVICE = 18; // 0x12
- field public static final int POWER_OFF = 17; // 0x11
- field public static final int SERVER_ERROR = 12; // 0xc
- field public static final int SERVER_UNREACHABLE = 9; // 0x9
- field public static final int TIMED_OUT = 13; // 0xd
- field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b
- field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
- field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
- field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
- field public static final int WIFI_LOST = 59; // 0x3b
- }
-
- public final class ImsiEncryptionInfo implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getKeyIdentifier();
- method @Nullable public java.security.PublicKey getPublicKey();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR;
- }
-
- public final class LteVopsSupportInfo implements android.os.Parcelable {
- ctor public LteVopsSupportInfo(int, int);
- method public int describeContents();
- method public int getEmcBearerSupport();
- method public int getVopsSupport();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
- field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
- field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
- field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
- }
-
- public class MbmsDownloadSession implements java.lang.AutoCloseable {
- field public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
- }
-
- public class MbmsGroupCallSession implements java.lang.AutoCloseable {
- field public static final String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall";
- }
-
- public class MbmsStreamingSession implements java.lang.AutoCloseable {
- field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
- }
-
- public final class ModemActivityInfo implements android.os.Parcelable {
- ctor public ModemActivityInfo(long, int, int, @NonNull int[], int);
- method public int describeContents();
- method public int getIdleTimeMillis();
- method public int getReceiveTimeMillis();
- method public int getSleepTimeMillis();
- method public long getTimestamp();
- method @NonNull public java.util.List<android.telephony.ModemActivityInfo.TransmitPower> getTransmitPowerInfo();
- method public boolean isValid();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR;
- field public static final int TX_POWER_LEVELS = 5; // 0x5
- field public static final int TX_POWER_LEVEL_0 = 0; // 0x0
- field public static final int TX_POWER_LEVEL_1 = 1; // 0x1
- field public static final int TX_POWER_LEVEL_2 = 2; // 0x2
- field public static final int TX_POWER_LEVEL_3 = 3; // 0x3
- field public static final int TX_POWER_LEVEL_4 = 4; // 0x4
- }
-
- public class ModemActivityInfo.TransmitPower {
- method @NonNull public android.util.Range<java.lang.Integer> getPowerRangeInDbm();
- method public int getTimeInMillis();
- }
-
- public final class NetworkRegistrationInfo implements android.os.Parcelable {
- method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
- method public int getRegistrationState();
- method public int getRejectCause();
- method public int getRoamingType();
- method public boolean isEmergencyEnabled();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
- field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
- field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
- field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
- field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
- field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
- }
-
- public static final class NetworkRegistrationInfo.Builder {
- ctor public NetworkRegistrationInfo.Builder();
- method @NonNull public android.telephony.NetworkRegistrationInfo build();
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
- method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
- }
-
- public abstract class NetworkService extends android.app.Service {
- ctor public NetworkService();
- method public android.os.IBinder onBind(android.content.Intent);
- method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int);
- field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService";
- }
-
- public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
- ctor public NetworkService.NetworkServiceProvider(int);
- method public abstract void close();
- method public final int getSlotIndex();
- method public final void notifyNetworkRegistrationInfoChanged();
- method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback);
- }
-
- public class NetworkServiceCallback {
- method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo);
- field public static final int RESULT_ERROR_BUSY = 3; // 0x3
- field public static final int RESULT_ERROR_FAILED = 5; // 0x5
- field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
- field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
- field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
- field public static final int RESULT_SUCCESS = 0; // 0x0
- }
-
- public interface NumberVerificationCallback {
- method public default void onCallReceived(@NonNull String);
- method public default void onVerificationFailed(int);
- field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
- field public static final int REASON_IN_ECBM = 5; // 0x5
- field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
- field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
- field public static final int REASON_TIMED_OUT = 1; // 0x1
- field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
- field public static final int REASON_UNSPECIFIED = 0; // 0x0
- }
-
- public final class PhoneNumberRange implements android.os.Parcelable {
- ctor public PhoneNumberRange(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
- method public int describeContents();
- method public boolean matches(@NonNull String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
- }
-
- public class PhoneNumberUtils {
- method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
- method public static boolean isUriNumber(@Nullable String);
- method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
- }
-
- public final class PreciseCallState implements android.os.Parcelable {
- ctor public PreciseCallState(int, int, int, int, int);
- method public int describeContents();
- method public int getBackgroundCallState();
- method public int getForegroundCallState();
- method public int getRingingCallState();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR;
- field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1
- field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4
- field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3
- field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7
- field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8
- field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2
- field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0
- field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5
- field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff
- field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6
- }
-
- public final class PreciseDataConnectionState implements android.os.Parcelable {
- method @Deprecated @NonNull public String getDataConnectionApn();
- method @Deprecated public int getDataConnectionApnTypeBitMask();
- method @Deprecated public int getDataConnectionFailCause();
- method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
- method @Deprecated public int getDataConnectionNetworkType();
- method @Deprecated public int getDataConnectionState();
- }
-
- public final class PreciseDisconnectCause {
- field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104
- field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b
- field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44
- field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39
- field public static final int BEARER_NOT_AVAIL = 58; // 0x3a
- field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41
- field public static final int BUSY = 17; // 0x11
- field public static final int CALL_BARRED = 240; // 0xf0
- field public static final int CALL_REJECTED = 21; // 0x15
- field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
- field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
- field public static final int CDMA_DROP = 1001; // 0x3e9
- field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
- field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
- field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
- field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
- field public static final int CDMA_REORDER = 1003; // 0x3eb
- field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
- field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
- field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
- field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
- field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
- field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b
- field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff
- field public static final int FACILITY_REJECTED = 29; // 0x1d
- field public static final int FDN_BLOCKED = 241; // 0xf1
- field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3
- field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2
- field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37
- field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58
- field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63
- field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f
- field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60
- field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c
- field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51
- field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65
- field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61
- field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62
- field public static final int NETWORK_DETACH = 261; // 0x105
- field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26
- field public static final int NETWORK_REJECT = 252; // 0xfc
- field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb
- field public static final int NORMAL = 16; // 0x10
- field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f
- field public static final int NOT_VALID = -1; // 0xffffffff
- field public static final int NO_ANSWER_FROM_USER = 19; // 0x13
- field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22
- field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0
- field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3
- field public static final int NO_USER_RESPONDING = 18; // 0x12
- field public static final int NO_VALID_SIM = 249; // 0xf9
- field public static final int NUMBER_CHANGED = 22; // 0x16
- field public static final int OEM_CAUSE_1 = 61441; // 0xf001
- field public static final int OEM_CAUSE_10 = 61450; // 0xf00a
- field public static final int OEM_CAUSE_11 = 61451; // 0xf00b
- field public static final int OEM_CAUSE_12 = 61452; // 0xf00c
- field public static final int OEM_CAUSE_13 = 61453; // 0xf00d
- field public static final int OEM_CAUSE_14 = 61454; // 0xf00e
- field public static final int OEM_CAUSE_15 = 61455; // 0xf00f
- field public static final int OEM_CAUSE_2 = 61442; // 0xf002
- field public static final int OEM_CAUSE_3 = 61443; // 0xf003
- field public static final int OEM_CAUSE_4 = 61444; // 0xf004
- field public static final int OEM_CAUSE_5 = 61445; // 0xf005
- field public static final int OEM_CAUSE_6 = 61446; // 0xf006
- field public static final int OEM_CAUSE_7 = 61447; // 0xf007
- field public static final int OEM_CAUSE_8 = 61448; // 0xf008
- field public static final int OEM_CAUSE_9 = 61449; // 0xf009
- field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46
- field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8
- field public static final int OUT_OF_SRV = 248; // 0xf8
- field public static final int PREEMPTION = 25; // 0x19
- field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f
- field public static final int QOS_NOT_AVAIL = 49; // 0x31
- field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd
- field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa
- field public static final int RADIO_LINK_FAILURE = 254; // 0xfe
- field public static final int RADIO_LINK_LOST = 255; // 0xff
- field public static final int RADIO_OFF = 247; // 0xf7
- field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103
- field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102
- field public static final int RADIO_SETUP_FAILURE = 257; // 0x101
- field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100
- field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66
- field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45
- field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32
- field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f
- field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f
- field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f
- field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f
- field public static final int STATUS_ENQUIRY = 30; // 0x1e
- field public static final int SWITCHING_CONGESTION = 42; // 0x2a
- field public static final int TEMPORARY_FAILURE = 41; // 0x29
- field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1
- field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57
- }
-
- public class ServiceState implements android.os.Parcelable {
- method public void fillInNotifierBundle(@NonNull android.os.Bundle);
- method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
- method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
- method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
- method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle);
- field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
- field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
- field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
- field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
- }
-
- public class SignalStrength implements android.os.Parcelable {
- ctor public SignalStrength(@NonNull android.telephony.SignalStrength);
- }
-
- public final class SmsCbCmasInfo implements android.os.Parcelable {
- ctor public SmsCbCmasInfo(int, int, int, int, int, int);
- method public int describeContents();
- method public int getCategory();
- method public int getCertainty();
- method public int getMessageClass();
- method public int getResponseType();
- method public int getSeverity();
- method public int getUrgency();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CMAS_CATEGORY_CBRNE = 10; // 0xa
- field public static final int CMAS_CATEGORY_ENV = 7; // 0x7
- field public static final int CMAS_CATEGORY_FIRE = 5; // 0x5
- field public static final int CMAS_CATEGORY_GEO = 0; // 0x0
- field public static final int CMAS_CATEGORY_HEALTH = 6; // 0x6
- field public static final int CMAS_CATEGORY_INFRA = 9; // 0x9
- field public static final int CMAS_CATEGORY_MET = 1; // 0x1
- field public static final int CMAS_CATEGORY_OTHER = 11; // 0xb
- field public static final int CMAS_CATEGORY_RESCUE = 4; // 0x4
- field public static final int CMAS_CATEGORY_SAFETY = 2; // 0x2
- field public static final int CMAS_CATEGORY_SECURITY = 3; // 0x3
- field public static final int CMAS_CATEGORY_TRANSPORT = 8; // 0x8
- field public static final int CMAS_CATEGORY_UNKNOWN = -1; // 0xffffffff
- field public static final int CMAS_CERTAINTY_LIKELY = 1; // 0x1
- field public static final int CMAS_CERTAINTY_OBSERVED = 0; // 0x0
- field public static final int CMAS_CERTAINTY_UNKNOWN = -1; // 0xffffffff
- field public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 3; // 0x3
- field public static final int CMAS_CLASS_CMAS_EXERCISE = 5; // 0x5
- field public static final int CMAS_CLASS_EXTREME_THREAT = 1; // 0x1
- field public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 6; // 0x6
- field public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0; // 0x0
- field public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 4; // 0x4
- field public static final int CMAS_CLASS_SEVERE_THREAT = 2; // 0x2
- field public static final int CMAS_CLASS_UNKNOWN = -1; // 0xffffffff
- field public static final int CMAS_RESPONSE_TYPE_ASSESS = 6; // 0x6
- field public static final int CMAS_RESPONSE_TYPE_AVOID = 5; // 0x5
- field public static final int CMAS_RESPONSE_TYPE_EVACUATE = 1; // 0x1
- field public static final int CMAS_RESPONSE_TYPE_EXECUTE = 3; // 0x3
- field public static final int CMAS_RESPONSE_TYPE_MONITOR = 4; // 0x4
- field public static final int CMAS_RESPONSE_TYPE_NONE = 7; // 0x7
- field public static final int CMAS_RESPONSE_TYPE_PREPARE = 2; // 0x2
- field public static final int CMAS_RESPONSE_TYPE_SHELTER = 0; // 0x0
- field public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; // 0xffffffff
- field public static final int CMAS_SEVERITY_EXTREME = 0; // 0x0
- field public static final int CMAS_SEVERITY_SEVERE = 1; // 0x1
- field public static final int CMAS_SEVERITY_UNKNOWN = -1; // 0xffffffff
- field public static final int CMAS_URGENCY_EXPECTED = 1; // 0x1
- field public static final int CMAS_URGENCY_IMMEDIATE = 0; // 0x0
- field public static final int CMAS_URGENCY_UNKNOWN = -1; // 0xffffffff
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbCmasInfo> CREATOR;
- }
-
- public final class SmsCbEtwsInfo implements android.os.Parcelable {
- ctor public SmsCbEtwsInfo(int, boolean, boolean, boolean, @Nullable byte[]);
- method public int describeContents();
- method @Nullable public byte[] getPrimaryNotificationSignature();
- method public long getPrimaryNotificationTimestamp();
- method public int getWarningType();
- method public boolean isEmergencyUserAlert();
- method public boolean isPopupAlert();
- method public boolean isPrimary();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbEtwsInfo> CREATOR;
- field public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0; // 0x0
- field public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 2; // 0x2
- field public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 4; // 0x4
- field public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 3; // 0x3
- field public static final int ETWS_WARNING_TYPE_TSUNAMI = 1; // 0x1
- field public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; // 0xffffffff
- }
-
- public final class SmsCbLocation implements android.os.Parcelable {
- ctor public SmsCbLocation(@NonNull String, int, int);
- method public int describeContents();
- method public int getCid();
- method public int getLac();
- method @NonNull public String getPlmn();
- method public boolean isInLocationArea(@NonNull android.telephony.SmsCbLocation);
- method public boolean isInLocationArea(@Nullable String, int, int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbLocation> CREATOR;
- }
-
- public final class SmsCbMessage implements android.os.Parcelable {
- ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, int, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int, int);
- method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
- method public int describeContents();
- method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
- method @NonNull public android.content.ContentValues getContentValues();
- method public int getDataCodingScheme();
- method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo();
- method public int getGeographicalScope();
- method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries();
- method @Nullable public String getLanguageCode();
- method @NonNull public android.telephony.SmsCbLocation getLocation();
- method public int getMaximumWaitingDuration();
- method @Nullable public String getMessageBody();
- method public int getMessageFormat();
- method public int getMessagePriority();
- method public long getReceivedTime();
- method public int getSerialNumber();
- method public int getServiceCategory();
- method public int getSlotIndex();
- method public int getSubscriptionId();
- method public boolean isCmasMessage();
- method public boolean isEmergencyMessage();
- method public boolean isEtwsMessage();
- method public boolean needGeoFencingCheck();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbMessage> CREATOR;
- field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; // 0x3
- field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0
- field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2
- field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1
- field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff
- field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1
- field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2
- field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3
- field public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; // 0x1
- field public static final int MESSAGE_PRIORITY_NORMAL = 0; // 0x0
- field public static final int MESSAGE_PRIORITY_URGENT = 2; // 0x2
- }
-
- public final class SmsManager {
- method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int);
- method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
- method public boolean disableCellBroadcastRange(int, int, int);
- method public boolean enableCellBroadcastRange(int, int, int);
- method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
- field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
- field public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; // 0x1
- field public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; // 0x2
- field public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; // 0x0
- }
-
- public class SmsMessage {
- method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
- method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long);
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0, to=255) int, @IntRange(from=1, to=255) int, @IntRange(from=1, to=255) int);
- }
-
- public class SubscriptionInfo implements android.os.Parcelable {
- method public boolean areUiccApplicationsEnabled();
- method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
- method public int getProfileClass();
- method public boolean isGroupDisabled();
- }
-
- public class SubscriptionManager {
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription();
- method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String);
- method @NonNull public int[] getActiveAndHiddenSubscriptionIdList();
- method @NonNull public int[] getActiveSubscriptionIdList();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String);
- method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int);
- method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int);
- method public void requestEmbeddedSubscriptionInfoListRefresh();
- method public void requestEmbeddedSubscriptionInfoListRefresh(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setDisplayName(@Nullable String, int, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIconTint(int, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean);
- field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
- field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
- field @Deprecated public static final int PROFILE_CLASS_DEFAULT;
- field public static final int PROFILE_CLASS_OPERATIONAL;
- field public static final int PROFILE_CLASS_PROVISIONING;
- field public static final int PROFILE_CLASS_TESTING;
- field public static final int PROFILE_CLASS_UNSET;
- field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI;
- field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
- }
-
- public class TelephonyFrameworkInitializer {
- method public static void registerServiceWrappers();
- method public static void setTelephonyServiceManager(@NonNull android.os.TelephonyServiceManager);
- }
-
- public final class TelephonyHistogram implements android.os.Parcelable {
- ctor public TelephonyHistogram(int, int, int);
- ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
- ctor public TelephonyHistogram(android.os.Parcel);
- method public void addTimeTaken(int);
- method public int describeContents();
- method public int getAverageTime();
- method public int getBucketCount();
- method public int[] getBucketCounters();
- method public int[] getBucketEndPoints();
- method public int getCategory();
- method public int getId();
- method public int getMaxTime();
- method public int getMinTime();
- method public int getSampleCount();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
- field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
- }
-
- public class TelephonyManager {
- method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
- method public int checkCarrierPrivilegesForPackage(String);
- method public int checkCarrierPrivilegesForPackageAnyPhone(String);
- method public void dial(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean);
- method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
- method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
- method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
- method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
- method public String getCdmaPrlVersion();
- method public int getCurrentPhoneType();
- method public int getCurrentPhoneType(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
- method @Deprecated public boolean getDataEnabled();
- method @Deprecated public boolean getDataEnabled(int);
- method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
- method public int getMaxNumberOfSimultaneouslyActiveSims();
- method public static long getMaxNumberVerificationTimeoutMillis();
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getMergedImsisFromGroup();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
- method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
- method public int getSimApplicationState();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimApplicationState(int);
- method public int getSimCardState();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimCardState(int);
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Locale getSimLocale();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo();
- method @Nullable public android.os.Bundle getVisualVoicemailSettings();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String);
- method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int);
- method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int);
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
- method public boolean isDataConnectivityPossible();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String);
- method public boolean needsOtaServiceProvisioning();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyUserActivity();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
- method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
- method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
- method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
- method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>);
- method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
- method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
- method public void updateServiceLocation();
- field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
- field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
- field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
- field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED";
- field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED";
- field public static final String ACTION_CARRIER_SIGNAL_RESET = "com.android.internal.telephony.CARRIER_SIGNAL_RESET";
- field public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED";
- field public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED";
- field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE";
- field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
- field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
- field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE";
- field public static final String ACTION_SERVICE_PROVIDERS_UPDATED = "android.telephony.action.SERVICE_PROVIDERS_UPDATED";
- field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS";
- field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
- field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
- field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
- field public static final int CARD_POWER_DOWN = 0; // 0x0
- field public static final int CARD_POWER_UP = 1; // 0x1
- field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
- field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
- field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
- field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
- field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
- field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
- field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
- field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto";
- field public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt";
- field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
- field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
- field public static final String EXTRA_DATA_SPN = "android.telephony.extra.DATA_SPN";
- field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
- field public static final String EXTRA_ERROR_CODE = "errorCode";
- field public static final String EXTRA_PCO_ID = "pcoId";
- field public static final String EXTRA_PCO_VALUE = "pcoValue";
- field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
- field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
- field public static final String EXTRA_PLMN = "android.telephony.extra.PLMN";
- field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
- field public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN";
- field public static final String EXTRA_SHOW_SPN = "android.telephony.extra.SHOW_SPN";
- field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
- field public static final String EXTRA_SPN = "android.telephony.extra.SPN";
- field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
- field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
- field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
- field public static final int KEY_TYPE_EPDG = 1; // 0x1
- field public static final int KEY_TYPE_WLAN = 2; // 0x2
- field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
- field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
- field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
- field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
- field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
- field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
- field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
- field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L
- field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L
- field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L
- field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L
- field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L
- field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L
- field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
- field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
- field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
- field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
- field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
- field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
- field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
- field public static final int RADIO_POWER_OFF = 0; // 0x0
- field public static final int RADIO_POWER_ON = 1; // 0x1
- field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
- field public static final int SET_CARRIER_RESTRICTION_ERROR = 2; // 0x2
- field public static final int SET_CARRIER_RESTRICTION_NOT_SUPPORTED = 1; // 0x1
- field public static final int SET_CARRIER_RESTRICTION_SUCCESS = 0; // 0x0
- field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
- field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
- field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
- field public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; // 0x4
- field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0
- field public static final int SIM_STATE_LOADED = 10; // 0xa
- field public static final int SIM_STATE_PRESENT = 11; // 0xb
- field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3
- field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1
- field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2
- field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff
- field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0
- }
-
- public final class UiccAccessRule implements android.os.Parcelable {
- ctor public UiccAccessRule(byte[], @Nullable String, long);
- method public int describeContents();
- method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
- method public int getCarrierPrivilegeStatus(android.content.pm.Signature, String);
- method public String getCertificateHexString();
- method @Nullable public String getPackageName();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
- }
-
- public class UiccSlotInfo implements android.os.Parcelable {
- ctor @Deprecated public UiccSlotInfo(boolean, boolean, String, int, int, boolean);
- method public int describeContents();
- method public String getCardId();
- method public int getCardStateInfo();
- method public boolean getIsActive();
- method public boolean getIsEuicc();
- method public boolean getIsExtendedApduSupported();
- method public int getLogicalSlotIdx();
- method public boolean isRemovable();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CARD_STATE_INFO_ABSENT = 1; // 0x1
- field public static final int CARD_STATE_INFO_ERROR = 3; // 0x3
- field public static final int CARD_STATE_INFO_PRESENT = 2; // 0x2
- field public static final int CARD_STATE_INFO_RESTRICTED = 4; // 0x4
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccSlotInfo> CREATOR;
- }
-
- public abstract class VisualVoicemailService extends android.app.Service {
- method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, String, short, String, android.app.PendingIntent);
- method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
- }
-
-}
-
-package android.telephony.cdma {
-
- public final class CdmaSmsCbProgramData implements android.os.Parcelable {
- method public int describeContents();
- method public int getCategory();
- method public int getOperation();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
- field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
- field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
- field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
- field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
- field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
- field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
- field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
- field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
- }
-
-}
-
-package android.telephony.data {
-
- public final class DataCallResponse implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
- method public int getCause();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses();
- method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses();
- method public int getId();
- method @NonNull public String getInterfaceName();
- method public int getLinkStatus();
- method @Deprecated public int getMtu();
- method public int getMtuV4();
- method public int getMtuV6();
- method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses();
- method public int getProtocolType();
- method public int getSuggestedRetryTime();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR;
- field public static final int LINK_STATUS_ACTIVE = 2; // 0x2
- field public static final int LINK_STATUS_DORMANT = 1; // 0x1
- field public static final int LINK_STATUS_INACTIVE = 0; // 0x0
- field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff
- }
-
- public static final class DataCallResponse.Builder {
- ctor public DataCallResponse.Builder();
- method @NonNull public android.telephony.data.DataCallResponse build();
- method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List<android.net.LinkAddress>);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int);
- method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int);
- method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int);
- }
-
- public final class DataProfile implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public String getApn();
- method public int getAuthType();
- method public int getBearerBitmask();
- method @Deprecated public int getMtu();
- method public int getMtuV4();
- method public int getMtuV6();
- method @Nullable public String getPassword();
- method public int getProfileId();
- method public int getProtocolType();
- method public int getRoamingProtocolType();
- method public int getSupportedApnTypesBitmask();
- method public int getType();
- method @Nullable public String getUserName();
- method public boolean isEnabled();
- method public boolean isPersistent();
- method public boolean isPreferred();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR;
- field public static final int TYPE_3GPP = 1; // 0x1
- field public static final int TYPE_3GPP2 = 2; // 0x2
- field public static final int TYPE_COMMON = 0; // 0x0
- }
-
- public static final class DataProfile.Builder {
- ctor public DataProfile.Builder();
- method @NonNull public android.telephony.data.DataProfile build();
- method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean);
- method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String);
- method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int);
- method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String);
- method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean);
- method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean);
- method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setType(int);
- method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String);
- }
-
- public abstract class DataService extends android.app.Service {
- ctor public DataService();
- method public android.os.IBinder onBind(android.content.Intent);
- method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int);
- field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
- field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
- field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2
- field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0
- field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService";
- }
-
- public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable {
- ctor public DataService.DataServiceProvider(int);
- method public abstract void close();
- method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
- method public final int getSlotIndex();
- method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
- method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback);
- method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback);
- method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback);
- method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback);
- }
-
- public class DataServiceCallback {
- method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
- method public void onDeactivateDataCallComplete(int);
- method public void onRequestDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>);
- method public void onSetDataProfileComplete(int);
- method public void onSetInitialAttachApnComplete(int);
- method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse);
- field public static final int RESULT_ERROR_BUSY = 3; // 0x3
- field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
- field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
- field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
- field public static final int RESULT_SUCCESS = 0; // 0x0
- }
-
- public abstract class QualifiedNetworksService extends android.app.Service {
- ctor public QualifiedNetworksService();
- method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
- field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService";
- }
-
- public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable {
- ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int);
- method public abstract void close();
- method public final int getSlotIndex();
- method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>);
- }
-
-}
-
-package android.telephony.euicc {
-
- public final class DownloadableSubscription implements android.os.Parcelable {
- method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
- method @Nullable public String getCarrierName();
- }
-
- public static final class DownloadableSubscription.Builder {
- ctor public DownloadableSubscription.Builder();
- ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription);
- method public android.telephony.euicc.DownloadableSubscription build();
- method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>);
- method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(String);
- method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(String);
- method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(String);
- }
-
- public class EuiccCardManager {
- method public void authenticateServer(String, String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void cancelSession(String, byte[], @android.telephony.euicc.EuiccCardManager.CancelReason int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void deleteProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void disableProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void listNotifications(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
- method public void loadBoundProfilePackage(String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void prepareDownload(String, @Nullable byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void removeNotificationFromList(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void requestAllProfiles(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>);
- method public void requestDefaultSmdpAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
- method public void requestEuiccChallenge(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void requestEuiccInfo1(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void requestEuiccInfo2(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
- method public void requestProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
- method public void requestRulesAuthTable(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>);
- method public void requestSmdsAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
- method public void resetMemory(String, @android.telephony.euicc.EuiccCardManager.ResetOption int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void retrieveNotification(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>);
- method public void retrieveNotificationList(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
- method public void setDefaultSmdpAddress(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void setNickname(String, String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
- method public void switchToProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
- field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0
- field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1
- field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3
- field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2
- field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
- field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
- field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
- field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd
- field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe
- field public static final int RESULT_OK = 0; // 0x0
- field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
- }
-
- @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason {
- }
-
- @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption {
- }
-
- public static interface EuiccCardManager.ResultCallback<T> {
- method public void onComplete(int, T);
- }
-
- public class EuiccManager {
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle);
- method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus();
- method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getSupportedCountries();
- method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getUnsupportedCountries();
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public boolean isSupportedCountry(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setSupportedCountries(@NonNull java.util.List<java.lang.String>);
- method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setUnsupportedCountries(@NonNull java.util.List<java.lang.String>);
- field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED";
- field @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public static final String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED";
- field public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
- field public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
- field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED";
- field public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; // 0x4
- field public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; // 0x2
- field public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; // 0x1
- field public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; // 0x3
- field public static final int EUICC_OTA_FAILED = 2; // 0x2
- field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1
- field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
- field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
- field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
- field public static final String EXTRA_ACTIVATION_TYPE = "android.telephony.euicc.extra.ACTIVATION_TYPE";
- field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
- field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION";
- field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION";
- field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
- field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
- field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID";
- field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
- }
-
- @IntDef(prefix={"EUICC_OTA_"}, value={android.telephony.euicc.EuiccManager.EUICC_OTA_IN_PROGRESS, android.telephony.euicc.EuiccManager.EUICC_OTA_FAILED, android.telephony.euicc.EuiccManager.EUICC_OTA_SUCCEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_NOT_NEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccManager.OtaStatus {
- }
-
- public final class EuiccNotification implements android.os.Parcelable {
- ctor public EuiccNotification(int, String, @android.telephony.euicc.EuiccNotification.Event int, @Nullable byte[]);
- method public int describeContents();
- method @Nullable public byte[] getData();
- method @android.telephony.euicc.EuiccNotification.Event public int getEvent();
- method public int getSeq();
- method public String getTargetAddr();
- method public void writeToParcel(android.os.Parcel, int);
- field @android.telephony.euicc.EuiccNotification.Event public static final int ALL_EVENTS = 15; // 0xf
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR;
- field public static final int EVENT_DELETE = 8; // 0x8
- field public static final int EVENT_DISABLE = 4; // 0x4
- field public static final int EVENT_ENABLE = 2; // 0x2
- field public static final int EVENT_INSTALL = 1; // 0x1
- }
-
- @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event {
- }
-
- public final class EuiccRulesAuthTable implements android.os.Parcelable {
- method public int describeContents();
- method public int findIndex(@android.service.euicc.EuiccProfileInfo.PolicyRule int, android.service.carrier.CarrierIdentifier);
- method public boolean hasPolicyRuleFlag(int, @android.telephony.euicc.EuiccRulesAuthTable.PolicyRuleFlag int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR;
- field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1
- }
-
- public static final class EuiccRulesAuthTable.Builder {
- ctor public EuiccRulesAuthTable.Builder(int);
- method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int);
- method public android.telephony.euicc.EuiccRulesAuthTable build();
- }
-
- @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag {
- }
-
-}
-
-package android.telephony.ims {
-
- public final class ImsCallForwardInfo implements android.os.Parcelable {
- ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
- method public int describeContents();
- method public int getCondition();
- method public String getNumber();
- method public int getServiceClass();
- method public int getStatus();
- method public int getTimeSeconds();
- method public int getToA();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CDIV_CF_REASON_ALL = 4; // 0x4
- field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5
- field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1
- field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6
- field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3
- field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2
- field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR;
- field public static final int STATUS_ACTIVE = 1; // 0x1
- field public static final int STATUS_NOT_ACTIVE = 0; // 0x0
- field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91
- field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81
- }
-
- public final class ImsCallProfile implements android.os.Parcelable {
- ctor public ImsCallProfile();
- ctor public ImsCallProfile(int, int);
- ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
- method public int describeContents();
- method public String getCallExtra(String);
- method public String getCallExtra(String, String);
- method public boolean getCallExtraBoolean(String);
- method public boolean getCallExtraBoolean(String, boolean);
- method public int getCallExtraInt(String);
- method public int getCallExtraInt(String, int);
- method public android.os.Bundle getCallExtras();
- method public int getCallType();
- method public static int getCallTypeFromVideoState(int);
- method public int getCallerNumberVerificationStatus();
- method public int getEmergencyCallRouting();
- method public int getEmergencyServiceCategories();
- method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
- method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
- method @NonNull public android.os.Bundle getProprietaryCallExtras();
- method public int getRestrictCause();
- method public int getServiceType();
- method public static int getVideoStateFromCallType(int);
- method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile);
- method public boolean hasKnownUserIntentEmergency();
- method public boolean isEmergencyCallTesting();
- method public boolean isVideoCall();
- method public boolean isVideoPaused();
- method public static int presentationToOir(int);
- method public void setCallExtra(String, String);
- method public void setCallExtraBoolean(String, boolean);
- method public void setCallExtraInt(String, int);
- method public void setCallRestrictCause(int);
- method public void setCallerNumberVerificationStatus(int);
- method public void setEmergencyCallRouting(int);
- method public void setEmergencyCallTesting(boolean);
- method public void setEmergencyServiceCategories(int);
- method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
- method public void setHasKnownUserIntentEmergency(boolean);
- method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
- method public void updateCallType(android.telephony.ims.ImsCallProfile);
- method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2
- field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
- field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
- field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
- field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
- field public static final int CALL_TYPE_VOICE = 2; // 0x2
- field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
- field public static final int CALL_TYPE_VS = 8; // 0x8
- field public static final int CALL_TYPE_VS_RX = 10; // 0xa
- field public static final int CALL_TYPE_VS_TX = 9; // 0x9
- field public static final int CALL_TYPE_VT = 4; // 0x4
- field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7
- field public static final int CALL_TYPE_VT_RX = 6; // 0x6
- field public static final int CALL_TYPE_VT_TX = 5; // 0x5
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR;
- field public static final int DIALSTRING_NORMAL = 0; // 0x0
- field public static final int DIALSTRING_SS_CONF = 1; // 0x1
- field public static final int DIALSTRING_USSD = 2; // 0x2
- field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
- field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
- field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
- field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE";
- field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
- field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
- field public static final String EXTRA_CNA = "cna";
- field public static final String EXTRA_CNAP = "cnap";
- field public static final String EXTRA_CODEC = "Codec";
- field public static final String EXTRA_DIALSTRING = "dialstring";
- field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
- field public static final String EXTRA_EMERGENCY_CALL = "e_call";
- field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER";
- field public static final String EXTRA_IS_CALL_PULL = "CallPull";
- field public static final String EXTRA_OI = "oi";
- field public static final String EXTRA_OIR = "oir";
- field public static final String EXTRA_REMOTE_URI = "remote_uri";
- field public static final String EXTRA_USSD = "ussd";
- field public static final int OIR_DEFAULT = 0; // 0x0
- field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2
- field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
- field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
- field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
- field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
- field public static final int SERVICE_TYPE_NONE = 0; // 0x0
- field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
- field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
- field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
- field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
- }
-
- public class ImsCallSessionListener {
- method public void callQualityChanged(@NonNull android.telephony.CallQuality);
- method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
- method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
- method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
- method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
- method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionInitiated(android.telephony.ims.ImsCallProfile);
- method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionInviteParticipantsRequestDelivered();
- method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
- method @Deprecated public void callSessionMayHandover(int, int);
- method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
- method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
- method public void callSessionMultipartyStateChanged(boolean);
- method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile);
- method public void callSessionRemoveParticipantsRequestDelivered();
- method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
- method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
- method public void callSessionRttMessageReceived(String);
- method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionRttModifyResponseReceived(int);
- method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification);
- method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo);
- method public void callSessionTtyModeReceived(int);
- method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo);
- method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile);
- method public void callSessionUpdated(android.telephony.ims.ImsCallProfile);
- method public void callSessionUssdMessageReceived(int, String);
- method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo);
- method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo);
- method public void onMayHandover(int, int);
- }
-
- public final class ImsConferenceState implements android.os.Parcelable {
- method public int describeContents();
- method public static int getConnectionStateForStatus(String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR;
- field public static final String DISPLAY_TEXT = "display-text";
- field public static final String ENDPOINT = "endpoint";
- field public static final String SIP_STATUS_CODE = "sipstatuscode";
- field public static final String STATUS = "status";
- field public static final String STATUS_ALERTING = "alerting";
- field public static final String STATUS_CONNECTED = "connected";
- field public static final String STATUS_CONNECT_FAIL = "connect-fail";
- field public static final String STATUS_DIALING_IN = "dialing-in";
- field public static final String STATUS_DIALING_OUT = "dialing-out";
- field public static final String STATUS_DISCONNECTED = "disconnected";
- field public static final String STATUS_DISCONNECTING = "disconnecting";
- field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
- field public static final String STATUS_ON_HOLD = "on-hold";
- field public static final String STATUS_PENDING = "pending";
- field public static final String STATUS_SEND_ONLY = "sendonly";
- field public static final String STATUS_SEND_RECV = "sendrecv";
- field public static final String USER = "user";
- field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants;
- }
-
- public final class ImsException extends java.lang.Exception {
- ctor public ImsException(@Nullable String);
- ctor public ImsException(@Nullable String, int);
- ctor public ImsException(@Nullable String, int, @Nullable Throwable);
- }
-
- public final class ImsExternalCallState implements android.os.Parcelable {
- ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
- method public int describeContents();
- method @NonNull public android.net.Uri getAddress();
- method public int getCallId();
- method public int getCallState();
- method public int getCallType();
- method @Nullable public android.net.Uri getLocalAddress();
- method public boolean isCallHeld();
- method public boolean isCallPullable();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALL_STATE_CONFIRMED = 1; // 0x1
- field public static final int CALL_STATE_TERMINATED = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
- }
-
- public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
- method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(int, int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(int, int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
- }
-
- @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
- ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
- }
-
- public final class ImsReasonInfo implements android.os.Parcelable {
- field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
- }
-
- public class ImsService extends android.app.Service {
- ctor public ImsService();
- method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
- method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
- method public void disableIms(int);
- method public void enableIms(int);
- method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
- method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
- method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
- method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
- method public void readyForFeatureCreation();
- }
-
- public final class ImsSsData implements android.os.Parcelable {
- ctor public ImsSsData(int, int, int, int, int);
- method public int describeContents();
- method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
- method public int getRequestType();
- method public int getResult();
- method public int getServiceClass();
- method public int getServiceType();
- method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
- method public int getTeleserviceType();
- method public boolean isTypeBarring();
- method public boolean isTypeCf();
- method public boolean isTypeClip();
- method public boolean isTypeClir();
- method public boolean isTypeColp();
- method public boolean isTypeColr();
- method public boolean isTypeCw();
- method public boolean isTypeIcb();
- method public boolean isTypeInterrogation();
- method public boolean isTypeUnConditional();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR;
- field public static final int RESULT_SUCCESS = 0; // 0x0
- field public static final int SERVICE_CLASS_DATA = 2; // 0x2
- field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20
- field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10
- field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40
- field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80
- field public static final int SERVICE_CLASS_FAX = 4; // 0x4
- field public static final int SERVICE_CLASS_NONE = 0; // 0x0
- field public static final int SERVICE_CLASS_SMS = 8; // 0x8
- field public static final int SERVICE_CLASS_VOICE = 1; // 0x1
- field public static final int SS_ACTIVATION = 0; // 0x0
- field public static final int SS_ALL_BARRING = 18; // 0x12
- field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3
- field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5
- field public static final int SS_ALL_TELESEVICES = 1; // 0x1
- field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0
- field public static final int SS_BAIC = 16; // 0x10
- field public static final int SS_BAIC_ROAMING = 17; // 0x11
- field public static final int SS_BAOC = 13; // 0xd
- field public static final int SS_BAOIC = 14; // 0xe
- field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf
- field public static final int SS_CFU = 0; // 0x0
- field public static final int SS_CFUT = 6; // 0x6
- field public static final int SS_CF_ALL = 4; // 0x4
- field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5
- field public static final int SS_CF_BUSY = 1; // 0x1
- field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3
- field public static final int SS_CF_NO_REPLY = 2; // 0x2
- field public static final int SS_CLIP = 7; // 0x7
- field public static final int SS_CLIR = 8; // 0x8
- field public static final int SS_CNAP = 11; // 0xb
- field public static final int SS_COLP = 9; // 0x9
- field public static final int SS_COLR = 10; // 0xa
- field public static final int SS_DEACTIVATION = 1; // 0x1
- field public static final int SS_ERASURE = 4; // 0x4
- field public static final int SS_INCOMING_BARRING = 20; // 0x14
- field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16
- field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15
- field public static final int SS_INTERROGATION = 2; // 0x2
- field public static final int SS_OUTGOING_BARRING = 19; // 0x13
- field public static final int SS_REGISTRATION = 3; // 0x3
- field public static final int SS_SMS_SERVICES = 4; // 0x4
- field public static final int SS_TELEPHONY = 2; // 0x2
- field public static final int SS_WAIT = 12; // 0xc
- }
-
- public static final class ImsSsData.Builder {
- ctor public ImsSsData.Builder(int, int, int, int, int);
- method @NonNull public android.telephony.ims.ImsSsData build();
- method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
- method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
- }
-
- public final class ImsSsInfo implements android.os.Parcelable {
- ctor @Deprecated public ImsSsInfo(int, @Nullable String);
- method public int describeContents();
- method public int getClirInterrogationStatus();
- method public int getClirOutgoingState();
- method @Deprecated public String getIcbNum();
- method @Nullable public String getIncomingCommunicationBarringNumber();
- method public int getProvisionStatus();
- method public int getStatus();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0
- field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1
- field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2
- field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0
- field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1
- field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4
- field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3
- field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
- field public static final int DISABLED = 0; // 0x0
- field public static final int ENABLED = 1; // 0x1
- field public static final int NOT_REGISTERED = -1; // 0xffffffff
- field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
- field public static final int SERVICE_PROVISIONED = 1; // 0x1
- field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
- }
-
- public static final class ImsSsInfo.Builder {
- ctor public ImsSsInfo.Builder(int);
- method @NonNull public android.telephony.ims.ImsSsInfo build();
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String);
- method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
- }
-
- public final class ImsStreamMediaProfile implements android.os.Parcelable {
- ctor public ImsStreamMediaProfile(int, int, int, int, int);
- method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
- method public int describeContents();
- method public int getAudioDirection();
- method public int getAudioQuality();
- method public int getRttMode();
- method public int getVideoDirection();
- method public int getVideoQuality();
- method public boolean isReceivingRttAudio();
- method public boolean isRttCall();
- method public void setReceivingRttAudio(boolean);
- method public void setRttMode(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
- field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2
- field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4
- field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5
- field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7
- field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6
- field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14
- field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11
- field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13
- field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12
- field public static final int AUDIO_QUALITY_G711A = 13; // 0xd
- field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf
- field public static final int AUDIO_QUALITY_G711U = 11; // 0xb
- field public static final int AUDIO_QUALITY_G722 = 14; // 0xe
- field public static final int AUDIO_QUALITY_G723 = 12; // 0xc
- field public static final int AUDIO_QUALITY_G729 = 16; // 0x10
- field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8
- field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9
- field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa
- field public static final int AUDIO_QUALITY_NONE = 0; // 0x0
- field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR;
- field public static final int DIRECTION_INACTIVE = 0; // 0x0
- field public static final int DIRECTION_INVALID = -1; // 0xffffffff
- field public static final int DIRECTION_RECEIVE = 1; // 0x1
- field public static final int DIRECTION_SEND = 2; // 0x2
- field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3
- field public static final int RTT_MODE_DISABLED = 0; // 0x0
- field public static final int RTT_MODE_FULL = 1; // 0x1
- field public static final int VIDEO_QUALITY_NONE = 0; // 0x0
- field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1
- field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2
- field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4
- field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8
- field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10
- }
-
- public final class ImsSuppServiceNotification implements android.os.Parcelable {
- ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR;
- field public final int code;
- field public final String[] history;
- field public final int index;
- field public final int notificationType;
- field public final String number;
- field public final int type;
- }
-
- public class ImsUtListener {
- method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo);
- method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData);
- method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]);
- method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]);
- method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]);
- method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle);
- method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUtConfigurationUpdated(int);
- field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir";
- field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
- }
-
- public abstract class ImsVideoCallProvider {
- ctor public ImsVideoCallProvider();
- method public void changeCallDataUsage(long);
- method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
- method public void changePeerDimensions(int, int);
- method public void changeVideoQuality(int);
- method public void handleCallSessionEvent(int);
- method public abstract void onRequestCallDataUsage();
- method public abstract void onRequestCameraCapabilities();
- method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile);
- method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile);
- method public abstract void onSetCamera(String);
- method public void onSetCamera(String, int);
- method public abstract void onSetDeviceOrientation(int);
- method public abstract void onSetDisplaySurface(android.view.Surface);
- method public abstract void onSetPauseImage(android.net.Uri);
- method public abstract void onSetPreviewSurface(android.view.Surface);
- method public abstract void onSetZoom(float);
- method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
- method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
- }
-
- public class ProvisioningManager {
- method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int);
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
- field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
- field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
- field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
- field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
- field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
- field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
- }
-
- public static class ProvisioningManager.Callback {
- ctor public ProvisioningManager.Callback();
- method public void onProvisioningIntChanged(int, int);
- method public void onProvisioningStringChanged(int, @NonNull String);
- }
-
- public class RcsUceAdapter {
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
- }
-
-}
-
-package android.telephony.ims.feature {
-
- public final class CapabilityChangeRequest implements android.os.Parcelable {
- method public void addCapabilitiesToDisableForTech(int, int);
- method public void addCapabilitiesToEnableForTech(int, int);
- method public int describeContents();
- method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable();
- method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR;
- }
-
- public static class CapabilityChangeRequest.CapabilityPair {
- ctor public CapabilityChangeRequest.CapabilityPair(int, int);
- method public int getCapability();
- method public int getRadioTech();
- }
-
- public abstract class ImsFeature {
- ctor public ImsFeature();
- method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method public int getFeatureState();
- method public final int getSlotIndex();
- method public abstract void onFeatureReady();
- method public abstract void onFeatureRemoved();
- method public final void setFeatureState(int);
- field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff
- field public static final int CAPABILITY_SUCCESS = 0; // 0x0
- field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0
- field public static final int FEATURE_MMTEL = 1; // 0x1
- field public static final int FEATURE_RCS = 2; // 0x2
- field public static final int STATE_INITIALIZING = 1; // 0x1
- field public static final int STATE_READY = 2; // 0x2
- field public static final int STATE_UNAVAILABLE = 0; // 0x0
- }
-
- @Deprecated public static class ImsFeature.Capabilities {
- field @Deprecated protected int mCapabilities;
- }
-
- protected static class ImsFeature.CapabilityCallbackProxy {
- method public void onChangeCapabilityConfigurationError(int, int, int);
- }
-
- public class MmTelFeature extends android.telephony.ims.feature.ImsFeature {
- ctor public MmTelFeature();
- method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int);
- method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile);
- method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm();
- method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint();
- method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation();
- method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt();
- method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
- method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle);
- method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo);
- method public final void notifyVoiceMessageCountUpdate(int);
- method public void onFeatureReady();
- method public void onFeatureRemoved();
- method public boolean queryCapabilityConfiguration(int, int);
- method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
- method public void setUiTtyMode(int, @Nullable android.os.Message);
- method public int shouldProcessCall(@NonNull String[]);
- field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
- field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
- field public static final int PROCESS_CALL_CSFB = 1; // 0x1
- field public static final int PROCESS_CALL_IMS = 0; // 0x0
- }
-
- public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
- ctor public MmTelFeature.MmTelCapabilities();
- ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
- ctor public MmTelFeature.MmTelCapabilities(int);
- method public final void addCapabilities(int);
- method public final boolean isCapable(int);
- method public final void removeCapabilities(int);
- }
-
- public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
- ctor public RcsFeature();
- method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
- method public void onFeatureReady();
- method public void onFeatureRemoved();
- }
-
-}
-
-package android.telephony.ims.stub {
-
- public class ImsCallSessionImplBase implements java.lang.AutoCloseable {
- ctor public ImsCallSessionImplBase();
- method public void accept(int, android.telephony.ims.ImsStreamMediaProfile);
- method public void close();
- method public void deflect(String);
- method public void extendToConference(String[]);
- method public String getCallId();
- method public android.telephony.ims.ImsCallProfile getCallProfile();
- method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider();
- method public android.telephony.ims.ImsCallProfile getLocalCallProfile();
- method public String getProperty(String);
- method public android.telephony.ims.ImsCallProfile getRemoteCallProfile();
- method public int getState();
- method public void hold(android.telephony.ims.ImsStreamMediaProfile);
- method public void inviteParticipants(String[]);
- method public boolean isInCall();
- method public boolean isMultiparty();
- method public void merge();
- method public void reject(int);
- method public void removeParticipants(String[]);
- method public void resume(android.telephony.ims.ImsStreamMediaProfile);
- method public void sendDtmf(char, android.os.Message);
- method public void sendRttMessage(String);
- method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
- method public void sendRttModifyResponse(boolean);
- method public void sendUssd(String);
- method public void setListener(android.telephony.ims.ImsCallSessionListener);
- method public void setMute(boolean);
- method public void start(String, android.telephony.ims.ImsCallProfile);
- method public void startConference(String[], android.telephony.ims.ImsCallProfile);
- method public void startDtmf(char);
- method public void stopDtmf();
- method public void terminate(int);
- method public void update(int, android.telephony.ims.ImsStreamMediaProfile);
- field public static final int USSD_MODE_NOTIFY = 0; // 0x0
- field public static final int USSD_MODE_REQUEST = 1; // 0x1
- }
-
- public static class ImsCallSessionImplBase.State {
- method public static String toString(int);
- field public static final int ESTABLISHED = 4; // 0x4
- field public static final int ESTABLISHING = 3; // 0x3
- field public static final int IDLE = 0; // 0x0
- field public static final int INITIATED = 1; // 0x1
- field public static final int INVALID = -1; // 0xffffffff
- field public static final int NEGOTIATING = 2; // 0x2
- field public static final int REESTABLISHING = 6; // 0x6
- field public static final int RENEGOTIATING = 5; // 0x5
- field public static final int TERMINATED = 8; // 0x8
- field public static final int TERMINATING = 7; // 0x7
- }
-
- public class ImsConfigImplBase {
- ctor public ImsConfigImplBase();
- method public int getConfigInt(int);
- method public String getConfigString(int);
- method public final void notifyProvisionedValueChanged(int, int);
- method public final void notifyProvisionedValueChanged(int, String);
- method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
- method public int setConfig(int, int);
- method public int setConfig(int, String);
- field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
- field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
- field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
- }
-
- public class ImsEcbmImplBase {
- ctor public ImsEcbmImplBase();
- method public final void enteredEcbm();
- method public void exitEmergencyCallbackMode();
- method public final void exitedEcbm();
- }
-
- public final class ImsFeatureConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR;
- }
-
- public static class ImsFeatureConfiguration.Builder {
- ctor public ImsFeatureConfiguration.Builder();
- method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int);
- method public android.telephony.ims.stub.ImsFeatureConfiguration build();
- }
-
- public static final class ImsFeatureConfiguration.FeatureSlotPair {
- ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int);
- field public final int featureType;
- field public final int slotId;
- }
-
- public class ImsMultiEndpointImplBase {
- ctor public ImsMultiEndpointImplBase();
- method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>);
- method public void requestImsExternalCallStateInfo();
- }
-
- public class ImsRegistrationImplBase {
- ctor public ImsRegistrationImplBase();
- method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
- method public final void onRegistered(int);
- method public final void onRegistering(int);
- method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
- method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
- field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
- field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
- field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
- }
-
- public class ImsSmsImplBase {
- ctor public ImsSmsImplBase();
- method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
- method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);
- method public String getSmsFormat();
- method public void onReady();
- method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException;
- method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException;
- method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException;
- method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException;
- method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException;
- method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException;
- method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]);
- field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
- field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
- field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
- field public static final int DELIVER_STATUS_OK = 1; // 0x1
- field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff
- field public static final int SEND_STATUS_ERROR = 2; // 0x2
- field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
- field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
- field public static final int SEND_STATUS_OK = 1; // 0x1
- field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
- field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
- }
-
- public class ImsUtImplBase {
- ctor public ImsUtImplBase();
- method public void close();
- method public int queryCallBarring(int);
- method public int queryCallBarringForServiceClass(int, int);
- method public int queryCallForward(int, String);
- method public int queryCallWaiting();
- method public int queryClip();
- method public int queryClir();
- method public int queryColp();
- method public int queryColr();
- method public void setListener(android.telephony.ims.ImsUtListener);
- method public int transact(android.os.Bundle);
- method public int updateCallBarring(int, int, String[]);
- method public int updateCallBarringForServiceClass(int, int, String[], int);
- method public int updateCallForward(int, int, String, int, int);
- method public int updateCallWaiting(boolean, int);
- method public int updateClip(boolean);
- method public int updateClir(int);
- method public int updateColp(boolean);
- method public int updateColr(int);
- }
-
-}
-
-package android.telephony.mbms {
-
- public static class DownloadRequest.Builder {
- method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String);
- }
-
- public final class FileInfo implements android.os.Parcelable {
- ctor public FileInfo(android.net.Uri, String);
- }
-
- public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
- ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
- }
-
- public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
- field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6
- field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3
- field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4
- field public static final int RESULT_INVALID_ACTION = 1; // 0x1
- field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2
- field public static final int RESULT_OK = 0; // 0x0
- field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5
- }
-
- public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
- ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date);
- }
-
- public final class UriPathPair implements android.os.Parcelable {
- method public int describeContents();
- method public android.net.Uri getContentUri();
- method public android.net.Uri getFilePathUri();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
- }
-
-}
-
-package android.telephony.mbms.vendor {
-
- public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
- ctor public MbmsDownloadServiceBase();
- method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
- method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
- method public android.os.IBinder asBinder();
- method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public void dispose(int) throws android.os.RemoteException;
- method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
- method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
- method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
- method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
- method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
- method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
- method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException;
- }
-
- public class MbmsGroupCallServiceBase extends android.app.Service {
- ctor public MbmsGroupCallServiceBase();
- method public void dispose(int) throws android.os.RemoteException;
- method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public android.os.IBinder onBind(android.content.Intent);
- method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback);
- method public void stopGroupCall(int, long);
- method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>);
- }
-
- public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface {
- ctor public MbmsStreamingServiceBase();
- method public android.os.IBinder asBinder();
- method public void dispose(int) throws android.os.RemoteException;
- method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException;
- method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
- method public void onAppCallbackDied(int, int);
- method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
- method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
- method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
- method public void stopStreaming(int, String) throws android.os.RemoteException;
- }
-
- public class VendorUtils {
- ctor public VendorUtils();
- method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String);
- field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
- field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
- field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
- field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
- field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
- field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
- field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
- field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
- field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
- field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
- field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
- field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
- }
-
-}
-
diff --git a/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java b/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java
new file mode 100644
index 000000000000..6c6375586225
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Telephony;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * This class provides utility functions related to CellBroadcast.
+ */
+public class CellBroadcastUtils {
+ private static final String TAG = "CellBroadcastUtils";
+ private static final boolean VDBG = false;
+
+ /**
+ * Utility method to query the default CBR's package name.
+ */
+ public static String getDefaultCellBroadcastReceiverPackageName(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ ResolveInfo resolveInfo = packageManager.resolveActivity(
+ new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION),
+ PackageManager.MATCH_SYSTEM_ONLY);
+ String packageName;
+
+ if (resolveInfo == null) {
+ Log.e(TAG, "getDefaultCellBroadcastReceiverPackageName: no package found");
+ return null;
+ }
+
+ packageName = resolveInfo.activityInfo.applicationInfo.packageName;
+
+ if (VDBG) {
+ Log.d(TAG, "getDefaultCellBroadcastReceiverPackageName: found package: " + packageName);
+ }
+
+ if (TextUtils.isEmpty(packageName) || packageManager.checkPermission(
+ android.Manifest.permission.READ_CELL_BROADCASTS, packageName)
+ == PackageManager.PERMISSION_DENIED) {
+ Log.e(TAG, "getDefaultCellBroadcastReceiverPackageName: returning null; "
+ + "permission check failed for : " + packageName);
+ return null;
+ }
+
+ return packageName;
+ }
+}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 726d250c49d0..4d15a93c2dbe 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2512,6 +2512,16 @@ public class CarrierConfigManager {
"parameters_use_for_5g_nr_signal_bar_int";
/**
+ * There are two signal strengths, NR and LTE signal strength, during NR (non-standalone).
+ * Boolean indicating whether to use LTE signal strength as primary during NR (non-standalone).
+ * By default this value is true.
+ *
+ * @hide
+ */
+ public static final String KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL =
+ "signal_strength_nr_nsa_use_lte_as_primary_bool";
+
+ /**
* String array of default bandwidth values per network type.
* The entries should be of form "network_name:downstream,upstream", with values in Kbps.
* @hide
@@ -3015,19 +3025,95 @@ public class CarrierConfigManager {
public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
/**
- * Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is
- * disabled.
+ * This configuration allows the system UI to determine how long to continue to display 5G icons
+ * when the device switches between different 5G scenarios.
*
- * System UI will show the 5G icon and start a timer with the timeout from this config when the
- * device connects to a 5G cell. System UI stops displaying 5G icon when both the device
- * disconnects from 5G cell and the timer is expired.
+ * There are seven 5G scenarios:
+ * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using
+ * millimeter wave.
+ * 2. connected: device currently connected to 5G cell as the secondary cell but not using
+ * millimeter wave.
+ * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in IDLE state.
+ * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in CONNECTED state.
+ * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a
+ * 5G cell as a secondary cell) but the use of 5G is restricted.
+ * 6. legacy: device is not camped on a network that has 5G capability
+ * 7. any: any of the above scenarios
+ *
+ * The configured string contains various timer rules separated by a semicolon.
+ * Each rule will have three items: prior 5G scenario, current 5G scenario, and grace period
+ * in seconds before changing the icon. When the 5G state changes from the prior to the current
+ * 5G scenario, the system UI will continue to show the icon for the prior 5G scenario (defined
+ * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace
+ * period. If the prior 5G scenario is reestablished, the timer will reset and start again if
+ * the UE changes 5G scenarios again. Defined states (5G scenarios #1-5) take precedence over
+ * 'any' (5G scenario #6), and unspecified transitions have a default grace period of 0.
+ * The order of rules in the configuration determines the priority (the first applicable timer
+ * rule will be used).
+ *
+ * Here is an example: "connected_mmwave,connected,30;connected_mmwave,any,10;connected,any,10"
+ * This configuration defines 3 timers:
+ * 1. When UE goes from 'connected_mmwave' to 'connected', system UI will continue to display
+ * the 5G icon for 'connected_mmwave' for 30 seconds.
+ * 2. When UE goes from 'connected_mmwave' to any other state (except for connected, since
+ * rule 1 would be used instead), system UI will continue to display the 5G icon for
+ * 'connected_mmwave' for 10 seconds.
+ * 3. When UE goes from 'connected' to any other state, system UI will continue to display the
+ * 5G icon for 'connected' for 10 seconds.
*
- * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next
- * lost. Allows us to momentarily lose 5G without blinking the icon.
* @hide
*/
- public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT =
- "5g_icon_display_grace_period_sec_int";
+ public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING =
+ "5g_icon_display_grace_period_string";
+
+ /**
+ * This configuration extends {@link #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING} to allow the
+ * system UI to continue displaying 5G icons after the initial timer expires.
+ *
+ * There are seven 5G scenarios:
+ * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using
+ * millimeter wave.
+ * 2. connected: device currently connected to 5G cell as the secondary cell but not using
+ * millimeter wave.
+ * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in IDLE state.
+ * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in CONNECTED state.
+ * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a
+ * 5G cell as a secondary cell) but the use of 5G is restricted.
+ * 6. legacy: device is not camped on a network that has 5G capability
+ * 7. any: any of the above scenarios
+ *
+ * The configured string contains various timer rules separated by a semicolon.
+ * Each rule will have three items: primary 5G scenario, secondary 5G scenario, and
+ * grace period in seconds before changing the icon. When the timer for the primary 5G timer
+ * expires, the system UI will continue to show the icon for the primary 5G scenario (defined
+ * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace
+ * period. If the primary 5G scenario is reestablished, the timers will reset and the system UI
+ * will continue to display the icon for the primary 5G scenario without interruption. If the
+ * secondary 5G scenario is lost, the timer will reset and the icon will reflect the true state.
+ * Defined states (5G scenarios #1-5) take precedence over 'any' (5G scenario #6), and
+ * unspecified transitions have a default grace period of 0. The order of rules in the
+ * configuration determines the priority (the first applicable timer rule will be used).
+ *
+ * Here is an example: "connected,not_restricted_rrc_idle,30"
+ * This configuration defines a secondary timer that extends the primary 'connected' timer.
+ * When the primary 'connected' timer expires while the UE is in the 'not_restricted_rrc_idle'
+ * 5G state, system UI will continue to display the 5G icon for 'connected' for 30 seconds.
+ * If the 5G state returns to 'connected', the timer will be reset without change to the icon,
+ * and if the 5G state changes to neither 'connected' not 'not_restricted_rrc_idle', the icon
+ * will change to reflect the true state.
+ *
+ * @hide
+ */
+ public static final String KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING =
+ "5g_icon_display_secondary_grace_period_string";
/**
* Controls time in milliseconds until DcTracker reevaluates 5G connection state.
@@ -3058,6 +3144,38 @@ public class CarrierConfigManager {
public static final String KEY_UNMETERED_NR_NSA_SUB6_BOOL = "unmetered_nr_nsa_sub6_bool";
/**
+ * Whether NR (non-standalone) should be unmetered when the device is roaming.
+ * If false, then the values for {@link #KEY_UNMETERED_NR_NSA_BOOL},
+ * {@link #KEY_UNMETERED_NR_NSA_MMWAVE_BOOL}, {@link #KEY_UNMETERED_NR_NSA_SUB6_BOOL},
+ * and unmetered {@link SubscriptionPlan} will be ignored.
+ * @hide
+ */
+ public static final String KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL =
+ "unmetered_nr_nsa_when_roaming_bool";
+
+ /**
+ * Whether NR (standalone) should be unmetered for all frequencies.
+ * If either {@link #KEY_UNMETERED_NR_SA_MMWAVE_BOOL} or
+ * {@link #KEY_UNMETERED_NR_SA_SUB6_BOOL} are true, then this value will be ignored.
+ * @hide
+ */
+ public static final String KEY_UNMETERED_NR_SA_BOOL = "unmetered_nr_sa_bool";
+
+ /**
+ * Whether NR (standalone) frequencies above 6GHz (millimeter wave) should be unmetered.
+ * If this is true, then the value for {@link #KEY_UNMETERED_NR_SA_BOOL} will be ignored.
+ * @hide
+ */
+ public static final String KEY_UNMETERED_NR_SA_MMWAVE_BOOL = "unmetered_nr_sa_mmwave_bool";
+
+ /**
+ * Whether NR (standalone) frequencies below 6GHz (sub6) should be unmetered.
+ * If this is true, then the value for {@link #KEY_UNMETERED_NR_SA_BOOL} will be ignored.
+ * @hide
+ */
+ public static final String KEY_UNMETERED_NR_SA_SUB6_BOOL = "unmetered_nr_sa_sub6_bool";
+
+ /**
* Support ASCII 7-BIT encoding for long SMS. This carrier config is used to enable
* this feature.
* @hide
@@ -3587,6 +3705,17 @@ public class CarrierConfigManager {
public static final String KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY =
"missed_incoming_call_sms_originator_string_array";
+
+ /**
+ * String array of Apn Type configurations.
+ * The entries should be of form "APN_TYPE_NAME:priority".
+ * priority is an integer that is sorted from highest to lowest.
+ * example: cbs:5
+ *
+ * @hide
+ */
+ public static final String KEY_APN_PRIORITY_STRING_ARRAY = "apn_priority_string_array";
+
/**
* The patterns of missed incoming call sms. This is the regular expression used for
* matching the missed incoming call's date, time, and caller id. The pattern should match
@@ -3979,10 +4108,10 @@ public class CarrierConfigManager {
});
sDefaults.putIntArray(KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY,
new int[] {
- -19, /* SIGNAL_STRENGTH_POOR */
+ -20, /* SIGNAL_STRENGTH_POOR */
-17, /* SIGNAL_STRENGTH_MODERATE */
-14, /* SIGNAL_STRENGTH_GOOD */
- -12 /* SIGNAL_STRENGTH_GREAT */
+ -11 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY,
new int[] {
@@ -4010,9 +4139,9 @@ public class CarrierConfigManager {
// Boundaries: [-20 dB, -3 dB]
new int[] {
-16, /* SIGNAL_STRENGTH_POOR */
- -11, /* SIGNAL_STRENGTH_MODERATE */
+ -12, /* SIGNAL_STRENGTH_MODERATE */
-9, /* SIGNAL_STRENGTH_GOOD */
- -7 /* SIGNAL_STRENGTH_GREAT */
+ -6 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
// Boundaries: [-23 dB, 40 dB]
@@ -4024,10 +4153,11 @@ public class CarrierConfigManager {
});
sDefaults.putInt(KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
CellSignalStrengthNr.USE_SSRSRP);
+ sDefaults.putBoolean(KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL, true);
sDefaults.putStringArray(KEY_BANDWIDTH_STRING_ARRAY, new String[]{
"GPRS:24,24", "EDGE:70,18", "UMTS:115,115", "CDMA-IS95A:14,14", "CDMA-IS95B:14,14",
"1xRTT:30,30", "EvDo-rev.0:750,48", "EvDo-rev.A:950,550", "HSDPA:4300,620",
- "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550:", "eHRPD:750,48",
+ "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550", "eHRPD:750,48",
"HSPAP:13000,3400", "TD-SCDMA:115,115", "LTE:30000,15000", "NR_NSA:47000,15000",
"NR_NSA_MMWAVE:145000,15000", "NR_SA:145000,15000"});
sDefaults.putBoolean(KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPSTREAM_BOOL, false);
@@ -4046,12 +4176,17 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING,
"connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G,"
+ "not_restricted_rrc_con:5G");
- sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
+ sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, "");
+ sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, "");
/* Default value is 1 hour. */
sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false);
sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, false);
sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_SUB6_BOOL, false);
+ sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL, false);
+ sDefaults.putBoolean(KEY_UNMETERED_NR_SA_BOOL, false);
+ sDefaults.putBoolean(KEY_UNMETERED_NR_SA_MMWAVE_BOOL, false);
+ sDefaults.putBoolean(KEY_UNMETERED_NR_SA_SUB6_BOOL, false);
sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_WIFI_CALLING_ICON_IN_STATUS_BAR_BOOL, false);
/* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */
@@ -4112,6 +4247,10 @@ public class CarrierConfigManager {
sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, TimeUnit.DAYS.toMillis(1));
sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY,
new String[0]);
+ sDefaults.putStringArray(KEY_APN_PRIORITY_STRING_ARRAY, new String[] {
+ "default:0", "mms:2", "supl:2", "dun:2", "hipri:3", "fota:2",
+ "ims:2", "cbs:2", "ia:2", "emergency:2", "mcx:3", "xcap:3"
+ });
sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]);
}
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 33a43c1e0319..1e5ce05ff28a 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -211,7 +211,7 @@ public abstract class CellIdentity implements Parcelable {
}
/** @hide */
- protected String getPlmn() {
+ public @Nullable String getPlmn() {
if (mMccStr == null || mMncStr == null) return null;
return mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index f21277cdd83c..68c833c37c99 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -279,6 +279,7 @@ public final class CellIdentityCdma extends CellIdentity {
mLongitude = in.readInt();
mLatitude = in.readInt();
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 1a913105db2e..849c613da748 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -323,6 +323,7 @@ public final class CellIdentityGsm extends CellIdentity {
mBsic = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 13a8273d64d4..1993550d52b8 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -403,6 +403,8 @@ public final class CellIdentityLte extends CellIdentity {
mBandwidth = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index f0d878001bf4..8dd7bdd57841 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -273,6 +273,8 @@ public final class CellIdentityNr extends CellIdentity {
mBands = in.createIntArray();
mNci = in.readLong();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
+
+ updateGlobalCellId();
}
/** Implement the Parcelable interface */
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 6dffe922ffd1..e74b70939d14 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -321,6 +321,8 @@ public final class CellIdentityTdscdma extends CellIdentity {
mUarfcn = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index eab174ade3b7..40cb27e95151 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -336,6 +336,8 @@ public final class CellIdentityWcdma extends CellIdentity {
mUarfcn = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 8562df1d015f..95fe90a47654 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -57,9 +57,9 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
// Boundaries: [-20 dB, -3 dB]
private int[] mSsRsrqThresholds = new int[] {
-16, /* SIGNAL_STRENGTH_POOR */
- -11, /* SIGNAL_STRENGTH_MODERATE */
+ -12, /* SIGNAL_STRENGTH_MODERATE */
-9, /* SIGNAL_STRENGTH_GOOD */
- -7 /* SIGNAL_STRENGTH_GREAT */
+ -6 /* SIGNAL_STRENGTH_GREAT */
};
// Lifted from Default carrier configs and max range of SSSINR
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 0ad572412309..bf21bb7c2a35 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -22,6 +22,8 @@ import android.compat.annotation.UnsupportedAppUsage;
/**
* Describes the cause of a disconnected call. Those disconnect causes can be converted into a more
* generic {@link android.telecom.DisconnectCause} object.
+ *
+ * Used in {@link PhoneStateListener#onCallDisconnectCauseChanged}.
*/
public final class DisconnectCause {
@@ -333,20 +335,17 @@ public final class DisconnectCause {
/**
* Indicates that the call is dropped due to RTCP inactivity, primarily due to media path
* disruption.
- * @hide
*/
public static final int MEDIA_TIMEOUT = 77;
/**
* Indicates that an emergency call cannot be placed over WFC because the service is not
* available in the current location.
- * @hide
*/
public static final int EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE = 78;
/**
* Indicates that WiFi calling service is not available in the current location.
- * @hide
*/
public static final int WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79;
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index 45deea206cfc..3d96fc634d6a 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -231,6 +231,8 @@ public class MbmsDownloadSession implements AutoCloseable {
private static final String DESTINATION_SANITY_CHECK_FILE_NAME = "destinationSanityCheckFile";
+ private static final int MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE = 10 * 1024; // 10KB
+
private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
private final Context mContext;
@@ -318,6 +320,16 @@ public class MbmsDownloadSession implements AutoCloseable {
return session;
}
+ /**
+ * Returns the maximum size of the service announcement file that can be provided via
+ * {@link #addServiceAnnouncementFile}
+ * @return The maximum length of the byte array passed as an argument to
+ * {@link #addServiceAnnouncementFile}.
+ */
+ public static int getMaximumServiceAnnouncementFileSize() {
+ return MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE;
+ }
+
private int bindAndInitialize() {
mServiceConnection = new ServiceConnection() {
@Override
@@ -424,6 +436,60 @@ public class MbmsDownloadSession implements AutoCloseable {
}
/**
+ * Inform the middleware of a service announcement file received from a group communication
+ * server.
+ *
+ * When participating in a group call via the {@link MbmsGroupCallSession} API, applications may
+ * receive a service announcement file from the group call server that informs them of
+ * files that may be relevant to users communicating on the group call.
+ *
+ * After supplying the service announcement file received from the server to the middleware via
+ * this API, applications will receive information on the available files via
+ * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}, and the available files will be
+ * downloadable via {@link MbmsDownloadSession#download} like other files published via
+ * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}.
+ *
+ * Asynchronous error codes via the {@link MbmsDownloadSessionCallback#onError(int, String)}
+ * callback may include any of the errors that are not specific to the streaming use-case.
+ *
+ * May throw an {@link IllegalStateException} when the middleware has not yet been bound,
+ * or an {@link IllegalArgumentException} if the file is too large.
+ *
+ * @param fileContents The contents of the service announcement file received from the group
+ * call server. If the size of this array is greater than the value of
+ * {@link #getMaximumServiceAnnouncementFileSize()}, an
+ * {@link IllegalArgumentException} will be thrown.
+ */
+ public void addServiceAnnouncementFile(@NonNull byte[] fileContents) {
+ IMbmsDownloadService downloadService = mService.get();
+ if (downloadService == null) {
+ throw new IllegalStateException("Middleware not yet bound");
+ }
+
+ if (fileContents.length > MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE) {
+ throw new IllegalArgumentException("File too large");
+ }
+
+ try {
+ int returnCode = downloadService.addServiceAnnouncementFile(
+ mSubscriptionId, fileContents);
+ if (returnCode == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return an unknown error code");
+ }
+ if (returnCode != MbmsErrors.SUCCESS) {
+ sendErrorToApp(returnCode, null);
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Remote process died");
+ mService.set(null);
+ sIsInitialized.set(false);
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+ }
+ }
+
+ /**
* Sets the temp file root for downloads.
* All temp files created for the middleware to write to will be contained in the specified
* directory. Applications that wish to specify a location only need to call this method once
diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java
index 68c9d998ba92..d9b5de5f878a 100644
--- a/telephony/java/android/telephony/PinResult.java
+++ b/telephony/java/android/telephony/PinResult.java
@@ -37,6 +37,7 @@ public final class PinResult implements Parcelable {
PIN_RESULT_TYPE_SUCCESS,
PIN_RESULT_TYPE_INCORRECT,
PIN_RESULT_TYPE_FAILURE,
+ PIN_RESULT_TYPE_ABORTED,
})
public @interface PinResultType {}
@@ -55,6 +56,11 @@ public final class PinResult implements Parcelable {
*/
public static final int PIN_RESULT_TYPE_FAILURE = PhoneConstants.PIN_GENERAL_FAILURE;
+ /**
+ * Indicates that the pin attempt was aborted.
+ */
+ public static final int PIN_RESULT_TYPE_ABORTED = PhoneConstants.PIN_OPERATION_ABORTED;
+
private static final PinResult sFailedResult =
new PinResult(PinResult.PIN_RESULT_TYPE_FAILURE, -1);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index a269bd1809d4..5c84297d3b86 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1392,15 +1392,16 @@ public class ServiceState implements Parcelable {
/** @hide */
public boolean isUsingCarrierAggregation() {
+ boolean isUsingCa = false;
NetworkRegistrationInfo nri = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (nri != null) {
DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
if (dsri != null) {
- return dsri.isUsingCarrierAggregation();
+ isUsingCa = dsri.isUsingCarrierAggregation();
}
}
- return false;
+ return isUsingCa || getCellBandwidths().length > 1;
}
/** @hide */
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 16fbd07f9495..5f09ca203dd9 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -83,6 +83,8 @@ public class SignalStrength implements Parcelable {
// Effectively final. Timestamp is set during construction of SignalStrength
private long mTimestampMillis;
+ private boolean mLteAsPrimaryInNrNsa = true;
+
CellSignalStrengthCdma mCdma;
CellSignalStrengthGsm mGsm;
CellSignalStrengthWcdma mWcdma;
@@ -190,12 +192,16 @@ public class SignalStrength implements Parcelable {
private CellSignalStrength getPrimary() {
// This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing
// newer faster RATs for default/for display purposes.
+
+ if (mLteAsPrimaryInNrNsa) {
+ if (mLte.isValid()) return mLte;
+ }
+ if (mNr.isValid()) return mNr;
if (mLte.isValid()) return mLte;
if (mCdma.isValid()) return mCdma;
if (mTdscdma.isValid()) return mTdscdma;
if (mWcdma.isValid()) return mWcdma;
if (mGsm.isValid()) return mGsm;
- if (mNr.isValid()) return mNr;
return mLte;
}
@@ -270,6 +276,10 @@ public class SignalStrength implements Parcelable {
/** @hide */
public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ if (cc != null) {
+ mLteAsPrimaryInNrNsa = cc.getBoolean(
+ CarrierConfigManager.KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL, true);
+ }
mCdma.updateLevel(cc, ss);
mGsm.updateLevel(cc, ss);
mWcdma.updateLevel(cc, ss);
diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java
index 2c4d5ae3b82b..3d5c6aad1042 100644
--- a/telephony/java/android/telephony/TelephonyDisplayInfo.java
+++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java
@@ -62,8 +62,6 @@ public final class TelephonyDisplayInfo implements Parcelable {
* {@link TelephonyManager#NETWORK_TYPE_LTE} network and has E-UTRA-NR Dual Connectivity(EN-DC)
* capability or is currently connected to the secondary
* {@link TelephonyManager#NETWORK_TYPE_NR} cellular network on millimeter wave bands.
- *
- * @see AccessNetworkConstants.NgranBands#FREQUENCY_RANGE_GROUP_2
*/
public static final int OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE = 4;
@@ -154,7 +152,14 @@ public final class TelephonyDisplayInfo implements Parcelable {
return Objects.hash(mNetworkType, mOverrideNetworkType);
}
- private static String overrideNetworkTypeToString(@OverrideNetworkType int type) {
+ /**
+ * Convert override network type to string.
+ *
+ * @param type Override network type
+ * @return Override network type in string format
+ * @hide
+ */
+ public static String overrideNetworkTypeToString(@OverrideNetworkType int type) {
switch (type) {
case OVERRIDE_NETWORK_TYPE_NONE: return "NONE";
case OVERRIDE_NETWORK_TYPE_LTE_CA: return "LTE_CA";
@@ -168,6 +173,6 @@ public final class TelephonyDisplayInfo implements Parcelable {
@Override
public String toString() {
return "TelephonyDisplayInfo {network=" + TelephonyManager.getNetworkTypeName(mNetworkType)
- + ", override=" + overrideNetworkTypeToString(mOverrideNetworkType);
+ + ", override=" + overrideNetworkTypeToString(mOverrideNetworkType) + "}";
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 74339e9833a1..7d1398b51ec8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10314,7 +10314,7 @@ public class TelephonyManager {
* <p>To recognize a carrier (including MVNO) as a first-class identity, Android assigns each
* carrier with a canonical integer a.k.a. carrier id. The carrier ID is an Android
* platform-wide identifier for a carrier. AOSP maintains carrier ID assignments in
- * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
*
* <p>Apps which have carrier-specific configurations or business logic can use the carrier id
* as an Android platform-wide identifier for carriers.
@@ -10376,7 +10376,7 @@ public class TelephonyManager {
*
* <p>For carriers without fine-grained specific carrier ids, return {@link #getSimCarrierId()}
* <p>Specific carrier ids are defined in the same way as carrier id
- * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
* except each with a "parent" id linking to its top-level carrier id.
*
* @return Returns fine-grained carrier id of the current subscription.
@@ -10425,7 +10425,7 @@ public class TelephonyManager {
* This is used for fallback when configurations/logic for exact carrier id
* {@link #getSimCarrierId()} are not found.
*
- * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
* can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
* was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
* by default. After carrier id table update, a new carrier id was assigned. If apps don't
@@ -10452,7 +10452,7 @@ public class TelephonyManager {
* used for fallback when configurations/logic for exact carrier id {@link #getSimCarrierId()}
* are not found.
*
- * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
* can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
* was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
* by default. After carrier id table update, a new carrier id was assigned. If apps don't
@@ -12977,4 +12977,21 @@ public class TelephonyManager {
}
return 0;
}
+
+ /**
+ * Whether device can connect to 5G network when two SIMs are active.
+ * @hide
+ * TODO b/153669716: remove or make system API.
+ */
+ public boolean canConnectTo5GInDsdsMode() {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) return true;
+ try {
+ return telephony.canConnectTo5GInDsdsMode();
+ } catch (RemoteException ex) {
+ return true;
+ } catch (NullPointerException ex) {
+ return true;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 44b0968eaa90..5500d635d2ff 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -269,10 +269,10 @@ public class EuiccManager {
* only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown
* Download error.
*
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE}
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE
*/
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
@@ -552,7 +552,7 @@ public class EuiccManager {
/**
* List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s
- * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * value, an integer. @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*
* @hide
*/
@@ -575,44 +575,44 @@ public class EuiccManager {
/**
* Internal system error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SYSTEM = 1;
/**
* SIM slot error. Failed to switch slot, failed to access the physical slot etc.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SIM_SLOT = 2;
/**
* eUICC card error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_EUICC_CARD = 3;
/**
* Generic switching profile error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SWITCH = 4;
/**
* Download profile error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_DOWNLOAD = 5;
/**
* Subscription's metadata error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_METADATA = 6;
/**
* eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x
* functions.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_EUICC_GSMA = 7;
@@ -620,13 +620,13 @@ public class EuiccManager {
* The exception of failing to execute an APDU command. It can be caused by an error
* happening on opening the basic or logical channel, or the response of the APDU command is
* not success (0x9000).
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_APDU = 8;
/**
* SMDX(SMDP/SMDS) error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SMDX = 9;
@@ -655,19 +655,19 @@ public class EuiccManager {
* Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is
* 0xA8B1051(176885841)
*
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10;
/**
* HTTP error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_HTTP = 11;
/**
* List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -695,56 +695,56 @@ public class EuiccManager {
/**
* Operation such as downloading/switching to another profile failed due to device being
* carrier locked.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CARRIER_LOCKED = 10000;
/**
* The activation code(SGP.22 v2.2 section[4.1]) is invalid.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_ACTIVATION_CODE = 10001;
/**
* The confirmation code(SGP.22 v2.2 section[4.7]) is invalid.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002;
/**
* The profile's carrier is incompatible with the LPA.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INCOMPATIBLE_CARRIER = 10003;
/**
* There is no more space available on the eUICC for new profiles.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004;
/**
* Timed out while waiting for an operation to complete. i.e restart, disable,
* switch reset etc.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_TIME_OUT = 10005;
/**
* eUICC is missing or defective on the device.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_EUICC_MISSING = 10006;
/**
* The eUICC card(hardware) version is incompatible with the software
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_UNSUPPORTED_VERSION = 10007;
/**
* No SIM card is available in the device.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_SIM_MISSING = 10008;
@@ -754,52 +754,52 @@ public class EuiccManager {
* 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch
* 3. operation was interrupted
* 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1)
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INSTALL_PROFILE = 10009;
/**
* Failed to load profile onto eUICC due to Profile Poicly Rules.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_DISALLOWED_BY_PPR = 10010;
/**
* Address is missing e.g SMDS/SMDP address is missing.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_ADDRESS_MISSING = 10011;
/**
* Certificate needed for authentication is not valid or missing. E.g SMDP/SMDS authentication
* failed.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CERTIFICATE_ERROR = 10012;
/**
* No profiles available.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_NO_PROFILES_AVAILABLE = 10013;
/**
* Failure to create a connection.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CONNECTION_ERROR = 10014;
/**
* Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_RESPONSE = 10015;
/**
* The operation is currently busy, try again later.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_OPERATION_BUSY = 10016;
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 95ebbf39e944..872f49d65d25 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -141,8 +141,7 @@ public class ImsMmTelManager implements RegistrationManager {
}
/**
- * Receives IMS capability status updates from the ImsService. This information is also
- * available via the {@see #isAvailable(int, int)} method below.
+ * Receives IMS capability status updates from the ImsService.
*
* @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
* @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
@@ -195,8 +194,6 @@ public class ImsMmTelManager implements RegistrationManager {
* If unavailable, the feature is not able to support the unavailable capability at this
* time.
*
- * This information can also be queried using the {@see #isAvailable(int, int)} API.
- *
* @param capabilities The new availability of the capabilities.
*/
public void onCapabilitiesStatusChanged(
@@ -497,8 +494,7 @@ public class ImsMmTelManager implements RegistrationManager {
/**
* Registers a {@link CapabilityCallback} with the system, which will provide MmTel service
* availability updates for the subscription specified in
- * {@link ImsManager#getImsMmTelManager(int)}. The method {@see #isAvailable(int, int)}
- * can also be used to query this information at any time.
+ * {@link ImsManager#getImsMmTelManager(int)}.
*
* Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
* subscription changed events and call
@@ -640,7 +636,6 @@ public class ImsMmTelManager implements RegistrationManager {
* @see android.telephony.CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL
* @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
- * @see #setAdvancedCallingSettingEnabled(boolean)
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for advanced calling is enabled, false otherwise.
@@ -859,7 +854,6 @@ public class ImsMmTelManager implements RegistrationManager {
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user’s “Video Calling” setting is currently enabled.
- * @see #setVtSettingEnabled(boolean)
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
@@ -934,7 +928,6 @@ public class ImsMmTelManager implements RegistrationManager {
*
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
- * @see #setVoWiFiSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1012,7 +1005,6 @@ public class ImsMmTelManager implements RegistrationManager {
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for Voice over WiFi while roaming is enabled, false
* if disabled.
- * @see #setVoWiFiRoamingSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1131,7 +1123,6 @@ public class ImsMmTelManager implements RegistrationManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
- * @see #setVoWiFiSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1316,7 +1307,6 @@ public class ImsMmTelManager implements RegistrationManager {
*
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
- * @see android.telecom.TelecomManager#getCurrentTtyMode
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index ed9b94b3d85e..71bc68e4b4c4 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -49,7 +49,7 @@ import java.util.function.Consumer;
*
* Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
*/
-public class ImsRcsManager implements RegistrationManager {
+public class ImsRcsManager {
private static final String TAG = "ImsRcsManager";
/**
@@ -173,11 +173,11 @@ public class ImsRcsManager implements RegistrationManager {
/**
* @hide
*/
- @Override
+ // @Override add back to RegistrationManager interface once public.
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void registerImsRegistrationCallback(
@NonNull @CallbackExecutor Executor executor,
- @NonNull RegistrationCallback c)
+ @NonNull RegistrationManager.RegistrationCallback c)
throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
@@ -204,7 +204,7 @@ public class ImsRcsManager implements RegistrationManager {
/**
* @hide
*/
- @Override
+ // @Override add back to RegistrationManager interface once public.
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterImsRegistrationCallback(
@NonNull RegistrationManager.RegistrationCallback c) {
@@ -228,10 +228,10 @@ public class ImsRcsManager implements RegistrationManager {
/**
* @hide
*/
- @Override
+ // @Override add back to RegistrationManager interface once public.
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
- @NonNull @ImsRegistrationState Consumer<Integer> stateCallback) {
+ @NonNull @RegistrationManager.ImsRegistrationState Consumer<Integer> stateCallback) {
if (stateCallback == null) {
throw new IllegalArgumentException("Must include a non-null stateCallback.");
}
@@ -260,7 +260,6 @@ public class ImsRcsManager implements RegistrationManager {
/**
* @hide
*/
- @Override
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getRegistrationTransportType(@NonNull @CallbackExecutor Executor executor,
@NonNull @AccessNetworkConstants.TransportType
@@ -347,8 +346,7 @@ public class ImsRcsManager implements RegistrationManager {
* inactive subscription, it will result in a no-op.
* @param c The RCS {@link AvailabilityCallback} to be removed.
* @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
- * @throws ImsException if the IMS service is not available when calling this method
- * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}.
+ * @throws ImsException if the IMS service is not available when calling this method.
* See {@link ImsException#getCode()} for more information on the error codes.
* @hide
*/
@@ -390,8 +388,7 @@ public class ImsRcsManager implements RegistrationManager {
* rather the subscription is capable of this service over IMS.
* @see #isAvailable(int)
* @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
- * @throws ImsException if the IMS service is not available when calling this method
- * {@link ImsRcsController#isCapable(int, int)}.
+ * @throws ImsException if the IMS service is not available when calling this method.
* See {@link ImsException#getCode()} for more information on the error codes.
* @hide
*/
@@ -424,9 +421,8 @@ public class ImsRcsManager implements RegistrationManager {
* @return true if the RCS capability is currently available for the associated subscription,
* false otherwise. If the capability is available, IMS is registered and the service is
* currently available over IMS.
- * @see #isCapable(int)
- * @throws ImsException if the IMS service is not available when calling this method
- * {@link ImsRcsController#isAvailable(int, int)}.
+ * @see #isCapable(int, int)
+ * @throws ImsException if the IMS service is not available when calling this method.
* See {@link ImsException#getCode()} for more information on the error codes.
* @hide
*/
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 1dbaff5df802..e085dec10546 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -270,7 +270,7 @@ public interface RegistrationManager {
* inactive subscription, it will result in a no-op.
*
* @param c The {@link RegistrationCallback} to be removed.
- * @see SubscriptionManager.OnSubscriptionsChangedListener
+ * @see android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index a3ce1b585f76..6840e8eed318 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -218,13 +218,7 @@ public class MmTelFeature extends ImsFeature {
* {@link MmTelCapabilities#CAPABILITY_TYPE_UT}, and
* {@link MmTelCapabilities#CAPABILITY_TYPE_SMS}.
*
- * The capabilities of this MmTelFeature will be set by the framework and can be queried with
- * {@see #queryCapabilityStatus()}.
- *
- * This MmTelFeature can then return the status of each of these capabilities (enabled or not)
- * by sending a {@see #notifyCapabilitiesStatusChanged} callback to the framework. The current
- * status can also be queried using {@see #queryCapabilityStatus()}.
- * @see #isCapable(int)
+ * The capabilities of this MmTelFeature will be set by the framework.
*/
public static class MmTelCapabilities extends Capabilities {
@@ -436,7 +430,6 @@ public class MmTelFeature extends ImsFeature {
/**
* @param listener A {@link Listener} used when the MmTelFeature receives an incoming call and
* notifies the framework.
- * @hide
*/
private void setListener(IImsMmTelListener listener) {
synchronized (mLock) {
@@ -448,6 +441,16 @@ public class MmTelFeature extends ImsFeature {
}
/**
+ * @return the listener associated with this MmTelFeature. May be null if it has not been set
+ * by the framework yet.
+ */
+ private IImsMmTelListener getListener() {
+ synchronized (mLock) {
+ return mListener;
+ }
+ }
+
+ /**
* The current capability status that this MmTelFeature has defined is available. This
* configuration will be used by the platform to figure out which capabilities are CURRENTLY
* available to be used.
@@ -495,15 +498,14 @@ public class MmTelFeature extends ImsFeature {
throw new IllegalArgumentException("ImsCallSessionImplBase and Bundle can not be "
+ "null.");
}
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Session is not available.");
- }
- try {
- mListener.onIncomingCall(c.getServiceImpl(), extras);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onIncomingCall(c.getServiceImpl(), extras);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
}
@@ -522,15 +524,14 @@ public class MmTelFeature extends ImsFeature {
throw new IllegalArgumentException("ImsCallProfile and ImsReasonInfo must not be "
+ "null.");
}
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Session is not available.");
- }
- try {
- mListener.onRejectedCall(callProfile, reason);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onRejectedCall(callProfile, reason);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
}
@@ -539,15 +540,14 @@ public class MmTelFeature extends ImsFeature {
* @hide
*/
public final void notifyIncomingCallSession(IImsCallSession c, Bundle extras) {
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Session is not available.");
- }
- try {
- mListener.onIncomingCall(c, extras);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onIncomingCall(c, extras);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
}
@@ -558,15 +558,14 @@ public class MmTelFeature extends ImsFeature {
*/
@SystemApi @TestApi
public final void notifyVoiceMessageCountUpdate(int count) {
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Session is not available.");
- }
- try {
- mListener.onVoiceMessageCountUpdate(count);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onVoiceMessageCountUpdate(count);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index ce9a73a21657..a9a33c0e1507 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -403,8 +403,7 @@ public class ImsSmsImplBase {
message.mWrappedSmsMessage.mMessageRef,
STATUS_REPORT_STATUS_ERROR);
} else {
- Log.w(LOG_TAG,
- "onSmsStatusReportReceivedWithoutMessageRef: Invalid pdu entered.");
+ Log.w(LOG_TAG, "onSmsStatusReportReceived: Invalid pdu entered.");
acknowledgeSmsReport(token, 0, STATUS_REPORT_STATUS_ERROR);
}
}
diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
index 52e4d333b29d..8611d26bc85b 100644
--- a/telephony/java/android/telephony/mbms/MbmsErrors.java
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -16,8 +16,12 @@
package android.telephony.mbms;
+import android.annotation.IntDef;
import android.telephony.MbmsStreamingSession;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class MbmsErrors {
/**
* Indicates that the middleware has sent an error code that is not defined in the version of
@@ -138,6 +142,13 @@ public class MbmsErrors {
/** Indicates the the middleware has no record of the supplied {@link FileInfo} */
public static final int ERROR_UNKNOWN_FILE_INFO = 403;
+
+ /**
+ * Indicates that the service announcement file passed via
+ * {@link android.telephony.MbmsDownloadSession#addServiceAnnouncementFile(byte[])}
+ * is malformed.
+ */
+ public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE = 404;
}
/**
@@ -156,5 +167,35 @@ public class MbmsErrors {
public static final int ERROR_DUPLICATE_START_GROUP_CALL = 502;
}
+ /** @hide */
+ @IntDef(value = {
+ SUCCESS,
+ ERROR_NO_UNIQUE_MIDDLEWARE,
+ ERROR_MIDDLEWARE_NOT_BOUND,
+ ERROR_MIDDLEWARE_LOST,
+ InitializationErrors.ERROR_DUPLICATE_INITIALIZE,
+ InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED,
+ InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+ GeneralErrors.ERROR_OUT_OF_MEMORY,
+ GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+ GeneralErrors.ERROR_IN_E911,
+ GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+ GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+ GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED,
+ StreamingErrors.ERROR_CONCURRENT_SERVICE_LIMIT_REACHED,
+ StreamingErrors.ERROR_UNABLE_TO_START_SERVICE,
+ StreamingErrors.ERROR_DUPLICATE_START_STREAM,
+ DownloadErrors.ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT,
+ DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST,
+ DownloadErrors.ERROR_UNKNOWN_FILE_INFO,
+ DownloadErrors.ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE,
+ GroupCallErrors.ERROR_UNABLE_TO_START_SERVICE,
+ GroupCallErrors.ERROR_DUPLICATE_START_GROUP_CALL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MbmsError {
+ }
+
private MbmsErrors() {}
}
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
index 445087fb78d5..36136ab280c4 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
@@ -35,6 +35,8 @@ interface IMbmsDownloadService
int setTempFileRootDirectory(int subId, String rootDirectoryPath);
+ int addServiceAnnouncementFile(int subId, in byte[] fileContents);
+
int download(in DownloadRequest downloadRequest);
int addStatusListener(in DownloadRequest downloadRequest,
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index 9f22d0a49806..3279ce66cd17 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -216,6 +216,28 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub {
}
/**
+ * Called when the client application wishes to receive file information according to a
+ * service announcement file received from a group call server.
+ *
+ * The service announcement file is in the format of a multipart MIME file with XML parts,
+ * though no validation is performed on the contents of the {@code fileContents} argument --
+ * implementing middleware applications should perform their own validation and return
+ * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE} if the file is
+ * malformed.
+ *
+ * @param subscriptionId The subscription id the service announcement applies to.
+ * @param fileContents The contents of the service announcement file.
+ * @return {@link MbmsErrors#SUCCESS}, or
+ * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE}
+ */
+ // TODO: are there any public specifications of what the file format is that I can link to?
+ @Override
+ public @MbmsErrors.MbmsError int addServiceAnnouncementFile(
+ int subscriptionId, @NonNull byte[] fileContents) {
+ return 0;
+ }
+
+ /**
* Issues a request to download a set of files.
*
* The middleware should expect that {@link #setTempFileRootDirectory(int, String)} has been
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 18e25921555a..76fc4f7d0519 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -109,11 +109,10 @@ public class DctConstants {
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_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51;
- public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52;
- public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53;
- public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54;
- public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 55;
- public static final int EVENT_SIM_STATE_UPDATED = BASE + 56;
+ public static final int EVENT_TELEPHONY_DISPLAY_INFO_CHANGED = BASE + 52;
+ public static final int EVENT_NR_TIMER_WATCHDOG = BASE + 53;
+ public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54;
+ public static final int EVENT_SIM_STATE_UPDATED = BASE + 55;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 1face6c4f4cd..5293efa6bce7 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2248,4 +2248,9 @@ interface ITelephony {
int setIccLockEnabled(int subId, boolean enabled, String password);
int changeIccLockPassword(int subId, String oldPassword, String newPassword);
+
+ /**
+ * Whether device can connect to 5G network when two SIMs are active.
+ */
+ boolean canConnectTo5GInDsdsMode();
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 6eea88f4c103..db9fdf54852d 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -111,6 +111,7 @@ public class PhoneConstants {
public static final int PIN_RESULT_SUCCESS = 0;
public static final int PIN_PASSWORD_INCORRECT = 1;
public static final int PIN_GENERAL_FAILURE = 2;
+ public static final int PIN_OPERATION_ABORTED = 3;
/**
* Return codes for <code>enableApnType()</code>
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index ff70f8ba3936..29286e8f429e 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -240,5 +240,5 @@ public interface TelephonyProperties
* two.
* Type: int
*/
- static final String PROPERTY_MAX_ACTIVE_MODEMS = "ro.telephony.max.active.modems";
+ static final String PROPERTY_MAX_ACTIVE_MODEMS = "telephony.active_modems.max_count";
}
diff --git a/test-base/api/lint-baseline.txt b/test-base/api/lint-baseline.txt
new file mode 100644
index 000000000000..86c8a910d20a
--- /dev/null
+++ b/test-base/api/lint-baseline.txt
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+MissingNullability: junit.framework.ComparisonFailure#getMessage():
+ Missing nullability on method `getMessage` return
diff --git a/test-mock/api/lint-baseline.txt b/test-mock/api/lint-baseline.txt
new file mode 100644
index 000000000000..c6ba3f5d8fd8
--- /dev/null
+++ b/test-mock/api/lint-baseline.txt
@@ -0,0 +1,143 @@
+// Baseline format: 1.0
+ArrayReturn: android.test.mock.MockContentProvider#bulkInsert(android.net.Uri, android.content.ContentValues[]) parameter #1:
+ Method parameter should be Collection<ContentValues> (or subclass) instead of raw array; was `android.content.ContentValues[]`
+ArrayReturn: android.test.mock.MockResources#getTextArray(int):
+ Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
+
+
+MissingNullability: android.test.mock.MockApplication#onConfigurationChanged(android.content.res.Configuration) parameter #0:
+ Missing nullability on parameter `newConfig` in method `onConfigurationChanged`
+MissingNullability: android.test.mock.MockContentProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0:
+ Missing nullability on parameter `context` in method `attachInfo`
+MissingNullability: android.test.mock.MockContentProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1:
+ Missing nullability on parameter `info` in method `attachInfo`
+MissingNullability: android.test.mock.MockContentProvider#bulkInsert(android.net.Uri, android.content.ContentValues[]) parameter #0:
+ Missing nullability on parameter `uri` in method `bulkInsert`
+MissingNullability: android.test.mock.MockContentProvider#bulkInsert(android.net.Uri, android.content.ContentValues[]) parameter #1:
+ Missing nullability on parameter `values` in method `bulkInsert`
+MissingNullability: android.test.mock.MockContentProvider#getStreamTypes(android.net.Uri, String):
+ Missing nullability on method `getStreamTypes` return
+MissingNullability: android.test.mock.MockContentProvider#getStreamTypes(android.net.Uri, String) parameter #0:
+ Missing nullability on parameter `url` in method `getStreamTypes`
+MissingNullability: android.test.mock.MockContentProvider#getStreamTypes(android.net.Uri, String) parameter #1:
+ Missing nullability on parameter `mimeTypeFilter` in method `getStreamTypes`
+MissingNullability: android.test.mock.MockContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean) parameter #0:
+ Missing nullability on parameter `uri` in method `notifyChange`
+MissingNullability: android.test.mock.MockContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean) parameter #1:
+ Missing nullability on parameter `observer` in method `notifyChange`
+MissingNullability: android.test.mock.MockContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #0:
+ Missing nullability on parameter `service` in method `bindIsolatedService`
+MissingNullability: android.test.mock.MockContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #2:
+ Missing nullability on parameter `instanceName` in method `bindIsolatedService`
+MissingNullability: android.test.mock.MockContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #3:
+ Missing nullability on parameter `executor` in method `bindIsolatedService`
+MissingNullability: android.test.mock.MockContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #4:
+ Missing nullability on parameter `conn` in method `bindIsolatedService`
+MissingNullability: android.test.mock.MockContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #0:
+ Missing nullability on parameter `service` in method `bindService`
+MissingNullability: android.test.mock.MockContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #2:
+ Missing nullability on parameter `executor` in method `bindService`
+MissingNullability: android.test.mock.MockContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #3:
+ Missing nullability on parameter `conn` in method `bindService`
+MissingNullability: android.test.mock.MockContext#getMainExecutor():
+ Missing nullability on method `getMainExecutor` return
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #0:
+ Missing nullability on parameter `intent` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #1:
+ Missing nullability on parameter `receiverPermission` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #2:
+ Missing nullability on parameter `receiverAppOp` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #3:
+ Missing nullability on parameter `resultReceiver` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #4:
+ Missing nullability on parameter `scheduler` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #6:
+ Missing nullability on parameter `initialData` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#sendOrderedBroadcast(android.content.Intent, String, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle) parameter #7:
+ Missing nullability on parameter `initialExtras` in method `sendOrderedBroadcast`
+MissingNullability: android.test.mock.MockContext#updateServiceGroup(android.content.ServiceConnection, int, int) parameter #0:
+ Missing nullability on parameter `conn` in method `updateServiceGroup`
+MissingNullability: android.test.mock.MockCursor#getNotificationUris():
+ Missing nullability on method `getNotificationUris` return
+MissingNullability: android.test.mock.MockCursor#setNotificationUris(android.content.ContentResolver, java.util.List<android.net.Uri>) parameter #0:
+ Missing nullability on parameter `cr` in method `setNotificationUris`
+MissingNullability: android.test.mock.MockCursor#setNotificationUris(android.content.ContentResolver, java.util.List<android.net.Uri>) parameter #1:
+ Missing nullability on parameter `uris` in method `setNotificationUris`
+MissingNullability: android.test.mock.MockPackageManager#getPackageArchiveInfo(String, int):
+ Missing nullability on method `getPackageArchiveInfo` return
+MissingNullability: android.test.mock.MockPackageManager#getPackageArchiveInfo(String, int) parameter #0:
+ Missing nullability on parameter `archiveFilePath` in method `getPackageArchiveInfo`
+MissingNullability: android.test.mock.MockPackageManager#hasSigningCertificate(String, byte[], int) parameter #0:
+ Missing nullability on parameter `packageName` in method `hasSigningCertificate`
+MissingNullability: android.test.mock.MockPackageManager#hasSigningCertificate(String, byte[], int) parameter #1:
+ Missing nullability on parameter `certificate` in method `hasSigningCertificate`
+MissingNullability: android.test.mock.MockPackageManager#hasSigningCertificate(int, byte[], int) parameter #1:
+ Missing nullability on parameter `certificate` in method `hasSigningCertificate`
+MissingNullability: android.test.mock.MockResources#getAnimation(int):
+ Missing nullability on method `getAnimation` return
+MissingNullability: android.test.mock.MockResources#getConfiguration():
+ Missing nullability on method `getConfiguration` return
+MissingNullability: android.test.mock.MockResources#getDisplayMetrics():
+ Missing nullability on method `getDisplayMetrics` return
+MissingNullability: android.test.mock.MockResources#getIdentifier(String, String, String) parameter #0:
+ Missing nullability on parameter `name` in method `getIdentifier`
+MissingNullability: android.test.mock.MockResources#getIdentifier(String, String, String) parameter #1:
+ Missing nullability on parameter `defType` in method `getIdentifier`
+MissingNullability: android.test.mock.MockResources#getIdentifier(String, String, String) parameter #2:
+ Missing nullability on parameter `defPackage` in method `getIdentifier`
+MissingNullability: android.test.mock.MockResources#getIntArray(int):
+ Missing nullability on method `getIntArray` return
+MissingNullability: android.test.mock.MockResources#getLayout(int):
+ Missing nullability on method `getLayout` return
+MissingNullability: android.test.mock.MockResources#getQuantityString(int, int):
+ Missing nullability on method `getQuantityString` return
+MissingNullability: android.test.mock.MockResources#getQuantityString(int, int, java.lang.Object...):
+ Missing nullability on method `getQuantityString` return
+MissingNullability: android.test.mock.MockResources#getQuantityString(int, int, java.lang.Object...) parameter #2:
+ Missing nullability on parameter `formatArgs` in method `getQuantityString`
+MissingNullability: android.test.mock.MockResources#getQuantityText(int, int):
+ Missing nullability on method `getQuantityText` return
+MissingNullability: android.test.mock.MockResources#getResourceEntryName(int):
+ Missing nullability on method `getResourceEntryName` return
+MissingNullability: android.test.mock.MockResources#getResourceName(int):
+ Missing nullability on method `getResourceName` return
+MissingNullability: android.test.mock.MockResources#getResourcePackageName(int):
+ Missing nullability on method `getResourcePackageName` return
+MissingNullability: android.test.mock.MockResources#getResourceTypeName(int):
+ Missing nullability on method `getResourceTypeName` return
+MissingNullability: android.test.mock.MockResources#getString(int):
+ Missing nullability on method `getString` return
+MissingNullability: android.test.mock.MockResources#getString(int, java.lang.Object...):
+ Missing nullability on method `getString` return
+MissingNullability: android.test.mock.MockResources#getString(int, java.lang.Object...) parameter #1:
+ Missing nullability on parameter `formatArgs` in method `getString`
+MissingNullability: android.test.mock.MockResources#getStringArray(int):
+ Missing nullability on method `getStringArray` return
+MissingNullability: android.test.mock.MockResources#getText(int):
+ Missing nullability on method `getText` return
+MissingNullability: android.test.mock.MockResources#getText(int, CharSequence):
+ Missing nullability on method `getText` return
+MissingNullability: android.test.mock.MockResources#getText(int, CharSequence) parameter #1:
+ Missing nullability on parameter `def` in method `getText`
+MissingNullability: android.test.mock.MockResources#getTextArray(int):
+ Missing nullability on method `getTextArray` return
+MissingNullability: android.test.mock.MockResources#getValue(String, android.util.TypedValue, boolean) parameter #0:
+ Missing nullability on parameter `name` in method `getValue`
+MissingNullability: android.test.mock.MockResources#getValue(String, android.util.TypedValue, boolean) parameter #1:
+ Missing nullability on parameter `outValue` in method `getValue`
+MissingNullability: android.test.mock.MockResources#getValue(int, android.util.TypedValue, boolean) parameter #1:
+ Missing nullability on parameter `outValue` in method `getValue`
+MissingNullability: android.test.mock.MockResources#getXml(int):
+ Missing nullability on method `getXml` return
+MissingNullability: android.test.mock.MockResources#obtainAttributes(android.util.AttributeSet, int[]):
+ Missing nullability on method `obtainAttributes` return
+MissingNullability: android.test.mock.MockResources#obtainAttributes(android.util.AttributeSet, int[]) parameter #0:
+ Missing nullability on parameter `set` in method `obtainAttributes`
+MissingNullability: android.test.mock.MockResources#obtainAttributes(android.util.AttributeSet, int[]) parameter #1:
+ Missing nullability on parameter `attrs` in method `obtainAttributes`
+MissingNullability: android.test.mock.MockResources#obtainTypedArray(int):
+ Missing nullability on method `obtainTypedArray` return
+MissingNullability: android.test.mock.MockResources#openRawResource(int):
+ Missing nullability on method `openRawResource` return
+MissingNullability: android.test.mock.MockResources#openRawResourceFd(int):
+ Missing nullability on method `openRawResourceFd` return
diff --git a/test-mock/api/system-lint-baseline.txt b/test-mock/api/system-lint-baseline.txt
new file mode 100644
index 000000000000..466bc5376ed6
--- /dev/null
+++ b/test-mock/api/system-lint-baseline.txt
@@ -0,0 +1,15 @@
+// Baseline format: 1.0
+IntentBuilderName: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler):
+ Methods creating an Intent should be named `create<Foo>Intent()`, was `registerReceiverForAllUsers`
+
+
+MissingNullability: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler):
+ Missing nullability on method `registerReceiverForAllUsers` return
+MissingNullability: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler) parameter #0:
+ Missing nullability on parameter `receiver` in method `registerReceiverForAllUsers`
+MissingNullability: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler) parameter #1:
+ Missing nullability on parameter `filter` in method `registerReceiverForAllUsers`
+MissingNullability: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler) parameter #2:
+ Missing nullability on parameter `broadcastPermission` in method `registerReceiverForAllUsers`
+MissingNullability: android.test.mock.MockContext#registerReceiverForAllUsers(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler) parameter #3:
+ Missing nullability on parameter `scheduler` in method `registerReceiverForAllUsers`
diff --git a/test-runner/api/lint-baseline.txt b/test-runner/api/lint-baseline.txt
new file mode 100644
index 000000000000..54947fe687c0
--- /dev/null
+++ b/test-runner/api/lint-baseline.txt
@@ -0,0 +1,173 @@
+// Baseline format: 1.0
+GenericException: android.test.ActivityInstrumentationTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ActivityInstrumentationTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ActivityInstrumentationTestCase2#runTest():
+ Methods must not throw generic exceptions (`java.lang.Throwable`)
+GenericException: android.test.ActivityInstrumentationTestCase2#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ActivityInstrumentationTestCase2#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ActivityUnitTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ActivityUnitTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ApplicationTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ApplicationTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ProviderTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ProviderTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ProviderTestCase2#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ProviderTestCase2#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ServiceTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.ServiceTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.SingleLaunchActivityTestCase#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.SingleLaunchActivityTestCase#tearDown():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: android.test.SyncBaseInstrumentation#setUp():
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+
+
+IntentBuilderName: android.test.IsolatedContext#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter):
+ Methods creating an Intent should be named `create<Foo>Intent()`, was `registerReceiver`
+
+
+MissingNullability: android.test.ComparisonFailure#getMessage():
+ Missing nullability on method `getMessage` return
+MissingNullability: android.test.InstrumentationTestRunner#onCreate(android.os.Bundle) parameter #0:
+ Missing nullability on parameter `arguments` in method `onCreate`
+MissingNullability: android.test.IsolatedContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #0:
+ Missing nullability on parameter `service` in method `bindIsolatedService`
+MissingNullability: android.test.IsolatedContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #2:
+ Missing nullability on parameter `instanceName` in method `bindIsolatedService`
+MissingNullability: android.test.IsolatedContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #3:
+ Missing nullability on parameter `executor` in method `bindIsolatedService`
+MissingNullability: android.test.IsolatedContext#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #4:
+ Missing nullability on parameter `conn` in method `bindIsolatedService`
+MissingNullability: android.test.IsolatedContext#bindService(android.content.Intent, android.content.ServiceConnection, int) parameter #0:
+ Missing nullability on parameter `service` in method `bindService`
+MissingNullability: android.test.IsolatedContext#bindService(android.content.Intent, android.content.ServiceConnection, int) parameter #1:
+ Missing nullability on parameter `conn` in method `bindService`
+MissingNullability: android.test.IsolatedContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #0:
+ Missing nullability on parameter `service` in method `bindService`
+MissingNullability: android.test.IsolatedContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #2:
+ Missing nullability on parameter `executor` in method `bindService`
+MissingNullability: android.test.IsolatedContext#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection) parameter #3:
+ Missing nullability on parameter `conn` in method `bindService`
+MissingNullability: android.test.IsolatedContext#checkUriPermission(android.net.Uri, String, String, int, int, int) parameter #0:
+ Missing nullability on parameter `uri` in method `checkUriPermission`
+MissingNullability: android.test.IsolatedContext#checkUriPermission(android.net.Uri, String, String, int, int, int) parameter #1:
+ Missing nullability on parameter `readPermission` in method `checkUriPermission`
+MissingNullability: android.test.IsolatedContext#checkUriPermission(android.net.Uri, String, String, int, int, int) parameter #2:
+ Missing nullability on parameter `writePermission` in method `checkUriPermission`
+MissingNullability: android.test.IsolatedContext#checkUriPermission(android.net.Uri, int, int, int) parameter #0:
+ Missing nullability on parameter `uri` in method `checkUriPermission`
+MissingNullability: android.test.IsolatedContext#getContentResolver():
+ Missing nullability on method `getContentResolver` return
+MissingNullability: android.test.IsolatedContext#getFilesDir():
+ Missing nullability on method `getFilesDir` return
+MissingNullability: android.test.IsolatedContext#getSystemService(String):
+ Missing nullability on method `getSystemService` return
+MissingNullability: android.test.IsolatedContext#getSystemService(String) parameter #0:
+ Missing nullability on parameter `name` in method `getSystemService`
+MissingNullability: android.test.IsolatedContext#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter):
+ Missing nullability on method `registerReceiver` return
+MissingNullability: android.test.IsolatedContext#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter) parameter #0:
+ Missing nullability on parameter `receiver` in method `registerReceiver`
+MissingNullability: android.test.IsolatedContext#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter) parameter #1:
+ Missing nullability on parameter `filter` in method `registerReceiver`
+MissingNullability: android.test.IsolatedContext#sendBroadcast(android.content.Intent) parameter #0:
+ Missing nullability on parameter `intent` in method `sendBroadcast`
+MissingNullability: android.test.IsolatedContext#sendOrderedBroadcast(android.content.Intent, String) parameter #0:
+ Missing nullability on parameter `intent` in method `sendOrderedBroadcast`
+MissingNullability: android.test.IsolatedContext#sendOrderedBroadcast(android.content.Intent, String) parameter #1:
+ Missing nullability on parameter `receiverPermission` in method `sendOrderedBroadcast`
+MissingNullability: android.test.IsolatedContext#unregisterReceiver(android.content.BroadcastReceiver) parameter #0:
+ Missing nullability on parameter `receiver` in method `unregisterReceiver`
+MissingNullability: android.test.RenamingDelegatingContext#databaseList():
+ Missing nullability on method `databaseList` return
+MissingNullability: android.test.RenamingDelegatingContext#deleteDatabase(String) parameter #0:
+ Missing nullability on parameter `name` in method `deleteDatabase`
+MissingNullability: android.test.RenamingDelegatingContext#deleteFile(String) parameter #0:
+ Missing nullability on parameter `name` in method `deleteFile`
+MissingNullability: android.test.RenamingDelegatingContext#fileList():
+ Missing nullability on method `fileList` return
+MissingNullability: android.test.RenamingDelegatingContext#getCacheDir():
+ Missing nullability on method `getCacheDir` return
+MissingNullability: android.test.RenamingDelegatingContext#getDatabasePath(String):
+ Missing nullability on method `getDatabasePath` return
+MissingNullability: android.test.RenamingDelegatingContext#getDatabasePath(String) parameter #0:
+ Missing nullability on parameter `name` in method `getDatabasePath`
+MissingNullability: android.test.RenamingDelegatingContext#getFileStreamPath(String):
+ Missing nullability on method `getFileStreamPath` return
+MissingNullability: android.test.RenamingDelegatingContext#getFileStreamPath(String) parameter #0:
+ Missing nullability on parameter `name` in method `getFileStreamPath`
+MissingNullability: android.test.RenamingDelegatingContext#openFileInput(String):
+ Missing nullability on method `openFileInput` return
+MissingNullability: android.test.RenamingDelegatingContext#openFileInput(String) parameter #0:
+ Missing nullability on parameter `name` in method `openFileInput`
+MissingNullability: android.test.RenamingDelegatingContext#openFileOutput(String, int):
+ Missing nullability on method `openFileOutput` return
+MissingNullability: android.test.RenamingDelegatingContext#openFileOutput(String, int) parameter #0:
+ Missing nullability on parameter `name` in method `openFileOutput`
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory):
+ Missing nullability on method `openOrCreateDatabase` return
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory) parameter #0:
+ Missing nullability on parameter `name` in method `openOrCreateDatabase`
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory) parameter #2:
+ Missing nullability on parameter `factory` in method `openOrCreateDatabase`
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler):
+ Missing nullability on method `openOrCreateDatabase` return
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler) parameter #0:
+ Missing nullability on parameter `name` in method `openOrCreateDatabase`
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler) parameter #2:
+ Missing nullability on parameter `factory` in method `openOrCreateDatabase`
+MissingNullability: android.test.RenamingDelegatingContext#openOrCreateDatabase(String, int, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler) parameter #3:
+ Missing nullability on parameter `errorHandler` in method `openOrCreateDatabase`
+
+
+ProtectedMember: android.test.ActivityInstrumentationTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.ActivityInstrumentationTestCase.setUp()}
+ProtectedMember: android.test.ActivityInstrumentationTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.ActivityInstrumentationTestCase.tearDown()}
+ProtectedMember: android.test.ActivityInstrumentationTestCase2#runTest():
+ Protected methods not allowed; must be public: method android.test.ActivityInstrumentationTestCase2.runTest()}
+ProtectedMember: android.test.ActivityInstrumentationTestCase2#setUp():
+ Protected methods not allowed; must be public: method android.test.ActivityInstrumentationTestCase2.setUp()}
+ProtectedMember: android.test.ActivityInstrumentationTestCase2#tearDown():
+ Protected methods not allowed; must be public: method android.test.ActivityInstrumentationTestCase2.tearDown()}
+ProtectedMember: android.test.ActivityUnitTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.ActivityUnitTestCase.setUp()}
+ProtectedMember: android.test.ActivityUnitTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.ActivityUnitTestCase.tearDown()}
+ProtectedMember: android.test.ApplicationTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.ApplicationTestCase.setUp()}
+ProtectedMember: android.test.ApplicationTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.ApplicationTestCase.tearDown()}
+ProtectedMember: android.test.ProviderTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.ProviderTestCase.setUp()}
+ProtectedMember: android.test.ProviderTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.ProviderTestCase.tearDown()}
+ProtectedMember: android.test.ProviderTestCase2#setUp():
+ Protected methods not allowed; must be public: method android.test.ProviderTestCase2.setUp()}
+ProtectedMember: android.test.ProviderTestCase2#tearDown():
+ Protected methods not allowed; must be public: method android.test.ProviderTestCase2.tearDown()}
+ProtectedMember: android.test.ServiceTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.ServiceTestCase.setUp()}
+ProtectedMember: android.test.ServiceTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.ServiceTestCase.tearDown()}
+ProtectedMember: android.test.SingleLaunchActivityTestCase#setUp():
+ Protected methods not allowed; must be public: method android.test.SingleLaunchActivityTestCase.setUp()}
+ProtectedMember: android.test.SingleLaunchActivityTestCase#tearDown():
+ Protected methods not allowed; must be public: method android.test.SingleLaunchActivityTestCase.tearDown()}
+ProtectedMember: android.test.SyncBaseInstrumentation#setUp():
+ Protected methods not allowed; must be public: method android.test.SyncBaseInstrumentation.setUp()}
diff --git a/tests/GamePerformance/Android.bp b/tests/GamePerformance/Android.bp
new file mode 100644
index 000000000000..648fd8151b4e
--- /dev/null
+++ b/tests/GamePerformance/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2018 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_helper_app {
+ name: "GamePerformance",
+ // Don't include this package in any target
+ dex_preopt: {
+ enabled: false,
+ },
+ optimize: {
+ enabled: false,
+ },
+ srcs: ["src/**/*.java"],
+ static_libs: ["android-support-test"],
+ libs: [
+ "android.test.base",
+ "android.test.runner",
+ ],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/tests/GamePerformance/Android.mk b/tests/GamePerformance/Android.mk
deleted file mode 100644
index 58654de34029..000000000000
--- a/tests/GamePerformance/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018 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)
-
-# Don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-
-LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
-
-LOCAL_PACKAGE_NAME := GamePerformance
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-
-include $(BUILD_PACKAGE)
diff --git a/tests/NullHomeTest/Android.bp b/tests/NullHomeTest/Android.bp
new file mode 100644
index 000000000000..99248bfe1da1
--- /dev/null
+++ b/tests/NullHomeTest/Android.bp
@@ -0,0 +1,22 @@
+// Copyright 2020 Google Inc. All Rights Reserved.
+//
+// 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: "NullHomeTest",
+ srcs: ["src/**/*.java"],
+ certificate: "platform",
+ platform_apis: true,
+ static_libs: ["android-support-test"],
+ test_suites: ["device-tests"],
+}
diff --git a/tests/NullHomeTest/AndroidManifest.xml b/tests/NullHomeTest/AndroidManifest.xml
new file mode 100644
index 000000000000..dc6402e03b5a
--- /dev/null
+++ b/tests/NullHomeTest/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.test.nullhome"
+ android:sharedUserId="android.uid.system" >
+
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.test.nullhome"
+ android:label="Check if no null Home exists/is enabled" />
+
+ <application android:label="Null Home Test">
+ <uses-library android:name="android.test.runner" />
+ </application>
+</manifest>
diff --git a/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
new file mode 100644
index 000000000000..1d77cdc51187
--- /dev/null
+++ b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.test.nullhome;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * Check if NullHome/SystemUserHome activity does not exist/is disabled.
+ *
+ * SystemUserHome is only enabled in bootable CSI (csi_x86, csi_arm64)
+ * products and should not be enabled in other products.
+ *
+ * Shell's NullHome is empty and caused issues in sevaral manual GUI tests
+ * that try to select/use it, and should be removed.
+ *
+ * Settings' FallbackHome is fine because it's specially handled by Settings.
+ *
+ */
+
+@RunWith(JUnit4.class)
+public class NullHomeTest {
+ private static final String TAG = "NullHomeTest";
+ private Context mContext;
+ private PackageManager mPm;
+
+ @Before
+ public void before() {
+ Log.d(TAG, "beforeClass()");
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ mPm = mContext.getPackageManager();
+ }
+
+ @Test
+ public void checkNullHome() {
+ final List<ResolveInfo> homeActivities = new ArrayList<>();
+
+ mPm.getHomeActivities(homeActivities);
+ for (ResolveInfo activity : homeActivities) {
+ Log.d(TAG, "Home activity: " + activity.activityInfo.packageName);
+ Assert.assertNotEquals(activity.activityInfo.packageName,
+ "com.android.internal.app.SystemUserHomeActivity");
+ Assert.assertNotEquals(activity.activityInfo.packageName,
+ "com.android.shell");
+ }
+ }
+}
diff --git a/tests/ProtoInputStreamTests/Android.bp b/tests/ProtoInputStreamTests/Android.bp
new file mode 100644
index 000000000000..ecc405664128
--- /dev/null
+++ b/tests/ProtoInputStreamTests/Android.bp
@@ -0,0 +1,33 @@
+// 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.
+
+android_test {
+ name: "ProtoInputStreamTests",
+ proto: {
+ type: "nano",
+ },
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.proto",
+ ],
+ platform_apis: true,
+ certificate: "platform",
+ test_suites: ["device-tests"],
+ libs: ["android.test.runner"],
+ static_libs: [
+ "androidx.test.rules",
+ "frameworks-base-testutils",
+ "mockito-target-minus-junit4",
+ ],
+}
diff --git a/tests/ProtoInputStreamTests/Android.mk b/tests/ProtoInputStreamTests/Android.mk
deleted file mode 100644
index eb747cc2cdcc..000000000000
--- a/tests/ProtoInputStreamTests/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := ProtoInputStreamTests
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_MODULE_TAGS := tests optional
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-proto-files-under, src)
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules \
- frameworks-base-testutils \
- mockito-target-minus-junit4
-
-include $(BUILD_PACKAGE) \ No newline at end of file
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
index ef15b668e24c..a50f0461fae6 100644
--- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -39,12 +39,12 @@ class MatchAllNetworkSpecifierTest {
}
@Test(expected = IllegalStateException::class)
- fun testSatisfiedBy() {
+ fun testCanBeSatisfiedBy() {
val specifier = MatchAllNetworkSpecifier()
val discoverySession = Mockito.mock(DiscoverySession::class.java)
val peerHandle = Mockito.mock(PeerHandle::class.java)
val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
peerHandle).build()
- specifier.satisfiedBy(wifiAwareNetworkSpecifier)
+ specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier)
}
}
diff --git a/tests/net/integration/AndroidManifest.xml b/tests/net/integration/AndroidManifest.xml
index 09c0e4826075..f5a4234ede9e 100644
--- a/tests/net/integration/AndroidManifest.xml
+++ b/tests/net/integration/AndroidManifest.xml
@@ -16,50 +16,55 @@
* limitations under the License.
*/
-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.net.integrationtests">
+ package="com.android.server.net.integrationtests">
<!-- For ConnectivityService registerReceiverAsUser (receiving broadcasts) -->
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<!-- PermissionMonitor sets network permissions for each user -->
- <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
<!-- ConnectivityService sends notifications to BatteryStats -->
- <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
<!-- Reading network status -->
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.NETWORK_FACTORY" />
- <uses-permission android:name="android.permission.NETWORK_STACK" />
- <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
- <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.NETWORK_FACTORY"/>
+ <!-- Obtain LinkProperties callbacks with sensitive fields -->
+ <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
+ <uses-permission android:name="android.permission.NETWORK_STACK"/>
+ <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY"/>
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<!-- Reading DeviceConfig flags -->
- <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
<application android:debuggable="true">
- <uses-library android:name="android.test.runner" />
+ <uses-library android:name="android.test.runner"/>
<!-- This manifest is merged with the base manifest of the real NetworkStack app.
- Remove the NetworkStackService from the base (real) manifest, and replace with a test
- service that responds to the same intent -->
+ Remove the NetworkStackService from the base (real) manifest, and replace with a test
+ service that responds to the same intent -->
<service android:name=".TestNetworkStackService"
- android:process="com.android.server.net.integrationtests.testnetworkstack">
+ android:process="com.android.server.net.integrationtests.testnetworkstack"
+ android:exported="true">
<intent-filter>
<action android:name="android.net.INetworkStackConnector.Test"/>
</intent-filter>
</service>
<service android:name=".NetworkStackInstrumentationService"
- android:process="com.android.server.net.integrationtests.testnetworkstack">
+ android:process="com.android.server.net.integrationtests.testnetworkstack"
+ android:exported="true">
<intent-filter>
<action android:name=".INetworkStackInstrumentation"/>
</intent-filter>
</service>
<service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
- android:process="com.android.server.net.integrationtests.testnetworkstack"
- android:permission="android.permission.BIND_JOB_SERVICE"/>
+ android:process="com.android.server.net.integrationtests.testnetworkstack"
+ android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.server.net.integrationtests"
- android:label="Frameworks Net Integration Tests" />
+ android:targetPackage="com.android.server.net.integrationtests"
+ android:label="Frameworks Net Integration Tests"/>
</manifest>
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index c4801aab5c32..bc069e148b99 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -28,10 +28,13 @@ import android.net.INetd
import android.net.INetworkPolicyManager
import android.net.INetworkStatsService
import android.net.LinkProperties
+import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkRequest
import android.net.TestNetworkStackClient
+import android.net.Uri
import android.net.metrics.IpConnectivityLog
import android.os.ConditionVariable
import android.os.IBinder
@@ -64,6 +67,8 @@ import org.mockito.Mockito.spy
import org.mockito.MockitoAnnotations
import org.mockito.Spy
import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import kotlin.test.fail
@@ -110,6 +115,10 @@ class ConnectivityServiceIntegrationTest {
private val bindingCondition = ConditionVariable(false)
private val realContext get() = InstrumentationRegistry.getInstrumentation().context
+ private val httpProbeUrl get() =
+ realContext.getResources().getString(R.string.config_captive_portal_http_url)
+ private val httpsProbeUrl get() =
+ realContext.getResources().getString(R.string.config_captive_portal_https_url)
private class InstrumentationServiceConnection : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
@@ -188,12 +197,8 @@ class ConnectivityServiceIntegrationTest {
val testCallback = TestableNetworkCallback()
cm.registerNetworkCallback(request, testCallback)
- nsInstrumentation.addHttpResponse(HttpResponse(
- "http://test.android.com",
- responseCode = 204, contentLength = 42, redirectUrl = null))
- nsInstrumentation.addHttpResponse(HttpResponse(
- "https://secure.test.android.com",
- responseCode = 204, contentLength = 42, redirectUrl = null))
+ nsInstrumentation.addHttpResponse(HttpResponse(httpProbeUrl, responseCode = 204))
+ nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204))
val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, LinkProperties(), context)
networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS)
@@ -204,4 +209,52 @@ class ConnectivityServiceIntegrationTest {
testCallback.expectAvailableThenValidatedCallbacks(na.network, TEST_TIMEOUT_MS)
assertEquals(2, nsInstrumentation.getRequestUrls().size)
}
+
+ @Test
+ fun testCapportApi() {
+ val request = NetworkRequest.Builder()
+ .clearCapabilities()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build()
+ val testCb = TestableNetworkCallback()
+ val apiUrl = "https://capport.android.com"
+
+ cm.registerNetworkCallback(request, testCb)
+ nsInstrumentation.addHttpResponse(HttpResponse(
+ apiUrl,
+ """
+ |{
+ | "captive": true,
+ | "user-portal-url": "https://login.capport.android.com",
+ | "venue-info-url": "https://venueinfo.capport.android.com"
+ |}
+ """.trimMargin()))
+
+ // Tests will fail if a non-mocked query is received: mock the HTTPS probe, but not the
+ // HTTP probe as it should not be sent.
+ // Even if the HTTPS probe succeeds, a portal should be detected as the API takes precedence
+ // in that case.
+ nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204))
+
+ val lp = LinkProperties()
+ lp.captivePortalApiUrl = Uri.parse(apiUrl)
+ val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, lp, context)
+ networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS)
+
+ na.addCapability(NET_CAPABILITY_INTERNET)
+ na.connect()
+
+ testCb.expectAvailableCallbacks(na.network, validated = false, tmt = TEST_TIMEOUT_MS)
+
+ val capportData = testCb.expectLinkPropertiesThat(na, TEST_TIMEOUT_MS) {
+ it.captivePortalData != null
+ }.lp.captivePortalData
+ assertNotNull(capportData)
+ assertTrue(capportData.isCaptive)
+ assertEquals(Uri.parse("https://login.capport.android.com"), capportData.userPortalUrl)
+ assertEquals(Uri.parse("https://venueinfo.capport.android.com"), capportData.venueInfoUrl)
+
+ val nc = testCb.expectCapabilitiesWith(NET_CAPABILITY_CAPTIVE_PORTAL, na, TEST_TIMEOUT_MS)
+ assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED))
+ }
} \ No newline at end of file
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt
index 45073d8df3f7..e2063138fef1 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt
@@ -22,16 +22,21 @@ import android.os.Parcelable
data class HttpResponse(
val requestUrl: String,
val responseCode: Int,
- val contentLength: Long,
- val redirectUrl: String?
+ val content: String = "",
+ val redirectUrl: String? = null
) : Parcelable {
- constructor(p: Parcel): this(p.readString(), p.readInt(), p.readLong(), p.readString())
+ constructor(p: Parcel): this(p.readString(), p.readInt(), p.readString(), p.readString())
+ constructor(requestUrl: String, contentBody: String): this(
+ requestUrl,
+ responseCode = 200,
+ content = contentBody,
+ redirectUrl = null)
override fun writeToParcel(dest: Parcel, flags: Int) {
with(dest) {
writeString(requestUrl)
writeInt(responseCode)
- writeLong(contentLength)
+ writeString(content)
writeString(redirectUrl)
}
}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt
index 4827d2997d93..e807952cec11 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt
@@ -65,6 +65,9 @@ class NetworkStackInstrumentationService : Service() {
*
* <p>For any subsequent HTTP/HTTPS query, the first response with a matching URL will be
* used to mock the query response.
+ *
+ * <p>All requests that are expected to be sent must have a mock response: if an unexpected
+ * request is seen, the test will fail.
*/
override fun addHttpResponse(response: HttpResponse) {
httpResponses.getValue(response.requestUrl).add(response)
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index eec3cdbe8d7f..a44ad1e05259 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -33,9 +33,11 @@ import com.android.server.net.integrationtests.NetworkStackInstrumentationServic
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
+import java.io.ByteArrayInputStream
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLConnection
+import java.nio.charset.StandardCharsets
private const val TEST_NETID = 42
@@ -52,7 +54,7 @@ class TestNetworkStackService : Service() {
doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE)
}
- private class TestPermissionChecker : NetworkStackConnector.PermissionChecker() {
+ private class TestPermissionChecker : NetworkStackService.PermissionChecker() {
override fun enforceNetworkStackCallingPermission() = Unit
}
@@ -62,8 +64,8 @@ class TestNetworkStackService : Service() {
override fun sendNetworkConditionsBroadcast(context: Context, broadcast: Intent) = Unit
}
- private inner class TestNetworkStackConnector(context: Context) :
- NetworkStackConnector(context, TestPermissionChecker()) {
+ private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector(
+ context, TestPermissionChecker(), NetworkStackService.Dependencies()) {
private val network = Network(TEST_NETID)
private val privateDnsBypassNetwork = TestNetwork(TEST_NETID)
@@ -71,11 +73,13 @@ class TestNetworkStackService : Service() {
private inner class TestNetwork(netId: Int) : Network(netId) {
override fun openConnection(url: URL): URLConnection {
val response = InstrumentationConnector.processRequest(url)
+ val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8)
val connection = mock(HttpURLConnection::class.java)
doReturn(response.responseCode).`when`(connection).responseCode
- doReturn(response.contentLength).`when`(connection).contentLengthLong
+ doReturn(responseBytes.size.toLong()).`when`(connection).contentLengthLong
doReturn(response.redirectUrl).`when`(connection).getHeaderField("location")
+ doReturn(ByteArrayInputStream(responseBytes)).`when`(connection).inputStream
return connection
}
}
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index a35fb407bca9..0ffafd45613a 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -92,6 +92,9 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
break;
case TRANSPORT_VPN:
mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
+ // VPNs deduce the SUSPENDED capability from their underlying networks and there
+ // is no public API to let VPN services set it.
+ mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
mScore = ConnectivityConstants.VPN_DEFAULT_SCORE;
break;
default:
diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java
index 2273bc61225c..ada5494efd60 100644
--- a/tests/net/java/android/net/Ikev2VpnProfileTest.java
+++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java
@@ -40,7 +40,10 @@ import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.security.auth.x500.X500Principal;
@@ -106,6 +109,7 @@ public class Ikev2VpnProfileTest {
assertTrue(profile.isBypassable());
assertTrue(profile.isMetered());
assertEquals(TEST_MTU, profile.getMaxMtu());
+ assertEquals(Ikev2VpnProfile.DEFAULT_ALGORITHMS, profile.getAllowedAlgorithms());
}
@Test
@@ -160,6 +164,78 @@ public class Ikev2VpnProfileTest {
}
@Test
+ public void testBuildWithAllowedAlgorithmsAead() throws Exception {
+ final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
+ builder.setAuthPsk(PSK_BYTES);
+
+ List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM);
+ builder.setAllowedAlgorithms(allowedAlgorithms);
+
+ final Ikev2VpnProfile profile = builder.build();
+ assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
+ }
+
+ @Test
+ public void testBuildWithAllowedAlgorithmsNormal() throws Exception {
+ final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
+ builder.setAuthPsk(PSK_BYTES);
+
+ List<String> allowedAlgorithms =
+ Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC);
+ builder.setAllowedAlgorithms(allowedAlgorithms);
+
+ final Ikev2VpnProfile profile = builder.build();
+ assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms());
+ }
+
+ @Test
+ public void testSetAllowedAlgorithmsEmptyList() throws Exception {
+ final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
+
+ try {
+ builder.setAllowedAlgorithms(new ArrayList<>());
+ fail("Expected exception due to no valid algorithm set");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testSetAllowedAlgorithmsInvalidList() throws Exception {
+ final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
+ List<String> allowedAlgorithms = new ArrayList<>();
+
+ try {
+ builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA256));
+ fail("Expected exception due to missing encryption");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.CRYPT_AES_CBC));
+ fail("Expected exception due to missing authentication");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testSetAllowedAlgorithmsInsecureAlgorithm() throws Exception {
+ final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
+ List<String> allowedAlgorithms = new ArrayList<>();
+
+ try {
+ builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_MD5));
+ fail("Expected exception due to insecure algorithm");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA1));
+ fail("Expected exception due to insecure algorithm");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
public void testBuildNoAuthMethodSet() throws Exception {
final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions();
diff --git a/tests/net/java/com/android/internal/net/VpnProfileTest.java b/tests/net/java/com/android/internal/net/VpnProfileTest.java
index ceca6f028866..e5daa71c30ea 100644
--- a/tests/net/java/com/android/internal/net/VpnProfileTest.java
+++ b/tests/net/java/com/android/internal/net/VpnProfileTest.java
@@ -33,7 +33,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/** Unit tests for {@link VpnProfile}. */
@SmallTest
@@ -41,6 +43,9 @@ import java.util.Arrays;
public class VpnProfileTest {
private static final String DUMMY_PROFILE_KEY = "Test";
+ private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23;
+ private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24;
+
@Test
public void testDefaults() throws Exception {
final VpnProfile p = new VpnProfile(DUMMY_PROFILE_KEY);
@@ -67,10 +72,11 @@ public class VpnProfileTest {
assertFalse(p.isMetered);
assertEquals(1360, p.maxMtu);
assertFalse(p.areAuthParamsInline);
+ assertFalse(p.isRestrictedToTestNetworks);
}
private VpnProfile getSampleIkev2Profile(String key) {
- final VpnProfile p = new VpnProfile(key);
+ final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */);
p.name = "foo";
p.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
@@ -116,7 +122,7 @@ public class VpnProfileTest {
@Test
public void testParcelUnparcel() {
- assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 22);
+ assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23);
}
@Test
@@ -159,14 +165,41 @@ public class VpnProfileTest {
assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooManyValues));
}
+ private String getEncodedDecodedIkev2ProfileMissingValues(int... missingIndices) {
+ // Sort to ensure when we remove, we can do it from greatest first.
+ Arrays.sort(missingIndices);
+
+ final String encoded = new String(getSampleIkev2Profile(DUMMY_PROFILE_KEY).encode());
+ final List<String> parts =
+ new ArrayList<>(Arrays.asList(encoded.split(VpnProfile.VALUE_DELIMITER)));
+
+ // Remove from back first to ensure indexing is consistent.
+ for (int i = missingIndices.length - 1; i >= 0; i--) {
+ parts.remove(missingIndices[i]);
+ }
+
+ return String.join(VpnProfile.VALUE_DELIMITER, parts.toArray(new String[0]));
+ }
+
@Test
public void testEncodeDecodeInvalidNumberOfValues() {
- final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
- final String encoded = new String(profile.encode());
- final byte[] tooFewValues =
- encoded.substring(0, encoded.lastIndexOf(VpnProfile.VALUE_DELIMITER)).getBytes();
+ final String tooFewValues =
+ getEncodedDecodedIkev2ProfileMissingValues(
+ ENCODED_INDEX_AUTH_PARAMS_INLINE,
+ ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */);
- assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues));
+ assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()));
+ }
+
+ @Test
+ public void testEncodeDecodeMissingIsRestrictedToTestNetworks() {
+ final String tooFewValues =
+ getEncodedDecodedIkev2ProfileMissingValues(
+ ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */);
+
+ // Verify decoding without isRestrictedToTestNetworks defaults to false
+ final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
+ assertFalse(decoded.isRestrictedToTestNetworks);
}
@Test
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 656fe489d8b8..ea4982ed7c7d 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -75,6 +75,7 @@ import static android.net.NetworkPolicyManager.RULE_NONE;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import static android.net.RouteInfo.RTN_UNREACHABLE;
+import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
@@ -5394,8 +5395,6 @@ public class ConnectivityServiceTest {
// Even though the VPN is unvalidated, it becomes the default network for our app.
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
- // TODO: this looks like a spurious callback.
- callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
callback.assertNoCallback();
assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore());
@@ -5425,6 +5424,47 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testVpnStartsWithUnderlyingCaps() throws Exception {
+ final int uid = Process.myUid();
+
+ final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder()
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .addTransportType(TRANSPORT_VPN)
+ .build();
+ mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
+ vpnNetworkCallback.assertNoCallback();
+
+ // Connect cell. It will become the default network, and in the absence of setting
+ // underlying networks explicitly it will become the sole underlying network for the vpn.
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ mCellNetworkAgent.connect(true);
+
+ final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
+ final ArraySet<UidRange> ranges = new ArraySet<>();
+ ranges.add(new UidRange(uid, uid));
+ mMockVpn.setNetworkAgent(vpnNetworkAgent);
+ mMockVpn.connect();
+ mMockVpn.setUids(ranges);
+ vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
+ false /* isStrictMode */);
+
+ vpnNetworkCallback.expectAvailableCallbacks(vpnNetworkAgent.getNetwork(),
+ false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS);
+ vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent.getNetwork(), TIMEOUT_MS,
+ nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED));
+
+ final NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork());
+ assertTrue(nc.hasTransport(TRANSPORT_VPN));
+ assertTrue(nc.hasTransport(TRANSPORT_CELLULAR));
+ assertFalse(nc.hasTransport(TRANSPORT_WIFI));
+ assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED));
+ assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
+ assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ }
+
+ @Test
public void testVpnSetUnderlyingNetworks() throws Exception {
final int uid = Process.myUid();
@@ -5454,9 +5494,12 @@ public class ConnectivityServiceTest {
assertFalse(nc.hasTransport(TRANSPORT_WIFI));
// For safety reasons a VPN without underlying networks is considered metered.
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
+ // A VPN without underlying networks is not suspended.
+ assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
// Connect cell and use it as an underlying network.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
mCellNetworkAgent.connect(true);
mService.setUnderlyingNetworksForVpn(
@@ -5465,10 +5508,12 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
(caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
- && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
mWiFiNetworkAgent.connect(true);
mService.setUnderlyingNetworksForVpn(
@@ -5477,7 +5522,8 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
(caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
- && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
// Don't disconnect, but note the VPN is not using wifi any more.
mService.setUnderlyingNetworksForVpn(
@@ -5486,16 +5532,36 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
(caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
- && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+
+ // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended.
+ mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+ (caps) -> caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, vpnNetworkAgent);
+
+ // Add NOT_SUSPENDED again and observe VPN is no longer suspended.
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+ (caps) -> caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, vpnNetworkAgent);
- // Use Wifi but not cell. Note the VPN is now unmetered.
+ // Use Wifi but not cell. Note the VPN is now unmetered and not suspended.
mService.setUnderlyingNetworksForVpn(
new Network[] { mWiFiNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
(caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
- && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ && caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
// Use both again.
mService.setUnderlyingNetworksForVpn(
@@ -5504,7 +5570,37 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
(caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
- && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+
+ // Cell is suspended again. As WiFi is not, this should not cause a callback.
+ mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ vpnNetworkCallback.assertNoCallback();
+
+ // Stop using WiFi. The VPN is suspended again.
+ mService.setUnderlyingNetworksForVpn(
+ new Network[] { mCellNetworkAgent.getNetwork() });
+ vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+ (caps) -> caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_CELLULAR)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ // While the SUSPENDED callback should in theory be sent here, it is not. This is
+ // a bug in ConnectivityService, but as the SUSPENDED and RESUMED callbacks have never
+ // been public and are deprecated and slated for removal, there is no sense in spending
+ // resources fixing this bug now.
+
+ // Use both again.
+ mService.setUnderlyingNetworksForVpn(
+ new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
+
+ vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+ (caps) -> caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
+ && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
+ && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ // As above, the RESUMED callback not being sent here is a bug, but not a bug that's
+ // worth anybody's time to fix.
// Disconnect cell. Receive update without even removing the dead network from the
// underlying networks – it's dead anyway. Not metered any more.
@@ -6226,6 +6322,7 @@ public class ConnectivityServiceTest {
int netId = network.getNetId();
callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
callback.assertNoCallback();
assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix());
@@ -6235,6 +6332,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, null);
inOrder.verify(mMockNetd).clatdStop(iface);
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
// If the RA prefix appears while DNS discovery is in progress, discovery is stopped and
@@ -6244,6 +6342,7 @@ public class ConnectivityServiceTest {
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString());
// Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS
// discovery has succeeded.
@@ -6251,6 +6350,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, null);
inOrder.verify(mMockNetd).clatdStop(iface);
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
@@ -6258,13 +6358,40 @@ public class ConnectivityServiceTest {
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromDns);
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
- // If the RA prefix reappears, clatd is restarted and prefix discovery is stopped.
+ // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix
+ // discovery is not stopped, and there are no callbacks.
+ lp.setNat64Prefix(pref64FromDns);
+ mCellNetworkAgent.sendLinkProperties(lp);
+ callback.assertNoCallback();
+ inOrder.verify(mMockNetd, never()).clatdStop(iface);
+ inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString());
+ inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString());
+
+ // If the RA is later withdrawn, nothing happens again.
+ lp.setNat64Prefix(null);
+ mCellNetworkAgent.sendLinkProperties(lp);
+ callback.assertNoCallback();
+ inOrder.verify(mMockNetd, never()).clatdStop(iface);
+ inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString());
+ inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString());
+
+ // If the RA prefix changes, clatd is restarted and prefix discovery is stopped.
lp.setNat64Prefix(pref64FromRa);
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromRa);
inOrder.verify(mMockNetd).clatdStop(iface);
inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
+
+ // Stopping prefix discovery results in a prefix removed notification.
+ mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */,
+ pref64FromDnsStr, 96);
+
inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
// If the RA prefix changes, clatd is restarted and prefix discovery is not started.
@@ -6272,7 +6399,9 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(lp);
expectNat64PrefixChange(callback, mCellNetworkAgent, newPref64FromRa);
inOrder.verify(mMockNetd).clatdStop(iface);
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
inOrder.verify(mMockNetd).clatdStart(iface, newPref64FromRa.toString());
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString());
inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
@@ -6285,11 +6414,45 @@ public class ConnectivityServiceTest {
inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString());
inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString());
// The transition between no prefix and DNS prefix is tested in testStackedLinkProperties.
+ // If the same prefix is learned first by DNS and then by RA, and clat is later stopped,
+ // (e.g., because the network disconnects) setPrefix64(netid, "") is never called.
+ lp.setNat64Prefix(null);
+ mCellNetworkAgent.sendLinkProperties(lp);
+ expectNat64PrefixChange(callback, mCellNetworkAgent, null);
+ inOrder.verify(mMockNetd).clatdStop(iface);
+ inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
+ inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
+ mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
+ pref64FromDnsStr, 96);
+ expectNat64PrefixChange(callback, mCellNetworkAgent, pref64FromDns);
+ inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any());
+
+ lp.setNat64Prefix(pref64FromDns);
+ mCellNetworkAgent.sendLinkProperties(lp);
callback.assertNoCallback();
+ inOrder.verify(mMockNetd, never()).clatdStop(iface);
+ inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString());
+ inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString());
+
+ // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but
+ // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that
+ // clat has been stopped, or the test will be flaky.
+ ConditionVariable cv = registerConnectivityBroadcast(1);
mCellNetworkAgent.disconnect();
+ callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ waitFor(cv);
+
+ inOrder.verify(mMockNetd).clatdStop(iface);
+ inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
+ inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString());
+
mCm.unregisterNetworkCallback(callback);
}
@@ -6953,7 +7116,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
null, null, null, null, null, new NetworkCapabilities(), 0,
- mServiceContext, null, null, mService, null, null, null, 0);
+ mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission(
android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED);
@@ -6969,7 +7132,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
null, null, null, null, null, new NetworkCapabilities(), 0,
- mServiceContext, null, null, mService, null, null, null, 0);
+ mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
@@ -6985,7 +7148,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
null, null, null, null, null, new NetworkCapabilities(), 0,
- mServiceContext, null, null, mService, null, null, null, 0);
+ mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
@@ -7002,7 +7165,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
null, null, network, null, null, new NetworkCapabilities(), 0,
- mServiceContext, null, null, mService, null, null, null, 0);
+ mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
@@ -7036,7 +7199,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo(
null, null, null, null, null, nc, 0, mServiceContext, null, null,
- mService, null, null, null, 0);
+ mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
@@ -7058,7 +7221,7 @@ public class ConnectivityServiceTest {
final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo(
null, null, null, null, null, nc, 0, mServiceContext, null, null,
- mService, null, null, null, 0);
+ mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
index 42d4cf3c382b..a10a3c81bc86 100644
--- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+// Don't warn about deprecated types anywhere in this test, because LegacyTypeTracker's very reason
+// for existence is to power deprecated APIs. The annotation has to apply to the whole file because
+// otherwise warnings will be generated by the imports of deprecated constants like TYPE_xxx.
+@file:Suppress("DEPRECATION")
+
package com.android.server
import android.net.ConnectivityManager.TYPE_ETHERNET
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 24a87177224e..aafa18a532fa 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -38,6 +38,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkProvider;
+import android.os.Binder;
import android.os.INetworkManagementService;
import android.text.format.DateUtils;
@@ -354,7 +355,7 @@ public class LingerMonitorTest {
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
caps, 50, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
- NetworkProvider.ID_NONE);
+ NetworkProvider.ID_NONE, Binder.getCallingUid());
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 1994d1f2ed45..f8d8a56b57c0 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -606,6 +607,7 @@ public class VpnTest {
.addCapability(NET_CAPABILITY_NOT_METERED)
.addCapability(NET_CAPABILITY_NOT_ROAMING)
.addCapability(NET_CAPABILITY_NOT_CONGESTED)
+ .addCapability(NET_CAPABILITY_NOT_SUSPENDED)
.setLinkUpstreamBandwidthKbps(20));
setMockedNetworks(networks);
@@ -621,6 +623,7 @@ public class VpnTest {
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+ assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
Vpn.applyUnderlyingCapabilities(
mConnectivityManager,
@@ -635,6 +638,7 @@ public class VpnTest {
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+ assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
Vpn.applyUnderlyingCapabilities(
mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */);
@@ -646,6 +650,7 @@ public class VpnTest {
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+ assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
Vpn.applyUnderlyingCapabilities(
mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */);
@@ -657,6 +662,7 @@ public class VpnTest {
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+ assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
Vpn.applyUnderlyingCapabilities(
mConnectivityManager,
@@ -671,6 +677,7 @@ public class VpnTest {
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+ assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
}
/**
diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
index 28785f7c9726..3aafe0b075f2 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
@@ -41,6 +41,7 @@ abstract class NetworkStatsBaseTest {
static final String TEST_IFACE = "test0";
static final String TEST_IFACE2 = "test1";
static final String TUN_IFACE = "test_nss_tun0";
+ static final String TUN_IFACE2 = "test_nss_tun1";
static final int UID_RED = 1001;
static final int UID_BLUE = 1002;
@@ -107,10 +108,14 @@ abstract class NetworkStatsBaseTest {
assertEquals("unexpected operations", operations, entry.operations);
}
- VpnInfo createVpnInfo(String[] underlyingIfaces) {
+ static VpnInfo createVpnInfo(String[] underlyingIfaces) {
+ return createVpnInfo(TUN_IFACE, underlyingIfaces);
+ }
+
+ static VpnInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) {
VpnInfo info = new VpnInfo();
info.ownerUid = UID_VPN;
- info.vpnIface = TUN_IFACE;
+ info.vpnIface = vpnIface;
info.underlyingIfaces = underlyingIfaces;
return info;
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index a21f5095c746..4473492d7972 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -104,7 +104,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnRewriteTrafficThroughItself() throws Exception {
+ public void testVpnRewriteTrafficThroughItself() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateVpnInfos(vpnInfos);
@@ -133,7 +133,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithClat() throws Exception {
+ public void testVpnWithClat() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
mFactory.updateVpnInfos(vpnInfos);
mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
@@ -166,7 +166,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithOneUnderlyingIface() throws Exception {
+ public void testVpnWithOneUnderlyingIface() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateVpnInfos(vpnInfos);
@@ -189,7 +189,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
+ public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateVpnInfos(vpnInfos);
@@ -217,7 +217,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
+ public void testVpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateVpnInfos(vpnInfos);
@@ -238,7 +238,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
+ public void testVpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is duplicating traffic across both WiFi and Cell.
@@ -264,7 +264,47 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
+ public void testConcurrentVpns() throws Exception {
+ // Assume two VPNs are connected on two different network interfaces. VPN1 is using
+ // TEST_IFACE and VPN2 is using TEST_IFACE2.
+ final VpnInfo[] vpnInfos = new VpnInfo[] {
+ createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}),
+ createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})};
+ mFactory.updateVpnInfos(vpnInfos);
+
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+ // over VPN1.
+ // 700 bytes (70 packets) were sent, and 3000 bytes (300 packets) were received by UID_RED
+ // over VPN2.
+ // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+ // over VPN1.
+ // 250 bytes (25 packets) were sent, and 500 bytes (50 packets) were received by UID_BLUE
+ // over VPN2.
+ // VPN1 sent 1650 bytes (150 packets), and received 3300 (300 packets) over TEST_IFACE.
+ // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
+ // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
+ // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
+ // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
+ // VPN2 sent 1045 bytes (95 packets), and received 3850 (350 packets) over TEST_IFACE2.
+ // Of 1045 bytes sent over Cell, expect 700 bytes attributed to UID_RED, 250 bytes
+ // attributed to UID_BLUE, and 95 bytes attributed to UID_VPN.
+ // Of 3850 bytes received over Cell, expect 3000 bytes attributed to UID_RED, 500 bytes
+ // attributed to UID_BLUE, and 350 bytes attributed to UID_VPN.
+ final NetworkStats tunStats =
+ parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_two_vpn);
+
+ assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
+ assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+ assertValues(tunStats, TEST_IFACE2, UID_RED, 3000L, 300L, 700L, 70L);
+ assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 250L, 25L);
+ assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L);
+ assertValues(tunStats, TEST_IFACE2, UID_VPN, 350L, 0L, 95L, 0L);
+ }
+
+ @Test
+ public void testVpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
@@ -291,7 +331,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
+ public void testVpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
@@ -314,7 +354,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
}
@Test
- public void vpnWithIncorrectUnderlyingIface() throws Exception {
+ public void testVpnWithIncorrectUnderlyingIface() throws Exception {
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1db90b71e2b1..a1bb0d586916 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -60,14 +60,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -95,8 +94,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.SimpleClock;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import androidx.test.InstrumentationRegistry;
@@ -126,6 +123,7 @@ import java.io.File;
import java.time.Clock;
import java.time.ZoneOffset;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Tests for {@link NetworkStatsService}.
@@ -168,14 +166,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private @Mock NetworkStatsSettings mSettings;
private @Mock IBinder mBinder;
private @Mock AlarmManager mAlarmManager;
- private @Mock TelephonyManager mTelephonyManager;
+ @Mock
+ private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
private HandlerThread mHandlerThread;
private NetworkStatsService mService;
private INetworkStatsSession mSession;
private INetworkManagementEventObserver mNetworkObserver;
- @Nullable
- private PhoneStateListener mPhoneStateListener;
private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
@Override
@@ -203,8 +200,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
mHandlerThread = new HandlerThread("HandlerThread");
final NetworkStatsService.Dependencies deps = makeDependencies();
mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
- mClock, mTelephonyManager, mSettings,
- mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
+ mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir,
+ getBaseDir(mStatsDir), deps);
mElapsedRealtime = 0L;
@@ -224,12 +221,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
verify(mNetManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
-
- // Capture the phone state listener that created by service.
- final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
- ArgumentCaptor.forClass(PhoneStateListener.class);
- verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
- mPhoneStateListener = phoneStateListenerCaptor.getValue();
}
@NonNull
@@ -239,6 +230,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public HandlerThread makeHandlerThread() {
return mHandlerThread;
}
+
+ @Override
+ public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(
+ @NonNull Context context, @NonNull Executor executor,
+ @NonNull NetworkStatsService service) {
+
+ return mNetworkStatsSubscriptionsMonitor;
+ }
};
}
@@ -678,10 +677,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// TODO: support per IMSI state
private void setMobileRatTypeAndWaitForIdle(int ratType) {
- final ServiceState mockSs = mock(ServiceState.class);
- when(mockSs.getDataNetworkType()).thenReturn(ratType);
- mPhoneStateListener.onServiceStateChanged(mockSs);
-
+ when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
+ .thenReturn(ratType);
+ mService.handleOnCollapsedRatTypeChanged();
HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn
new file mode 100644
index 000000000000..eb0513b10049
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn
@@ -0,0 +1,9 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 test_nss_tun1 0x0 1001 0 3000 300 700 70 0 0 0 0 0 0 0 0 0 0 0 0
+5 test_nss_tun1 0x0 1002 0 500 50 250 25 0 0 0 0 0 0 0 0 0 0 0 0
+6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+7 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
+8 test1 0x0 1004 0 3850 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+9 test1 0x0 1004 1 0 0 1045 95 0 0 0 0 0 0 0 0 0 0 0 0 \ No newline at end of file
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index 8d99ac7100eb..7218ae3550c6 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -222,6 +222,10 @@ public class TestableLooper {
return sLoopers.get(test);
}
+ public static void remove(Object test) {
+ sLoopers.remove(test);
+ }
+
static class LooperFrameworkMethod extends FrameworkMethod {
private HandlerThread mHandlerThread;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index f354bb610224..7afb0000aea1 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1659,13 +1659,24 @@ class Linker {
return 1;
}
- // First extract the Package name without modifying it (via --rename-manifest-package).
+ // First extract the package name without modifying it (via --rename-manifest-package).
if (Maybe<AppInfo> maybe_app_info =
ExtractAppInfoFromManifest(manifest_xml.get(), context_->GetDiagnostics())) {
+ // Extract the package name from the manifest ignoring the value of --rename-manifest-package.
const AppInfo& app_info = maybe_app_info.value();
context_->SetCompilationPackage(app_info.package);
}
+ // Determine the package name under which to merge resources.
+ if (options_.rename_resources_package) {
+ if (!options_.custom_java_package) {
+ // Generate the R.java under the original package name instead of the package name specified
+ // through --rename-resources-package.
+ options_.custom_java_package = context_->GetCompilationPackage();
+ }
+ context_->SetCompilationPackage(options_.rename_resources_package.value());
+ }
+
// Now that the compilation package is set, load the dependencies. This will also extract
// the Android framework's versionCode and versionName, if they exist.
if (!LoadSymbolsFromIncludePaths()) {
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 7c583858ee1d..e62e0a6b9f62 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -43,6 +43,7 @@ struct LinkOptions {
bool output_to_directory = false;
bool auto_add_overlay = false;
OutputFormat output_format = OutputFormat::kApk;
+ Maybe<std::string> rename_resources_package;
// Java/Proguard options.
Maybe<std::string> generate_java_class_path;
@@ -244,10 +245,16 @@ class LinkCommand : public Command {
&options_.auto_add_overlay);
AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
&options_.manifest_fixer_options.rename_manifest_package);
+ AddOptionalFlag("--rename-resources-package", "Renames the package in resources table",
+ &options_.rename_resources_package);
AddOptionalFlag("--rename-instrumentation-target-package",
"Changes the name of the target package for instrumentation. Most useful\n"
"when used in conjunction with --rename-manifest-package.",
&options_.manifest_fixer_options.rename_instrumentation_target_package);
+ AddOptionalFlag("--rename-overlay-target-package",
+ "Changes the name of the target package for overlay. Most useful\n"
+ "when used in conjunction with --rename-manifest-package.",
+ &options_.manifest_fixer_options.rename_overlay_target_package);
AddOptionalFlagList("-0", "File extensions not to compress.",
&options_.extensions_to_not_compress);
AddOptionalSwitch("--no-compress", "Do not compress any resources.",
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 49909f6e2b8e..06303c273261 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -236,6 +236,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
}
}
+ if (options_.rename_overlay_target_package) {
+ if (!util::IsJavaPackageName(options_.rename_overlay_target_package.value())) {
+ diag->Error(DiagMessage()
+ << "invalid overlay target package override '"
+ << options_.rename_overlay_target_package.value()
+ << "'");
+ return false;
+ }
+ }
+
// Common <intent-filter> actions.
xml::XmlNodeAction intent_filter_action;
intent_filter_action["action"].Action(RequiredNameIsNotEmpty);
@@ -337,7 +347,17 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
manifest_action["instrumentation"]["meta-data"] = meta_data_action;
manifest_action["original-package"];
- manifest_action["overlay"];
+ manifest_action["overlay"].Action([&](xml::Element* el) -> bool {
+ if (!options_.rename_overlay_target_package) {
+ return true;
+ }
+
+ if (xml::Attribute* attr =
+ el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
+ attr->value = options_.rename_overlay_target_package.value();
+ }
+ return true;
+ });
manifest_action["protected-broadcast"];
manifest_action["adopt-permissions"];
manifest_action["uses-permission"];
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index 3ef57d0d0e42..ec4367b450fb 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -44,6 +44,10 @@ struct ManifestFixerOptions {
// <instrumentation>.
Maybe<std::string> rename_instrumentation_target_package;
+ // The Android package to use instead of the one defined in 'android:targetPackage' in
+ // <overlay>.
+ Maybe<std::string> rename_overlay_target_package;
+
// The version name to set if 'android:versionName' is not defined in <manifest> or if
// replace_version is set.
Maybe<std::string> version_name_default;
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 3f1ee36dea4a..3aba4e2ec49f 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -325,6 +325,32 @@ TEST_F(ManifestFixerTest,
EXPECT_THAT(attr->value, StrEq("com.android"));
}
+TEST_F(ManifestFixerTest,
+ RenameManifestOverlayPackageAndFullyQualifyTarget) {
+ ManifestFixerOptions options;
+ options.rename_overlay_target_package = std::string("com.android");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <overlay android:targetName="Customization" android:targetPackage="android" />
+ </manifest>)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Element* overlay_el =
+ manifest_el->FindChild({}, "overlay");
+ ASSERT_THAT(overlay_el, NotNull());
+
+ xml::Attribute* attr =
+ overlay_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("com.android"));
+}
+
TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
ManifestFixerOptions options;
options.version_name_default = std::string("Beta");
diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp
index fa7d3d4031d4..f521a63255e1 100644
--- a/tools/bit/adb.cpp
+++ b/tools/bit/adb.cpp
@@ -200,7 +200,7 @@ skip_bytes(int fd, ssize_t size, char* scratch, int scratchSize)
static int
skip_unknown_field(int fd, uint64_t tag, char* scratch, int scratchSize) {
- bool done;
+ bool done = false;
int err;
uint64_t size;
switch (tag & 0x7) {
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 0b2077d9bba0..de6b4785ec37 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -18,10 +18,10 @@ Generate API lists for non-SDK API enforcement.
"""
import argparse
from collections import defaultdict
+import functools
import os
-import sys
import re
-import functools
+import sys
# Names of flags recognized by the `hiddenapi` tool.
FLAG_WHITELIST = "whitelist"
@@ -30,6 +30,7 @@ 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_GREYLIST_MAX_R = "greylist-max-r"
FLAG_CORE_PLATFORM_API = "core-platform-api"
FLAG_PUBLIC_API = "public-api"
FLAG_SYSTEM_API = "system-api"
@@ -43,13 +44,14 @@ FLAGS_API_LIST = [
FLAG_GREYLIST_MAX_O,
FLAG_GREYLIST_MAX_P,
FLAG_GREYLIST_MAX_Q,
+ FLAG_GREYLIST_MAX_R,
]
ALL_FLAGS = FLAGS_API_LIST + [
FLAG_CORE_PLATFORM_API,
FLAG_PUBLIC_API,
FLAG_SYSTEM_API,
FLAG_TEST_API,
- ]
+]
FLAGS_API_LIST_SET = set(FLAGS_API_LIST)
ALL_FLAGS_SET = set(ALL_FLAGS)
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 91f875ed9918..ba1267b28fbb 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -368,10 +368,13 @@ static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination
// Don't generate a variable twice
if (!hasDefaultFlags[i]) variableNames[fieldName] = false;
}
+ // hasDefaultFlags[i] has been initialized in the above for-loop,
+ // but clang-tidy analyzer still report uninitized values.
+ // So we use NOLINT to suppress those false positives.
bool allDefaults = true;
for (size_t i=0; i<fieldsInOrder.size(); i++) {
- allDefaults &= hasDefaultFlags[i];
+ allDefaults &= hasDefaultFlags[i]; // NOLINT(clang-analyzer-core.uninitialized.Assign)
}
parents->erase(messageName); // erase the message type name when exit the message.
@@ -384,7 +387,7 @@ static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination
printf("Privacy* %s[] = {\n", messageName.c_str());
for (size_t i=0; i<fieldsInOrder.size(); i++) {
const FieldDescriptor* field = fieldsInOrder[i];
- if (hasDefaultFlags[i]) continue;
+ if (hasDefaultFlags[i]) continue; // NOLINT(clang-analyzer-core.uninitialized.Branch)
printf(" &%s,\n", getFieldName(field).c_str());
policyCount++;
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 47d8f13bf9ef..29e09a11590b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -892,7 +892,7 @@ public class WifiManager {
* The RSSI (signal strength) has changed.
*
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- * @see {@link #EXTRA_NEW_RSSI}
+ * @see #EXTRA_NEW_RSSI
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
index 00cb243efcaa..689ace5bf5b9 100644
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ b/wifi/java/android/net/wifi/WpsInfo.java
@@ -22,7 +22,7 @@ import android.os.Parcelable;
/**
* A class representing Wi-Fi Protected Setup
*
- * {@see WifiP2pConfig}
+ * {@see android.net.wifi.p2p.WifiP2pConfig}
*/
public class WpsInfo implements Parcelable {