summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rwxr-xr-xapi/current.txt33
-rw-r--r--api/system-current.txt19
-rw-r--r--api/test-current.txt76
-rw-r--r--cmds/statsd/src/atoms.proto15
-rw-r--r--config/hiddenapi-greylist.txt269
-rw-r--r--core/java/android/content/Context.java3
-rw-r--r--core/java/android/net/CaptivePortal.java2
-rw-r--r--core/java/android/net/ConnectivityManager.java68
-rw-r--r--core/java/android/net/DnsResolver.java255
-rw-r--r--core/java/android/net/IConnectivityManager.aidl2
-rw-r--r--core/java/android/net/NattSocketKeepalive.java13
-rw-r--r--core/java/android/net/NetworkAgent.java8
-rw-r--r--core/java/android/net/NetworkStats.java351
-rw-r--r--core/java/android/net/SocketKeepalive.java19
-rw-r--r--core/java/android/net/StaticIpConfiguration.aidl (renamed from services/net/java/android/net/StaticIpConfigurationParcelable.aidl)9
-rw-r--r--core/java/android/net/StaticIpConfiguration.java2
-rw-r--r--core/java/android/net/TcpSocketKeepalive.java11
-rw-r--r--core/java/android/net/apf/ApfCapabilities.aidl20
-rw-r--r--core/java/android/net/metrics/DhcpErrorEvent.java48
-rw-r--r--core/java/android/net/metrics/ValidationProbeEvent.java7
-rw-r--r--core/java/android/nfc/NfcAdapter.java30
-rw-r--r--core/java/android/os/INetworkManagementService.aidl11
-rw-r--r--core/java/android/widget/TextView.java2
-rw-r--r--core/java/com/android/internal/app/AlertActivity.java4
-rw-r--r--core/java/com/android/internal/app/AssistUtils.java3
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java1
-rw-r--r--core/java/com/android/internal/app/IntentForwarderActivity.java2
-rw-r--r--core/java/com/android/internal/app/LocaleHelper.java6
-rw-r--r--core/java/com/android/internal/app/LocalePicker.java5
-rw-r--r--core/java/com/android/internal/app/LocaleStore.java9
-rw-r--r--core/java/com/android/internal/app/NetInitiatedActivity.java2
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java4
-rw-r--r--core/java/com/android/internal/app/WindowDecorActionBar.java3
-rw-r--r--core/java/com/android/internal/database/SortCursor.java4
-rw-r--r--core/java/com/android/internal/http/HttpDateTime.java2
-rw-r--r--core/java/com/android/internal/net/NetworkStatsFactory.java5
-rw-r--r--core/java/com/android/internal/net/VpnInfo.java10
-rw-r--r--core/java/com/android/internal/os/AndroidPrintStream.java2
-rw-r--r--core/java/com/android/internal/os/BaseCommand.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java16
-rw-r--r--core/java/com/android/internal/os/BinderInternal.java3
-rw-r--r--core/java/com/android/internal/os/ClassLoaderFactory.java2
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java9
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java6
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java5
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java3
-rw-r--r--core/java/com/android/internal/os/ZygoteSecurityException.java3
-rw-r--r--core/java/com/android/internal/policy/DecorView.java5
-rw-r--r--core/java/com/android/internal/policy/PhoneFallbackEventHandler.java7
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java3
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java11
-rw-r--r--core/java/com/android/internal/util/BitwiseInputStream.java7
-rw-r--r--core/java/com/android/internal/util/BitwiseOutputStream.java6
-rw-r--r--core/java/com/android/internal/util/CharSequences.java4
-rw-r--r--core/java/com/android/internal/util/FastMath.java3
-rw-r--r--core/java/com/android/internal/util/FastXmlSerializer.java2
-rw-r--r--core/java/com/android/internal/util/GrowingArrayUtils.java4
-rw-r--r--core/java/com/android/internal/util/HexDump.java6
-rw-r--r--core/java/com/android/internal/util/IState.java2
-rw-r--r--core/java/com/android/internal/util/MemInfoReader.java6
-rw-r--r--core/java/com/android/internal/util/Preconditions.java8
-rw-r--r--core/java/com/android/internal/util/State.java6
-rw-r--r--core/java/com/android/internal/util/StateMachine.java11
-rw-r--r--core/java/com/android/internal/view/ActionBarPolicy.java10
-rw-r--r--core/java/com/android/internal/view/InputConnectionWrapper.java3
-rw-r--r--core/java/com/android/internal/view/WindowManagerPolicyThread.java2
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenu.java2
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuItem.java2
-rw-r--r--core/java/com/android/internal/view/menu/ContextMenuBuilder.java2
-rw-r--r--core/java/com/android/internal/view/menu/IconMenuItemView.java4
-rw-r--r--core/java/com/android/internal/view/menu/IconMenuView.java7
-rw-r--r--core/java/com/android/internal/view/menu/MenuDialogHelper.java4
-rw-r--r--core/java/com/android/internal/widget/AbsActionBarView.java2
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java2
-rw-r--r--core/java/com/android/internal/widget/ActionBarOverlayLayout.java3
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java2
-rw-r--r--core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java3
-rw-r--r--core/java/com/android/internal/widget/LockPatternChecker.java2
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java31
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java26
-rw-r--r--core/java/com/android/internal/widget/PointerLocationView.java7
-rw-r--r--core/java/com/android/internal/widget/PreferenceImageView.java2
-rw-r--r--core/java/com/android/internal/widget/RecyclerView.java2
-rw-r--r--core/java/com/android/internal/widget/ScrollBarUtils.java3
-rw-r--r--core/java/com/android/internal/widget/SlidingTab.java14
-rw-r--r--core/java/com/android/internal/widget/TextViewInputDisabler.java3
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java5
-rw-r--r--core/java/com/android/server/ResettableTimeout.java3
-rw-r--r--core/java/com/android/server/net/BaseNetworkObserver.java1
-rw-r--r--core/java/com/android/server/net/NetlinkTracker.java4
-rw-r--r--core/java/com/google/android/collect/Lists.java1
-rw-r--r--core/java/com/google/android/collect/Sets.java6
-rw-r--r--core/java/com/google/android/util/AbstractMessageParser.java11
-rw-r--r--core/jni/android_net_NetUtils.cpp2
-rw-r--r--core/proto/android/stats/connectivity/Android.bp25
-rw-r--r--core/proto/android/stats/connectivity/network_stack.proto (renamed from services/net/java/android/net/ApfCapabilitiesParcelable.aidl)15
-rw-r--r--core/res/AndroidManifest.xml15
-rw-r--r--core/res/res/drawable/ic_bluetooth_share_icon.xml27
-rw-r--r--core/res/res/values-night/colors_device_defaults.xml19
-rw-r--r--core/res/res/values/colors_device_defaults.xml1
-rw-r--r--core/res/res/values/config.xml9
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java54
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java9
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java9
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java13
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java14
-rw-r--r--core/tests/coretests/src/android/view/DisplayCutoutTest.java9
-rw-r--r--core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java44
-rw-r--r--core/xsd/Android.bp2
-rw-r--r--core/xsd/permission.xsd9
-rw-r--r--core/xsd/schema/current.txt66
-rw-r--r--data/etc/Android.bp8
-rw-r--r--data/etc/com.android.emergency.xml23
-rw-r--r--data/etc/privapp-permissions-platform.xml8
-rw-r--r--media/java/android/media/projection/OWNERS1
-rw-r--r--packages/ExternalStorageProvider/Android.bp19
-rw-r--r--packages/ExternalStorageProvider/Android.mk13
-rw-r--r--packages/ExternalStorageProvider/tests/Android.bp25
-rw-r--r--packages/ExternalStorageProvider/tests/AndroidManifest.xml13
-rw-r--r--packages/ExternalStorageProvider/tests/AndroidTest.xml29
-rw-r--r--packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java53
-rw-r--r--packages/NetworkStack/Android.bp41
-rw-r--r--packages/NetworkStack/proguard.flags9
-rw-r--r--packages/NetworkStack/res/values/config.xml5
-rw-r--r--packages/NetworkStack/src/android/net/apf/ApfFilter.java90
-rw-r--r--packages/NetworkStack/src/android/net/apf/ApfGenerator.java10
-rw-r--r--packages/NetworkStack/src/android/net/dhcp/DhcpClient.java7
-rw-r--r--packages/NetworkStack/src/android/net/ip/IpClient.java3
-rw-r--r--packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java6
-rw-r--r--packages/NetworkStack/src/android/net/util/NetworkStackUtils.java16
-rw-r--r--packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java9
-rw-r--r--packages/NetworkStack/tests/src/android/net/apf/ApfTest.java2
-rw-r--r--packages/Shell/AndroidManifest.xml2
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java1
-rw-r--r--packages/Shell/tests/Android.mk2
-rw-r--r--packages/Shell/tests/AndroidManifest.xml2
-rw-r--r--packages/Shell/tests/AndroidTest.xml2
-rw-r--r--packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java7
-rw-r--r--packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java62
-rw-r--r--packages/SystemUI/OWNERS1
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/OWNERS1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java44
-rw-r--r--services/core/Android.bp2
-rw-r--r--services/core/java/com/android/server/BatteryService.java19
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java68
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java29
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java7
-rw-r--r--services/core/java/com/android/server/connectivity/DnsManager.java24
-rw-r--r--services/core/java/com/android/server/connectivity/KeepaliveTracker.java108
-rw-r--r--services/core/java/com/android/server/connectivity/Nat464Xlat.java10
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java5
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java19
-rw-r--r--services/core/java/com/android/server/connectivity/PermissionMonitor.java84
-rw-r--r--services/core/java/com/android/server/connectivity/TcpKeepaliveController.java15
-rw-r--r--services/core/java/com/android/server/connectivity/Tethering.java108
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java511
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java13
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java4
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java87
-rw-r--r--services/core/java/com/android/server/media/projection/OWNERS1
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsRecorder.java6
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java70
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java13
-rw-r--r--services/core/java/com/android/server/os/BugreportManagerServiceImpl.java6
-rw-r--r--services/core/java/com/android/server/policy/EventLogTags.logtags8
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java11
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java45
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java14
-rw-r--r--services/core/xsd/Android.bp2
-rw-r--r--services/core/xsd/default-permissions.xsd2
-rw-r--r--services/core/xsd/schema/current.txt9
-rw-r--r--services/net/Android.bp5
-rw-r--r--services/net/java/android/net/DhcpResultsParcelable.aidl4
-rw-r--r--services/net/java/android/net/ProvisioningConfigurationParcelable.aidl8
-rw-r--r--services/net/java/android/net/TcpKeepalivePacketData.java39
-rw-r--r--services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl2
-rw-r--r--services/net/java/android/net/shared/IpConfigurationParcelableUtil.java64
-rw-r--r--services/net/java/android/net/shared/NetworkMonitorUtils.java8
-rw-r--r--services/net/java/android/net/shared/ProvisioningConfiguration.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java9
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java2
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java13
-rw-r--r--telephony/java/android/telephony/AccessNetworkConstants.java3
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java35
-rw-r--r--telephony/java/android/telephony/DataSpecificRegistrationInfo.java (renamed from telephony/java/android/telephony/DataSpecificRegistrationStates.java)58
-rw-r--r--telephony/java/android/telephony/LteVopsSupportInfo.java2
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java44
-rw-r--r--telephony/java/android/telephony/ServiceState.java5
-rw-r--r--telephony/java/android/telephony/SmsManager.java243
-rw-r--r--telephony/java/android/telephony/SubscriptionInfo.java2
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java44
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java54
-rw-r--r--telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java (renamed from telephony/java/android/telephony/VoiceSpecificRegistrationStates.java)47
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java19
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl5
-rw-r--r--tests/net/java/android/net/NetworkStatsTest.java35
-rw-r--r--tests/net/java/android/net/TcpKeepalivePacketDataTest.java23
-rw-r--r--tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java62
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java488
-rw-r--r--tests/net/java/com/android/server/connectivity/DnsManagerTest.java6
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java4
-rw-r--r--tests/net/java/com/android/server/connectivity/Nat464XlatTest.java12
-rw-r--r--tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java215
-rw-r--r--tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java69
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java290
-rw-r--r--tests/utils/testutils/Android.bp5
-rw-r--r--tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java66
-rw-r--r--tests/utils/testutils/java/com/android/test/filters/SelectTest.java13
-rw-r--r--tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java43
230 files changed, 4177 insertions, 1852 deletions
diff --git a/Android.bp b/Android.bp
index fd307e7796a1..523e35637f84 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1552,6 +1552,7 @@ droidstubs {
":openjdk_java_files",
":non_openjdk_java_files",
":opt-telephony-common-srcs",
+ "core/java/**/*.java",
],
arg_files: [
"core/res/AndroidManifest.xml",
diff --git a/api/current.txt b/api/current.txt
index e740b85a3e46..766b6b3609c4 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -54,6 +54,7 @@ package android {
field public static final String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
field public static final String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
field public static final String BROADCAST_WAP_PUSH = "android.permission.BROADCAST_WAP_PUSH";
+ field public static final String CALL_COMPANION_APP = "android.permission.CALL_COMPANION_APP";
field public static final String CALL_PHONE = "android.permission.CALL_PHONE";
field public static final String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
field public static final String CAMERA = "android.permission.CAMERA";
@@ -27116,7 +27117,7 @@ package android.net {
public class ConnectivityManager {
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
method public boolean bindProcessToNetwork(@Nullable android.net.Network);
- method public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+ method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.Network getActiveNetwork();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
@@ -27194,7 +27195,7 @@ package android.net {
public static class ConnectivityManager.NetworkCallback {
ctor public ConnectivityManager.NetworkCallback();
method public void onAvailable(android.net.Network);
- method public void onBlockedStatusChanged(android.net.Network, boolean);
+ method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
@@ -27230,6 +27231,7 @@ package android.net {
method @NonNull public static android.net.DnsResolver getInstance();
method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
+ method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback);
field public static final int CLASS_IN = 1; // 0x1
field public static final int FLAG_EMPTY = 0; // 0x0
field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
@@ -27650,7 +27652,7 @@ package android.net {
method public final void start(@IntRange(from=0xa, to=0xe10) int);
method public final void stop();
field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1
- field public static final int ERROR_HARDWARE_UNSUPPORTED = -30; // 0xffffffe2
+ field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0
field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8
field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
@@ -27658,6 +27660,7 @@ package android.net {
field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7
field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6
+ field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2
}
public static class SocketKeepalive.Callback {
@@ -41957,6 +41960,7 @@ package android.telecom {
field public static final String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
field public static final String EXTRA_INCOMING_VIDEO_STATE = "android.telecom.extra.INCOMING_VIDEO_STATE";
field public static final String EXTRA_IS_DEFAULT_CALL_SCREENING_APP = "android.telecom.extra.IS_DEFAULT_CALL_SCREENING_APP";
+ field public static final String EXTRA_IS_ENABLED = "android.telecom.extra.IS_ENABLED";
field public static final String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
field public static final String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
field public static final String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
@@ -41968,6 +41972,7 @@ package android.telecom {
field public static final String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
field public static final String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
field public static final String METADATA_INCLUDE_SELF_MANAGED_CALLS = "android.telecom.INCLUDE_SELF_MANAGED_CALLS";
+ field public static final String METADATA_IN_CALL_SERVICE_CAR_MODE_UI = "android.telecom.IN_CALL_SERVICE_CAR_MODE_UI";
field public static final String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
field public static final String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -42960,7 +42965,7 @@ package android.telephony {
method public String getCountryIso();
method public int getDataRoaming();
method public CharSequence getDisplayName();
- method public String getGroupUuid();
+ method @Nullable public String getGroupUuid();
method public String getIccId();
method public int getIconTint();
method @Deprecated public int getMcc();
@@ -43001,7 +43006,7 @@ package android.telephony {
method public boolean isNetworkRoaming(int);
method public static boolean isUsableSubscriptionId(int);
method public static boolean isValidSubscriptionId(int);
- method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
+ method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean removeSubscriptionsFromGroup(@NonNull int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setMetered(boolean, int);
@@ -43010,7 +43015,7 @@ package android.telephony {
method public void setSubscriptionOverrideCongested(int, boolean, long);
method public void setSubscriptionOverrideUnmetered(int, boolean, long);
method public void setSubscriptionPlans(int, @NonNull java.util.List<android.telephony.SubscriptionPlan>);
- method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, android.app.PendingIntent);
+ method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, @NonNull android.app.PendingIntent);
field public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
field public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
field public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
@@ -43429,26 +43434,26 @@ package android.telephony.data {
public static class ApnSetting.Builder {
ctor public ApnSetting.Builder();
method public android.telephony.data.ApnSetting build();
- method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(@Nullable String);
method @NonNull public android.telephony.data.ApnSetting.Builder setApnTypeBitmask(int);
method @NonNull public android.telephony.data.ApnSetting.Builder setAuthType(int);
method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierEnabled(boolean);
method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierId(int);
- method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(@Nullable String);
method @Deprecated public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(java.net.InetAddress);
- method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(@Nullable String);
method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int);
- method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(android.net.Uri);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(@Nullable android.net.Uri);
method @NonNull public android.telephony.data.ApnSetting.Builder setMvnoType(int);
method @NonNull public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int);
- method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(String);
- method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(@Nullable String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(@Nullable String);
method @NonNull public android.telephony.data.ApnSetting.Builder setProtocol(int);
method @Deprecated public android.telephony.data.ApnSetting.Builder setProxyAddress(java.net.InetAddress);
- method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(@Nullable String);
method @NonNull public android.telephony.data.ApnSetting.Builder setProxyPort(int);
method @NonNull public android.telephony.data.ApnSetting.Builder setRoamingProtocol(int);
- method @NonNull public android.telephony.data.ApnSetting.Builder setUser(String);
+ method @NonNull public android.telephony.data.ApnSetting.Builder setUser(@Nullable String);
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index a6328a54ca1d..1717382272f3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -836,7 +836,7 @@ package android.content {
method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@RequiresPermission @NonNull android.content.Intent, @NonNull android.os.UserHandle);
field public static final String BACKUP_SERVICE = "backup";
field public static final String CONTEXTHUB_SERVICE = "contexthub";
field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android";
@@ -3086,7 +3086,6 @@ package android.metrics {
package android.net {
public class CaptivePortal implements android.os.Parcelable {
- ctor public CaptivePortal(@NonNull android.os.IBinder);
method public void logEvent(int, @NonNull String);
method public void useNetwork();
field public static final int APP_RETURN_DISMISSED = 0; // 0x0
@@ -3095,14 +3094,14 @@ package android.net {
}
public class ConnectivityManager {
- method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull java.io.FileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method public boolean getAvoidBadWifi();
+ method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+ method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl();
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi();
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
@@ -3276,7 +3275,7 @@ package android.net {
method @Nullable public String getDomains();
method @Nullable public java.net.InetAddress getGateway();
method @Nullable public android.net.LinkAddress getIpAddress();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String);
+ method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
method public void setDomains(@Nullable String);
method public void setGateway(@Nullable java.net.InetAddress);
method public void setIpAddress(@Nullable android.net.LinkAddress);
@@ -3496,7 +3495,7 @@ package android.net.metrics {
}
public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
- method public static String getProbeName(int);
+ method @NonNull public static String getProbeName(int);
field public static final int DNS_FAILURE = 0; // 0x0
field public static final int DNS_SUCCESS = 1; // 0x1
field public static final int PROBE_DNS = 0; // 0x0
@@ -5917,11 +5916,11 @@ package android.telephony {
field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc
}
- public final class DataSpecificRegistrationStates implements android.os.Parcelable {
+ 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 public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationStates> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
}
public final class DisconnectCause {
@@ -6030,7 +6029,7 @@ package android.telephony {
method public int getAccessNetworkTechnology();
method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
method @Nullable public android.telephony.CellIdentity getCellIdentity();
- method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates();
+ method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
method public int getDomain();
method public int getRegistrationState();
method public int getRejectCause();
diff --git a/api/test-current.txt b/api/test-current.txt
index 3c0a75eb5bc6..ca7410931a50 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -602,7 +602,6 @@ package android.media.audiofx {
package android.net {
public class CaptivePortal implements android.os.Parcelable {
- ctor public CaptivePortal(@NonNull android.os.IBinder);
method public void logEvent(int, @NonNull String);
method public void useNetwork();
field public static final int APP_RETURN_DISMISSED = 0; // 0x0
@@ -696,7 +695,7 @@ package android.net {
method @Nullable public String getDomains();
method @Nullable public java.net.InetAddress getGateway();
method @Nullable public android.net.LinkAddress getIpAddress();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String);
+ method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
method public void setDomains(@Nullable String);
method public void setGateway(@Nullable java.net.InetAddress);
method public void setIpAddress(@Nullable android.net.LinkAddress);
@@ -915,7 +914,7 @@ package android.net.metrics {
}
public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
- method public static String getProbeName(int);
+ method @NonNull public static String getProbeName(int);
field public static final int DNS_FAILURE = 0; // 0x0
field public static final int DNS_SUCCESS = 1; // 0x1
field public static final int PROBE_DNS = 0; // 0x0
@@ -1485,10 +1484,34 @@ package android.telecom {
package android.telephony {
+ public final class AccessNetworkConstants {
+ field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+ field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
+ }
+
public class CarrierConfigManager {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
}
+ 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 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 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_OVERRIDE_METADATA = "mbms-download-service-override";
}
@@ -1501,12 +1524,59 @@ package android.telephony {
field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
}
+ public final class NetworkRegistrationInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAccessNetworkTechnology();
+ method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+ method @Nullable public android.telephony.CellIdentity getCellIdentity();
+ method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
+ method public int getDomain();
+ method public int getRegistrationState();
+ method public int getRejectCause();
+ method public int getRoamingType();
+ method public int getTransportType();
+ method public boolean isEmergencyEnabled();
+ method public boolean isRoaming();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+ field public static final int DOMAIN_CS = 1; // 0x1
+ field public static final int DOMAIN_PS = 2; // 0x2
+ 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
+ field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+ field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+ field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+ field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+ field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+ }
+
+ 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 setRegistrationState(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
+ }
+
public class ServiceState implements android.os.Parcelable {
+ method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
method public void setCdmaSystemAndNetworkId(int, int);
method public void setCellBandwidths(int[]);
method public void setChannelNumber(int);
+ method public void setDataRoamingType(int);
method public void setRilDataRadioTechnology(int);
method public void setRilVoiceRadioTechnology(int);
+ method public void setVoiceRoamingType(int);
}
public class TelephonyManager {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2a9f24863852..564e9186b868 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -32,6 +32,7 @@ import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
import "frameworks/base/core/proto/android/server/enums.proto";
+import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
import "frameworks/base/core/proto/android/telecomm/enums.proto";
import "frameworks/base/core/proto/android/telephony/enums.proto";
@@ -164,6 +165,7 @@ message Atom {
BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
ProcessStartTime process_start_time = 169;
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
+ NetworkStackReported network_stack_reported = 182;
}
// Pulled events will start at field 10000.
@@ -3052,3 +3054,16 @@ message ProcessStartTime {
optional string hosting_name = 9;
}
+/**
+ * Push network stack events.
+ *
+ * Log from:
+ * frameworks/base/packages/NetworkStack/
+ */
+message NetworkStackReported {
+ // The id that indicates the event reported from NetworkStack.
+ optional int32 event_id = 1;
+ // The data for the reported events.
+ optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES];
+}
+
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index e3c7a2f9431a..7efadf20c3e4 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -794,11 +794,6 @@ Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
Lcom/android/internal/app/AlertActivity;-><init>()V
-Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController;
-Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;
-Lcom/android/internal/app/AlertActivity;->setupAlert()V
-Lcom/android/internal/app/AssistUtils;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName;
Lcom/android/internal/app/ChooserActivity;-><init>()V
Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -826,34 +821,9 @@ Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_stopWatchingMode:I
Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService;
-Lcom/android/internal/app/IntentForwarderActivity;->TAG:Ljava/lang/String;
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
-Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;-><init>(Ljava/util/Locale;Z)V
-Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->compare(Lcom/android/internal/app/LocaleStore$LocaleInfo;Lcom/android/internal/app/LocaleStore$LocaleInfo;)I
-Lcom/android/internal/app/LocaleHelper;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
-Lcom/android/internal/app/LocaleHelper;->getDisplayName(Ljava/util/Locale;Ljava/util/Locale;Z)Ljava/lang/String;
-Lcom/android/internal/app/LocaleHelper;->normalizeForSearch(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;
-Lcom/android/internal/app/LocalePicker$LocaleInfo;->getLocale()Ljava/util/Locale;
-Lcom/android/internal/app/LocalePicker;->getLocales()Landroid/os/LocaleList;
-Lcom/android/internal/app/LocalePicker;->updateLocale(Ljava/util/Locale;)V
-Lcom/android/internal/app/LocalePicker;->updateLocales(Landroid/os/LocaleList;)V
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameInUiLanguage()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameNative()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getId()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getLocale()Ljava/util/Locale;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getParent()Ljava/util/Locale;
-Lcom/android/internal/app/LocaleStore;->fillCache(Landroid/content/Context;)V
-Lcom/android/internal/app/LocaleStore;->getLevelLocales(Landroid/content/Context;Ljava/util/Set;Lcom/android/internal/app/LocaleStore$LocaleInfo;Z)Ljava/util/Set;
-Lcom/android/internal/app/LocaleStore;->getLocaleInfo(Ljava/util/Locale;)Lcom/android/internal/app/LocaleStore$LocaleInfo;
-Lcom/android/internal/app/NetInitiatedActivity;->handleNIVerify(Landroid/content/Intent;)V
Lcom/android/internal/app/ResolverActivity;-><init>()V
-Lcom/android/internal/app/ResolverActivity;->mAdapter:Lcom/android/internal/app/ResolverActivity$ResolveListAdapter;
-Lcom/android/internal/app/ResolverActivity;->mPm:Landroid/content/pm/PackageManager;
-Lcom/android/internal/app/ResolverActivity;->onCreate(Landroid/os/Bundle;Landroid/content/Intent;Ljava/lang/CharSequence;[Landroid/content/Intent;Ljava/util/List;Z)V
-Lcom/android/internal/app/WindowDecorActionBar$TabImpl;->mCallback:Landroid/app/ActionBar$TabListener;
-Lcom/android/internal/app/WindowDecorActionBar;->mTabScrollView:Lcom/android/internal/widget/ScrollingTabContainerView;
-Lcom/android/internal/app/WindowDecorActionBar;->setShowHideAnimationEnabled(Z)V
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
@@ -861,10 +831,6 @@ Lcom/android/internal/backup/LocalTransport;->mDataDir:Ljava/io/File;
Lcom/android/internal/backup/LocalTransport;->mRestorePackage:I
Lcom/android/internal/backup/LocalTransport;->mRestorePackages:[Landroid/content/pm/PackageInfo;
Lcom/android/internal/content/PackageMonitor;-><init>()V
-Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V
-Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor;
-Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor;
-Lcom/android/internal/http/HttpDateTime;->parse(Ljava/lang/String;)J
Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;-><init>()V
Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorId:Ljava/lang/String;
Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorIdEncoding:I
@@ -878,48 +844,11 @@ Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/
Lcom/android/internal/logging/MetricsLogger;-><init>()V
Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
Lcom/android/internal/net/VpnConfig;-><init>()V
-Lcom/android/internal/os/AndroidPrintStream;-><init>(ILjava/lang/String;)V
Lcom/android/internal/os/BaseCommand;-><init>()V
-Lcom/android/internal/os/BaseCommand;->mArgs:Landroid/os/ShellCommand;
Lcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType;
-Lcom/android/internal/os/BinderInternal;->getContextObject()Landroid/os/IBinder;
-Lcom/android/internal/os/BinderInternal;->handleGc()V
-Lcom/android/internal/os/ClassLoaderFactory;->createClassloaderNamespace(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String;
Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->name:Ljava/lang/String;
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_stime:I
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_uptime:J
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_utime:I
-Lcom/android/internal/os/ProcessCpuTracker;-><init>(Z)V
-Lcom/android/internal/os/ProcessCpuTracker;->countWorkingStats()I
-Lcom/android/internal/os/ProcessCpuTracker;->getWorkingStats(I)Lcom/android/internal/os/ProcessCpuTracker$Stats;
-Lcom/android/internal/os/ProcessCpuTracker;->update()V
-Lcom/android/internal/os/RuntimeInit;->commonInit()V
-Lcom/android/internal/os/RuntimeInit;->getApplicationObject()Landroid/os/IBinder;
-Lcom/android/internal/os/RuntimeInit;->initialized:Z
-Lcom/android/internal/os/RuntimeInit;->main([Ljava/lang/String;)V
-Lcom/android/internal/os/RuntimeInit;->mApplicationObject:Landroid/os/IBinder;
-Lcom/android/internal/os/ZygoteConnection;->closeSocket()V
-Lcom/android/internal/os/ZygoteConnection;->mSocket:Landroid/net/LocalSocket;
-Lcom/android/internal/os/ZygoteConnection;->mSocketOutStream:Ljava/io/DataOutputStream;
-Lcom/android/internal/os/ZygoteConnection;->peer:Landroid/net/Credentials;
-Lcom/android/internal/os/ZygoteInit;->main([Ljava/lang/String;)V
-Lcom/android/internal/os/ZygoteInit;->mResources:Landroid/content/res/Resources;
-Lcom/android/internal/os/ZygoteSecurityException;-><init>(Ljava/lang/String;)V
-Lcom/android/internal/policy/DecorView;->mLastBottomInset:I
-Lcom/android/internal/policy/DecorView;->mLastLeftInset:I
-Lcom/android/internal/policy/DecorView;->mLastRightInset:I
-Lcom/android/internal/policy/DecorView;->mWindow:Lcom/android/internal/policy/PhoneWindow;
Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->mContext:Landroid/content/Context;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->mView:Landroid/view/View;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyDown(ILandroid/view/KeyEvent;)Z
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyUp(ILandroid/view/KeyEvent;)Z
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->startCallActivity()V
-Lcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/policy/PhoneWindow;->mTitle:Ljava/lang/CharSequence;
Lcom/android/internal/preference/YesNoPreference;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Lcom/android/internal/R$anim;->fade_in:I
Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I
@@ -1671,203 +1600,15 @@ Lcom/android/internal/telephony/uicc/IccUtils;->parseToBnW([BI)Landroid/graphics
Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap;
Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I
-Lcom/android/internal/util/ArrayUtils;->contains([II)Z
-Lcom/android/internal/util/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z
-Lcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I
-Lcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-Lcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
-Lcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/BitwiseInputStream;-><init>([B)V
-Lcom/android/internal/util/BitwiseInputStream;->available()I
-Lcom/android/internal/util/BitwiseInputStream;->read(I)I
-Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B
-Lcom/android/internal/util/BitwiseInputStream;->skip(I)V
-Lcom/android/internal/util/BitwiseOutputStream;-><init>(I)V
-Lcom/android/internal/util/BitwiseOutputStream;->toByteArray()[B
-Lcom/android/internal/util/BitwiseOutputStream;->write(II)V
-Lcom/android/internal/util/BitwiseOutputStream;->writeByteArray(I[B)V
-Lcom/android/internal/util/CharSequences;->compareToIgnoreCase(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
-Lcom/android/internal/util/CharSequences;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
-Lcom/android/internal/util/FastMath;->round(F)I
-Lcom/android/internal/util/FastXmlSerializer;-><init>()V
-Lcom/android/internal/util/GrowingArrayUtils;->append([III)[I
-Lcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/HexDump;->hexStringToByteArray(Ljava/lang/String;)[B
-Lcom/android/internal/util/HexDump;->toHexString(I)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([B)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([BII)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
-Lcom/android/internal/util/IState;->getName()Ljava/lang/String;
Lcom/android/internal/util/MemInfoReader;-><init>()V
-Lcom/android/internal/util/MemInfoReader;->getCachedSize()J
-Lcom/android/internal/util/MemInfoReader;->getFreeSize()J
-Lcom/android/internal/util/MemInfoReader;->getRawInfo()[J
-Lcom/android/internal/util/MemInfoReader;->getTotalSize()J
-Lcom/android/internal/util/MemInfoReader;->readMemInfo()V
-Lcom/android/internal/util/Preconditions;->checkArgument(Z)V
-Lcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V
-Lcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I
-Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/android/internal/util/Preconditions;->checkState(Z)V
-Lcom/android/internal/util/Preconditions;->checkState(ZLjava/lang/String;)V
-Lcom/android/internal/util/State;-><init>()V
-Lcom/android/internal/util/State;->enter()V
-Lcom/android/internal/util/State;->exit()V
-Lcom/android/internal/util/State;->getName()Ljava/lang/String;
-Lcom/android/internal/util/State;->processMessage(Landroid/os/Message;)Z
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;)V
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Handler;)V
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Looper;)V
-Lcom/android/internal/util/StateMachine;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
-Lcom/android/internal/util/StateMachine;->obtainMessage(III)Landroid/os/Message;
-Lcom/android/internal/util/StateMachine;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message;
-Lcom/android/internal/util/StateMachine;->sendMessage(I)V
-Lcom/android/internal/util/StateMachine;->sendMessage(II)V
-Lcom/android/internal/util/StateMachine;->sendMessage(IIILjava/lang/Object;)V
-Lcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V
-Lcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V
-Lcom/android/internal/view/ActionBarPolicy;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/ActionBarPolicy;->get(Landroid/content/Context;)Lcom/android/internal/view/ActionBarPolicy;
-Lcom/android/internal/view/ActionBarPolicy;->getEmbeddedMenuWidthLimit()I
-Lcom/android/internal/view/ActionBarPolicy;->getMaxActionButtons()I
-Lcom/android/internal/view/ActionBarPolicy;->getStackedTabMaxWidth()I
-Lcom/android/internal/view/ActionBarPolicy;->getTabContainerHeight()I
-Lcom/android/internal/view/ActionBarPolicy;->hasEmbeddedTabs()Z
-Lcom/android/internal/view/ActionBarPolicy;->mContext:Landroid/content/Context;
-Lcom/android/internal/view/ActionBarPolicy;->showsOverflowMenuButton()Z
Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
-Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->dispose()V
-Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->getInstance()Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;
-Lcom/android/internal/view/menu/ActionMenu;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/menu/ActionMenuItem;-><init>(Landroid/content/Context;IIIILjava/lang/CharSequence;)V
-Lcom/android/internal/view/menu/ContextMenuBuilder;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/menu/IconMenuItemView;->getTextAppropriateLayoutParams()Lcom/android/internal/view/menu/IconMenuView$LayoutParams;
-Lcom/android/internal/view/menu/IconMenuItemView;->setIconMenuView(Lcom/android/internal/view/menu/IconMenuView;)V
-Lcom/android/internal/view/menu/IconMenuItemView;->setItemInvoker(Lcom/android/internal/view/menu/MenuBuilder$ItemInvoker;)V
-Lcom/android/internal/view/menu/IconMenuView$SavedState;-><init>(Landroid/os/Parcel;)V
-Lcom/android/internal/view/menu/IconMenuView;->createMoreItemView()Lcom/android/internal/view/menu/IconMenuItemView;
-Lcom/android/internal/view/menu/IconMenuView;->getNumActualItemsShown()I
-Lcom/android/internal/view/menu/IconMenuView;->mItemBackground:Landroid/graphics/drawable/Drawable;
-Lcom/android/internal/view/menu/IconMenuView;->mMaxItems:I
-Lcom/android/internal/view/menu/IconMenuView;->mMenu:Lcom/android/internal/view/menu/MenuBuilder;
-Lcom/android/internal/view/menu/MenuDialogHelper;-><init>(Lcom/android/internal/view/menu/MenuBuilder;)V
-Lcom/android/internal/view/menu/MenuDialogHelper;->dismiss()V
-Lcom/android/internal/view/menu/MenuDialogHelper;->show(Landroid/os/IBinder;)V
-Lcom/android/internal/view/WindowManagerPolicyThread;->getLooper()Landroid/os/Looper;
-Lcom/android/internal/widget/AbsActionBarView;->dismissPopupMenus()V
-Lcom/android/internal/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/ActionBarOverlayLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V
-Lcom/android/internal/widget/EditableInputConnection;-><init>(Landroid/widget/TextView;)V
Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory;
-Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->setDefaultTouchRecepient(Landroid/view/View;)V
-Lcom/android/internal/widget/LockPatternChecker;->checkPassword(Lcom/android/internal/widget/LockPatternUtils;Ljava/lang/String;ILcom/android/internal/widget/LockPatternChecker$OnCheckCallback;)Landroid/os/AsyncTask;
-Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;-><init>(I)V
-Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->getTimeoutMs()I
-Lcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;I)Z
-Lcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I
-Lcom/android/internal/widget/LockPatternUtils;->getDevicePolicyManager()Landroid/app/admin/DevicePolicyManager;
-Lcom/android/internal/widget/LockPatternUtils;->getKeyguardStoredPasswordQuality(I)I
-Lcom/android/internal/widget/LockPatternUtils;->getLockSettings()Lcom/android/internal/widget/ILockSettings;
-Lcom/android/internal/widget/LockPatternUtils;->getOwnerInfo(I)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->getPowerButtonInstantlyLocks(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->getString(Ljava/lang/String;I)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->isDeviceEncryptionEnabled()Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isTactileFeedbackEnabled()Z
-Lcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->mContentResolver:Landroid/content/ContentResolver;
-Lcom/android/internal/widget/LockPatternUtils;->mContext:Landroid/content/Context;
-Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[B
-Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V
-Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
-Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
-Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V
-Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfoEnabled(ZI)V
-Lcom/android/internal/widget/LockPatternUtils;->setString(Ljava/lang/String;Ljava/lang/String;I)V
-Lcom/android/internal/widget/LockPatternView$Cell;->column:I
-Lcom/android/internal/widget/LockPatternView$Cell;->row:I
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Animate:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Correct:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Wrong:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcel;)V
-Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcelable;Ljava/lang/String;IZZZ)V
-Lcom/android/internal/widget/LockPatternView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/LockPatternView;->clearPattern()V
-Lcom/android/internal/widget/LockPatternView;->disableInput()V
-Lcom/android/internal/widget/LockPatternView;->enableInput()V
-Lcom/android/internal/widget/LockPatternView;->getCellStates()[[Lcom/android/internal/widget/LockPatternView$CellState;
-Lcom/android/internal/widget/LockPatternView;->mInStealthMode:Z
-Lcom/android/internal/widget/LockPatternView;->mPaint:Landroid/graphics/Paint;
-Lcom/android/internal/widget/LockPatternView;->mPathPaint:Landroid/graphics/Paint;
-Lcom/android/internal/widget/LockPatternView;->mPattern:Ljava/util/ArrayList;
-Lcom/android/internal/widget/LockPatternView;->mPatternDisplayMode:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView;->mPatternInProgress:Z
-Lcom/android/internal/widget/LockPatternView;->mSquareHeight:F
-Lcom/android/internal/widget/LockPatternView;->mSquareWidth:F
-Lcom/android/internal/widget/LockPatternView;->notifyPatternDetected()V
-Lcom/android/internal/widget/LockPatternView;->setDisplayMode(Lcom/android/internal/widget/LockPatternView$DisplayMode;)V
-Lcom/android/internal/widget/LockPatternView;->setInStealthMode(Z)V
-Lcom/android/internal/widget/LockPatternView;->setOnPatternListener(Lcom/android/internal/widget/LockPatternView$OnPatternListener;)V
-Lcom/android/internal/widget/LockPatternView;->setTactileFeedbackEnabled(Z)V
Lcom/android/internal/widget/PointerLocationView$PointerState;-><init>()V
-Lcom/android/internal/widget/PointerLocationView$PointerState;->mCurDown:Z
-Lcom/android/internal/widget/PointerLocationView;->mCurDown:Z
-Lcom/android/internal/widget/PointerLocationView;->mCurNumPointers:I
-Lcom/android/internal/widget/PointerLocationView;->mMaxNumPointers:I
-Lcom/android/internal/widget/PointerLocationView;->mPointers:Ljava/util/ArrayList;
-Lcom/android/internal/widget/PointerLocationView;->mPrintCoords:Z
-Lcom/android/internal/widget/PreferenceImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/RecyclerView$RecycledViewPool$ScrapData;->mScrapHeap:Ljava/util/ArrayList;
-Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I
-Lcom/android/internal/widget/SlidingTab$Slider;->tab:Landroid/widget/ImageView;
-Lcom/android/internal/widget/SlidingTab$Slider;->text:Landroid/widget/TextView;
-Lcom/android/internal/widget/SlidingTab;->mAnimationDoneListener:Landroid/view/animation/Animation$AnimationListener;
-Lcom/android/internal/widget/SlidingTab;->mLeftSlider:Lcom/android/internal/widget/SlidingTab$Slider;
-Lcom/android/internal/widget/SlidingTab;->mRightSlider:Lcom/android/internal/widget/SlidingTab$Slider;
-Lcom/android/internal/widget/SlidingTab;->onAnimationDone()V
-Lcom/android/internal/widget/SlidingTab;->resetView()V
-Lcom/android/internal/widget/SlidingTab;->setHoldAfterTrigger(ZZ)V
-Lcom/android/internal/widget/SlidingTab;->setLeftHintText(I)V
-Lcom/android/internal/widget/SlidingTab;->setLeftTabResources(IIII)V
-Lcom/android/internal/widget/SlidingTab;->setOnTriggerListener(Lcom/android/internal/widget/SlidingTab$OnTriggerListener;)V
-Lcom/android/internal/widget/SlidingTab;->setRightHintText(I)V
-Lcom/android/internal/widget/SlidingTab;->setRightTabResources(IIII)V
-Lcom/android/internal/widget/TextViewInputDisabler;-><init>(Landroid/widget/TextView;)V
-Lcom/android/internal/widget/TextViewInputDisabler;->setInputEnabled(Z)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrolled(IFI)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrollStateChanged(I)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageSelected(I)V
-Lcom/android/internal/widget/ViewPager;->getCurrentItem()I
Lcom/android/server/net/BaseNetworkObserver;-><init>()V
-Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V
-Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V
-Lcom/android/server/net/NetlinkTracker;->getLinkProperties()Landroid/net/LinkProperties;
Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V
-Lcom/android/server/ResettableTimeout;->mLock:Landroid/os/ConditionVariable;
-Lcom/android/server/ResettableTimeout;->mOffAt:J
-Lcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
-Lcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet;
-Lcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet;
-Lcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet;
-Lcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet;
-Lcom/google/android/collect/Sets;->newSortedSet()Ljava/util/SortedSet;
Lcom/google/android/gles_jni/EGLImpl;-><init>()V
Lcom/google/android/gles_jni/GLImpl;-><init>()V
Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList;
@@ -2150,17 +1891,7 @@ Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Lan
Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z
Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->ACRONYM:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->FLICKR:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->FORMAT:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->GOOGLE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->HTML:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->LINK:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->MUSIC:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->PHOTO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->SMILEY:Lcom/google/android/util/AbstractMessageParser$Token$Type;
Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->YOUTUBE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
Lgov/nist/core/Debug;->printStackTrace(Ljava/lang/Exception;)V
Lgov/nist/core/GenericObject;-><init>()V
Lgov/nist/core/GenericObject;->dbgPrint()V
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8625a04963a7..9223f71b4428 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1711,7 +1711,8 @@ public abstract class Context {
*/
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@SystemApi
- public void startActivityAsUser(@RequiresPermission Intent intent, UserHandle user) {
+ public void startActivityAsUser(@RequiresPermission @NonNull Intent intent,
+ @NonNull UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index ebd8a7e3528a..db1951520a26 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -64,8 +64,6 @@ public class CaptivePortal implements Parcelable {
private final IBinder mBinder;
/** @hide */
- @SystemApi
- @TestApi
public CaptivePortal(@NonNull IBinder binder) {
mBinder = binder;
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 16322353add2..4a64128f146b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -44,6 +44,7 @@ import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -64,6 +65,8 @@ import com.android.internal.util.Protocol;
import libcore.net.event.NetworkEventDispatcher;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
@@ -1345,12 +1348,15 @@ public class ConnectivityManager {
}
/**
- * Gets the URL that should be used for resolving whether a captive portal is present.
+ * Gets a URL that can be used for resolving whether a captive portal is present.
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
* portal is present.
* 2. This URL must be HTTP as redirect responses are used to find captive portal
* sign-in pages. Captive portals cannot respond to HTTPS requests with redirects.
*
+ * The system network validation may be using different strategies to detect captive portals,
+ * so this method does not necessarily return a URL used by the system. It only returns a URL
+ * that may be relevant for other components trying to detect captive portals.
* @hide
*/
@SystemApi
@@ -1920,14 +1926,24 @@ public class ConnectivityManager {
* @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
* given socket.
**/
- public SocketKeepalive createSocketKeepalive(@NonNull Network network,
+ public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
@NonNull UdpEncapsulationSocket socket,
@NonNull InetAddress source,
@NonNull InetAddress destination,
@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) {
- return new NattSocketKeepalive(mService, network, socket.getFileDescriptor(),
- socket.getResourceId(), source, destination, executor, callback);
+ ParcelFileDescriptor dup;
+ try {
+ // Dup is needed here as the pfd inside the socket is owned by the IpSecService,
+ // which cannot be obtained by the app process.
+ dup = ParcelFileDescriptor.dup(socket.getFileDescriptor());
+ } catch (IOException ignored) {
+ // Construct an invalid fd, so that if the user later calls start(), it will fail with
+ // ERROR_INVALID_SOCKET.
+ dup = new ParcelFileDescriptor(new FileDescriptor());
+ }
+ return new NattSocketKeepalive(mService, network, dup, socket.getResourceId(), source,
+ destination, executor, callback);
}
/**
@@ -1935,9 +1951,9 @@ public class ConnectivityManager {
* by system apps which don't use IpSecService to create {@link UdpEncapsulationSocket}.
*
* @param network The {@link Network} the socket is on.
- * @param fd The {@link FileDescriptor} that needs to be kept alive. The provided
- * {@link FileDescriptor} must be bound to a port and the keepalives will be sent from
- * that port.
+ * @param pfd The {@link ParcelFileDescriptor} that needs to be kept alive. The provided
+ * {@link ParcelFileDescriptor} must be bound to a port and the keepalives will be sent
+ * from that port.
* @param source The source address of the {@link UdpEncapsulationSocket}.
* @param destination The destination address of the {@link UdpEncapsulationSocket}. The
* keepalive packets will always be sent to port 4500 of the given {@code destination}.
@@ -1953,14 +1969,23 @@ public class ConnectivityManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
- public SocketKeepalive createNattKeepalive(@NonNull Network network,
- @NonNull FileDescriptor fd,
+ public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network,
+ @NonNull ParcelFileDescriptor pfd,
@NonNull InetAddress source,
@NonNull InetAddress destination,
@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) {
- return new NattSocketKeepalive(mService, network, fd, INVALID_RESOURCE_ID /* Unused */,
- source, destination, executor, callback);
+ ParcelFileDescriptor dup;
+ try {
+ // TODO: Consider remove unnecessary dup.
+ dup = pfd.dup();
+ } catch (IOException ignored) {
+ // Construct an invalid fd, so that if the user later calls start(), it will fail with
+ // ERROR_INVALID_SOCKET.
+ dup = new ParcelFileDescriptor(new FileDescriptor());
+ }
+ return new NattSocketKeepalive(mService, network, dup,
+ INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback);
}
/**
@@ -1984,11 +2009,19 @@ public class ConnectivityManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
- public SocketKeepalive createSocketKeepalive(@NonNull Network network,
+ public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
@NonNull Socket socket,
@NonNull Executor executor,
@NonNull Callback callback) {
- return new TcpSocketKeepalive(mService, network, socket, executor, callback);
+ ParcelFileDescriptor dup;
+ try {
+ dup = ParcelFileDescriptor.fromSocket(socket);
+ } catch (UncheckedIOException ignored) {
+ // Construct an invalid fd, so that if the user later calls start(), it will fail with
+ // ERROR_INVALID_SOCKET.
+ dup = new ParcelFileDescriptor(new FileDescriptor());
+ }
+ return new TcpSocketKeepalive(mService, network, dup, executor, callback);
}
/**
@@ -3320,7 +3353,7 @@ public class ConnectivityManager {
* @param network The {@link Network} whose blocked status has changed.
* @param blocked The blocked status of this {@link Network}.
*/
- public void onBlockedStatusChanged(Network network, boolean blocked) {}
+ public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
private NetworkRequest networkRequest;
}
@@ -4101,9 +4134,12 @@ public class ConnectivityManager {
* @hide
*/
@SystemApi
- public boolean getAvoidBadWifi() {
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_STACK})
+ public boolean shouldAvoidBadWifi() {
try {
- return mService.getAvoidBadWifi();
+ return mService.shouldAvoidBadWifi();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 59802514c7a3..687b721834cb 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -22,6 +22,10 @@ import static android.net.NetworkUtils.resNetworkResult;
import static android.net.NetworkUtils.resNetworkSend;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -30,12 +34,18 @@ import android.annotation.Nullable;
import android.os.CancellationSignal;
import android.os.Looper;
import android.system.ErrnoException;
+import android.system.Os;
import android.util.Log;
+import libcore.io.IoUtils;
+
import java.io.FileDescriptor;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
@@ -52,6 +62,7 @@ public final class DnsResolver {
private static final String TAG = "DnsResolver";
private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
private static final int MAXPACKET = 8 * 1024;
+ private static final int SLEEP_TIME = 2;
@IntDef(prefix = { "CLASS_" }, value = {
CLASS_IN
@@ -188,9 +199,9 @@ public final class DnsResolver {
* Send a raw DNS query.
* The answer will be provided asynchronously through the provided {@link AnswerCallback}.
*
- * @param network {@link Network} specifying which network for querying.
+ * @param network {@link Network} specifying which network to query on.
* {@code null} for query on default network.
- * @param query blob message
+ * @param query blob message to query
* @param flags flags as a combination of the FLAGS_* constants
* @param executor The {@link Executor} that the callback should be executed on.
* @param cancellationSignal used by the caller to signal if the query should be
@@ -205,26 +216,29 @@ public final class DnsResolver {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
+ final Object lock = new Object();
final FileDescriptor queryfd;
try {
queryfd = resNetworkSend((network != null
? network.netId : NETID_UNSET), query, query.length, flags);
} catch (ErrnoException e) {
- callback.onQueryException(e);
+ executor.execute(() -> {
+ callback.onQueryException(e);
+ });
return;
}
- maybeAddCancellationSignal(cancellationSignal, queryfd);
- registerFDListener(executor, queryfd, callback);
+ registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
+ maybeAddCancellationSignal(cancellationSignal, queryfd, lock);
}
/**
* Send a DNS query with the specified name, class and query type.
* The answer will be provided asynchronously through the provided {@link AnswerCallback}.
*
- * @param network {@link Network} specifying which network for querying.
+ * @param network {@link Network} specifying which network to query on.
* {@code null} for query on default network.
- * @param domain domain name for querying
+ * @param domain domain name to query
* @param nsClass dns class as one of the CLASS_* constants
* @param nsType dns resource record (RR) type as one of the TYPE_* constants
* @param flags flags as a combination of the FLAGS_* constants
@@ -242,40 +256,180 @@ public final class DnsResolver {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
+ final Object lock = new Object();
final FileDescriptor queryfd;
try {
queryfd = resNetworkQuery((network != null
? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
} catch (ErrnoException e) {
- callback.onQueryException(e);
+ executor.execute(() -> {
+ callback.onQueryException(e);
+ });
return;
}
- maybeAddCancellationSignal(cancellationSignal, queryfd);
- registerFDListener(executor, queryfd, callback);
+ registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
+ maybeAddCancellationSignal(cancellationSignal, queryfd, lock);
+ }
+
+ private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback {
+ private final List<InetAddress> mAllAnswers;
+ private ParseException mParseException;
+ private ErrnoException mErrnoException;
+ private final InetAddressAnswerCallback mUserCallback;
+ private final int mTargetAnswerCount;
+ private int mReceivedAnswerCount = 0;
+
+ InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) {
+ mTargetAnswerCount = size;
+ mAllAnswers = new ArrayList<>();
+ mUserCallback = callback;
+ }
+
+ private boolean maybeReportException() {
+ if (mErrnoException != null) {
+ mUserCallback.onQueryException(mErrnoException);
+ return true;
+ }
+ if (mParseException != null) {
+ mUserCallback.onParseException(mParseException);
+ return true;
+ }
+ return false;
+ }
+
+ private void maybeReportAnswer() {
+ if (++mReceivedAnswerCount != mTargetAnswerCount) return;
+ if (mAllAnswers.isEmpty() && maybeReportException()) return;
+ // TODO: Do RFC6724 sort.
+ mUserCallback.onAnswer(mAllAnswers);
+ }
+
+ @Override
+ public void onAnswer(@NonNull List<InetAddress> answer) {
+ mAllAnswers.addAll(answer);
+ maybeReportAnswer();
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ mParseException = e;
+ maybeReportAnswer();
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ mErrnoException = e;
+ maybeReportAnswer();
+ }
+ }
+
+ /**
+ * Send a DNS query with the specified name, get back a set of InetAddresses asynchronously.
+ * The answer will be provided asynchronously through the provided
+ * {@link InetAddressAnswerCallback}.
+ *
+ * @param network {@link Network} specifying which network to query on.
+ * {@code null} for query on default network.
+ * @param domain domain name to query
+ * @param flags flags as a combination of the FLAGS_* constants
+ * @param executor The {@link Executor} that the callback should be executed on.
+ * @param cancellationSignal used by the caller to signal if the query should be
+ * cancelled. May be {@code null}.
+ * @param callback an {@link InetAddressAnswerCallback} which will be called to notify the
+ * caller of the result of dns query.
+ */
+ public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
+ @NonNull @CallbackExecutor Executor executor,
+ @Nullable CancellationSignal cancellationSignal,
+ @NonNull InetAddressAnswerCallback callback) {
+ if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+ return;
+ }
+ final Object lock = new Object();
+ final boolean queryIpv6 = haveIpv6(network);
+ final boolean queryIpv4 = haveIpv4(network);
+
+ final FileDescriptor v4fd;
+ final FileDescriptor v6fd;
+
+ int queryCount = 0;
+
+ if (queryIpv6) {
+ try {
+ v6fd = resNetworkQuery((network != null
+ ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
+ } catch (ErrnoException e) {
+ executor.execute(() -> {
+ callback.onQueryException(e);
+ });
+ return;
+ }
+ queryCount++;
+ } else v6fd = null;
+
+ // TODO: Use device flag to controll the sleep time.
+ // Avoiding gateways drop packets if queries are sent too close together
+ try {
+ Thread.sleep(SLEEP_TIME);
+ } catch (InterruptedException ex) { }
+
+ if (queryIpv4) {
+ try {
+ v4fd = resNetworkQuery((network != null
+ ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
+ } catch (ErrnoException e) {
+ if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid.
+ executor.execute(() -> {
+ callback.onQueryException(e);
+ });
+ return;
+ }
+ queryCount++;
+ } else v4fd = null;
+
+ final InetAddressAnswerAccumulator accumulator =
+ new InetAddressAnswerAccumulator(queryCount, callback);
+
+ if (queryIpv6) registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock);
+ if (queryIpv4) registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock);
+
+ if (cancellationSignal == null) return;
+ cancellationSignal.setOnCancelListener(() -> {
+ synchronized (lock) {
+ if (queryIpv4) cancelQuery(v4fd);
+ if (queryIpv6) cancelQuery(v6fd);
+ }
+ });
}
private <T> void registerFDListener(@NonNull Executor executor,
- @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback) {
+ @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback,
+ @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
queryfd,
FD_EVENTS,
(fd, events) -> {
executor.execute(() -> {
- byte[] answerbuf = null;
- try {
- answerbuf = resNetworkResult(fd);
- } catch (ErrnoException e) {
- Log.e(TAG, "resNetworkResult:" + e.toString());
- answerCallback.onQueryException(e);
- return;
- }
-
- try {
- answerCallback.onAnswer(
- answerCallback.parser.parse(answerbuf));
- } catch (ParseException e) {
- answerCallback.onParseException(e);
+ synchronized (lock) {
+ if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+ return;
+ }
+ byte[] answerbuf = null;
+ try {
+ answerbuf = resNetworkResult(fd); // Closes fd, marks it invalid.
+ } catch (ErrnoException e) {
+ Log.e(TAG, "resNetworkResult:" + e.toString());
+ answerCallback.onQueryException(e);
+ return;
+ }
+
+ try {
+ answerCallback.onAnswer(
+ answerCallback.parser.parse(answerbuf));
+ } catch (ParseException e) {
+ answerCallback.onParseException(e);
+ }
}
});
// Unregister this fd listener
@@ -283,15 +437,52 @@ public final class DnsResolver {
});
}
+ private void cancelQuery(@NonNull FileDescriptor queryfd) {
+ if (!queryfd.valid()) return;
+ Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd);
+ resNetworkCancel(queryfd); // Closes fd, marks it invalid.
+ }
+
private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal,
- @NonNull FileDescriptor queryfd) {
+ @NonNull FileDescriptor queryfd, @NonNull Object lock) {
if (cancellationSignal == null) return;
- cancellationSignal.setOnCancelListener(
- () -> {
- Looper.getMainLooper().getQueue()
- .removeOnFileDescriptorEventListener(queryfd);
- resNetworkCancel(queryfd);
- });
+ cancellationSignal.setOnCancelListener(() -> {
+ synchronized (lock) {
+ cancelQuery(queryfd);
+ }
+ });
+ }
+
+ // These two functions match the behaviour of have_ipv4 and have_ipv6 in the native resolver.
+ private boolean haveIpv4(@Nullable Network network) {
+ final SocketAddress addrIpv4 =
+ new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0);
+ return checkConnectivity(network, AF_INET, addrIpv4);
+ }
+
+ private boolean haveIpv6(@Nullable Network network) {
+ final SocketAddress addrIpv6 =
+ new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0);
+ return checkConnectivity(network, AF_INET6, addrIpv6);
+ }
+
+ private boolean checkConnectivity(@Nullable Network network,
+ int domain, @NonNull SocketAddress addr) {
+ final FileDescriptor socket;
+ try {
+ socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP);
+ } catch (ErrnoException e) {
+ return false;
+ }
+ try {
+ if (network != null) network.bindSocket(socket);
+ Os.connect(socket, addr);
+ } catch (IOException | ErrnoException e) {
+ return false;
+ } finally {
+ IoUtils.closeQuietly(socket);
+ }
+ return true;
}
private static class DnsAddressAnswer extends DnsPacket {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 24e6a855ffe8..61648dc7f1d8 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -182,7 +182,7 @@ interface IConnectivityManager
void startCaptivePortalApp(in Network network);
void startCaptivePortalAppInternal(in Network network, in Bundle appExtras);
- boolean getAvoidBadWifi();
+ boolean shouldAvoidBadWifi();
int getMultipathPreference(in Network Network);
NetworkRequest getDefaultRequest();
diff --git a/core/java/android/net/NattSocketKeepalive.java b/core/java/android/net/NattSocketKeepalive.java
index 84da294f8940..b0ce0c71fbeb 100644
--- a/core/java/android/net/NattSocketKeepalive.java
+++ b/core/java/android/net/NattSocketKeepalive.java
@@ -17,10 +17,10 @@
package android.net;
import android.annotation.NonNull;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
-import java.io.FileDescriptor;
import java.net.InetAddress;
import java.util.concurrent.Executor;
@@ -31,21 +31,19 @@ public final class NattSocketKeepalive extends SocketKeepalive {
@NonNull private final InetAddress mSource;
@NonNull private final InetAddress mDestination;
- @NonNull private final FileDescriptor mFd;
private final int mResourceId;
NattSocketKeepalive(@NonNull IConnectivityManager service,
@NonNull Network network,
- @NonNull FileDescriptor fd,
+ @NonNull ParcelFileDescriptor pfd,
int resourceId,
@NonNull InetAddress source,
@NonNull InetAddress destination,
@NonNull Executor executor,
@NonNull Callback callback) {
- super(service, network, executor, callback);
+ super(service, network, pfd, executor, callback);
mSource = source;
mDestination = destination;
- mFd = fd;
mResourceId = resourceId;
}
@@ -53,8 +51,8 @@ public final class NattSocketKeepalive extends SocketKeepalive {
void startImpl(int intervalSec) {
mExecutor.execute(() -> {
try {
- mService.startNattKeepaliveWithFd(mNetwork, mFd, mResourceId, intervalSec,
- mCallback,
+ mService.startNattKeepaliveWithFd(mNetwork, mPfd.getFileDescriptor(), mResourceId,
+ intervalSec, mCallback,
mSource.getHostAddress(), mDestination.getHostAddress());
} catch (RemoteException e) {
Log.e(TAG, "Error starting socket keepalive: ", e);
@@ -75,6 +73,5 @@ public final class NattSocketKeepalive extends SocketKeepalive {
throw e.rethrowFromSystemServer();
}
});
-
}
}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index b55f6ba06438..1edea556c574 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -488,14 +488,14 @@ public abstract class NetworkAgent extends Handler {
* Requests that the network hardware send the specified packet at the specified interval.
*/
protected void startSocketKeepalive(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
}
/**
* Requests that the network hardware stops sending keepalive packets.
*/
protected void stopSocketKeepalive(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
}
/**
@@ -511,7 +511,7 @@ public abstract class NetworkAgent extends Handler {
* override this method.
*/
protected void addKeepalivePacketFilter(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
}
/**
@@ -520,7 +520,7 @@ public abstract class NetworkAgent extends Handler {
* must override this method.
*/
protected void removeKeepalivePacketFilter(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
}
/**
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 9cf582bef1d4..27e041496173 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -18,6 +18,7 @@ package android.net;
import static android.os.Process.CLAT_UID;
+import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,6 +34,7 @@ import libcore.util.EmptyArray;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.function.Predicate;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
@@ -993,23 +995,33 @@ public class NetworkStats implements Parcelable {
if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) {
return;
}
+ filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
+ && (limitTag == TAG_ALL || limitTag == e.tag)
+ && (limitIfaces == INTERFACES_ALL
+ || ArrayUtils.contains(limitIfaces, e.iface)));
+ }
+
+ /**
+ * Only keep entries with {@link #set} value less than {@link #SET_DEBUG_START}.
+ *
+ * <p>This mutates the original structure in place.
+ */
+ public void filterDebugEntries() {
+ filter(e -> e.set < SET_DEBUG_START);
+ }
+ private void filter(Predicate<Entry> predicate) {
Entry entry = new Entry();
int nextOutputEntry = 0;
for (int i = 0; i < size; i++) {
entry = getValues(i, entry);
- final boolean matches =
- (limitUid == UID_ALL || limitUid == entry.uid)
- && (limitTag == TAG_ALL || limitTag == entry.tag)
- && (limitIfaces == INTERFACES_ALL
- || ArrayUtils.contains(limitIfaces, entry.iface));
-
- if (matches) {
- setValues(nextOutputEntry, entry);
+ if (predicate.test(entry)) {
+ if (nextOutputEntry != i) {
+ setValues(nextOutputEntry, entry);
+ }
nextOutputEntry++;
}
}
-
size = nextOutputEntry;
}
@@ -1175,133 +1187,217 @@ public class NetworkStats implements Parcelable {
/**
* VPN accounting. Move some VPN's underlying traffic to other UIDs that use tun0 iface.
*
- * This method should only be called on delta NetworkStats. Do not call this method on a
- * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may
- * change over time.
- *
- * This method performs adjustments for one active VPN package and one VPN iface at a time.
+ * <p>This method should only be called on delta NetworkStats. Do not call this method on a
+ * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may change
+ * over time.
*
- * It is possible for the VPN software to use multiple underlying networks. This method
- * only migrates traffic for the primary underlying network.
+ * <p>This method performs adjustments for one active VPN package and one VPN iface at a time.
*
* @param tunUid uid of the VPN application
* @param tunIface iface of the vpn tunnel
- * @param underlyingIface the primary underlying network iface used by the VPN application
- * @return true if it successfully adjusts the accounting for VPN, false otherwise
+ * @param underlyingIfaces underlying network ifaces used by the VPN application
*/
- public boolean migrateTun(int tunUid, String tunIface, String underlyingIface) {
- Entry tunIfaceTotal = new Entry();
- Entry underlyingIfaceTotal = new Entry();
+ public void migrateTun(int tunUid, @NonNull String tunIface,
+ @NonNull String[] underlyingIfaces) {
+ // Combined usage by all apps using VPN.
+ final Entry tunIfaceTotal = new Entry();
+ // Usage by VPN, grouped by its {@code underlyingIfaces}.
+ final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.length];
+ // Usage by VPN, summed across all its {@code underlyingIfaces}.
+ final Entry underlyingIfacesTotal = new Entry();
+
+ for (int i = 0; i < perInterfaceTotal.length; i++) {
+ perInterfaceTotal[i] = new Entry();
+ }
- tunAdjustmentInit(tunUid, tunIface, underlyingIface, tunIfaceTotal, underlyingIfaceTotal);
+ tunAdjustmentInit(tunUid, tunIface, underlyingIfaces, tunIfaceTotal, perInterfaceTotal,
+ underlyingIfacesTotal);
- // If tunIface < underlyingIface, it leaves the overhead traffic in the VPN app.
- // If tunIface > underlyingIface, the VPN app doesn't get credit for data compression.
+ // If tunIface < underlyingIfacesTotal, it leaves the overhead traffic in the VPN app.
+ // If tunIface > underlyingIfacesTotal, the VPN app doesn't get credit for data compression.
// Negative stats should be avoided.
- Entry pool = tunGetPool(tunIfaceTotal, underlyingIfaceTotal);
- if (pool.isEmpty()) {
- return true;
- }
- Entry moved =
- addTrafficToApplications(tunUid, tunIface, underlyingIface, tunIfaceTotal, pool);
- deductTrafficFromVpnApp(tunUid, underlyingIface, moved);
-
- if (!moved.isEmpty()) {
- Slog.wtf(TAG, "Failed to deduct underlying network traffic from VPN package. Moved="
- + moved);
- return false;
- }
- return true;
+ final Entry[] moved =
+ addTrafficToApplications(tunUid, tunIface, underlyingIfaces, tunIfaceTotal,
+ perInterfaceTotal, underlyingIfacesTotal);
+ deductTrafficFromVpnApp(tunUid, underlyingIfaces, moved);
}
/**
* Initializes the data used by the migrateTun() method.
*
- * This is the first pass iteration which does the following work:
- * (1) Adds up all the traffic through the tunUid's underlyingIface
- * (both foreground and background).
- * (2) Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
+ * <p>This is the first pass iteration which does the following work:
+ *
+ * <ul>
+ * <li>Adds up all the traffic through the tunUid's underlyingIfaces (both foreground and
+ * background).
+ * <li>Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
+ * </ul>
+ *
+ * @param tunUid uid of the VPN application
+ * @param tunIface iface of the vpn tunnel
+ * @param underlyingIfaces underlying network ifaces used by the VPN application
+ * @param tunIfaceTotal output parameter; combined data usage by all apps using VPN
+ * @param perInterfaceTotal output parameter; data usage by VPN app, grouped by its {@code
+ * underlyingIfaces}
+ * @param underlyingIfacesTotal output parameter; data usage by VPN, summed across all of its
+ * {@code underlyingIfaces}
*/
- private void tunAdjustmentInit(int tunUid, String tunIface, String underlyingIface,
- Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
- Entry recycle = new Entry();
+ private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
+ @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
+ @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
+ final Entry recycle = new Entry();
for (int i = 0; i < size; i++) {
getValues(i, recycle);
if (recycle.uid == UID_ALL) {
throw new IllegalStateException(
"Cannot adjust VPN accounting on an iface aggregated NetworkStats.");
- } if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
+ }
+ if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
throw new IllegalStateException(
"Cannot adjust VPN accounting on a NetworkStats containing SET_DBG_VPN_*");
}
-
- if (recycle.uid == tunUid && recycle.tag == TAG_NONE
- && Objects.equals(underlyingIface, recycle.iface)) {
- underlyingIfaceTotal.add(recycle);
+ if (recycle.tag != TAG_NONE) {
+ // TODO(b/123666283): Take all tags for tunUid into account.
+ continue;
}
- if (recycle.uid != tunUid && recycle.tag == TAG_NONE
- && Objects.equals(tunIface, recycle.iface)) {
+ if (recycle.uid == tunUid) {
+ // Add up traffic through tunUid's underlying interfaces.
+ for (int j = 0; j < underlyingIfaces.length; j++) {
+ if (Objects.equals(underlyingIfaces[j], recycle.iface)) {
+ perInterfaceTotal[j].add(recycle);
+ underlyingIfacesTotal.add(recycle);
+ break;
+ }
+ }
+ } else if (tunIface.equals(recycle.iface)) {
// Add up all tunIface traffic excluding traffic from the vpn app itself.
tunIfaceTotal.add(recycle);
}
}
}
- private static Entry tunGetPool(Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
- Entry pool = new Entry();
- pool.rxBytes = Math.min(tunIfaceTotal.rxBytes, underlyingIfaceTotal.rxBytes);
- pool.rxPackets = Math.min(tunIfaceTotal.rxPackets, underlyingIfaceTotal.rxPackets);
- pool.txBytes = Math.min(tunIfaceTotal.txBytes, underlyingIfaceTotal.txBytes);
- pool.txPackets = Math.min(tunIfaceTotal.txPackets, underlyingIfaceTotal.txPackets);
- pool.operations = Math.min(tunIfaceTotal.operations, underlyingIfaceTotal.operations);
- return pool;
- }
+ /**
+ * Distributes traffic across apps that are using given {@code tunIface}, and returns the total
+ * traffic that should be moved off of {@code tunUid} grouped by {@code underlyingIfaces}.
+ *
+ * @param tunUid uid of the VPN application
+ * @param tunIface iface of the vpn tunnel
+ * @param underlyingIfaces underlying network ifaces used by the VPN application
+ * @param tunIfaceTotal combined data usage across all apps using {@code tunIface}
+ * @param perInterfaceTotal data usage by VPN app, grouped by its {@code underlyingIfaces}
+ * @param underlyingIfacesTotal data usage by VPN, summed across all of its {@code
+ * underlyingIfaces}
+ */
+ private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
+ @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
+ @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
+ // Traffic that should be moved off of each underlying interface for tunUid (see
+ // deductTrafficFromVpnApp below).
+ final Entry[] moved = new Entry[underlyingIfaces.length];
+ for (int i = 0; i < underlyingIfaces.length; i++) {
+ moved[i] = new Entry();
+ }
- private Entry addTrafficToApplications(int tunUid, String tunIface, String underlyingIface,
- Entry tunIfaceTotal, Entry pool) {
- Entry moved = new Entry();
- Entry tmpEntry = new Entry();
- tmpEntry.iface = underlyingIface;
+ final Entry tmpEntry = new Entry();
for (int i = 0; i < size; i++) {
- // the vpn app is excluded from the redistribution but all moved traffic will be
- // deducted from the vpn app (see deductTrafficFromVpnApp below).
- if (Objects.equals(iface[i], tunIface) && uid[i] != tunUid) {
- if (tunIfaceTotal.rxBytes > 0) {
- tmpEntry.rxBytes = pool.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
- } else {
- tmpEntry.rxBytes = 0;
+ if (!Objects.equals(iface[i], tunIface)) {
+ // Consider only entries that go onto the VPN interface.
+ continue;
+ }
+ if (uid[i] == tunUid) {
+ // Exclude VPN app from the redistribution, as it can choose to create packet
+ // streams by writing to itself.
+ continue;
+ }
+ tmpEntry.uid = uid[i];
+ tmpEntry.tag = tag[i];
+ tmpEntry.metered = metered[i];
+ tmpEntry.roaming = roaming[i];
+ tmpEntry.defaultNetwork = defaultNetwork[i];
+
+ // In a first pass, compute each UID's total share of data across all underlyingIfaces.
+ // This is computed on the basis of the share of each UID's usage over tunIface.
+ // TODO: Consider refactoring first pass into a separate helper method.
+ long totalRxBytes = 0;
+ if (tunIfaceTotal.rxBytes > 0) {
+ // Note - The multiplication below should not overflow since NetworkStatsService
+ // processes this every time device has transmitted/received amount equivalent to
+ // global threshold alert (~ 2MB) across all interfaces.
+ final long rxBytesAcrossUnderlyingIfaces =
+ underlyingIfacesTotal.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
+ // app must not be blamed for more than it consumed on tunIface
+ totalRxBytes = Math.min(rxBytes[i], rxBytesAcrossUnderlyingIfaces);
+ }
+ long totalRxPackets = 0;
+ if (tunIfaceTotal.rxPackets > 0) {
+ final long rxPacketsAcrossUnderlyingIfaces =
+ underlyingIfacesTotal.rxPackets * rxPackets[i] / tunIfaceTotal.rxPackets;
+ totalRxPackets = Math.min(rxPackets[i], rxPacketsAcrossUnderlyingIfaces);
+ }
+ long totalTxBytes = 0;
+ if (tunIfaceTotal.txBytes > 0) {
+ final long txBytesAcrossUnderlyingIfaces =
+ underlyingIfacesTotal.txBytes * txBytes[i] / tunIfaceTotal.txBytes;
+ totalTxBytes = Math.min(txBytes[i], txBytesAcrossUnderlyingIfaces);
+ }
+ long totalTxPackets = 0;
+ if (tunIfaceTotal.txPackets > 0) {
+ final long txPacketsAcrossUnderlyingIfaces =
+ underlyingIfacesTotal.txPackets * txPackets[i] / tunIfaceTotal.txPackets;
+ totalTxPackets = Math.min(txPackets[i], txPacketsAcrossUnderlyingIfaces);
+ }
+ long totalOperations = 0;
+ if (tunIfaceTotal.operations > 0) {
+ final long operationsAcrossUnderlyingIfaces =
+ underlyingIfacesTotal.operations * operations[i] / tunIfaceTotal.operations;
+ totalOperations = Math.min(operations[i], operationsAcrossUnderlyingIfaces);
+ }
+ // In a second pass, distribute these values across interfaces in the proportion that
+ // each interface represents of the total traffic of the underlying interfaces.
+ for (int j = 0; j < underlyingIfaces.length; j++) {
+ tmpEntry.iface = underlyingIfaces[j];
+ tmpEntry.rxBytes = 0;
+ // Reset 'set' to correct value since it gets updated when adding debug info below.
+ tmpEntry.set = set[i];
+ if (underlyingIfacesTotal.rxBytes > 0) {
+ tmpEntry.rxBytes =
+ totalRxBytes
+ * perInterfaceTotal[j].rxBytes
+ / underlyingIfacesTotal.rxBytes;
}
- if (tunIfaceTotal.rxPackets > 0) {
- tmpEntry.rxPackets = pool.rxPackets * rxPackets[i] / tunIfaceTotal.rxPackets;
- } else {
- tmpEntry.rxPackets = 0;
+ tmpEntry.rxPackets = 0;
+ if (underlyingIfacesTotal.rxPackets > 0) {
+ tmpEntry.rxPackets =
+ totalRxPackets
+ * perInterfaceTotal[j].rxPackets
+ / underlyingIfacesTotal.rxPackets;
}
- if (tunIfaceTotal.txBytes > 0) {
- tmpEntry.txBytes = pool.txBytes * txBytes[i] / tunIfaceTotal.txBytes;
- } else {
- tmpEntry.txBytes = 0;
+ tmpEntry.txBytes = 0;
+ if (underlyingIfacesTotal.txBytes > 0) {
+ tmpEntry.txBytes =
+ totalTxBytes
+ * perInterfaceTotal[j].txBytes
+ / underlyingIfacesTotal.txBytes;
}
- if (tunIfaceTotal.txPackets > 0) {
- tmpEntry.txPackets = pool.txPackets * txPackets[i] / tunIfaceTotal.txPackets;
- } else {
- tmpEntry.txPackets = 0;
+ tmpEntry.txPackets = 0;
+ if (underlyingIfacesTotal.txPackets > 0) {
+ tmpEntry.txPackets =
+ totalTxPackets
+ * perInterfaceTotal[j].txPackets
+ / underlyingIfacesTotal.txPackets;
}
- if (tunIfaceTotal.operations > 0) {
+ tmpEntry.operations = 0;
+ if (underlyingIfacesTotal.operations > 0) {
tmpEntry.operations =
- pool.operations * operations[i] / tunIfaceTotal.operations;
- } else {
- tmpEntry.operations = 0;
+ totalOperations
+ * perInterfaceTotal[j].operations
+ / underlyingIfacesTotal.operations;
}
- tmpEntry.uid = uid[i];
- tmpEntry.tag = tag[i];
- tmpEntry.set = set[i];
- tmpEntry.metered = metered[i];
- tmpEntry.roaming = roaming[i];
- tmpEntry.defaultNetwork = defaultNetwork[i];
+
combineValues(tmpEntry);
if (tag[i] == TAG_NONE) {
- moved.add(tmpEntry);
+ moved[j].add(tmpEntry);
// Add debug info
tmpEntry.set = SET_DBG_VPN_IN;
combineValues(tmpEntry);
@@ -1311,38 +1407,45 @@ public class NetworkStats implements Parcelable {
return moved;
}
- private void deductTrafficFromVpnApp(int tunUid, String underlyingIface, Entry moved) {
- // Add debug info
- moved.uid = tunUid;
- moved.set = SET_DBG_VPN_OUT;
- moved.tag = TAG_NONE;
- moved.iface = underlyingIface;
- moved.metered = METERED_ALL;
- moved.roaming = ROAMING_ALL;
- moved.defaultNetwork = DEFAULT_NETWORK_ALL;
- combineValues(moved);
-
- // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
- // the TAG_NONE traffic.
- //
- // Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO,
- // which should be the case as it comes directly from the /proc file. We only blend in the
- // roaming data after applying these adjustments, by checking the NetworkIdentity of the
- // underlying iface.
- int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
- METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
- if (idxVpnBackground != -1) {
- tunSubtract(idxVpnBackground, this, moved);
- }
+ private void deductTrafficFromVpnApp(
+ int tunUid,
+ @NonNull String[] underlyingIfaces,
+ @NonNull Entry[] moved) {
+ for (int i = 0; i < underlyingIfaces.length; i++) {
+ // Add debug info
+ moved[i].uid = tunUid;
+ moved[i].set = SET_DBG_VPN_OUT;
+ moved[i].tag = TAG_NONE;
+ moved[i].iface = underlyingIfaces[i];
+ moved[i].metered = METERED_ALL;
+ moved[i].roaming = ROAMING_ALL;
+ moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
+ combineValues(moved[i]);
+
+ // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
+ // the TAG_NONE traffic.
+ //
+ // Relies on the fact that the underlying traffic only has state ROAMING_NO and
+ // METERED_NO, which should be the case as it comes directly from the /proc file.
+ // We only blend in the roaming data after applying these adjustments, by checking the
+ // NetworkIdentity of the underlying iface.
+ final int idxVpnBackground = findIndex(underlyingIfaces[i], tunUid, SET_DEFAULT,
+ TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+ if (idxVpnBackground != -1) {
+ // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
+ // from foreground usage.
+ tunSubtract(idxVpnBackground, this, moved[i]);
+ }
- int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
- METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
- if (idxVpnForeground != -1) {
- tunSubtract(idxVpnForeground, this, moved);
+ final int idxVpnForeground = findIndex(underlyingIfaces[i], tunUid, SET_FOREGROUND,
+ TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+ if (idxVpnForeground != -1) {
+ tunSubtract(idxVpnForeground, this, moved[i]);
+ }
}
}
- private static void tunSubtract(int i, NetworkStats left, Entry right) {
+ private static void tunSubtract(int i, @NonNull NetworkStats left, @NonNull Entry right) {
long rxBytes = Math.min(left.rxBytes[i], right.rxBytes);
left.rxBytes[i] -= rxBytes;
right.rxBytes -= rxBytes;
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index 0e768dfc8eb9..9d91620bdf96 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -21,8 +21,10 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Binder;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
@@ -73,10 +75,15 @@ public abstract class SocketKeepalive implements AutoCloseable {
/** The target socket is not idle. */
public static final int ERROR_SOCKET_NOT_IDLE = -26;
- /** The hardware does not support this request. */
- public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
+ /** The device does not support this request. */
+ public static final int ERROR_UNSUPPORTED = -30;
+ /** @hide TODO: delete when telephony code has been updated. */
+ public static final int ERROR_HARDWARE_UNSUPPORTED = ERROR_UNSUPPORTED;
/** The hardware returned an error. */
public static final int ERROR_HARDWARE_ERROR = -31;
+ /** The limitation of resource is reached. */
+ public static final int ERROR_INSUFFICIENT_RESOURCES = -32;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -147,15 +154,18 @@ public abstract class SocketKeepalive implements AutoCloseable {
@NonNull final IConnectivityManager mService;
@NonNull final Network mNetwork;
+ @NonNull final ParcelFileDescriptor mPfd;
@NonNull final Executor mExecutor;
@NonNull final ISocketKeepaliveCallback mCallback;
// TODO: remove slot since mCallback could be used to identify which keepalive to stop.
@Nullable Integer mSlot;
SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
+ @NonNull ParcelFileDescriptor pfd,
@NonNull Executor executor, @NonNull Callback callback) {
mService = service;
mNetwork = network;
+ mPfd = pfd;
mExecutor = executor;
mCallback = new ISocketKeepaliveCallback.Stub() {
@Override
@@ -233,6 +243,11 @@ public abstract class SocketKeepalive implements AutoCloseable {
@Override
public final void close() {
stop();
+ try {
+ mPfd.close();
+ } catch (IOException e) {
+ // Nothing much can be done.
+ }
}
/**
diff --git a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl b/core/java/android/net/StaticIpConfiguration.aidl
index 6fffb423edb5..8aac701fe7e1 100644
--- a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl
+++ b/core/java/android/net/StaticIpConfiguration.aidl
@@ -17,11 +17,4 @@
package android.net;
-import android.net.LinkAddress;
-
-parcelable StaticIpConfigurationParcelable {
- LinkAddress ipAddress;
- String gateway;
- String[] dnsServers;
- String domains;
-}
+@JavaOnlyStableParcelable parcelable StaticIpConfiguration; \ No newline at end of file
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 0728d83cbdb1..14dbca0183f0 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -134,7 +134,7 @@ public final class StaticIpConfiguration implements Parcelable {
* route to the gateway as well. This configuration is arguably invalid, but it used to work
* in K and earlier, and other OSes appear to accept it.
*/
- public @NonNull List<RouteInfo> getRoutes(String iface) {
+ public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) {
List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
if (ipAddress != null) {
RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
diff --git a/core/java/android/net/TcpSocketKeepalive.java b/core/java/android/net/TcpSocketKeepalive.java
index 26cc8ff181b2..436397ea7754 100644
--- a/core/java/android/net/TcpSocketKeepalive.java
+++ b/core/java/android/net/TcpSocketKeepalive.java
@@ -17,25 +17,22 @@
package android.net;
import android.annotation.NonNull;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import java.io.FileDescriptor;
-import java.net.Socket;
import java.util.concurrent.Executor;
/** @hide */
final class TcpSocketKeepalive extends SocketKeepalive {
- private final Socket mSocket;
-
TcpSocketKeepalive(@NonNull IConnectivityManager service,
@NonNull Network network,
- @NonNull Socket socket,
+ @NonNull ParcelFileDescriptor pfd,
@NonNull Executor executor,
@NonNull Callback callback) {
- super(service, network, executor, callback);
- mSocket = socket;
+ super(service, network, pfd, executor, callback);
}
/**
@@ -57,7 +54,7 @@ final class TcpSocketKeepalive extends SocketKeepalive {
void startImpl(int intervalSec) {
mExecutor.execute(() -> {
try {
- final FileDescriptor fd = mSocket.getFileDescriptor$();
+ final FileDescriptor fd = mPfd.getFileDescriptor();
mService.startTcpKeepalive(mNetwork, fd, intervalSec, mCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error starting packet keepalive: ", e);
diff --git a/core/java/android/net/apf/ApfCapabilities.aidl b/core/java/android/net/apf/ApfCapabilities.aidl
new file mode 100644
index 000000000000..7c4d4c2da4bc
--- /dev/null
+++ b/core/java/android/net/apf/ApfCapabilities.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright (C) 2019 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.net.apf;
+
+@JavaOnlyStableParcelable parcelable ApfCapabilities; \ No newline at end of file
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index 8beaa40ec2fc..84823464a093 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -37,27 +37,6 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event {
public static final int DHCP_ERROR = 4;
public static final int MISC_ERROR = 5;
- public static final int L2_TOO_SHORT = (L2_ERROR << 24) | (1 << 16);
- public static final int L2_WRONG_ETH_TYPE = (L2_ERROR << 24) | (2 << 16);
-
- public static final int L3_TOO_SHORT = (L3_ERROR << 24) | (1 << 16);
- public static final int L3_NOT_IPV4 = (L3_ERROR << 24) | (2 << 16);
- public static final int L3_INVALID_IP = (L3_ERROR << 24) | (3 << 16);
-
- public static final int L4_NOT_UDP = (L4_ERROR << 24) | (1 << 16);
- public static final int L4_WRONG_PORT = (L4_ERROR << 24) | (2 << 16);
-
- public static final int BOOTP_TOO_SHORT = (DHCP_ERROR << 24) | (1 << 16);
- public static final int DHCP_BAD_MAGIC_COOKIE = (DHCP_ERROR << 24) | (2 << 16);
- public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR << 24) | (3 << 16);
- public static final int DHCP_NO_MSG_TYPE = (DHCP_ERROR << 24) | (4 << 16);
- public static final int DHCP_UNKNOWN_MSG_TYPE = (DHCP_ERROR << 24) | (5 << 16);
- public static final int DHCP_NO_COOKIE = (DHCP_ERROR << 24) | (6 << 16);
-
- public static final int BUFFER_UNDERFLOW = (MISC_ERROR << 24) | (1 << 16);
- public static final int RECEIVE_ERROR = (MISC_ERROR << 24) | (2 << 16);
- public static final int PARSING_ERROR = (MISC_ERROR << 24) | (3 << 16);
-
// error code byte format (MSB to LSB):
// byte 0: error type
// byte 1: error subtype
@@ -66,6 +45,33 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event {
/** @hide */
public final int errorCode;
+ private static final int L2_ERROR_TYPE = L2_ERROR << 8;
+ private static final int L3_ERROR_TYPE = L3_ERROR << 8;
+ private static final int L4_ERROR_TYPE = L4_ERROR << 8;
+ private static final int DHCP_ERROR_TYPE = DHCP_ERROR << 8;
+ private static final int MISC_ERROR_TYPE = MISC_ERROR << 8;
+
+ public static final int L2_TOO_SHORT = (L2_ERROR_TYPE | 0x1) << 16;
+ public static final int L2_WRONG_ETH_TYPE = (L2_ERROR_TYPE | 0x2) << 16;
+
+ public static final int L3_TOO_SHORT = (L3_ERROR_TYPE | 0x1) << 16;
+ public static final int L3_NOT_IPV4 = (L3_ERROR_TYPE | 0x2) << 16;
+ public static final int L3_INVALID_IP = (L3_ERROR_TYPE | 0x3) << 16;
+
+ public static final int L4_NOT_UDP = (L4_ERROR_TYPE | 0x1) << 16;
+ public static final int L4_WRONG_PORT = (L4_ERROR_TYPE | 0x2) << 16;
+
+ public static final int BOOTP_TOO_SHORT = (DHCP_ERROR_TYPE | 0x1) << 16;
+ public static final int DHCP_BAD_MAGIC_COOKIE = (DHCP_ERROR_TYPE | 0x2) << 16;
+ public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR_TYPE | 0x3) << 16;
+ public static final int DHCP_NO_MSG_TYPE = (DHCP_ERROR_TYPE | 0x4) << 16;
+ public static final int DHCP_UNKNOWN_MSG_TYPE = (DHCP_ERROR_TYPE | 0x5) << 16;
+ public static final int DHCP_NO_COOKIE = (DHCP_ERROR_TYPE | 0x6) << 16;
+
+ public static final int BUFFER_UNDERFLOW = (MISC_ERROR_TYPE | 0x1) << 16;
+ public static final int RECEIVE_ERROR = (MISC_ERROR_TYPE | 0x2) << 16;
+ public static final int PARSING_ERROR = (MISC_ERROR_TYPE | 0x3) << 16;
+
public DhcpErrorEvent(int errorCode) {
this.errorCode = errorCode;
}
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 9eb87ef43cbb..ebca7e6d5607 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -153,11 +153,14 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event {
return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION);
}
- public static String getProbeName(int probeType) {
+ /**
+ * Get the name of a probe specified by its probe type.
+ */
+ public static @NonNull String getProbeName(int probeType) {
return Decoder.constants.get(probeType & 0xff, "PROBE_???");
}
- private static String getValidationStage(int probeType) {
+ private static @NonNull String getValidationStage(int probeType) {
return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index a7d2ee98b45c..b90a60e5bca0 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -373,7 +373,8 @@ public final class NfcAdapter {
* A callback to be invoked when the system successfully delivers your {@link NdefMessage}
* to another device.
* @see #setOnNdefPushCompleteCallback
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public interface OnNdefPushCompleteCallback {
@@ -398,7 +399,8 @@ public final class NfcAdapter {
* content currently visible to the user. Alternatively, you can call {@link
* #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
* same data.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public interface CreateNdefMessageCallback {
@@ -427,7 +429,8 @@ public final class NfcAdapter {
/**
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public interface CreateBeamUrisCallback {
@@ -981,7 +984,8 @@ public final class NfcAdapter {
* @param uris an array of Uri(s) to push over Android Beam
* @param activity activity for which the Uri(s) will be pushed
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public void setBeamPushUris(Uri[] uris, Activity activity) {
@@ -1068,7 +1072,8 @@ public final class NfcAdapter {
* @param callback callback, or null to disable
* @param activity activity for which the Uri(s) will be pushed
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
@@ -1157,7 +1162,8 @@ public final class NfcAdapter {
* to only register one at a time, and to do so in that activity's
* {@link Activity#onCreate}
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public void setNdefPushMessage(NdefMessage message, Activity activity,
@@ -1275,7 +1281,8 @@ public final class NfcAdapter {
* to only register one at a time, and to do so in that activity's
* {@link Activity#onCreate}
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
@@ -1361,7 +1368,8 @@ public final class NfcAdapter {
* to only register one at a time, and to do so in that activity's
* {@link Activity#onCreate}
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
@@ -1577,7 +1585,8 @@ public final class NfcAdapter {
* @param activity the current foreground Activity that has registered data to share
* @return whether the Beam animation was successfully invoked
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
public boolean invokeBeam(Activity activity) {
@@ -1821,7 +1830,8 @@ public final class NfcAdapter {
* @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
* @return true if NDEF Push feature is enabled
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @deprecated this feature is deprecated.
+ * @deprecated this feature is deprecated. File sharing can work using other technology like
+ * Bluetooth.
*/
@java.lang.Deprecated
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 6536fc991b30..03e8c154e3fc 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -330,12 +330,6 @@ interface INetworkManagementService
*/
void removeIdleTimer(String iface);
- /**
- * Configure name servers, search paths, and resolver parameters for the given network.
- */
- void setDnsConfigurationForNetwork(int netId, in String[] servers, in String[] domains,
- in int[] params, String tlsHostname, in String[] tlsServers);
-
void setFirewallEnabled(boolean enabled);
boolean isFirewallEnabled();
void setFirewallInterfaceRule(String iface, boolean allow);
@@ -381,11 +375,6 @@ interface INetworkManagementService
void createVirtualNetwork(int netId, boolean secure);
/**
- * Remove a network.
- */
- void removeNetwork(int netId);
-
- /**
* Add an interface to a network.
*/
void addInterfaceToNetwork(String iface, int netId);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8a199275b123..080c0d23f426 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9420,7 +9420,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Return true iff there is a selection inside this text view.
+ * Return true iff there is a selection of nonzero length inside this text view.
*/
public boolean hasSelection() {
final int selectionStart = getSelectionStart();
diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java
index 999a908251dd..0b08099b51ed 100644
--- a/core/java/com/android/internal/app/AlertActivity.java
+++ b/core/java/com/android/internal/app/AlertActivity.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
@@ -38,11 +39,13 @@ public abstract class AlertActivity extends Activity implements DialogInterface
*
* @see #mAlertParams
*/
+ @UnsupportedAppUsage
protected AlertController mAlert;
/**
* The parameters for the alert.
*/
+ @UnsupportedAppUsage
protected AlertController.AlertParams mAlertParams;
@Override
@@ -90,6 +93,7 @@ public abstract class AlertActivity extends Activity implements DialogInterface
* @see #mAlert
* @see #mAlertParams
*/
+ @UnsupportedAppUsage
protected void setupAlert() {
mAlert.installContent(mAlertParams);
}
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index fed0a89a4d75..9ae614982fb5 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -18,6 +18,7 @@ package com.android.internal.app;
import com.android.internal.R;
+import android.annotation.UnsupportedAppUsage;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
@@ -53,6 +54,7 @@ public class AssistUtils {
private final Context mContext;
private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
+ @UnsupportedAppUsage
public AssistUtils(Context context) {
mContext = context;
mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface(
@@ -155,6 +157,7 @@ public class AssistUtils {
}
}
+ @UnsupportedAppUsage
public ComponentName getAssistComponentForUser(int userId) {
final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.ASSISTANT, userId);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c31f17af67af..6343908738fc 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -20,6 +20,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.usage.UsageStatsManager;
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 4728124c17c5..ed771406db5c 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
import android.annotation.Nullable;
import android.annotation.StringRes;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
@@ -50,6 +51,7 @@ import java.util.Set;
* be passed in and out of a managed profile.
*/
public class IntentForwarderActivity extends Activity {
+ @UnsupportedAppUsage
public static String TAG = "IntentForwarderActivity";
public static String FORWARD_INTENT_TO_PARENT
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index 0a230a90a735..aef4dbf41d35 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -17,6 +17,7 @@
package com.android.internal.app;
import android.annotation.IntRange;
+import android.annotation.UnsupportedAppUsage;
import android.icu.text.ListFormatter;
import android.icu.util.ULocale;
import android.os.LocaleList;
@@ -84,6 +85,7 @@ public class LocaleHelper {
* @param locale the locale that might be used for certain operations (i.e. case conversion)
* @return the string normalized for search
*/
+ @UnsupportedAppUsage
public static String normalizeForSearch(String str, Locale locale) {
// TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.)
// If needed we might use case folding and ICU/CLDR's collation-based loose searching.
@@ -109,6 +111,7 @@ public class LocaleHelper {
* @param sentenceCase true if the result should be sentence-cased
* @return the localized name of the locale.
*/
+ @UnsupportedAppUsage
public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) {
final ULocale displayULocale = ULocale.forLocale(displayLocale);
String result = shouldUseDialectName(locale)
@@ -135,6 +138,7 @@ public class LocaleHelper {
* @param displayLocale the locale in which to display the name.
* @return the localized country name.
*/
+ @UnsupportedAppUsage
public static String getDisplayCountry(Locale locale, Locale displayLocale) {
final String languageTag = locale.toLanguageTag();
final ULocale uDisplayLocale = ULocale.forLocale(displayLocale);
@@ -226,6 +230,7 @@ public class LocaleHelper {
*
* @param sortLocale the locale to be used for sorting.
*/
+ @UnsupportedAppUsage
public LocaleInfoComparator(Locale sortLocale, boolean countryMode) {
mCollator = Collator.getInstance(sortLocale);
mCountryMode = countryMode;
@@ -253,6 +258,7 @@ public class LocaleHelper {
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
+ @UnsupportedAppUsage
@Override
public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) {
// We don't care about the various suggestion types, just "suggested" (!= 0)
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index c8c2fcf60d1f..75174246cd99 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -18,6 +18,7 @@ package com.android.internal.app;
import com.android.internal.R;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.ListFragment;
@@ -70,6 +71,7 @@ public class LocalePicker extends ListFragment {
return label;
}
+ @UnsupportedAppUsage
public Locale getLocale() {
return locale;
}
@@ -251,6 +253,7 @@ public class LocalePicker extends ListFragment {
*
* @see #updateLocales(LocaleList)
*/
+ @UnsupportedAppUsage
public static void updateLocale(Locale locale) {
updateLocales(new LocaleList(locale));
}
@@ -260,6 +263,7 @@ public class LocalePicker extends ListFragment {
* Note that the system looks halted for a while during the Locale migration,
* so the caller need to take care of it.
*/
+ @UnsupportedAppUsage
public static void updateLocales(LocaleList locales) {
try {
final IActivityManager am = ActivityManager.getService();
@@ -281,6 +285,7 @@ public class LocalePicker extends ListFragment {
*
* @return The locale list.
*/
+ @UnsupportedAppUsage
public static LocaleList getLocales() {
try {
return ActivityManager.getService()
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index d24701372453..df2df4e92200 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.LocaleList;
import android.provider.Settings;
@@ -80,14 +81,17 @@ public class LocaleStore {
return mId;
}
+ @UnsupportedAppUsage
public Locale getLocale() {
return mLocale;
}
+ @UnsupportedAppUsage
public Locale getParent() {
return mParent;
}
+ @UnsupportedAppUsage
public String getId() {
return mId;
}
@@ -114,6 +118,7 @@ public class LocaleStore {
return (mSuggestionFlags & suggestionMask) == suggestionMask;
}
+ @UnsupportedAppUsage
public String getFullNameNative() {
if (mFullNameNative == null) {
mFullNameNative =
@@ -139,6 +144,7 @@ public class LocaleStore {
* For instance German will show as "Deutsch" in the list, but we will also search for
* "allemand" if the system UI is in French.
*/
+ @UnsupportedAppUsage
public String getFullNameInUiLanguage() {
// We don't cache the UI name because the default locale keeps changing
return LocaleHelper.getDisplayName(mLocale, true /* sentence case */);
@@ -253,6 +259,7 @@ public class LocaleStore {
}
}
+ @UnsupportedAppUsage
public static void fillCache(Context context) {
if (sFullyInitialized) {
return;
@@ -339,6 +346,7 @@ public class LocaleStore {
* Example: if the parent is "ar", then the region list will contain all Arabic locales.
* (this is not language based, but language-script, so that it works for zh-Hant and so on.
*/
+ @UnsupportedAppUsage
public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
LocaleInfo parent, boolean translatedOnly) {
fillCache(context);
@@ -364,6 +372,7 @@ public class LocaleStore {
return result;
}
+ @UnsupportedAppUsage
public static LocaleInfo getLocaleInfo(Locale locale) {
String id = locale.toLanguageTag();
LocaleInfo result;
diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java
index d3bae16d03a7..9a802a9c0fa9 100644
--- a/core/java/com/android/internal/app/NetInitiatedActivity.java
+++ b/core/java/com/android/internal/app/NetInitiatedActivity.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.annotation.UnsupportedAppUsage;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -141,6 +142,7 @@ public class NetInitiatedActivity extends AlertActivity implements DialogInterfa
locationManager.sendNiResponse(notificationId, response);
}
+ @UnsupportedAppUsage
private void handleNIVerify(Intent intent) {
int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
notificationId = notifId;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ceb06f511108..5ab76694df65 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -19,6 +19,7 @@ package com.android.internal.app;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.UiThread;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
@@ -90,6 +91,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@UiThread
public class ResolverActivity extends Activity {
+ @UnsupportedAppUsage
protected ResolveListAdapter mAdapter;
private boolean mSafeForwardingMode;
private AbsListView mAdapterView;
@@ -110,6 +112,7 @@ public class ResolverActivity extends Activity {
// Whether or not this activity supports choosing a default handler for the intent.
private boolean mSupportsAlwaysUseOption;
protected ResolverDrawerLayout mResolverDrawerLayout;
+ @UnsupportedAppUsage
protected PackageManager mPm;
protected int mLaunchedFromUid;
@@ -242,6 +245,7 @@ public class ResolverActivity extends Activity {
* Compatibility version for other bundled services that use this overload without
* a default title resource
*/
+ @UnsupportedAppUsage
protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, Intent[] initialIntents,
List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index 119f30df8946..e71ee66c677c 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -84,6 +84,7 @@ public class WindowDecorActionBar extends ActionBar implements
private ActionBarContextView mContextView;
private ActionBarContainer mSplitView;
private View mContentView;
+ @UnsupportedAppUsage
private ScrollingTabContainerView mTabScrollView;
private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
@@ -331,6 +332,7 @@ public class WindowDecorActionBar extends ActionBar implements
*
* @param enabled true to animate, false to not animate.
*/
+ @UnsupportedAppUsage
public void setShowHideAnimationEnabled(boolean enabled) {
mShowHideAnimationEnabled = enabled;
if (!enabled && mCurrentShowAnim != null) {
@@ -1147,6 +1149,7 @@ public class WindowDecorActionBar extends ActionBar implements
* @hide
*/
public class TabImpl extends ActionBar.Tab {
+ @UnsupportedAppUsage
private ActionBar.TabListener mCallback;
private Object mTag;
private Drawable mIcon;
diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java
index 00255128972c..7fe809ee319b 100644
--- a/core/java/com/android/internal/database/SortCursor.java
+++ b/core/java/com/android/internal/database/SortCursor.java
@@ -16,6 +16,7 @@
package com.android.internal.database;
+import android.annotation.UnsupportedAppUsage;
import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.DataSetObserver;
@@ -28,7 +29,9 @@ import android.util.Log;
public class SortCursor extends AbstractCursor
{
private static final String TAG = "SortCursor";
+ @UnsupportedAppUsage
private Cursor mCursor; // updated in onMove
+ @UnsupportedAppUsage
private Cursor[] mCursors;
private int [] mSortColumns;
private final int ROWCACHESIZE = 64;
@@ -52,6 +55,7 @@ public class SortCursor extends AbstractCursor
}
};
+ @UnsupportedAppUsage
public SortCursor(Cursor[] cursors, String sortcolumn)
{
mCursors = cursors;
diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java
index 8ebd4aaf1ac0..f7706e310952 100644
--- a/core/java/com/android/internal/http/HttpDateTime.java
+++ b/core/java/com/android/internal/http/HttpDateTime.java
@@ -16,6 +16,7 @@
package com.android.internal.http;
+import android.annotation.UnsupportedAppUsage;
import android.text.format.Time;
import java.util.Calendar;
@@ -82,6 +83,7 @@ public final class HttpDateTime {
int second;
}
+ @UnsupportedAppUsage
public static long parse(String timeString)
throws IllegalArgumentException {
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index f8483461c2d2..1f3b4c4121d1 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -256,6 +256,11 @@ public class NetworkStatsFactory {
return stats;
}
+ /**
+ * @deprecated Use NetworkStatsService#getDetailedUidStats which also accounts for
+ * VPN traffic
+ */
+ @Deprecated
public NetworkStats readNetworkStatsDetail() throws IOException {
return readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
}
diff --git a/core/java/com/android/internal/net/VpnInfo.java b/core/java/com/android/internal/net/VpnInfo.java
index b1a412871bd2..e74af5eb50de 100644
--- a/core/java/com/android/internal/net/VpnInfo.java
+++ b/core/java/com/android/internal/net/VpnInfo.java
@@ -19,6 +19,8 @@ package com.android.internal.net;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
+
/**
* A lightweight container used to carry information of the ongoing VPN.
* Internal use only..
@@ -28,14 +30,14 @@ import android.os.Parcelable;
public class VpnInfo implements Parcelable {
public int ownerUid;
public String vpnIface;
- public String primaryUnderlyingIface;
+ public String[] underlyingIfaces;
@Override
public String toString() {
return "VpnInfo{"
+ "ownerUid=" + ownerUid
+ ", vpnIface='" + vpnIface + '\''
- + ", primaryUnderlyingIface='" + primaryUnderlyingIface + '\''
+ + ", underlyingIfaces='" + Arrays.toString(underlyingIfaces) + '\''
+ '}';
}
@@ -48,7 +50,7 @@ public class VpnInfo implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(ownerUid);
dest.writeString(vpnIface);
- dest.writeString(primaryUnderlyingIface);
+ dest.writeStringArray(underlyingIfaces);
}
public static final Parcelable.Creator<VpnInfo> CREATOR = new Parcelable.Creator<VpnInfo>() {
@@ -57,7 +59,7 @@ public class VpnInfo implements Parcelable {
VpnInfo info = new VpnInfo();
info.ownerUid = source.readInt();
info.vpnIface = source.readString();
- info.primaryUnderlyingIface = source.readString();
+ info.underlyingIfaces = source.readStringArray();
return info;
}
diff --git a/core/java/com/android/internal/os/AndroidPrintStream.java b/core/java/com/android/internal/os/AndroidPrintStream.java
index 7f4807a5b863..fe2341144d28 100644
--- a/core/java/com/android/internal/os/AndroidPrintStream.java
+++ b/core/java/com/android/internal/os/AndroidPrintStream.java
@@ -16,6 +16,7 @@
package com.android.internal.os;
+import android.annotation.UnsupportedAppUsage;
import android.util.Log;
/**
@@ -34,6 +35,7 @@ class AndroidPrintStream extends LoggingPrintStream {
* @param priority from {@link android.util.Log}
* @param tag to log
*/
+ @UnsupportedAppUsage
public AndroidPrintStream(int priority, String tag) {
if (tag == null) {
throw new NullPointerException("tag");
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
index 05ec9e90513e..278f40660ee9 100644
--- a/core/java/com/android/internal/os/BaseCommand.java
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -17,12 +17,14 @@
package com.android.internal.os;
+import android.annotation.UnsupportedAppUsage;
import android.os.ShellCommand;
import java.io.PrintStream;
public abstract class BaseCommand {
+ @UnsupportedAppUsage
final protected ShellCommand mArgs = new ShellCommand() {
@Override public int onCommand(String cmd) {
return 0;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4ad454514532..274c44446a8c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -30,6 +30,7 @@ import android.content.IntentFilter;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
+import android.net.INetworkStatsService;
import android.net.NetworkStats;
import android.net.Uri;
import android.net.wifi.WifiActivityEnergyInfo;
@@ -87,7 +88,6 @@ import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.location.gnssmetrics.GnssMetrics;
-import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -11092,7 +11092,6 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
private final Object mWifiNetworkLock = new Object();
@@ -11114,11 +11113,16 @@ public class BatteryStatsImpl extends BatteryStats {
private NetworkStats readNetworkStatsLocked(String[] ifaces) {
try {
if (!ArrayUtils.isEmpty(ifaces)) {
- return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces,
- NetworkStats.TAG_NONE, mNetworkStatsPool.acquire());
+ INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+ if (statsService != null) {
+ return statsService.getDetailedUidStats(ifaces);
+ } else {
+ Slog.e(TAG, "Failed to get networkStatsService ");
+ }
}
- } catch (IOException e) {
- Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces));
+ } catch (RemoteException e) {
+ Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e);
}
return null;
}
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index 5bddd2f98983..6efcbda9a00d 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -17,6 +17,7 @@
package com.android.internal.os;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
@@ -94,6 +95,7 @@ public class BinderInternal {
* an implementation of IServiceManager, which you can use to find
* other services.
*/
+ @UnsupportedAppUsage
public static final native IBinder getContextObject();
/**
@@ -105,6 +107,7 @@ public class BinderInternal {
public static final native void setMaxThreads(int numThreads);
+ @UnsupportedAppUsage
static native final void handleGc();
public static void forceGc(String reason) {
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
index 99a1a19686e4..d32349834dd8 100644
--- a/core/java/com/android/internal/os/ClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -16,6 +16,7 @@
package com.android.internal.os;
+import android.annotation.UnsupportedAppUsage;
import android.os.Trace;
import dalvik.system.DelegateLastClassLoader;
@@ -132,6 +133,7 @@ public class ClassLoaderFactory {
return classLoader;
}
+ @UnsupportedAppUsage
private static native String createClassloaderNamespace(ClassLoader classLoader,
int targetSdkVersion,
String librarySearchPath,
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 1ee4269d974b..e097ddbdab40 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -18,6 +18,7 @@ package com.android.internal.os;
import static android.os.Process.*;
+import android.annotation.UnsupportedAppUsage;
import android.os.FileUtils;
import android.os.Process;
import android.os.StrictMode;
@@ -197,6 +198,7 @@ public class ProcessCpuTracker {
public boolean interesting;
public String baseName;
+ @UnsupportedAppUsage
public String name;
public int nameWidth;
@@ -212,6 +214,7 @@ public class ProcessCpuTracker {
/**
* Time in milliseconds.
*/
+ @UnsupportedAppUsage
public long rel_uptime;
/**
@@ -227,11 +230,13 @@ public class ProcessCpuTracker {
/**
* Time in milliseconds.
*/
+ @UnsupportedAppUsage
public int rel_utime;
/**
* Time in milliseconds.
*/
+ @UnsupportedAppUsage
public int rel_stime;
public long base_minfaults;
@@ -292,6 +297,7 @@ public class ProcessCpuTracker {
};
+ @UnsupportedAppUsage
public ProcessCpuTracker(boolean includeThreads) {
mIncludeThreads = includeThreads;
long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK);
@@ -311,6 +317,7 @@ public class ProcessCpuTracker {
update();
}
+ @UnsupportedAppUsage
public void update() {
if (DEBUG) Slog.v(TAG, "Update: " + this);
@@ -713,11 +720,13 @@ public class ProcessCpuTracker {
return statses;
}
+ @UnsupportedAppUsage
final public int countWorkingStats() {
buildWorkingProcs();
return mWorkingProcs.size();
}
+ @UnsupportedAppUsage
final public Stats getWorkingStats(int index) {
return mWorkingProcs.get(index);
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index e37e650f6e50..eac150dbd320 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -16,6 +16,7 @@
package com.android.internal.os;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
@@ -48,8 +49,10 @@ public class RuntimeInit {
final static boolean DEBUG = false;
/** true if commonInit() has been called */
+ @UnsupportedAppUsage
private static boolean initialized;
+ @UnsupportedAppUsage
private static IBinder mApplicationObject;
private static volatile boolean mCrashing = false;
@@ -186,6 +189,7 @@ public class RuntimeInit {
}
}
+ @UnsupportedAppUsage
protected static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
@@ -315,6 +319,7 @@ public class RuntimeInit {
return new MethodAndArgsCaller(m, argv);
}
+ @UnsupportedAppUsage
public static final void main(String[] argv) {
enableDdms();
if (argv.length == 2 && argv[1].equals("application")) {
@@ -402,6 +407,7 @@ public class RuntimeInit {
mApplicationObject = app;
}
+ @UnsupportedAppUsage
public static final IBinder getApplicationObject() {
return mApplicationObject;
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 14958ca539de..034c37cdf4c3 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,6 +26,7 @@ import static android.system.OsConstants.STDOUT_FILENO;
import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS;
import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
+import android.annotation.UnsupportedAppUsage;
import android.metrics.LogMaker;
import android.net.Credentials;
import android.net.LocalSocket;
@@ -65,9 +66,12 @@ class ZygoteConnection {
* that it closes when the child process terminates. In other cases,
* it is closed in the peer.
*/
+ @UnsupportedAppUsage
private final LocalSocket mSocket;
+ @UnsupportedAppUsage
private final DataOutputStream mSocketOutStream;
private final BufferedReader mSocketReader;
+ @UnsupportedAppUsage
private final Credentials peer;
private final String abiList;
private boolean isEof;
@@ -396,6 +400,7 @@ class ZygoteConnection {
/**
* Closes socket associated with this connection.
*/
+ @UnsupportedAppUsage
void closeSocket() {
try {
mSocket.close();
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c6303518d9ae..ce1ee3dc957a 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,6 +19,7 @@ package com.android.internal.os;
import static android.system.OsConstants.S_IRWXG;
import static android.system.OsConstants.S_IRWXO;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
@@ -105,6 +106,7 @@ public class ZygoteInit {
/**
* Used to pre-load resources.
*/
+ @UnsupportedAppUsage
private static Resources mResources;
/**
@@ -787,6 +789,7 @@ public class ZygoteInit {
return result;
}
+ @UnsupportedAppUsage
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
diff --git a/core/java/com/android/internal/os/ZygoteSecurityException.java b/core/java/com/android/internal/os/ZygoteSecurityException.java
index 13b47597c1eb..7e50cb885324 100644
--- a/core/java/com/android/internal/os/ZygoteSecurityException.java
+++ b/core/java/com/android/internal/os/ZygoteSecurityException.java
@@ -16,10 +16,13 @@
package com.android.internal.os;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Exception thrown when a security policy is violated.
*/
class ZygoteSecurityException extends RuntimeException {
+ @UnsupportedAppUsage
ZygoteSecurityException(String message) {
super(message);
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 6ad1d72eaec4..b38a7c1c47b2 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -41,6 +41,7 @@ import java.util.List;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -207,8 +208,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
private int mLastTopInset = 0;
+ @UnsupportedAppUsage
private int mLastBottomInset = 0;
+ @UnsupportedAppUsage
private int mLastRightInset = 0;
+ @UnsupportedAppUsage
private int mLastLeftInset = 0;
private boolean mLastHasTopStableInset = false;
private boolean mLastHasBottomStableInset = false;
@@ -219,6 +223,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private int mRootScrollY = 0;
+ @UnsupportedAppUsage
private PhoneWindow mWindow;
ViewGroup mContentRoot;
diff --git a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
index d8ee4dd34269..791c2d7aa4b2 100644
--- a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
+++ b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
@@ -16,6 +16,7 @@
package com.android.internal.policy;
+import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
@@ -41,7 +42,9 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
private static String TAG = "PhoneFallbackEventHandler";
private static final boolean DEBUG = false;
+ @UnsupportedAppUsage
Context mContext;
+ @UnsupportedAppUsage
View mView;
AudioManager mAudioManager;
@@ -50,6 +53,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
TelephonyManager mTelephonyManager;
MediaSessionManager mMediaSessionManager;
+ @UnsupportedAppUsage
public PhoneFallbackEventHandler(Context context) {
mContext = context;
}
@@ -74,6 +78,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
}
}
+ @UnsupportedAppUsage
boolean onKeyDown(int keyCode, KeyEvent event) {
/* ****************************************************************************
* HOW TO DECIDE WHERE YOUR KEY HANDLING GOES.
@@ -207,6 +212,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
&& (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null);
}
+ @UnsupportedAppUsage
boolean onKeyUp(int keyCode, KeyEvent event) {
if (DEBUG) {
Log.d(TAG, "up " + keyCode);
@@ -270,6 +276,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
return false;
}
+ @UnsupportedAppUsage
void startCallActivity() {
sendCloseSystemWindows();
Intent intent = new Intent(Intent.ACTION_CALL_BUTTON);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index daea9a8eff41..0fa43a6f069d 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -63,6 +63,7 @@ import com.android.internal.view.menu.MenuView;
import com.android.internal.widget.DecorContentParent;
import com.android.internal.widget.SwipeDismissLayout;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.Context;
@@ -237,6 +238,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private boolean mForcedStatusBarColor = false;
private boolean mForcedNavigationBarColor = false;
+ @UnsupportedAppUsage
private CharSequence mTitle = null;
private int mTitleColor = 0;
@@ -300,6 +302,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
static final RotationWatcher sRotationWatcher = new RotationWatcher();
+ @UnsupportedAppUsage
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 4b662670f5e7..eb556855ad41 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -18,6 +18,7 @@ package com.android.internal.util;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.util.ArraySet;
import dalvik.system.VMRuntime;
@@ -51,6 +52,7 @@ public class ArrayUtils {
return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen);
}
+ @UnsupportedAppUsage
public static int[] newUnpaddedIntArray(int minLen) {
return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen);
}
@@ -71,6 +73,7 @@ public class ArrayUtils {
return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen);
}
+ @UnsupportedAppUsage
@SuppressWarnings("unchecked")
public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) {
return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen);
@@ -108,6 +111,7 @@ public class ArrayUtils {
* it will return the same empty array every time to avoid reallocation,
* although this is not guaranteed.
*/
+ @UnsupportedAppUsage
@SuppressWarnings("unchecked")
public static <T> T[] emptyArray(Class<T> kind) {
if (kind == Object.class) {
@@ -144,6 +148,7 @@ public class ArrayUtils {
/**
* Checks if given array is null or has zero elements.
*/
+ @UnsupportedAppUsage
public static <T> boolean isEmpty(@Nullable T[] array) {
return array == null || array.length == 0;
}
@@ -196,6 +201,7 @@ public class ArrayUtils {
* @param value the value to check for
* @return true if the value is present in the array
*/
+ @UnsupportedAppUsage
public static <T> boolean contains(@Nullable T[] array, T value) {
return indexOf(array, value) != -1;
}
@@ -204,6 +210,7 @@ public class ArrayUtils {
* Return first index of {@code value} in {@code array}, or {@code -1} if
* not found.
*/
+ @UnsupportedAppUsage
public static <T> int indexOf(@Nullable T[] array, T value) {
if (array == null) return -1;
for (int i = 0; i < array.length; i++) {
@@ -238,6 +245,7 @@ public class ArrayUtils {
return false;
}
+ @UnsupportedAppUsage
public static boolean contains(@Nullable int[] array, int value) {
if (array == null) return false;
for (int element : array) {
@@ -329,6 +337,7 @@ public class ArrayUtils {
* Adds value to given array if not already present, providing set-like
* behavior.
*/
+ @UnsupportedAppUsage
@SuppressWarnings("unchecked")
public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) {
return appendElement(kind, array, element, false);
@@ -358,6 +367,7 @@ public class ArrayUtils {
/**
* Removes value from given array if present, providing set-like behavior.
*/
+ @UnsupportedAppUsage
@SuppressWarnings("unchecked")
public static @Nullable <T> T[] removeElement(Class<T> kind, @Nullable T[] array, T element) {
if (array != null) {
@@ -404,6 +414,7 @@ public class ArrayUtils {
* Adds value to given array if not already present, providing set-like
* behavior.
*/
+ @UnsupportedAppUsage
public static @NonNull int[] appendInt(@Nullable int[] cur, int val) {
return appendInt(cur, val, false);
}
diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java
index 86f74f302518..6ff67e9b9718 100644
--- a/core/java/com/android/internal/util/BitwiseInputStream.java
+++ b/core/java/com/android/internal/util/BitwiseInputStream.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
+
/**
* An object that provides bitwise incremental read access to a byte array.
*
@@ -49,6 +51,7 @@ public class BitwiseInputStream {
*
* @param buf a byte array containing data
*/
+ @UnsupportedAppUsage
public BitwiseInputStream(byte buf[]) {
mBuf = buf;
mEnd = buf.length << 3;
@@ -58,6 +61,7 @@ public class BitwiseInputStream {
/**
* Return the number of bit still available for reading.
*/
+ @UnsupportedAppUsage
public int available() {
return mEnd - mPos;
}
@@ -71,6 +75,7 @@ public class BitwiseInputStream {
* @param bits the amount of data to read (gte 0, lte 8)
* @return byte of read data (possibly partially filled, from lsb)
*/
+ @UnsupportedAppUsage
public int read(int bits) throws AccessException {
int index = mPos >>> 3;
int offset = 16 - (mPos & 0x07) - bits; // &7==%8
@@ -92,6 +97,7 @@ public class BitwiseInputStream {
* @param bits the amount of data to read
* @return newly allocated byte array of read data
*/
+ @UnsupportedAppUsage
public byte[] readByteArray(int bits) throws AccessException {
int bytes = (bits >>> 3) + ((bits & 0x07) > 0 ? 1 : 0); // &7==%8
byte[] arr = new byte[bytes];
@@ -107,6 +113,7 @@ public class BitwiseInputStream {
*
* @param bits the amount by which to increment the position
*/
+ @UnsupportedAppUsage
public void skip(int bits) throws AccessException {
if ((mPos + bits) > mEnd) {
throw new AccessException("illegal skip " +
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
index ddecbed1d97c..cdd6f173484c 100644
--- a/core/java/com/android/internal/util/BitwiseOutputStream.java
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
+
/**
* An object that provides bitwise incremental write access to a byte array.
*
@@ -49,6 +51,7 @@ public class BitwiseOutputStream {
*
* @param startingLength initial internal byte array length in bytes
*/
+ @UnsupportedAppUsage
public BitwiseOutputStream(int startingLength) {
mBuf = new byte[startingLength];
mEnd = startingLength << 3;
@@ -60,6 +63,7 @@ public class BitwiseOutputStream {
*
* @return newly allocated byte array
*/
+ @UnsupportedAppUsage
public byte[] toByteArray() {
int len = (mPos >>> 3) + ((mPos & 0x07) > 0 ? 1 : 0); // &7==%8
byte[] newBuf = new byte[len];
@@ -89,6 +93,7 @@ public class BitwiseOutputStream {
* @param bits the amount of data to write (gte 0, lte 8)
* @param data to write, will be masked to expose only bits param from lsb
*/
+ @UnsupportedAppUsage
public void write(int bits, int data) throws AccessException {
if ((bits < 0) || (bits > 8)) {
throw new AccessException("illegal write (" + bits + " bits)");
@@ -109,6 +114,7 @@ public class BitwiseOutputStream {
* @param bits the amount of data to write
* @param arr the byte array containing data to be written
*/
+ @UnsupportedAppUsage
public void writeByteArray(int bits, byte[] arr) throws AccessException {
for (int i = 0; i < arr.length; i++) {
int increment = Math.min(8, bits - (i << 3));
diff --git a/core/java/com/android/internal/util/CharSequences.java b/core/java/com/android/internal/util/CharSequences.java
index fdaa4bce25db..6b6c43ce8195 100644
--- a/core/java/com/android/internal/util/CharSequences.java
+++ b/core/java/com/android/internal/util/CharSequences.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
+
/**
* {@link CharSequence} utility methods.
*/
@@ -93,6 +95,7 @@ public class CharSequences {
/**
* Compares two character sequences for equality.
*/
+ @UnsupportedAppUsage
public static boolean equals(CharSequence a, CharSequence b) {
if (a.length() != b.length()) {
return false;
@@ -114,6 +117,7 @@ public class CharSequences {
* @param another The other CharSequence.
* @return See {@link Comparable#compareTo}.
*/
+ @UnsupportedAppUsage
public static int compareToIgnoreCase(CharSequence me, CharSequence another) {
// Code adapted from String#compareTo
int myLen = me.length(), anotherLen = another.length();
diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java
index 88a17e6ba259..35efe708795e 100644
--- a/core/java/com/android/internal/util/FastMath.java
+++ b/core/java/com/android/internal/util/FastMath.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Fast and loose math routines.
*/
@@ -26,6 +28,7 @@ public class FastMath {
* thought it may return slightly different results. It does not try to
* handle (in any meaningful way) NaN or infinities.
*/
+ @UnsupportedAppUsage
public static int round(float value) {
long lx = (long) (value * (65536 * 256f));
return (int) ((lx + 0x800000) >> 24);
diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
index b85b84fb3dc8..9f76aeb663c5 100644
--- a/core/java/com/android/internal/util/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -18,6 +18,7 @@ package com.android.internal.util;
import org.xmlpull.v1.XmlSerializer;
+import android.annotation.UnsupportedAppUsage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -69,6 +70,7 @@ public class FastXmlSerializer implements XmlSerializer {
private int mNesting = 0;
private boolean mLineStart = true;
+ @UnsupportedAppUsage
public FastXmlSerializer() {
this(DEFAULT_BUFFER_LEN);
}
diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java
index 968d9204b106..9f563667e019 100644
--- a/core/java/com/android/internal/util/GrowingArrayUtils.java
+++ b/core/java/com/android/internal/util/GrowingArrayUtils.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
+
/**
* A helper class that aims to provide comparable growth performance to ArrayList, but on primitive
* arrays. Common array operations are implemented for efficient use in dynamic containers.
@@ -37,6 +39,7 @@ public final class GrowingArrayUtils {
* @return the array to which the element was appended. This may be different than the given
* array.
*/
+ @UnsupportedAppUsage
public static <T> T[] append(T[] array, int currentSize, T element) {
assert currentSize <= array.length;
@@ -54,6 +57,7 @@ public final class GrowingArrayUtils {
/**
* Primitive int version of {@link #append(Object[], int, Object)}.
*/
+ @UnsupportedAppUsage
public static int[] append(int[] array, int currentSize, int element) {
assert currentSize <= array.length;
diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java
index af004009e1ee..6ffc92853b08 100644
--- a/core/java/com/android/internal/util/HexDump.java
+++ b/core/java/com/android/internal/util/HexDump.java
@@ -17,6 +17,7 @@
package com.android.internal.util;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
public class HexDump
{
@@ -100,16 +101,19 @@ public class HexDump
return toHexString(toByteArray(b));
}
+ @UnsupportedAppUsage
public static String toHexString(byte[] array)
{
return toHexString(array, 0, array.length, true);
}
+ @UnsupportedAppUsage
public static String toHexString(byte[] array, boolean upperCase)
{
return toHexString(array, 0, array.length, upperCase);
}
+ @UnsupportedAppUsage
public static String toHexString(byte[] array, int offset, int length)
{
return toHexString(array, offset, length, true);
@@ -131,6 +135,7 @@ public class HexDump
return new String(buf);
}
+ @UnsupportedAppUsage
public static String toHexString(int i)
{
return toHexString(toByteArray(i));
@@ -164,6 +169,7 @@ public class HexDump
throw new RuntimeException ("Invalid hex char '" + c + "'");
}
+ @UnsupportedAppUsage
public static byte[] hexStringToByteArray(String hexString)
{
int length = hexString.length();
diff --git a/core/java/com/android/internal/util/IState.java b/core/java/com/android/internal/util/IState.java
index 056f8e9b0424..eb66e2ce94d7 100644
--- a/core/java/com/android/internal/util/IState.java
+++ b/core/java/com/android/internal/util/IState.java
@@ -16,6 +16,7 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
import android.os.Message;
/**
@@ -67,5 +68,6 @@ public interface IState {
*
* @return name of state.
*/
+ @UnsupportedAppUsage
String getName();
}
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 8d7166679b78..630916ebeecb 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -16,12 +16,14 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
import android.os.Debug;
import android.os.StrictMode;
public final class MemInfoReader {
final long[] mInfos = new long[Debug.MEMINFO_COUNT];
+ @UnsupportedAppUsage
public void readMemInfo() {
// Permit disk reads here, as /proc/meminfo isn't really "on
// disk" and should be fast. TODO: make BlockGuard ignore
@@ -37,6 +39,7 @@ public final class MemInfoReader {
/**
* Total amount of RAM available to the kernel.
*/
+ @UnsupportedAppUsage
public long getTotalSize() {
return mInfos[Debug.MEMINFO_TOTAL] * 1024;
}
@@ -44,6 +47,7 @@ public final class MemInfoReader {
/**
* Amount of RAM that is not being used for anything.
*/
+ @UnsupportedAppUsage
public long getFreeSize() {
return mInfos[Debug.MEMINFO_FREE] * 1024;
}
@@ -52,6 +56,7 @@ public final class MemInfoReader {
* Amount of RAM that the kernel is being used for caches, not counting caches
* that are mapped in to processes.
*/
+ @UnsupportedAppUsage
public long getCachedSize() {
return getCachedSizeKb() * 1024;
}
@@ -107,6 +112,7 @@ public final class MemInfoReader {
return mInfos[Debug.MEMINFO_ZRAM_TOTAL];
}
+ @UnsupportedAppUsage
public long[] getRawInfo() {
return mInfos;
}
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 91c76afdf5b2..3a5720f6e918 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -18,6 +18,7 @@ package com.android.internal.util;
import android.annotation.IntRange;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.text.TextUtils;
import java.util.Collection;
@@ -28,6 +29,7 @@ import java.util.Collection;
*/
public class Preconditions {
+ @UnsupportedAppUsage
public static void checkArgument(boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
@@ -42,6 +44,7 @@ public class Preconditions {
* be converted to a string using {@link String#valueOf(Object)}
* @throws IllegalArgumentException if {@code expression} is false
*/
+ @UnsupportedAppUsage
public static void checkArgument(boolean expression, final Object errorMessage) {
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
@@ -106,6 +109,7 @@ public class Preconditions {
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
+ @UnsupportedAppUsage
public static @NonNull <T> T checkNotNull(final T reference) {
if (reference == null) {
throw new NullPointerException();
@@ -123,6 +127,7 @@ public class Preconditions {
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
+ @UnsupportedAppUsage
public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
@@ -158,6 +163,7 @@ public class Preconditions {
* @param message exception message
* @throws IllegalStateException if {@code expression} is false
*/
+ @UnsupportedAppUsage
public static void checkState(final boolean expression, String message) {
if (!expression) {
throw new IllegalStateException(message);
@@ -171,6 +177,7 @@ public class Preconditions {
* @param expression a boolean expression
* @throws IllegalStateException if {@code expression} is false
*/
+ @UnsupportedAppUsage
public static void checkState(final boolean expression) {
checkState(expression, null);
}
@@ -338,6 +345,7 @@ public class Preconditions {
*
* @throws IllegalArgumentException if {@code value} was not within the range
*/
+ @UnsupportedAppUsage
public static int checkArgumentInRange(int value, int lower, int upper,
String valueName) {
if (value < lower) {
diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java
index 3eadff58bc09..3c61e035e886 100644
--- a/core/java/com/android/internal/util/State.java
+++ b/core/java/com/android/internal/util/State.java
@@ -16,6 +16,7 @@
package com.android.internal.util;
+import android.annotation.UnsupportedAppUsage;
import android.os.Message;
/**
@@ -28,12 +29,14 @@ public class State implements IState {
/**
* Constructor
*/
+ @UnsupportedAppUsage
protected State() {
}
/* (non-Javadoc)
* @see com.android.internal.util.IState#enter()
*/
+ @UnsupportedAppUsage
@Override
public void enter() {
}
@@ -41,6 +44,7 @@ public class State implements IState {
/* (non-Javadoc)
* @see com.android.internal.util.IState#exit()
*/
+ @UnsupportedAppUsage
@Override
public void exit() {
}
@@ -48,6 +52,7 @@ public class State implements IState {
/* (non-Javadoc)
* @see com.android.internal.util.IState#processMessage(android.os.Message)
*/
+ @UnsupportedAppUsage
@Override
public boolean processMessage(Message msg) {
return false;
@@ -65,6 +70,7 @@ public class State implements IState {
*
* @see com.android.internal.util.IState#processMessage(android.os.Message)
*/
+ @UnsupportedAppUsage
@Override
public String getName() {
String name = getClass().getName();
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 7398e9526a42..dacdae6fd6c6 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1301,6 +1301,7 @@ public class StateMachine {
*
* @param name of the state machine
*/
+ @UnsupportedAppUsage
protected StateMachine(String name) {
mSmThread = new HandlerThread(name);
mSmThread.start();
@@ -1314,6 +1315,7 @@ public class StateMachine {
*
* @param name of the state machine
*/
+ @UnsupportedAppUsage
protected StateMachine(String name, Looper looper) {
initStateMachine(name, looper);
}
@@ -1323,6 +1325,7 @@ public class StateMachine {
*
* @param name of the state machine
*/
+ @UnsupportedAppUsage
protected StateMachine(String name, Handler handler) {
initStateMachine(name, handler.getLooper());
}
@@ -1678,6 +1681,7 @@ public class StateMachine {
* @param arg2 is assigned to Message.arg2
* @return A Message object from the global pool
*/
+ @UnsupportedAppUsage
public final Message obtainMessage(int what, int arg1, int arg2) {
return Message.obtain(mSmHandler, what, arg1, arg2);
}
@@ -1697,6 +1701,7 @@ public class StateMachine {
* @param obj is assigned to Message.obj
* @return A Message object from the global pool
*/
+ @UnsupportedAppUsage
public final Message obtainMessage(int what, int arg1, int arg2, Object obj) {
return Message.obtain(mSmHandler, what, arg1, arg2, obj);
}
@@ -1706,6 +1711,7 @@ public class StateMachine {
*
* Message is ignored if state machine has quit.
*/
+ @UnsupportedAppUsage
public void sendMessage(int what) {
// mSmHandler can be null if the state machine has quit.
SmHandler smh = mSmHandler;
@@ -1719,6 +1725,7 @@ public class StateMachine {
*
* Message is ignored if state machine has quit.
*/
+ @UnsupportedAppUsage
public void sendMessage(int what, Object obj) {
// mSmHandler can be null if the state machine has quit.
SmHandler smh = mSmHandler;
@@ -1732,6 +1739,7 @@ public class StateMachine {
*
* Message is ignored if state machine has quit.
*/
+ @UnsupportedAppUsage
public void sendMessage(int what, int arg1) {
// mSmHandler can be null if the state machine has quit.
SmHandler smh = mSmHandler;
@@ -1758,6 +1766,7 @@ public class StateMachine {
*
* Message is ignored if state machine has quit.
*/
+ @UnsupportedAppUsage
public void sendMessage(int what, int arg1, int arg2, Object obj) {
// mSmHandler can be null if the state machine has quit.
SmHandler smh = mSmHandler;
@@ -1771,6 +1780,7 @@ public class StateMachine {
*
* Message is ignored if state machine has quit.
*/
+ @UnsupportedAppUsage
public void sendMessage(Message msg) {
// mSmHandler can be null if the state machine has quit.
SmHandler smh = mSmHandler;
@@ -2074,6 +2084,7 @@ public class StateMachine {
* @param pw
* @param args
*/
+ @UnsupportedAppUsage
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(getName() + ":");
pw.println(" total records=" + getLogRecCount());
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index 755faf333a1e..d18c35e703da 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -18,6 +18,7 @@ package com.android.internal.view;
import com.android.internal.R;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -29,12 +30,15 @@ import android.os.Build;
* about how the action bar should lay out and behave on the current device.
*/
public class ActionBarPolicy {
+ @UnsupportedAppUsage
private Context mContext;
+ @UnsupportedAppUsage
public static ActionBarPolicy get(Context context) {
return new ActionBarPolicy(context);
}
+ @UnsupportedAppUsage
private ActionBarPolicy(Context context) {
mContext = context;
}
@@ -44,6 +48,7 @@ public class ActionBarPolicy {
* bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit.
* "always" items can override this.
*/
+ @UnsupportedAppUsage
public int getMaxActionButtons() {
final Configuration config = mContext.getResources().getConfiguration();
final int width = config.screenWidthDp;
@@ -62,14 +67,17 @@ public class ActionBarPolicy {
return 2;
}
}
+ @UnsupportedAppUsage
public boolean showsOverflowMenuButton() {
return true;
}
+ @UnsupportedAppUsage
public int getEmbeddedMenuWidthLimit() {
return mContext.getResources().getDisplayMetrics().widthPixels / 2;
}
+ @UnsupportedAppUsage
public boolean hasEmbeddedTabs() {
final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
@@ -85,6 +93,7 @@ public class ActionBarPolicy {
width >= 480 || (width >= 640 && height >= 480);
}
+ @UnsupportedAppUsage
public int getTabContainerHeight() {
TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar,
com.android.internal.R.attr.actionBarStyle, 0);
@@ -106,6 +115,7 @@ public class ActionBarPolicy {
Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}
+ @UnsupportedAppUsage
public int getStackedTabMaxWidth() {
return mContext.getResources().getDimensionPixelSize(
R.dimen.action_bar_stacked_tab_max_width);
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 5b65bbe1e90e..666c9e093218 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -19,6 +19,7 @@ package com.android.internal.view;
import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.inputmethodservice.AbstractInputMethodService;
import android.os.Bundle;
import android.os.Handler;
@@ -78,6 +79,7 @@ public class InputConnectionWrapper implements InputConnection {
* sequence number is set to a new integer. We use a sequence number so that replies that
* occur after a timeout has expired are not interpreted as replies to a later request.
*/
+ @UnsupportedAppUsage
@AnyThread
private static InputContextCallback getInstance() {
synchronized (InputContextCallback.class) {
@@ -102,6 +104,7 @@ public class InputConnectionWrapper implements InputConnection {
/**
* Makes the given InputContextCallback available for use in the future.
*/
+ @UnsupportedAppUsage
@AnyThread
private void dispose() {
synchronized (InputContextCallback.class) {
diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
index c8c38bb01886..b009a2d8ca30 100644
--- a/core/java/com/android/internal/view/WindowManagerPolicyThread.java
+++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
@@ -16,6 +16,7 @@
package com.android.internal.view;
+import android.annotation.UnsupportedAppUsage;
import android.os.Looper;
/**
@@ -35,6 +36,7 @@ public class WindowManagerPolicyThread {
return mThread;
}
+ @UnsupportedAppUsage
public static Looper getLooper() {
return mLooper;
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java
index c657b872e71e..977c1f6fda7b 100644
--- a/core/java/com/android/internal/view/menu/ActionMenu.java
+++ b/core/java/com/android/internal/view/menu/ActionMenu.java
@@ -19,6 +19,7 @@ package com.android.internal.view.menu;
import java.util.ArrayList;
import java.util.List;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -39,6 +40,7 @@ public class ActionMenu implements Menu {
private ArrayList<ActionMenuItem> mItems;
+ @UnsupportedAppUsage
public ActionMenu(Context context) {
mContext = context;
mItems = new ArrayList<ActionMenuItem>();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index b807a42e922e..ed253d58fb82 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -17,6 +17,7 @@
package com.android.internal.view.menu;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
@@ -69,6 +70,7 @@ public class ActionMenuItem implements MenuItem {
private static final int HIDDEN = 0x00000008;
private static final int ENABLED = 0x00000010;
+ @UnsupportedAppUsage
public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering,
CharSequence title) {
mContext = context;
diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
index 82f061cb86ca..3d3aceb4a85f 100644
--- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
@@ -16,6 +16,7 @@
package com.android.internal.view.menu;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
@@ -39,6 +40,7 @@ import android.view.View;
*/
public class ContextMenuBuilder extends MenuBuilder implements ContextMenu {
+ @UnsupportedAppUsage
public ContextMenuBuilder(Context context) {
super(context);
}
diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java
index 6c8f330fbcc8..3d888d347d65 100644
--- a/core/java/com/android/internal/view/menu/IconMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java
@@ -18,6 +18,7 @@ package com.android.internal.view.menu;
import com.android.internal.view.menu.MenuBuilder.ItemInvoker;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
@@ -213,6 +214,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie
}
}
+ @UnsupportedAppUsage
public void setItemInvoker(ItemInvoker itemInvoker) {
mItemInvoker = itemInvoker;
}
@@ -232,6 +234,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie
}
}
+ @UnsupportedAppUsage
void setIconMenuView(IconMenuView iconMenuView) {
mIconMenuView = iconMenuView;
}
@@ -267,6 +270,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie
* @return layout params appropriate for this view. If layout params already exist, it will
* augment them to be appropriate to the current text size.
*/
+ @UnsupportedAppUsage
IconMenuView.LayoutParams getTextAppropriateLayoutParams() {
IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams();
if (lp == null) {
diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java
index dab43ebfe5d5..6f264341f7b4 100644
--- a/core/java/com/android/internal/view/menu/IconMenuView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuView.java
@@ -18,6 +18,7 @@ package com.android.internal.view.menu;
import com.android.internal.view.menu.MenuBuilder.ItemInvoker;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -51,6 +52,7 @@ import java.util.ArrayList;
public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuView, Runnable {
private static final int ITEM_CAPTION_CYCLE_DELAY = 1000;
+ @UnsupportedAppUsage
private MenuBuilder mMenu;
/** Height of each row */
@@ -58,6 +60,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi
/** Maximum number of rows to be shown */
private int mMaxRows;
/** Maximum number of items to show in the icon menu. */
+ @UnsupportedAppUsage
private int mMaxItems;
/** Maximum number of items per row */
private int mMaxItemsPerRow;
@@ -82,6 +85,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi
private Drawable mMoreIcon;
/** Background of each item (should contain the selected and focused states) */
+ @UnsupportedAppUsage
private Drawable mItemBackground;
/** Default animations for this menu */
@@ -288,6 +292,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi
* have a MenuItemData backing it.
* @return The IconMenuItemView for the 'More' button
*/
+ @UnsupportedAppUsage
IconMenuItemView createMoreItemView() {
Context context = getContext();
LayoutInflater inflater = LayoutInflater.from(context);
@@ -494,6 +499,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi
* {@link MenuView.ItemView} implementation--eg: excludes More
* item).
*/
+ @UnsupportedAppUsage
int getNumActualItemsShown() {
return mNumActualItemsShown;
}
@@ -717,6 +723,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi
/**
* Constructor called from {@link #CREATOR}
*/
+ @UnsupportedAppUsage
private SavedState(Parcel in) {
super(in);
focusedPosition = in.readInt();
diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
index ecab29fdbbd4..88d0a03bd55f 100644
--- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
@@ -16,6 +16,7 @@
package com.android.internal.view.menu;
+import android.annotation.UnsupportedAppUsage;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
@@ -36,6 +37,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen
ListMenuPresenter mPresenter;
private MenuPresenter.Callback mPresenterCallback;
+ @UnsupportedAppUsage
public MenuDialogHelper(MenuBuilder menu) {
mMenu = menu;
}
@@ -45,6 +47,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen
*
* @param windowToken Optional token to assign to the window.
*/
+ @UnsupportedAppUsage
public void show(IBinder windowToken) {
// Many references to mMenu, create local reference
final MenuBuilder menu = mMenu;
@@ -132,6 +135,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen
*
* @see Dialog#dismiss()
*/
+ @UnsupportedAppUsage
@Override
public void dismiss() {
if (mDialog != null) {
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 582c4f1dd669..9ccee7fc32ff 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -27,6 +27,7 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -294,6 +295,7 @@ public abstract class AbsActionBarView extends ViewGroup {
return isOverflowReserved() && getVisibility() == VISIBLE;
}
+ @UnsupportedAppUsage
public void dismissPopupMenus() {
if (mActionMenuPresenter != null) {
mActionMenuPresenter.dismissPopupMenus();
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 693b194caa8b..78ed53fa918c 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -21,6 +21,7 @@ import android.widget.ActionMenuPresenter;
import android.widget.ActionMenuView;
import com.android.internal.view.menu.MenuBuilder;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -58,6 +59,7 @@ public class ActionBarContextView extends AbsActionBarView {
this(context, null);
}
+ @UnsupportedAppUsage
public ActionBarContextView(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.actionModeStyle);
}
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 4a1c95532ba0..efa8f2c3888a 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -18,6 +18,7 @@ package com.android.internal.widget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
@@ -168,6 +169,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
init(context);
}
+ @UnsupportedAppUsage
public ActionBarOverlayLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
@@ -672,6 +674,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
return finalY > mActionBarTop.getHeight();
}
+ @UnsupportedAppUsage
@Override
public void setWindowCallback(Window.Callback cb) {
pullChildren();
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 7f7528dd3de0..4bf34c83a872 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spanned;
@@ -41,6 +42,7 @@ public class EditableInputConnection extends BaseInputConnection {
// A negative value means that this connection has been finished by the InputMethodManager.
private int mBatchEditNesting;
+ @UnsupportedAppUsage
public EditableInputConnection(TextView textview) {
super(textview, true);
mTextView = textview;
diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
index b2001cbe15ef..cc7911da0b96 100644
--- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
+++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -36,6 +37,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout {
private final Rect mTempRect = new Rect();
private View mDefaultTouchRecepient;
+ @UnsupportedAppUsage
public LinearLayoutWithDefaultTouchRecepient(Context context) {
super(context);
}
@@ -44,6 +46,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout {
super(context, attrs);
}
+ @UnsupportedAppUsage
public void setDefaultTouchRecepient(View defaultTouchRecepient) {
mDefaultTouchRecepient = defaultTouchRecepient;
}
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index 586ece0a274a..2a485f129ab8 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -1,5 +1,6 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.os.AsyncTask;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
@@ -223,6 +224,7 @@ public final class LockPatternChecker {
* @param userId The user to check against the pattern.
* @param callback The callback to be invoked with the check result.
*/
+ @UnsupportedAppUsage
public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils,
final String password,
final int userId,
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 8eae8afe2407..a3bfd021ca87 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -27,6 +27,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.admin.DevicePolicyManager;
import android.app.admin.PasswordMetrics;
import android.app.trust.IStrongAuthTracker;
@@ -169,7 +170,9 @@ public class LockPatternUtils {
public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp";
private static final String HISTORY_DELIMITER = ",";
+ @UnsupportedAppUsage
private final Context mContext;
+ @UnsupportedAppUsage
private final ContentResolver mContentResolver;
private DevicePolicyManager mDevicePolicyManager;
private ILockSettings mLockSettingsService;
@@ -212,6 +215,7 @@ public class LockPatternUtils {
public static final class RequestThrottledException extends Exception {
private int mTimeoutMs;
+ @UnsupportedAppUsage
public RequestThrottledException(int timeoutMs) {
mTimeoutMs = timeoutMs;
}
@@ -220,12 +224,14 @@ public class LockPatternUtils {
* @return The amount of time in ms before another request may
* be executed
*/
+ @UnsupportedAppUsage
public int getTimeoutMs() {
return mTimeoutMs;
}
}
+ @UnsupportedAppUsage
public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
mDevicePolicyManager =
@@ -254,6 +260,7 @@ public class LockPatternUtils {
return trust;
}
+ @UnsupportedAppUsage
public LockPatternUtils(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
@@ -262,6 +269,7 @@ public class LockPatternUtils {
mHandler = looper != null ? new Handler(looper) : null;
}
+ @UnsupportedAppUsage
@VisibleForTesting
public ILockSettings getLockSettings() {
if (mLockSettingsService == null) {
@@ -312,6 +320,7 @@ public class LockPatternUtils {
return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId);
}
+ @UnsupportedAppUsage
public void reportFailedPasswordAttempt(int userId) {
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
return;
@@ -320,6 +329,7 @@ public class LockPatternUtils {
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
}
+ @UnsupportedAppUsage
public void reportSuccessfulPasswordAttempt(int userId) {
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
return;
@@ -479,6 +489,7 @@ public class LockPatternUtils {
* @param password The password to check.
* @return Whether the password matches the stored one.
*/
+ @UnsupportedAppUsage
public boolean checkPassword(String password, int userId) throws RequestThrottledException {
return checkPassword(password, userId, null /* progressCallback */);
}
@@ -602,6 +613,7 @@ public class LockPatternUtils {
* Used by device policy manager to validate the current password
* information it has.
*/
+ @UnsupportedAppUsage
public int getActivePasswordQuality(int userId) {
int quality = getKeyguardStoredPasswordQuality(userId);
@@ -672,6 +684,7 @@ public class LockPatternUtils {
*
* @return true if lock screen is disabled
*/
+ @UnsupportedAppUsage
public boolean isLockScreenDisabled(int userId) {
if (isSecure(userId)) {
return false;
@@ -754,16 +767,19 @@ public class LockPatternUtils {
}
}
+ @UnsupportedAppUsage
public void setOwnerInfo(String info, int userId) {
setString(LOCK_SCREEN_OWNER_INFO, info, userId);
updateCryptoUserInfo(userId);
}
+ @UnsupportedAppUsage
public void setOwnerInfoEnabled(boolean enabled, int userId) {
setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
updateCryptoUserInfo(userId);
}
+ @UnsupportedAppUsage
public String getOwnerInfo(int userId) {
return getString(LOCK_SCREEN_OWNER_INFO, userId);
}
@@ -829,6 +845,7 @@ public class LockPatternUtils {
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
*/
+ @UnsupportedAppUsage
public void saveLockPassword(String password, String savedPassword, int requestedQuality,
int userHandle) {
if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) {
@@ -926,6 +943,7 @@ public class LockPatternUtils {
* encrypted with the default password.
* @return true if device encryption is enabled
*/
+ @UnsupportedAppUsage
public static boolean isDeviceEncryptionEnabled() {
return StorageManager.isEncrypted();
}
@@ -951,6 +969,7 @@ public class LockPatternUtils {
*
* @return stored password quality
*/
+ @UnsupportedAppUsage
public int getKeyguardStoredPasswordQuality(int userHandle) {
return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
}
@@ -1072,6 +1091,7 @@ public class LockPatternUtils {
* @param pattern The pattern.
* @return The pattern in string form.
*/
+ @UnsupportedAppUsage
public static String patternToString(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return "";
@@ -1107,6 +1127,7 @@ public class LockPatternUtils {
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
*/
+ @UnsupportedAppUsage
public static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return null;
@@ -1193,11 +1214,13 @@ public class LockPatternUtils {
* @param userId the user for which to report the value
* @return Whether the lock screen is secured.
*/
+ @UnsupportedAppUsage
public boolean isSecure(int userId) {
int mode = getKeyguardStoredPasswordQuality(userId);
return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId);
}
+ @UnsupportedAppUsage
public boolean isLockPasswordEnabled(int userId) {
return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId);
}
@@ -1215,6 +1238,7 @@ public class LockPatternUtils {
/**
* @return Whether the lock pattern is enabled
*/
+ @UnsupportedAppUsage
public boolean isLockPatternEnabled(int userId) {
return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
}
@@ -1239,6 +1263,7 @@ public class LockPatternUtils {
/**
* @return Whether the visible pattern is enabled.
*/
+ @UnsupportedAppUsage
public boolean isVisiblePatternEnabled(int userId) {
return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId);
}
@@ -1298,6 +1323,7 @@ public class LockPatternUtils {
/**
* @return Whether tactile feedback for the pattern is enabled.
*/
+ @UnsupportedAppUsage
public boolean isTactileFeedbackEnabled() {
return Settings.System.getIntForUser(mContentResolver,
Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
@@ -1308,6 +1334,7 @@ public class LockPatternUtils {
* pattern until the deadline has passed.
* @return the chosen deadline.
*/
+ @UnsupportedAppUsage
public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
if (userId == USER_FRP) {
@@ -1360,6 +1387,7 @@ public class LockPatternUtils {
}
}
+ @UnsupportedAppUsage
private void setLong(String secureSettingKey, long value, int userHandle) {
try {
getLockSettings().setLong(secureSettingKey, value, userHandle);
@@ -1369,6 +1397,7 @@ public class LockPatternUtils {
}
}
+ @UnsupportedAppUsage
private String getString(String secureSettingKey, int userHandle) {
try {
return getLockSettings().getString(secureSettingKey, null, userHandle);
@@ -1377,6 +1406,7 @@ public class LockPatternUtils {
}
}
+ @UnsupportedAppUsage
private void setString(String secureSettingKey, String value, int userHandle) {
try {
getLockSettings().setString(secureSettingKey, value, userHandle);
@@ -1390,6 +1420,7 @@ public class LockPatternUtils {
setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId);
}
+ @UnsupportedAppUsage
public boolean getPowerButtonInstantlyLocks(int userId) {
return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index e8fc5989354a..70efd0081fcc 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -19,6 +19,7 @@ package com.android.internal.widget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -79,7 +80,9 @@ public class LockPatternView extends View {
private boolean mDrawingProfilingStarted = false;
+ @UnsupportedAppUsage
private final Paint mPaint = new Paint();
+ @UnsupportedAppUsage
private final Paint mPathPaint = new Paint();
/**
@@ -99,6 +102,7 @@ public class LockPatternView extends View {
private static final String TAG = "LockPatternView";
private OnPatternListener mOnPatternListener;
+ @UnsupportedAppUsage
private final ArrayList<Cell> mPattern = new ArrayList<Cell>(9);
/**
@@ -120,16 +124,21 @@ public class LockPatternView extends View {
private long mAnimatingPeriodStart;
private long[] mLineFadeStart = new long[9];
+ @UnsupportedAppUsage
private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
private boolean mInputEnabled = true;
+ @UnsupportedAppUsage
private boolean mInStealthMode = false;
private boolean mEnableHapticFeedback = true;
+ @UnsupportedAppUsage
private boolean mPatternInProgress = false;
private boolean mFadePattern = true;
private float mHitFactor = 0.6f;
+ @UnsupportedAppUsage
private float mSquareWidth;
+ @UnsupportedAppUsage
private float mSquareHeight;
private final Path mCurrentPath = new Path();
@@ -154,7 +163,9 @@ public class LockPatternView extends View {
* Represents a cell in the 3 X 3 matrix of the unlock pattern view.
*/
public static final class Cell {
+ @UnsupportedAppUsage
final int row;
+ @UnsupportedAppUsage
final int column;
// keep # objects limited to 9
@@ -232,16 +243,19 @@ public class LockPatternView extends View {
/**
* The pattern drawn is correct (i.e draw it in a friendly color)
*/
+ @UnsupportedAppUsage
Correct,
/**
* Animate the pattern (for demo, and help).
*/
+ @UnsupportedAppUsage
Animate,
/**
* The pattern is wrong (i.e draw a foreboding color)
*/
+ @UnsupportedAppUsage
Wrong
}
@@ -277,6 +291,7 @@ public class LockPatternView extends View {
this(context, null);
}
+ @UnsupportedAppUsage
public LockPatternView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -348,6 +363,7 @@ public class LockPatternView extends View {
a.recycle();
}
+ @UnsupportedAppUsage
public CellState[][] getCellStates() {
return mCellStates;
}
@@ -372,6 +388,7 @@ public class LockPatternView extends View {
*
* @param inStealthMode Whether in stealth mode.
*/
+ @UnsupportedAppUsage
public void setInStealthMode(boolean inStealthMode) {
mInStealthMode = inStealthMode;
}
@@ -390,6 +407,7 @@ public class LockPatternView extends View {
*
* @param tactileFeedbackEnabled Whether tactile feedback is enabled
*/
+ @UnsupportedAppUsage
public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) {
mEnableHapticFeedback = tactileFeedbackEnabled;
}
@@ -398,6 +416,7 @@ public class LockPatternView extends View {
* Set the call back for pattern detection.
* @param onPatternListener The call back.
*/
+ @UnsupportedAppUsage
public void setOnPatternListener(
OnPatternListener onPatternListener) {
mOnPatternListener = onPatternListener;
@@ -426,6 +445,7 @@ public class LockPatternView extends View {
* in progress result to correct or wrong.
* @param displayMode The display mode.
*/
+ @UnsupportedAppUsage
public void setDisplayMode(DisplayMode displayMode) {
mPatternDisplayMode = displayMode;
if (displayMode == DisplayMode.Animate) {
@@ -565,6 +585,7 @@ public class LockPatternView extends View {
}
}
+ @UnsupportedAppUsage
private void notifyPatternDetected() {
sendAccessEvent(R.string.lockscreen_access_pattern_detected);
if (mOnPatternListener != null) {
@@ -582,6 +603,7 @@ public class LockPatternView extends View {
/**
* Clear the pattern.
*/
+ @UnsupportedAppUsage
public void clearPattern() {
resetPattern();
}
@@ -622,6 +644,7 @@ public class LockPatternView extends View {
* Disable input (for instance when displaying a message that will
* timeout so user doesn't get view into messy state).
*/
+ @UnsupportedAppUsage
public void disableInput() {
mInputEnabled = false;
}
@@ -629,6 +652,7 @@ public class LockPatternView extends View {
/**
* Enable input.
*/
+ @UnsupportedAppUsage
public void enableInput() {
mInputEnabled = true;
}
@@ -1307,6 +1331,7 @@ public class LockPatternView extends View {
/**
* Constructor called from {@link LockPatternView#onSaveInstanceState()}
*/
+ @UnsupportedAppUsage
private SavedState(Parcelable superState, String serializedPattern, int displayMode,
boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) {
super(superState);
@@ -1320,6 +1345,7 @@ public class LockPatternView extends View {
/**
* Constructor called from {@link #CREATOR}
*/
+ @UnsupportedAppUsage
private SavedState(Parcel in) {
super(in);
mSerializedPattern = in.readString();
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 5847033feb1e..65e10029f37e 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -53,6 +54,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
private int mTraceCount;
// True if the pointer is down.
+ @UnsupportedAppUsage
private boolean mCurDown;
// Most recent coordinates.
@@ -120,10 +122,14 @@ public class PointerLocationView extends View implements InputDeviceListener,
private final Paint mPathPaint;
private final FontMetricsInt mTextMetrics = new FontMetricsInt();
private int mHeaderBottom;
+ @UnsupportedAppUsage
private boolean mCurDown;
+ @UnsupportedAppUsage
private int mCurNumPointers;
+ @UnsupportedAppUsage
private int mMaxNumPointers;
private int mActivePointerId;
+ @UnsupportedAppUsage
private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
private final PointerCoords mTempCoords = new PointerCoords();
@@ -132,6 +138,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
private final FasterStringBuilder mText = new FasterStringBuilder();
+ @UnsupportedAppUsage
private boolean mPrintCoords = true;
public PointerLocationView(Context c) {
diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java
index 8730cdab258b..02a0b8d436b9 100644
--- a/core/java/com/android/internal/widget/PreferenceImageView.java
+++ b/core/java/com/android/internal/widget/PreferenceImageView.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
@@ -29,6 +30,7 @@ public class PreferenceImageView extends ImageView {
this(context, null);
}
+ @UnsupportedAppUsage
public PreferenceImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index 408a4e9b02a4..b66a7b44f05d 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -20,6 +20,7 @@ import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.Observable;
@@ -4953,6 +4954,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch.
*/
static class ScrapData {
+ @UnsupportedAppUsage
ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
int mMaxScrap = DEFAULT_MAX_SCRAP;
long mCreateRunningAverageNs = 0;
diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java
index 0ae9f74167d5..982e3152fc7c 100644
--- a/core/java/com/android/internal/widget/ScrollBarUtils.java
+++ b/core/java/com/android/internal/widget/ScrollBarUtils.java
@@ -16,8 +16,11 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
+
public class ScrollBarUtils {
+ @UnsupportedAppUsage
public static int getThumbLength(int size, int thickness, int extent, int range) {
// Avoid the tiny thumb.
final int minLength = thickness * 2;
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index 79adada9cc98..4b5d62467af0 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -83,7 +84,9 @@ public class SlidingTab extends ViewGroup {
*/
private final int mOrientation;
+ @UnsupportedAppUsage
private final Slider mLeftSlider;
+ @UnsupportedAppUsage
private final Slider mRightSlider;
private Slider mCurrentSlider;
private boolean mTracking;
@@ -95,6 +98,7 @@ public class SlidingTab extends ViewGroup {
/**
* Listener used to reset the view when the current animation completes.
*/
+ @UnsupportedAppUsage
private final AnimationListener mAnimationDoneListener = new AnimationListener() {
public void onAnimationStart(Animation animation) {
@@ -178,7 +182,9 @@ public class SlidingTab extends ViewGroup {
private static final int STATE_PRESSED = 1;
private static final int STATE_ACTIVE = 2;
+ @UnsupportedAppUsage
private final ImageView tab;
+ @UnsupportedAppUsage
private final TextView text;
private final ImageView target;
private int currentState = STATE_NORMAL;
@@ -708,6 +714,7 @@ public class SlidingTab extends ViewGroup {
slider.startAnimation(trans1, trans2);
}
+ @UnsupportedAppUsage
private void onAnimationDone() {
resetView();
mAnimating = false;
@@ -722,6 +729,7 @@ public class SlidingTab extends ViewGroup {
return mOrientation == HORIZONTAL;
}
+ @UnsupportedAppUsage
private void resetView() {
mLeftSlider.reset(false);
mRightSlider.reset(false);
@@ -763,6 +771,7 @@ public class SlidingTab extends ViewGroup {
* @param barId the resource of the bar drawable (stateful)
* @param tabId the resource of the
*/
+ @UnsupportedAppUsage
public void setLeftTabResources(int iconId, int targetId, int barId, int tabId) {
mLeftSlider.setIcon(iconId);
mLeftSlider.setTarget(targetId);
@@ -776,6 +785,7 @@ public class SlidingTab extends ViewGroup {
*
* @param resId
*/
+ @UnsupportedAppUsage
public void setLeftHintText(int resId) {
if (isHorizontal()) {
mLeftSlider.setHintText(resId);
@@ -793,6 +803,7 @@ public class SlidingTab extends ViewGroup {
* @param barId the resource of the bar drawable (stateful)
* @param tabId the resource of the
*/
+ @UnsupportedAppUsage
public void setRightTabResources(int iconId, int targetId, int barId, int tabId) {
mRightSlider.setIcon(iconId);
mRightSlider.setTarget(targetId);
@@ -806,12 +817,14 @@ public class SlidingTab extends ViewGroup {
*
* @param resId
*/
+ @UnsupportedAppUsage
public void setRightHintText(int resId) {
if (isHorizontal()) {
mRightSlider.setHintText(resId);
}
}
+ @UnsupportedAppUsage
public void setHoldAfterTrigger(boolean holdLeft, boolean holdRight) {
mHoldLeftOnTransition = holdLeft;
mHoldRightOnTransition = holdRight;
@@ -838,6 +851,7 @@ public class SlidingTab extends ViewGroup {
*
* @param listener the OnDialTriggerListener to attach to this view
*/
+ @UnsupportedAppUsage
public void setOnTriggerListener(OnTriggerListener listener) {
mOnTriggerListener = listener;
}
diff --git a/core/java/com/android/internal/widget/TextViewInputDisabler.java b/core/java/com/android/internal/widget/TextViewInputDisabler.java
index fb0b3b95b6f2..8d8f0fe52d64 100644
--- a/core/java/com/android/internal/widget/TextViewInputDisabler.java
+++ b/core/java/com/android/internal/widget/TextViewInputDisabler.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.text.InputFilter;
import android.text.Spanned;
import android.widget.TextView;
@@ -38,11 +39,13 @@ public class TextViewInputDisabler {
}
};
+ @UnsupportedAppUsage
public TextViewInputDisabler(TextView textView) {
mTextView = textView;
mDefaultFilters = mTextView.getFilters();
}
+ @UnsupportedAppUsage
public void setInputEnabled(boolean enabled) {
mTextView.setFilters(enabled ? mDefaultFilters : mNoInputFilters);
}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 64bdc6e1eb37..574a09f8d3af 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -18,6 +18,7 @@ package com.android.internal.widget;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -243,6 +244,7 @@ public class ViewPager extends ViewGroup {
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
+ @UnsupportedAppUsage
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
/**
@@ -251,6 +253,7 @@ public class ViewPager extends ViewGroup {
*
* @param position Position index of the new selected page.
*/
+ @UnsupportedAppUsage
public void onPageSelected(int position);
/**
@@ -263,6 +266,7 @@ public class ViewPager extends ViewGroup {
* @see com.android.internal.widget.ViewPager#SCROLL_STATE_DRAGGING
* @see com.android.internal.widget.ViewPager#SCROLL_STATE_SETTLING
*/
+ @UnsupportedAppUsage
public void onPageScrollStateChanged(int state);
}
@@ -483,6 +487,7 @@ public class ViewPager extends ViewGroup {
setCurrentItemInternal(item, smoothScroll, false);
}
+ @UnsupportedAppUsage
public int getCurrentItem() {
return mCurItem;
}
diff --git a/core/java/com/android/server/ResettableTimeout.java b/core/java/com/android/server/ResettableTimeout.java
index ac5b160670b0..64083f72aff5 100644
--- a/core/java/com/android/server/ResettableTimeout.java
+++ b/core/java/com/android/server/ResettableTimeout.java
@@ -18,6 +18,7 @@ package com.android.server;
import android.os.SystemClock;
+import android.annotation.UnsupportedAppUsage;
import android.os.ConditionVariable;
/**
@@ -120,9 +121,11 @@ abstract class ResettableTimeout
}
}
+ @UnsupportedAppUsage
private ConditionVariable mLock = new ConditionVariable();
// turn it off at this time.
+ @UnsupportedAppUsage
private volatile long mOffAt;
private volatile boolean mOffCalled;
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
index 3d9fb5c872f7..a0740eee5df6 100644
--- a/core/java/com/android/server/net/BaseNetworkObserver.java
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -16,6 +16,7 @@
package com.android.server.net;
+import android.annotation.UnsupportedAppUsage;
import android.net.INetworkManagementEventObserver;
import android.net.LinkAddress;
import android.net.RouteInfo;
diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java
index 5b421d988e0a..647fb5b9d079 100644
--- a/core/java/com/android/server/net/NetlinkTracker.java
+++ b/core/java/com/android/server/net/NetlinkTracker.java
@@ -16,6 +16,7 @@
package com.android.server.net;
+import android.annotation.UnsupportedAppUsage;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;
@@ -79,6 +80,7 @@ public class NetlinkTracker extends BaseNetworkObserver {
private static final boolean DBG = false;
+ @UnsupportedAppUsage
public NetlinkTracker(String iface, Callback callback) {
TAG = "NetlinkTracker/" + iface;
mInterfaceName = iface;
@@ -187,10 +189,12 @@ public class NetlinkTracker extends BaseNetworkObserver {
/**
* Returns a copy of this object's LinkProperties.
*/
+ @UnsupportedAppUsage
public synchronized LinkProperties getLinkProperties() {
return new LinkProperties(mLinkProperties);
}
+ @UnsupportedAppUsage
public synchronized void clearLinkProperties() {
// Clear the repository before clearing mLinkProperties. That way, if a clear() happens
// while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java
index 3ea873bbb0f9..8f6594aefb0a 100644
--- a/core/java/com/google/android/collect/Lists.java
+++ b/core/java/com/google/android/collect/Lists.java
@@ -57,6 +57,7 @@ public class Lists {
* @param elements the elements that the list should contain, in order
* @return a newly-created {@code ArrayList} containing those elements
*/
+ @UnsupportedAppUsage
public static <E> ArrayList<E> newArrayList(E... elements) {
int capacity = (elements.length * 110) / 100 + 5;
ArrayList<E> list = new ArrayList<E>(capacity);
diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java
index dd3cab15d0b2..09b5e51ae2c6 100644
--- a/core/java/com/google/android/collect/Sets.java
+++ b/core/java/com/google/android/collect/Sets.java
@@ -16,6 +16,7 @@
package com.google.android.collect;
+import android.annotation.UnsupportedAppUsage;
import android.util.ArraySet;
import java.util.Collections;
@@ -42,6 +43,7 @@ public class Sets {
*
* @return a newly-created, initially-empty {@code HashSet}
*/
+ @UnsupportedAppUsage
public static <K> HashSet<K> newHashSet() {
return new HashSet<K>();
}
@@ -63,6 +65,7 @@ public class Sets {
* @return a newly-created {@code HashSet} containing those elements (minus
* duplicates)
*/
+ @UnsupportedAppUsage
public static <E> HashSet<E> newHashSet(E... elements) {
int capacity = elements.length * 4 / 3 + 1;
HashSet<E> set = new HashSet<E>(capacity);
@@ -75,6 +78,7 @@ public class Sets {
*
* @return a newly-created, initially-empty {@code SortedSet}.
*/
+ @UnsupportedAppUsage
public static <E> SortedSet<E> newSortedSet() {
return new TreeSet<E>();
}
@@ -95,6 +99,7 @@ public class Sets {
/**
* Creates a {@code ArraySet} instance.
*/
+ @UnsupportedAppUsage
public static <E> ArraySet<E> newArraySet() {
return new ArraySet<E>();
}
@@ -102,6 +107,7 @@ public class Sets {
/**
* Creates a {@code ArraySet} instance containing the given elements.
*/
+ @UnsupportedAppUsage
public static <E> ArraySet<E> newArraySet(E... elements) {
int capacity = elements.length * 4 / 3 + 1;
ArraySet<E> set = new ArraySet<E>(capacity);
diff --git a/core/java/com/google/android/util/AbstractMessageParser.java b/core/java/com/google/android/util/AbstractMessageParser.java
index 1871682ee063..9d12f82aeb75 100644
--- a/core/java/com/google/android/util/AbstractMessageParser.java
+++ b/core/java/com/google/android/util/AbstractMessageParser.java
@@ -16,6 +16,7 @@
package com.google.android.util;
+import android.annotation.UnsupportedAppUsage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -654,15 +655,25 @@ public abstract class AbstractMessageParser {
public static abstract class Token {
public enum Type {
+ @UnsupportedAppUsage
HTML ("html"),
+ @UnsupportedAppUsage
FORMAT ("format"), // subtype of HTML
+ @UnsupportedAppUsage
LINK ("l"),
+ @UnsupportedAppUsage
SMILEY ("e"),
+ @UnsupportedAppUsage
ACRONYM ("a"),
+ @UnsupportedAppUsage
MUSIC ("m"),
+ @UnsupportedAppUsage
GOOGLE_VIDEO ("v"),
+ @UnsupportedAppUsage
YOUTUBE_VIDEO ("yt"),
+ @UnsupportedAppUsage
PHOTO ("p"),
+ @UnsupportedAppUsage
FLICKR ("f");
//stringreps for HTML and FORMAT don't really matter
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index d7a981ed3e9d..82acf6fb432b 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -470,6 +470,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz,
std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE);
+ jniSetFileDescriptorOfFD(env, javaFd, -1);
if (res < 0) {
throwErrnoException(env, "resNetworkResult", -res);
return nullptr;
@@ -490,6 +491,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz,
static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
resNetworkCancel(fd);
+ jniSetFileDescriptorOfFD(env, javaFd, -1);
}
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
new file mode 100644
index 000000000000..5aa4ddbdf7f9
--- /dev/null
+++ b/core/proto/android/stats/connectivity/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_library_static {
+ name: "networkstackprotosnano",
+ proto: {
+ type: "nano",
+ },
+ srcs: [
+ "network_stack.proto",
+ ],
+ sdk_version: "system_current",
+ no_framework_libs: true,
+} \ No newline at end of file
diff --git a/services/net/java/android/net/ApfCapabilitiesParcelable.aidl b/core/proto/android/stats/connectivity/network_stack.proto
index f0645d2782d2..7d9aa1c6eb23 100644
--- a/services/net/java/android/net/ApfCapabilitiesParcelable.aidl
+++ b/core/proto/android/stats/connectivity/network_stack.proto
@@ -14,10 +14,13 @@
* limitations under the License.
*/
-package android.net;
+syntax = "proto2";
+
+package android.stats.connectivity;
+option java_multiple_files = true;
+option java_outer_classname = "NetworkStackProto";
+
+message NetworkStackEventData {
+
+}
-parcelable ApfCapabilitiesParcelable {
- int apfVersionSupported;
- int maximumApfProgramSize;
- int apfPacketFormat;
-} \ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e62df2a189a7..9aedb7618142 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -608,6 +608,9 @@
<protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL" />
+ <!-- For tether entitlement recheck-->
+ <protected-broadcast
+ android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
<!-- ====================================================================== -->
@@ -1009,6 +1012,18 @@
android:description="@string/permdesc_manageOwnCalls"
android:protectionLevel="normal" />
+ <!--Allows an app which implements the
+ {@link android.telecom.InCallService} API to be eligible to be enabled as a calling companion app. This
+ means that the Telecom framework will bind to the app's InCallService implementation when
+ there are calls active. The app can use the InCallService API to view information about
+ calls on the system and control these calls.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.CALL_COMPANION_APP"
+ android:label="@string/permlab_callCompanionApp"
+ android:description="@string/permdesc_callCompanionApp"
+ android:protectionLevel="normal" />
+
<!-- Allows a calling app to continue a call which was started in another app. An example is a
video calling app that wants to continue a voice call on the user's mobile network.<p>
When the handover of a call from one app to another takes place, there are two devices
diff --git a/core/res/res/drawable/ic_bluetooth_share_icon.xml b/core/res/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 000000000000..2446402be93f
--- /dev/null
+++ b/core/res/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<!-- This drawable should only be used by the Bluetooth application for its share target icon. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/accent_device_default">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
+</vector> \ No newline at end of file
diff --git a/core/res/res/values-night/colors_device_defaults.xml b/core/res/res/values-night/colors_device_defaults.xml
new file mode 100644
index 000000000000..08ad4926197b
--- /dev/null
+++ b/core/res/res/values-night/colors_device_defaults.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <color name="accent_device_default">@color/accent_device_default_dark</color>
+</resources> \ No newline at end of file
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 256c53133096..212e1cc55137 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -35,6 +35,7 @@
<color name="accent_device_default_light">@color/accent_material_light</color>
<color name="accent_device_default_dark">@color/accent_material_dark</color>
+ <color name="accent_device_default">@color/accent_device_default_light</color>
<color name="background_device_default_dark">@color/background_material_dark</color>
<color name="background_device_default_light">@color/background_material_light</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 97ae8e5215fe..7698d271cfac 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -302,6 +302,15 @@
Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
<integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
+ <!-- The URL returned by ConnectivityManager#getCaptivePortalServerUrl. The actual returned
+ value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL. This is the default value
+ used if that setting is unset.
+ This is *NOT* a URL that will always be used by the system network validation to detect
+ captive portals: NetworkMonitor may use different strategies and will not necessarily use
+ this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays
+ instead. -->
+ <string translatable="false" name="config_networkDefaultCaptivePortalServerUrl">http://connectivitycheck.gstatic.com/generate_204</string>
+
<!-- If the hardware supports specially marking packets that caused a wakeup of the
main CPU, set this value to the mark used. -->
<integer name="config_networkWakeupPacketMark">0</integer>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 75aa60f1242a..4f6775b99e10 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1185,6 +1185,15 @@
<string name="permdesc_manageOwnCalls">Allows the app to route its calls through the system in
order to improve the calling experience.</string>
+ <!-- Title of an application permission. When granted the app is allowed to be enabled as
+ a companion app. [CHAR LIMIT=NONE]-->
+ <string name="permlab_callCompanionApp">see and control calls through the system.</string>
+ <!-- Description of an application permission. When granted the app is allowed to be enabled as
+ a companion app. [CHAR LIMIT=NONE]-->
+ <string name="permdesc_callCompanionApp">Allows the app to see and control ongoing calls on the
+ device. This includes information such as call numbers for calls and the state of the
+ calls.</string>
+
<!-- Title of an application permission. When granted the user is giving access to a third
party app to continue a call which originated in another app. For example, the user
could be in a voice call over their carrier's mobile network, and a third party video
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a95fa540e33a..05303c96ea80 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1945,6 +1945,7 @@
<java-symbol type="integer" name="config_networkNotifySwitchType" />
<java-symbol type="array" name="config_networkNotifySwitches" />
<java-symbol type="integer" name="config_networkAvoidBadWifi" />
+ <java-symbol type="string" name="config_networkDefaultCaptivePortalServerUrl" />
<java-symbol type="integer" name="config_networkWakeupPacketMark" />
<java-symbol type="integer" name="config_networkWakeupPacketMask" />
<java-symbol type="bool" name="config_apfDrop802_3Frames" />
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 1b6560322a13..707d7b30e09b 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -19,13 +19,22 @@ package android.net;
import com.google.caliper.BeforeExperiment;
import com.google.caliper.Param;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
public class NetworkStatsBenchmark {
- private static final String UNDERLYING_IFACE = "wlan0";
+ private static final String[] UNDERLYING_IFACES = {"wlan0", "rmnet0"};
private static final String TUN_IFACE = "tun0";
private static final int TUN_UID = 999999999;
@Param({"100", "1000"})
private int mSize;
+ /**
+ * Should not be more than the length of {@link #UNDERLYING_IFACES}.
+ */
+ @Param({"1", "2"})
+ private int mNumUnderlyingIfaces;
private NetworkStats mNetworkStats;
@BeforeExperiment
@@ -33,8 +42,10 @@ public class NetworkStatsBenchmark {
mNetworkStats = new NetworkStats(0, mSize + 2);
int uid = 0;
NetworkStats.Entry recycle = new NetworkStats.Entry();
+ final List<String> allIfaces = getAllIfacesForBenchmark(); // also contains TUN_IFACE.
+ final int totalIfaces = allIfaces.size();
for (int i = 0; i < mSize; i++) {
- recycle.iface = (i < mSize / 2) ? TUN_IFACE : UNDERLYING_IFACE;
+ recycle.iface = allIfaces.get(i % totalIfaces);
recycle.uid = uid;
recycle.set = i % 2;
recycle.tag = NetworkStats.TAG_NONE;
@@ -48,22 +59,39 @@ public class NetworkStatsBenchmark {
uid++;
}
}
- recycle.iface = UNDERLYING_IFACE;
- recycle.uid = TUN_UID;
- recycle.set = NetworkStats.SET_FOREGROUND;
- recycle.tag = NetworkStats.TAG_NONE;
- recycle.rxBytes = 90000 * mSize;
- recycle.rxPackets = 40 * mSize;
- recycle.txBytes = 180000 * mSize;
- recycle.txPackets = 1200 * mSize;
- recycle.operations = 0;
- mNetworkStats.addValues(recycle);
+
+ for (int i = 0; i < mNumUnderlyingIfaces; i++) {
+ recycle.iface = UNDERLYING_IFACES[i];
+ recycle.uid = TUN_UID;
+ recycle.set = NetworkStats.SET_FOREGROUND;
+ recycle.tag = NetworkStats.TAG_NONE;
+ recycle.rxBytes = 90000 * mSize;
+ recycle.rxPackets = 40 * mSize;
+ recycle.txBytes = 180000 * mSize;
+ recycle.txPackets = 1200 * mSize;
+ recycle.operations = 0;
+ mNetworkStats.addValues(recycle);
+ }
+ }
+
+ private String[] getVpnUnderlyingIfaces() {
+ return Arrays.copyOf(UNDERLYING_IFACES, mNumUnderlyingIfaces);
+ }
+
+ /**
+ * Same as {@link #getVpnUnderlyingIfaces}, but also contains {@link #TUN_IFACE}.
+ */
+ private List<String> getAllIfacesForBenchmark() {
+ List<String> ifaces = new ArrayList<>();
+ ifaces.add(TUN_IFACE);
+ ifaces.addAll(Arrays.asList(getVpnUnderlyingIfaces()));
+ return ifaces;
}
public void timeMigrateTun(int reps) {
for (int i = 0; i < reps; i++) {
NetworkStats stats = mNetworkStats.clone();
- stats.migrateTun(TUN_UID, TUN_IFACE, UNDERLYING_IFACE);
+ stats.migrateTun(TUN_UID, TUN_IFACE, getVpnUnderlyingIfaces());
}
}
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index b1f855246320..c59098795faf 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -29,6 +29,15 @@ import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link ClientTransaction}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksCoreTests:ClientTransactionTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index fb0f5344f643..32e5f008c729 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -41,6 +41,15 @@ import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link ObjectPool}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksCoreTests:ObjectPoolTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index fe58116002f2..6620a2e86272 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -26,9 +26,8 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
-import static junit.framework.Assert.assertEquals;
-
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
@@ -58,7 +57,15 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
-/** Test {@link TransactionExecutor} logic. */
+/**
+ * Test {@link TransactionExecutor} logic.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksCoreTests:TransactionExecutorTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 104208eefef7..d922c16a9297 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -21,8 +21,8 @@ import static android.app.servertransaction.TestUtils.mergedConfig;
import static android.app.servertransaction.TestUtils.referrerIntentList;
import static android.app.servertransaction.TestUtils.resultInfoList;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
@@ -60,7 +60,15 @@ import org.junit.runner.RunWith;
import java.util.List;
import java.util.Map;
-/** Test parcelling and unparcelling of transactions and transaction items. */
+/**
+ * Test parcelling and unparcelling of transactions and transaction items.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksCoreTests:TransactionParcelTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index fe45fe7d3aaf..a3df1a094ec0 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -40,6 +40,15 @@ import org.junit.runner.RunWith;
import java.util.Arrays;
+/**
+ * Tests for {@link DisplayCutout}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksCoreTests:DisplayCutoutTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java b/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java
deleted file mode 100644
index 941cfdb20fed..000000000000
--- a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java
+++ /dev/null
@@ -1,44 +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 com.android.server.wm.test.filters;
-
-import android.os.Bundle;
-
-import com.android.test.filters.SelectTest;
-
-/**
- * JUnit test filter that select Window Manager Service related tests from FrameworksCoreTests.
- *
- * <p>Use this filter when running FrameworksCoreTests as
- * <pre>
- * adb shell am instrument -w \
- * -e filter com.android.server.wm.test.filters.CoreTestsFilter \
- * -e selectTest_verbose true \
- * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
- * </pre>
- */
-public final class CoreTestsFilter extends SelectTest {
-
- private static final String[] SELECTED_CORE_TESTS = {
- "android.app.servertransaction.", // all tests under the package.
- "android.view.DisplayCutoutTest",
- };
-
- public CoreTestsFilter(Bundle testArgs) {
- super(addSelectTest(testArgs, SELECTED_CORE_TESTS));
- }
-}
diff --git a/core/xsd/Android.bp b/core/xsd/Android.bp
index 81669eb290db..738f33076ac9 100644
--- a/core/xsd/Android.bp
+++ b/core/xsd/Android.bp
@@ -2,5 +2,5 @@ xsd_config {
name: "permission",
srcs: ["permission.xsd"],
api_dir: "schema",
- package_name: "com.android.xml.permission",
+ package_name: "com.android.xml.permission.configfile",
}
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index d90863b2c716..2ef2d04d3b34 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -60,8 +60,6 @@
<xs:attribute name="uid" type="xs:int"/>
</xs:complexType>
<xs:complexType name="split-permission">
- <xs:attribute name="name" type="xs:string"/>
- <xs:attribute name="targetSdk" type="xs:int"/>
<xs:sequence>
<xs:element name="library" maxOccurs="unbounded">
<xs:complexType>
@@ -69,6 +67,8 @@
</xs:complexType>
</xs:element>
</xs:sequence>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="targetSdk" type="xs:int"/>
</xs:complexType>
<xs:complexType name="library">
<xs:attribute name="name" type="xs:string"/>
@@ -78,6 +78,7 @@
<xs:complexType name="feature">
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="notLowRam" type="xs:string"/>
+ <xs:attribute name="version" type="xs:int"/>
</xs:complexType>
<xs:complexType name="unavailable-feature">
<xs:attribute name="name" type="xs:string"/>
@@ -124,7 +125,6 @@
<xs:attribute name="package" type="xs:string"/>
</xs:complexType>
<xs:complexType name="privapp-permissions">
- <xs:attribute name="package" type="xs:string"/>
<xs:sequence>
<xs:element name="permission" maxOccurs="unbounded">
<xs:complexType>
@@ -137,9 +137,9 @@
</xs:complexType>
</xs:element>
</xs:sequence>
+ <xs:attribute name="package" type="xs:string"/>
</xs:complexType>
<xs:complexType name="oem-permissions">
- <xs:attribute name="package" type="xs:string"/>
<xs:sequence>
<xs:element name="permission" maxOccurs="unbounded">
<xs:complexType>
@@ -152,6 +152,7 @@
</xs:complexType>
</xs:element>
</xs:sequence>
+ <xs:attribute name="package" type="xs:string"/>
</xs:complexType>
<xs:complexType name="hidden-api-whitelisted-app">
<xs:attribute name="package" type="xs:string"/>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index 82bb0feac089..c25bc146045b 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -1,5 +1,5 @@
// Signature format: 2.0
-package com.android.xml.permission {
+package com.android.xml.permission.configfile {
public class AllowAssociation {
ctor public AllowAssociation();
@@ -97,8 +97,10 @@ package com.android.xml.permission {
ctor public Feature();
method public String getName();
method public String getNotLowRam();
+ method public int getVersion();
method public void setName(String);
method public void setNotLowRam(String);
+ method public void setVersion(int);
}
public class Group {
@@ -125,8 +127,8 @@ package com.android.xml.permission {
public class OemPermissions {
ctor public OemPermissions();
- method public java.util.List<com.android.xml.permission.OemPermissions.DenyPermission> getDenyPermission();
- method public java.util.List<com.android.xml.permission.OemPermissions.Permission> getPermission();
+ method public java.util.List<com.android.xml.permission.configfile.OemPermissions.DenyPermission> getDenyPermission();
+ method public java.util.List<com.android.xml.permission.configfile.OemPermissions.Permission> getPermission();
method public String get_package();
method public void set_package(String);
}
@@ -151,37 +153,37 @@ package com.android.xml.permission {
public class Permissions {
ctor public Permissions();
- method public java.util.List<com.android.xml.permission.AllowAssociation> getAllowAssociation();
- method public java.util.List<com.android.xml.permission.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings();
- method public java.util.List<com.android.xml.permission.AllowImplicitBroadcast> getAllowImplicitBroadcast();
- method public java.util.List<com.android.xml.permission.AllowInDataUsageSave> getAllowInDataUsageSave();
- method public java.util.List<com.android.xml.permission.AllowInPowerSave> getAllowInPowerSave();
- method public java.util.List<com.android.xml.permission.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle();
- method public java.util.List<com.android.xml.permission.AllowUnthrottledLocation> getAllowUnthrottledLocation();
- method public java.util.List<com.android.xml.permission.AppLink> getAppLink();
- method public java.util.List<com.android.xml.permission.AssignPermission> getAssignPermission();
- method public java.util.List<com.android.xml.permission.BackupTransportWhitelistedService> getBackupTransportWhitelistedService();
- method public java.util.List<com.android.xml.permission.BugreportWhitelisted> getBugreportWhitelisted();
- method public java.util.List<com.android.xml.permission.DefaultEnabledVrApp> getDefaultEnabledVrApp();
- method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp();
- method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp();
- method public java.util.List<com.android.xml.permission.Feature> getFeature();
- method public java.util.List<com.android.xml.permission.Group> getGroup();
- method public java.util.List<com.android.xml.permission.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp();
- method public java.util.List<com.android.xml.permission.Library> getLibrary();
- method public java.util.List<com.android.xml.permission.OemPermissions> getOemPermissions();
- method public java.util.List<com.android.xml.permission.Permission> getPermission();
- method public java.util.List<com.android.xml.permission.PrivappPermissions> getPrivappPermissions();
- method public java.util.List<com.android.xml.permission.SplitPermission> getSplitPermission();
- method public java.util.List<com.android.xml.permission.SystemUserBlacklistedApp> getSystemUserBlacklistedApp();
- method public java.util.List<com.android.xml.permission.SystemUserWhitelistedApp> getSystemUserWhitelistedApp();
- method public java.util.List<com.android.xml.permission.UnavailableFeature> getUnavailableFeature();
+ method public java.util.List<com.android.xml.permission.configfile.AllowAssociation> getAllowAssociation();
+ method public java.util.List<com.android.xml.permission.configfile.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings();
+ method public java.util.List<com.android.xml.permission.configfile.AllowImplicitBroadcast> getAllowImplicitBroadcast();
+ method public java.util.List<com.android.xml.permission.configfile.AllowInDataUsageSave> getAllowInDataUsageSave();
+ method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSave> getAllowInPowerSave();
+ method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle();
+ method public java.util.List<com.android.xml.permission.configfile.AllowUnthrottledLocation> getAllowUnthrottledLocation();
+ method public java.util.List<com.android.xml.permission.configfile.AppLink> getAppLink();
+ method public java.util.List<com.android.xml.permission.configfile.AssignPermission> getAssignPermission();
+ method public java.util.List<com.android.xml.permission.configfile.BackupTransportWhitelistedService> getBackupTransportWhitelistedService();
+ method public java.util.List<com.android.xml.permission.configfile.BugreportWhitelisted> getBugreportWhitelisted();
+ method public java.util.List<com.android.xml.permission.configfile.DefaultEnabledVrApp> getDefaultEnabledVrApp();
+ method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp();
+ method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp();
+ method public java.util.List<com.android.xml.permission.configfile.Feature> getFeature();
+ method public java.util.List<com.android.xml.permission.configfile.Group> getGroup();
+ method public java.util.List<com.android.xml.permission.configfile.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp();
+ method public java.util.List<com.android.xml.permission.configfile.Library> getLibrary();
+ method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions();
+ method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission();
+ method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions();
+ method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission();
+ method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp();
+ method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp();
+ method public java.util.List<com.android.xml.permission.configfile.UnavailableFeature> getUnavailableFeature();
}
public class PrivappPermissions {
ctor public PrivappPermissions();
- method public java.util.List<com.android.xml.permission.PrivappPermissions.DenyPermission> getDenyPermission();
- method public java.util.List<com.android.xml.permission.PrivappPermissions.Permission> getPermission();
+ method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.DenyPermission> getDenyPermission();
+ method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.Permission> getPermission();
method public String get_package();
method public void set_package(String);
}
@@ -200,7 +202,7 @@ package com.android.xml.permission {
public class SplitPermission {
ctor public SplitPermission();
- method public java.util.List<com.android.xml.permission.SplitPermission.Library> getLibrary();
+ method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
method public String getName();
method public int getTargetSdk();
method public void setName(String);
@@ -233,7 +235,7 @@ package com.android.xml.permission {
public class XmlParser {
ctor public XmlParser();
- method public static com.android.xml.permission.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static com.android.xml.permission.configfile.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index bb4765835890..3968f84471c5 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -66,6 +66,14 @@ prebuilt_etc {
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.emergency",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.emergency.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.launcher3",
product_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.emergency.xml b/data/etc/com.android.emergency.xml
new file mode 100644
index 000000000000..28f99dd1d018
--- /dev/null
+++ b/data/etc/com.android.emergency.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<permissions>
+ <privapp-permissions package="com.android.emergency">
+ <!-- Required to place emergency calls from emergency info screen. -->
+ <permission name="android.permission.CALL_PRIVILEGED"/>
+ <permission name="android.permission.MANAGE_USERS"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 78bbcf137f2a..d44f5a934280 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -48,12 +48,6 @@ applications that come with the platform
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
</privapp-permissions>
- <privapp-permissions package="com.android.emergency">
- <!-- Required to place emergency calls from emergency info screen. -->
- <permission name="android.permission.CALL_PRIVILEGED"/>
- <permission name="android.permission.MANAGE_USERS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.externalstorage">
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
@@ -268,6 +262,8 @@ applications that come with the platform
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.MOVE_PACKAGE"/>
<permission name="android.permission.PACKAGE_USAGE_STATS" />
+ <!-- Needed for test only -->
+ <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
<permission name="android.permission.READ_FRAME_BUFFER"/>
<permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
<!-- Needed for test only -->
diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS
new file mode 100644
index 000000000000..7e7335d68d3b
--- /dev/null
+++ b/media/java/android/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/packages/ExternalStorageProvider/Android.bp b/packages/ExternalStorageProvider/Android.bp
new file mode 100644
index 000000000000..973fef3e666d
--- /dev/null
+++ b/packages/ExternalStorageProvider/Android.bp
@@ -0,0 +1,19 @@
+android_app {
+ name: "ExternalStorageProvider",
+
+ manifest: "AndroidManifest.xml",
+
+ resource_dirs: [
+ "res",
+ ],
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ platform_apis: true,
+
+ certificate: "platform",
+
+ privileged: true,
+}
diff --git a/packages/ExternalStorageProvider/Android.mk b/packages/ExternalStorageProvider/Android.mk
deleted file mode 100644
index 9e99313cd03a..000000000000
--- a/packages/ExternalStorageProvider/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := ExternalStorageProvider
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-include $(BUILD_PACKAGE)
diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp
new file mode 100644
index 000000000000..83427d4ebf00
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/Android.bp
@@ -0,0 +1,25 @@
+android_test {
+ name: "ExternalStorageProviderTests",
+
+ manifest: "AndroidManifest.xml",
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ libs: [
+ "android.test.base",
+ "android.test.mock",
+ "android.test.runner",
+ ],
+
+ static_libs: [
+ "android-support-test",
+ "mockito-target",
+ "truth-prebuilt",
+ ],
+
+ certificate: "platform",
+
+ instrumentation_for: "ExternalStorageProvider",
+}
diff --git a/packages/ExternalStorageProvider/tests/AndroidManifest.xml b/packages/ExternalStorageProvider/tests/AndroidManifest.xml
new file mode 100644
index 000000000000..58b6e86dfc77
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.externalstorage.tests">
+
+ <application android:label="ExternalStorageProvider Tests">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.externalstorage"
+ android:label="ExternalStorageProvider Tests" />
+</manifest>
+
diff --git a/packages/ExternalStorageProvider/tests/AndroidTest.xml b/packages/ExternalStorageProvider/tests/AndroidTest.xml
new file mode 100644
index 000000000000..e5fa73f59836
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs Tests for ExternalStorageProvider.">
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="ExternalStorageProviderTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="framework-base-presubmit" />
+ <option name="test-tag" value="ExternalStorageProviderTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.externalstorage.tests" />
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
new file mode 100644
index 000000000000..a88b3e146ea1
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package com.android.externalstorage;
+
+import static com.android.externalstorage.ExternalStorageProvider.AUTHORITY;
+
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.pm.ProviderInfo;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class ExternalStorageProviderTest {
+ @Test
+ public void onCreate_shouldUpdateVolumes() throws Exception {
+ ExternalStorageProvider externalStorageProvider = new ExternalStorageProvider();
+ ExternalStorageProvider spyProvider = spy(externalStorageProvider);
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = AUTHORITY;
+ providerInfo.grantUriPermissions = true;
+ providerInfo.exported = true;
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ spyProvider.attachInfoForTesting(
+ InstrumentationRegistry.getTargetContext(), providerInfo);
+ }
+ });
+
+ verify(spyProvider, atLeast(1)).updateVolumes();
+ }
+}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 8872147b65ed..0bd5c5f59133 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -14,11 +14,16 @@
// limitations under the License.
//
+java_defaults {
+ name: "NetworkStackCommon",
+ sdk_version: "system_current",
+ min_sdk_version: "28",
+}
+
// Library including the network stack, used to compile both variants of the network stack
android_library {
name: "NetworkStackBase",
- sdk_version: "system_current",
- min_sdk_version: "28",
+ defaults: ["NetworkStackCommon"],
srcs: [
"src/**/*.java",
":framework-networkstack-shared-srcs",
@@ -29,38 +34,40 @@ android_library {
"netd_aidl_interface-java",
"networkstack-aidl-interfaces-java",
"datastallprotosnano",
+ "networkstackprotosnano",
],
manifest: "AndroidManifestBase.xml",
}
-// Non-updatable in-process network stack for devices not using the module
-android_app {
- name: "InProcessNetworkStack",
- sdk_version: "system_current",
- min_sdk_version: "28",
- certificate: "platform",
+java_defaults {
+ name: "NetworkStackAppCommon",
+ defaults: ["NetworkStackCommon"],
privileged: true,
static_libs: [
"NetworkStackBase",
],
+ // Resources already included in NetworkStackBase
+ resource_dirs: [],
jarjar_rules: "jarjar-rules-shared.txt",
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
// The permission configuration *must* be included to ensure security of the device
required: ["NetworkStackPermissionStub"],
+}
+
+// Non-updatable network stack running in the system server process for devices not using the module
+android_app {
+ name: "InProcessNetworkStack",
+ defaults: ["NetworkStackAppCommon"],
+ certificate: "platform",
manifest: "AndroidManifest_InProcess.xml",
}
// Updatable network stack packaged as an application
android_app {
name: "NetworkStack",
- sdk_version: "system_current",
- min_sdk_version: "28",
+ defaults: ["NetworkStackAppCommon"],
certificate: "networkstack",
- privileged: true,
- static_libs: [
- "NetworkStackBase"
- ],
- jarjar_rules: "jarjar-rules-shared.txt",
- // The permission configuration *must* be included to ensure security of the device
- required: ["NetworkStackPermissionStub"],
manifest: "AndroidManifest.xml",
}
diff --git a/packages/NetworkStack/proguard.flags b/packages/NetworkStack/proguard.flags
new file mode 100644
index 000000000000..c60f6c338d83
--- /dev/null
+++ b/packages/NetworkStack/proguard.flags
@@ -0,0 +1,9 @@
+-keepclassmembers class android.net.ip.IpClient {
+ static final int CMD_*;
+ static final int EVENT_*;
+}
+
+-keepclassmembers class android.net.dhcp.DhcpClient {
+ static final int CMD_*;
+ static final int EVENT_*;
+}
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
new file mode 100644
index 000000000000..52425e57ba3a
--- /dev/null
+++ b/packages/NetworkStack/res/values/config.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Captive portal http url -->
+ <string name="config_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
+</resources> \ No newline at end of file
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 3dd90eeff767..d2f32591cbbe 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -74,6 +74,7 @@ import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
@@ -282,6 +283,7 @@ public class ApfFilter {
private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
// TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
+ private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
// Endianness is not an issue for this constant because the APF interpreter always operates in
// network byte order.
@@ -881,10 +883,23 @@ public class ApfFilter {
protected final TcpKeepaliveAckData mPacket;
protected final byte[] mSrcDstAddr;
+ protected final byte[] mPortSeqAckFingerprint;
TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) {
mPacket = packet;
mSrcDstAddr = srcDstAddr;
+ mPortSeqAckFingerprint = generatePortSeqAckFingerprint(mPacket.srcPort,
+ mPacket.dstPort, mPacket.seq, mPacket.ack);
+ }
+
+ static byte[] generatePortSeqAckFingerprint(int srcPort, int dstPort, int seq, int ack) {
+ final ByteBuffer fp = ByteBuffer.allocate(12);
+ fp.order(ByteOrder.BIG_ENDIAN);
+ fp.putShort((short) srcPort);
+ fp.putShort((short) dstPort);
+ fp.putInt(seq);
+ fp.putInt(ack);
+ return fp.array();
}
static byte[] concatArrays(final byte[]... arr) {
@@ -919,10 +934,6 @@ public class ApfFilter {
private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
private static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
- private static final int IPV4_TCP_SRC_PORT_OFFSET = 0;
- private static final int IPV4_TCP_DST_PORT_OFFSET = 2;
- private static final int IPV4_TCP_SEQ_OFFSET = 4;
- private static final int IPV4_TCP_ACK_OFFSET = 8;
TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
this(new TcpKeepaliveAckData(sentKeepalivePacket));
@@ -934,12 +945,12 @@ public class ApfFilter {
@Override
void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
- gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
- gen.addJumpIfR0NotEquals(IPPROTO_TCP, nextFilterLabel);
+
gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
- // Pass the packet if it's not zero-sized :
+ // Skip to the next filter if it's not zero-sized :
+ // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0
// Load the IP header size into R1
gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
// Load the TCP header size into R0 (it's indexed by R1)
@@ -947,27 +958,18 @@ public class ApfFilter {
// Size offset is in the top nibble, but it must be multiplied by 4, and the two
// top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2.
gen.addRightShift(2);
- // R0 += R1 -> R0 contains TCP + IP headers lenght
- gen.addAddR1();
- // Add the Ethernet header length to R0.
- gen.addLoadImmediate(Register.R1, ETH_HEADER_LEN);
+ // R0 += R1 -> R0 contains TCP + IP headers length
gen.addAddR1();
- // Compare total length of headers to the size of the packet.
- gen.addLoadFromMemory(Register.R1, gen.PACKET_SIZE_MEMORY_SLOT);
+ // Load IPv4 total length
+ gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET);
gen.addNeg(Register.R0);
gen.addAddR1();
gen.addJumpIfR0NotEquals(0, nextFilterLabel);
-
// Add IPv4 header length
gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
- gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SRC_PORT_OFFSET);
- gen.addJumpIfR0NotEquals(mPacket.srcPort, nextFilterLabel);
- gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_DST_PORT_OFFSET);
- gen.addJumpIfR0NotEquals(mPacket.dstPort, nextFilterLabel);
- gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SEQ_OFFSET);
- gen.addJumpIfR0NotEquals(mPacket.seq, nextFilterLabel);
- gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_ACK_OFFSET);
- gen.addJumpIfR0NotEquals(mPacket.ack, nextFilterLabel);
+ gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
+ gen.addAddR1();
+ gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel);
maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
gen.addJump(mCountAndDropLabel);
@@ -1169,9 +1171,10 @@ public class ApfFilter {
gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
}
- // If any keepalive filters,
- generateKeepaliveFilter(gen);
+ // If any keepalive filter matches, drop
+ generateV4KeepaliveFilters(gen);
+ // Otherwise, this is an IPv4 unicast, pass
// If L2 broadcast packet, drop.
// TODO: can we invert this condition to fall through to the common pass case below?
maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
@@ -1180,7 +1183,7 @@ public class ApfFilter {
maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
gen.addJump(mCountAndDropLabel);
} else {
- generateKeepaliveFilter(gen);
+ generateV4KeepaliveFilters(gen);
}
// Otherwise, pass
@@ -1188,12 +1191,25 @@ public class ApfFilter {
gen.addJump(mCountAndPassLabel);
}
- private void generateKeepaliveFilter(ApfGenerator gen) throws IllegalInstructionException {
+ private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
+ final String skipV4KeepaliveFilter = "skip_v4_keepalive_filter";
+ final boolean haveV4KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks,
+ ack -> ack instanceof TcpKeepaliveAckV4);
+
+ // If no keepalive acks
+ if (!haveV4KeepaliveAcks) return;
+
+ // If not tcp, skip keepalive filters
+ gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
+ gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV4KeepaliveFilter);
+
// Drop IPv4 Keepalive acks
for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
if (ack instanceof TcpKeepaliveAckV4) ack.generateFilterLocked(gen);
}
+
+ gen.defineLabel(skipV4KeepaliveFilter);
}
/**
@@ -1244,11 +1260,14 @@ public class ApfFilter {
maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
+ // If any keepalive filter matches, drop
+ generateV6KeepaliveFilters(gen);
// Not multicast. Pass.
maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
gen.addJump(mCountAndPassLabel);
gen.defineLabel(skipIPv6MulticastFilterLabel);
} else {
+ generateV6KeepaliveFilters(gen);
// If not ICMPv6, pass.
maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
@@ -1272,12 +1291,27 @@ public class ApfFilter {
maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(skipUnsolicitedMulticastNALabel);
+ }
+
+ private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
+ final String skipV6KeepaliveFilter = "skip_v6_keepalive_filter";
+ final boolean haveV6KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks,
+ ack -> ack instanceof TcpKeepaliveAckV6);
+
+ // If no keepalive acks
+ if (!haveV6KeepaliveAcks) return;
+
+ // If not tcp, skip keepalive filters
+ gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
+ gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV6KeepaliveFilter);
// Drop IPv6 Keepalive acks
for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
if (ack instanceof TcpKeepaliveAckV6) ack.generateFilterLocked(gen);
}
+
+ gen.defineLabel(skipV6KeepaliveFilter);
}
/**
@@ -1294,6 +1328,8 @@ public class ApfFilter {
* <li>Pass all non-IPv4 and non-IPv6 packets,
* <li>Drop IPv6 ICMPv6 NAs to ff02::1.
* <li>Drop IPv6 ICMPv6 RSs.
+ * <li>Filter IPv4 packets (see generateIPv4FilterLocked())
+ * <li>Filter IPv6 packets (see generateIPv6FilterLocked())
* <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
* insertion of RA filters here, or if there aren't any, just passes the packets.
* </ul>
@@ -1737,7 +1773,7 @@ public class ApfFilter {
}
pw.decreaseIndent();
- pw.println("Keepalive filter:");
+ pw.println("Keepalive filters:");
pw.increaseIndent();
for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
final TcpKeepaliveAck keepaliveAck = mKeepaliveAcks.valueAt(i);
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
index 809327a0b79d..44ce2db8547c 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
@@ -108,7 +108,7 @@ public class ApfGenerator {
private String mLabel;
// When mOpcode == Opcodes.JNEBS:
private byte[] mCompareBytes;
- // Offset in bytes from the begining of this program. Set by {@link ApfGenerator#generate}.
+ // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}.
int offset;
Instruction(Opcodes opcode, Register register) {
@@ -431,7 +431,7 @@ public class ApfGenerator {
/**
* Add an instruction to the end of the program to load the byte at offset {@code offset}
- * bytes from the begining of the packet into {@code register}.
+ * bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad8(Register register, int offset) {
Instruction instruction = new Instruction(Opcodes.LDB, register);
@@ -442,7 +442,7 @@ public class ApfGenerator {
/**
* Add an instruction to the end of the program to load 16-bits at offset {@code offset}
- * bytes from the begining of the packet into {@code register}.
+ * bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad16(Register register, int offset) {
Instruction instruction = new Instruction(Opcodes.LDH, register);
@@ -453,7 +453,7 @@ public class ApfGenerator {
/**
* Add an instruction to the end of the program to load 32-bits at offset {@code offset}
- * bytes from the begining of the packet into {@code register}.
+ * bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad32(Register register, int offset) {
Instruction instruction = new Instruction(Opcodes.LDW, register);
@@ -464,7 +464,7 @@ public class ApfGenerator {
/**
* Add an instruction to the end of the program to load a byte from the packet into
- * {@code register}. The offset of the loaded byte from the begining of the packet is
+ * {@code register}. The offset of the loaded byte from the beginning of the packet is
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad8Indexed(Register register, int offset) {
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
index 0b7809e9f614..79d6a554e251 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
@@ -102,9 +102,9 @@ public class DhcpClient extends StateMachine {
private static final String TAG = "DhcpClient";
private static final boolean DBG = true;
- private static final boolean STATE_DBG = false;
- private static final boolean MSG_DBG = false;
- private static final boolean PACKET_DBG = false;
+ private static final boolean STATE_DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean MSG_DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean PACKET_DBG = Log.isLoggable(TAG, Log.DEBUG);
// Metrics events: must be kept in sync with server-side aggregation code.
/** Represents transitions from DhcpInitState to DhcpBoundState */
@@ -126,6 +126,7 @@ public class DhcpClient extends StateMachine {
// DhcpClient uses IpClient's handler.
private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE;
+ // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
/* Commands from controller to start/stop DHCP */
public static final int CMD_START_DHCP = PUBLIC_BASE + 1;
public static final int CMD_STOP_DHCP = PUBLIC_BASE + 2;
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 61dc966076a8..7a06af41f951 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -282,6 +282,7 @@ public class IpClient extends StateMachine {
public static final String DUMP_ARG_CONFIRM = "confirm";
+ // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
private static final int CMD_TERMINATE_AFTER_STOP = 1;
private static final int CMD_STOP = 2;
private static final int CMD_START = 3;
@@ -897,7 +898,7 @@ public class IpClient extends StateMachine {
// accompanying code in IpReachabilityMonitor) is unreachable.
final boolean ignoreIPv6ProvisioningLoss =
mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
- && mCm.getAvoidBadWifi();
+ && mCm.shouldAvoidBadWifi();
// Additionally:
//
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
index e73cba626f15..c19a24eb7fb6 100644
--- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
+++ b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
@@ -129,8 +129,8 @@ import java.util.Map;
*/
public class IpReachabilityMonitor {
private static final String TAG = "IpReachabilityMonitor";
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
public interface Callback {
// This callback function must execute as quickly as possible as it is
@@ -332,7 +332,7 @@ public class IpReachabilityMonitor {
}
private boolean avoidingBadLinks() {
- return !mUsingMultinetworkPolicyTracker || mCm.getAvoidBadWifi();
+ return !mUsingMultinetworkPolicyTracker || mCm.shouldAvoidBadWifi();
}
public void probeAll() {
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
index 481dbdadbac0..fedb8d110197 100644
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
@@ -17,10 +17,13 @@
package android.net.util;
import android.annotation.NonNull;
+import android.util.SparseArray;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.List;
+import java.util.function.Predicate;
+
/**
* Collection of utilities for the network stack.
@@ -65,4 +68,17 @@ public class NetworkStackUtils {
}
return array;
}
+
+ /**
+ * @return True if there exists at least one element in the sparse array for which
+ * condition {@code predicate}
+ */
+ public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) {
+ for (int i = 0; i < array.size(); ++i) {
+ if (predicate.test(array.valueAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 73b203c3df49..f3476ed1566f 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -83,6 +83,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.RingBufferIndices;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.networkstack.R;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -1710,9 +1711,15 @@ public class NetworkMonitor extends StateMachine {
/**
* Get the captive portal server HTTP URL that is configured on the device.
+ *
+ * NetworkMonitor does not use {@link ConnectivityManager#getCaptivePortalServerUrl()} as
+ * it has its own updatable strategies to detect captive portals. The framework only advises
+ * on one URL that can be used, while NetworkMonitor may implement more complex logic.
*/
public String getCaptivePortalServerHttpUrl(Context context) {
- return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(context);
+ final String defaultUrl =
+ context.getResources().getString(R.string.config_captive_portal_http_url);
+ return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(context, defaultUrl);
}
/**
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
index 88a05d506aa4..a0e508f130a5 100644
--- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
+++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
@@ -1006,7 +1006,7 @@ public class ApfTest {
private static final int IPV4_HEADER_LEN = 20;
private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0;
- private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
+ private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
private static final int IPV4_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 12;
private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 2687c682b28a..8778e30e0498 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -161,6 +161,8 @@
<!-- Permission needed to run network tests in CTS -->
<uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" />
+ <!-- Permission needed to test tcp keepalive offload. -->
+ <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index a9ff21fef99c..1060c7b7ce79 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1095,6 +1095,7 @@ public class BugreportProgressService extends Service {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
+ Looper.prepare();
zipBugreport(info);
sendBugreportNotification(info, takingScreenshot);
return null;
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index b93ddde16e4a..44ff3383d566 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -9,7 +9,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
mockito-target-minus-junit4 \
ub-uiautomator \
junit \
diff --git a/packages/Shell/tests/AndroidManifest.xml b/packages/Shell/tests/AndroidManifest.xml
index 6d564c640fcd..e845ef95b28e 100644
--- a/packages/Shell/tests/AndroidManifest.xml
+++ b/packages/Shell/tests/AndroidManifest.xml
@@ -36,7 +36,7 @@
</activity>
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml
index e592d82bfaf7..e03b68a03d0e 100644
--- a/packages/Shell/tests/AndroidTest.xml
+++ b/packages/Shell/tests/AndroidTest.xml
@@ -22,7 +22,7 @@
<option name="test-tag" value="ShellTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.shell.tests" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
index cef74ae39c60..433eca23080e 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
@@ -20,7 +20,6 @@ import static com.android.shell.BugreportProgressService.findSendToAccount;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
-import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
@@ -29,12 +28,12 @@ import android.accounts.AccountManager;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
import android.test.mock.MockContext;
import android.util.Pair;
-import org.junit.Before;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index e69b0a81b97e..3a71632cf1ca 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -42,34 +42,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.io.BufferedOutputStream;
-import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import libcore.io.Streams;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Instrumentation;
@@ -82,9 +54,6 @@ import android.os.Bundle;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.service.notification.StatusBarNotification;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
@@ -92,8 +61,39 @@ import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
+import libcore.io.Streams;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
/**
* Integration tests for {@link BugreportReceiver}.
* <p>
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 3f6ebf0fe09d..99c48cb0eaec 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -20,6 +20,7 @@ juliacr@google.com
juliatuttle@google.com
kozynski@google.com
kprevas@google.com
+lynhan@google.com
madym@google.com
mankoff@google.com
nbenbernou@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/media/OWNERS b/packages/SystemUI/src/com/android/systemui/media/OWNERS
new file mode 100644
index 000000000000..69ea57bfd397
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/OWNERS
@@ -0,0 +1 @@
+per-file MediaProjectionPermissionActivity.java = michaelwr@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index b83fa6252a27..b4f0fec90fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -17,6 +17,9 @@
package com.android.systemui.statusbar.policy;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
+
+import static com.android.internal.telephony.PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -35,6 +38,7 @@ import android.os.Looper;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
@@ -96,6 +100,16 @@ public class NetworkControllerImpl extends BroadcastReceiver
private final CurrentUserTracker mUserTracker;
private Config mConfig;
+ private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onActiveDataSubscriptionIdChanged(int subId) {
+ mActiveMobileDataSubscription = subId;
+ doUpdateMobileControllers();
+ }
+ };
+
+ private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
// Subcontrollers.
@VisibleForTesting
final WifiSignalController mWifiSignalController;
@@ -269,6 +283,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mSubscriptionListener = new SubListener();
}
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
+ mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
// broadcasts
IntentFilter filter = new IntentFilter();
@@ -513,6 +528,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
@VisibleForTesting
void handleConfigurationChanged() {
+ updateMobileControllers();
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
MobileSignalController controller = mMobileSignalControllers.valueAt(i);
controller.setConfiguration(mConfig);
@@ -527,13 +543,39 @@ public class NetworkControllerImpl extends BroadcastReceiver
doUpdateMobileControllers();
}
+ private void filterMobileSubscriptionInSameGroup(List<SubscriptionInfo> subscriptions) {
+ if (subscriptions.size() == MAX_PHONE_COUNT_DUAL_SIM) {
+ SubscriptionInfo info1 = subscriptions.get(0);
+ SubscriptionInfo info2 = subscriptions.get(1);
+ if (info1.getGroupUuid() != null && info1.getGroupUuid().equals(info2.getGroupUuid())) {
+ // If both subscriptions are primary, show both.
+ if (!info1.isOpportunistic() && !info2.isOpportunistic()) return;
+
+ // If carrier required, always show signal bar of primary subscription.
+ // Otherwise, show whichever subscription is currently active for Internet.
+ boolean alwaysShowPrimary = CarrierConfigManager.getDefaultConfig()
+ .getBoolean(CarrierConfigManager
+ .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN);
+ if (alwaysShowPrimary) {
+ subscriptions.remove(info1.isOpportunistic() ? info1 : info2);
+ } else {
+ subscriptions.remove(info1.getSubscriptionId() == mActiveMobileDataSubscription
+ ? info2 : info1);
+ }
+ }
+ }
+ }
+
@VisibleForTesting
void doUpdateMobileControllers() {
List<SubscriptionInfo> subscriptions = mSubscriptionManager
- .getActiveSubscriptionInfoList(true);
+ .getActiveSubscriptionInfoList(false);
if (subscriptions == null) {
subscriptions = Collections.emptyList();
}
+
+ filterMobileSubscriptionInSameGroup(subscriptions);
+
// If there have been no relevant changes to any of the subscriptions, we can leave as is.
if (hasCorrectMobileControllers(subscriptions)) {
// Even if the controllers are correct, make sure we have the right no sims state.
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 48b69b029643..75c6849208f7 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -20,6 +20,7 @@ java_library_static {
":mediaupdateservice_aidl",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
+ "java/com/android/server/policy/EventLogTags.logtags",
],
libs: [
@@ -48,6 +49,7 @@ java_library_static {
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
+ "dnsresolver_aidl_interface-java",
"netd_aidl_interface-java",
"netd_event_listener_interface-java",
],
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 50f15ca0739f..3b78fdafbd94 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -356,10 +356,27 @@ public final class BatteryService extends SystemService {
&& (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
}
+ private boolean shouldShutdownLocked() {
+ if (mHealthInfo.batteryLevel > 0) {
+ return false;
+ }
+
+ // Battery-less devices should not shutdown.
+ if (!mHealthInfo.batteryPresent) {
+ return false;
+ }
+
+ // If battery state is not CHARGING, shutdown.
+ // - If battery present and state == unknown, this is an unexpected error state.
+ // - If level <= 0 and state == full, this is also an unexpected state
+ // - All other states (NOT_CHARGING, DISCHARGING) means it is not charging.
+ return mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_CHARGING;
+ }
+
private void shutdownIfNoPowerLocked() {
// shut down gracefully if our battery is critically low and we are not powered.
// wait until the system has booted before attempting to display the shutdown dialog.
- if (mHealthInfo.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
+ if (shouldShutdownLocked()) {
mHandler.post(new Runnable() {
@Override
public void run() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2d70f3555ac7..699cf605bcec 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -63,6 +63,7 @@ import android.net.ConnectionInfo;
import android.net.ConnectivityManager;
import android.net.ICaptivePortal;
import android.net.IConnectivityManager;
+import android.net.IDnsResolver;
import android.net.IIpConnectivityMetrics;
import android.net.INetd;
import android.net.INetdEventCallback;
@@ -294,6 +295,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
private INetworkManagementService mNMS;
@VisibleForTesting
+ protected IDnsResolver mDnsResolver;
+ @VisibleForTesting
protected INetd mNetd;
private INetworkStatsService mStatsService;
private INetworkPolicyManager mPolicyManager;
@@ -525,6 +528,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
return sMagicDecoderRing.get(what, Integer.toString(what));
}
+ private static IDnsResolver getDnsResolver() {
+ return IDnsResolver.Stub
+ .asInterface(ServiceManager.getService("dnsresolver"));
+ }
+
/** Handler thread used for both of the handlers below. */
@VisibleForTesting
protected final HandlerThread mHandlerThread;
@@ -810,13 +818,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
- this(context, netManager, statsService, policyManager, new IpConnectivityLog());
+ this(context, netManager, statsService, policyManager,
+ getDnsResolver(), new IpConnectivityLog());
}
@VisibleForTesting
protected ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
- IpConnectivityLog logger) {
+ IDnsResolver dnsresolver, IpConnectivityLog logger) {
if (DBG) log("ConnectivityService starting up");
mSystemProperties = getSystemProperties();
@@ -853,6 +862,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mPolicyManagerInternal = checkNotNull(
LocalServices.getService(NetworkPolicyManagerInternal.class),
"missing NetworkPolicyManagerInternal");
+ mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
mProxyTracker = makeProxyTracker();
mNetd = NetdService.getInstance();
@@ -988,7 +998,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mKeepaliveTracker = new KeepaliveTracker(mHandler);
+ mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
mContext.getSystemService(NotificationManager.class));
@@ -1006,7 +1016,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
- mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties);
+ mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
registerPrivateDnsSettingsCallbacks();
}
@@ -3021,9 +3031,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
// NetworkFactories, so network traffic isn't interrupted for an unnecessarily
// long time.
try {
- mNMS.removeNetwork(nai.network.netId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
+ mNetd.networkDestroy(nai.network.netId);
+ } catch (RemoteException | ServiceSpecificException e) {
+ loge("Exception destroying network: " + e);
}
mDnsManager.removeNetwork(nai.network);
}
@@ -3475,8 +3485,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mMultinetworkPolicyTracker.getAvoidBadWifi();
}
- @Override
- public boolean getAvoidBadWifi() {
+ /**
+ * Return whether the device should maintain continuous, working connectivity by switching away
+ * from WiFi networks having no connectivity.
+ * @see MultinetworkPolicyTracker#getAvoidBadWifi()
+ */
+ public boolean shouldAvoidBadWifi() {
if (!checkNetworkStackPermission()) {
throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
}
@@ -4295,7 +4309,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* @return VPN information for accounting, or null if we can't retrieve all required
- * information, e.g primary underlying iface.
+ * information, e.g underlying ifaces.
*/
@Nullable
private VpnInfo createVpnInfo(Vpn vpn) {
@@ -4307,17 +4321,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
// see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
// the underlyingNetworks list.
if (underlyingNetworks == null) {
- NetworkAgentInfo defaultNetwork = getDefaultNetwork();
- if (defaultNetwork != null && defaultNetwork.linkProperties != null) {
- info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName();
+ NetworkAgentInfo defaultNai = getDefaultNetwork();
+ if (defaultNai != null && defaultNai.linkProperties != null) {
+ underlyingNetworks = new Network[] { defaultNai.network };
}
- } else if (underlyingNetworks.length > 0) {
- LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
- if (linkProperties != null) {
- info.primaryUnderlyingIface = linkProperties.getInterfaceName();
+ }
+ if (underlyingNetworks != null && underlyingNetworks.length > 0) {
+ List<String> interfaces = new ArrayList<>();
+ for (Network network : underlyingNetworks) {
+ LinkProperties lp = getLinkProperties(network);
+ if (lp != null) {
+ interfaces.add(lp.getInterfaceName());
+ }
+ }
+ if (!interfaces.isEmpty()) {
+ info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
}
}
- return info.primaryUnderlyingIface == null ? null : info;
+ return info.underlyingIfaces == null ? null : info;
}
/**
@@ -5368,8 +5389,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
- mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS,
- factorySerialNumber);
+ mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver,
+ mNMS, factorySerialNumber);
// Make sure the network capabilities reflect what the agent info says.
nai.networkCapabilities = mixInCapabilities(nai, nc);
final String extraInfo = networkInfo.getExtraInfo();
@@ -6688,7 +6709,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public String getCaptivePortalServerUrl() {
enforceConnectivityInternalPermission();
- return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(mContext);
+ final String defaultUrl = mContext.getResources().getString(
+ R.string.config_networkDefaultCaptivePortalServerUrl);
+ return NetworkMonitorUtils.getCaptivePortalServerHttpUrl(mContext, defaultUrl);
}
@Override
@@ -6696,7 +6719,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
enforceKeepalivePermission();
mKeepaliveTracker.startNattKeepalive(
- getNetworkAgentInfoForNetwork(network),
+ getNetworkAgentInfoForNetwork(network), null /* fd */,
intervalSeconds, cb,
srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
}
@@ -6705,7 +6728,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId,
int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
String dstAddr) {
- enforceKeepalivePermission();
mKeepaliveTracker.startNattKeepalive(
getNetworkAgentInfoForNetwork(network), fd, resourceId,
intervalSeconds, cb,
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 06b85daf2023..0a91721f31d6 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1605,20 +1605,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void setDnsConfigurationForNetwork(int netId, String[] servers, String[] domains,
- int[] params, String tlsHostname, String[] tlsServers) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- final String[] tlsFingerprints = new String[0];
- try {
- mNetdService.setResolverConfiguration(
- netId, servers, domains, params, tlsHostname, tlsServers, tlsFingerprints);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
public void addVpnUidRanges(int netId, UidRange[] ranges) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -2076,21 +2062,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void removeNetwork(int netId) {
- mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
-
- try {
- mNetdService.networkDestroy(netId);
- } catch (ServiceSpecificException e) {
- Log.w(TAG, "removeNetwork(" + netId + "): ", e);
- throw e;
- } catch (RemoteException e) {
- Log.w(TAG, "removeNetwork(" + netId + "): ", e);
- throw e.rethrowAsRuntimeException();
- }
- }
-
- @Override
public void addInterfaceToNetwork(String iface, int netId) {
modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index fdd698f19991..9c5c152726dd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -627,11 +627,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
r.callingPackage = callingPackage;
r.callerUid = Binder.getCallingUid();
r.callerPid = Binder.getCallingPid();
- if (r.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && r.subId != subId) {
- throw new IllegalArgumentException(
- "PhoneStateListener cannot concurrently listen on multiple " +
- "subscriptions. Previously registered on subId: " + r.subId);
- }
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -1888,7 +1883,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
pw.println("mDataConnectionState=" + mDataConnectionState[i]);
pw.println("mCellLocation=" + mCellLocation[i]);
pw.println("mCellInfo=" + mCellInfo.get(i));
- pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i).toString());
+ pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
pw.decreaseIndent();
}
pw.println("mCallNetworkType=" + mCallNetworkType);
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index d8bb635f2ce8..1913635f80e2 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -30,13 +30,15 @@ import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.net.IDnsResolver;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkUtils;
import android.net.Uri;
import android.net.shared.PrivateDnsConfig;
import android.os.Binder;
-import android.os.INetworkManagementService;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -229,7 +231,7 @@ public class DnsManager {
private final Context mContext;
private final ContentResolver mContentResolver;
- private final INetworkManagementService mNMS;
+ private final IDnsResolver mDnsResolver;
private final MockableSystemProperties mSystemProperties;
// TODO: Replace these Maps with SparseArrays.
private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap;
@@ -243,10 +245,10 @@ public class DnsManager {
private String mPrivateDnsMode;
private String mPrivateDnsSpecifier;
- public DnsManager(Context ctx, INetworkManagementService nms, MockableSystemProperties sp) {
+ public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) {
mContext = ctx;
mContentResolver = mContext.getContentResolver();
- mNMS = nms;
+ mDnsResolver = dnsResolver;
mSystemProperties = sp;
mPrivateDnsMap = new HashMap<>();
mPrivateDnsValidationMap = new HashMap<>();
@@ -260,6 +262,12 @@ public class DnsManager {
}
public void removeNetwork(Network network) {
+ try {
+ mDnsResolver.clearResolverConfiguration(network.netId);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Slog.e(TAG, "Error clearing DNS configuration: " + e);
+ return;
+ }
mPrivateDnsMap.remove(network.netId);
mPrivateDnsValidationMap.remove(network.netId);
}
@@ -344,10 +352,12 @@ public class DnsManager {
Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)",
netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs),
Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers)));
+ final String[] tlsFingerprints = new String[0];
try {
- mNMS.setDnsConfigurationForNetwork(
- netId, assignedServers, domainStrs, params, tlsHostname, tlsServers);
- } catch (Exception e) {
+ mDnsResolver.setResolverConfiguration(
+ netId, assignedServers, domainStrs, params,
+ tlsHostname, tlsServers, tlsFingerprints);
+ } catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error setting DNS configuration: " + e);
return;
}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 0e3d82c0a660..d7a57b992eef 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NattSocketKeepalive.NATT_PORT;
import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER;
@@ -23,6 +24,7 @@ import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
import static android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE;
import static android.net.SocketKeepalive.BINDER_DIED;
import static android.net.SocketKeepalive.DATA_RECEIVED;
+import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
import static android.net.SocketKeepalive.ERROR_INVALID_INTERVAL;
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
import static android.net.SocketKeepalive.ERROR_INVALID_NETWORK;
@@ -34,6 +36,7 @@ import static android.net.SocketKeepalive.SUCCESS;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.Context;
import android.net.ISocketKeepaliveCallback;
import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
@@ -84,10 +87,13 @@ public class KeepaliveTracker {
private final Handler mConnectivityServiceHandler;
@NonNull
private final TcpKeepaliveController mTcpController;
+ @NonNull
+ private final Context mContext;
- public KeepaliveTracker(Handler handler) {
+ public KeepaliveTracker(Context context, Handler handler) {
mConnectivityServiceHandler = handler;
mTcpController = new TcpKeepaliveController(handler);
+ mContext = context;
}
/**
@@ -101,6 +107,7 @@ public class KeepaliveTracker {
private final ISocketKeepaliveCallback mCallback;
private final int mUid;
private final int mPid;
+ private final boolean mPrivileged;
private final NetworkAgentInfo mNai;
private final int mType;
private final FileDescriptor mFd;
@@ -108,6 +115,11 @@ public class KeepaliveTracker {
public static final int TYPE_NATT = 1;
public static final int TYPE_TCP = 2;
+ // Max allowed unprivileged keepalive slots per network. Caller's permission will be
+ // enforced if number of existing keepalives reach this limit.
+ // TODO: consider making this limit configurable via resources.
+ private static final int MAX_UNPRIVILEGED_SLOTS = 3;
+
// Keepalive slot. A small integer that identifies this keepalive among the ones handled
// by this network.
private int mSlot = NO_KEEPALIVE;
@@ -127,16 +139,40 @@ public class KeepaliveTracker {
@NonNull KeepalivePacketData packet,
int interval,
int type,
- @NonNull FileDescriptor fd) {
+ @Nullable FileDescriptor fd) throws InvalidSocketException {
mCallback = callback;
mPid = Binder.getCallingPid();
mUid = Binder.getCallingUid();
+ mPrivileged = (PERMISSION_GRANTED == mContext.checkPermission(PERMISSION, mPid, mUid));
mNai = nai;
mPacket = packet;
mInterval = interval;
mType = type;
- mFd = fd;
+
+ // For SocketKeepalive, a dup of fd is kept in mFd so the source port from which the
+ // keepalives are sent cannot be reused by another app even if the fd gets closed by
+ // the user. A null is acceptable here for backward compatibility of PacketKeepalive
+ // API.
+ try {
+ if (fd != null) {
+ mFd = Os.dup(fd);
+ } else {
+ Log.d(TAG, toString() + " calls with null fd");
+ if (!mPrivileged) {
+ throw new SecurityException(
+ "null fd is not allowed for unprivileged access.");
+ }
+ if (mType == TYPE_TCP) {
+ throw new IllegalArgumentException(
+ "null fd is not allowed for tcp socket keepalives.");
+ }
+ mFd = null;
+ }
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Cannot dup fd: ", e);
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
+ }
try {
mCallback.asBinder().linkToDeath(this, 0);
@@ -167,7 +203,7 @@ public class KeepaliveTracker {
+ "->"
+ IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+ " interval=" + mInterval
- + " uid=" + mUid + " pid=" + mPid
+ + " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
+ " packetData=" + HexDump.toHexString(mPacket.getPacket())
+ " ]";
}
@@ -207,9 +243,27 @@ public class KeepaliveTracker {
return SUCCESS;
}
+ private int checkPermission() {
+ final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai);
+ int unprivilegedCount = 0;
+ if (networkKeepalives == null) {
+ return ERROR_INVALID_NETWORK;
+ }
+ for (KeepaliveInfo ki : networkKeepalives.values()) {
+ if (!ki.mPrivileged) {
+ unprivilegedCount++;
+ }
+ if (unprivilegedCount >= MAX_UNPRIVILEGED_SLOTS) {
+ return mPrivileged ? SUCCESS : ERROR_INSUFFICIENT_RESOURCES;
+ }
+ }
+ return SUCCESS;
+ }
+
private int isValid() {
synchronized (mNai) {
int error = checkInterval();
+ if (error == SUCCESS) error = checkPermission();
if (error == SUCCESS) error = checkNetworkConnected();
if (error == SUCCESS) error = checkSourceAddress();
return error;
@@ -272,6 +326,18 @@ public class KeepaliveTracker {
}
}
+ // Close the duplicated fd that maintains the lifecycle of socket whenever
+ // keepalive is running.
+ if (mFd != null) {
+ try {
+ Os.close(mFd);
+ } catch (ErrnoException e) {
+ // This should not happen since system server controls the lifecycle of fd when
+ // keepalive offload is running.
+ Log.wtf(TAG, "Error closing fd for keepalive " + mSlot + ": " + e);
+ }
+ }
+
if (reason == SUCCESS) {
try {
mCallback.onStopped();
@@ -355,8 +421,9 @@ public class KeepaliveTracker {
return;
}
ki.stop(reason);
- Log.d(TAG, "Stopped keepalive " + slot + " on " + networkName);
networkKeepalives.remove(slot);
+ Log.d(TAG, "Stopped keepalive " + slot + " on " + networkName + ", "
+ + networkKeepalives.size() + " remains.");
if (networkKeepalives.isEmpty()) {
mKeepalives.remove(nai);
}
@@ -389,7 +456,8 @@ public class KeepaliveTracker {
ki = mKeepalives.get(nai).get(slot);
} catch(NullPointerException e) {}
if (ki == null) {
- Log.e(TAG, "Event for unknown keepalive " + slot + " on " + nai.name());
+ Log.e(TAG, "Event " + message.what + " for unknown keepalive " + slot + " on "
+ + nai.name());
return;
}
@@ -419,7 +487,6 @@ public class KeepaliveTracker {
}
} else {
// Keepalive successfully stopped, or error.
- ki.mStartedState = KeepaliveInfo.NOT_STARTED;
if (reason == SUCCESS) {
// The message indicated success stopping : don't call handleStopKeepalive.
if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name());
@@ -429,6 +496,7 @@ public class KeepaliveTracker {
handleStopKeepalive(nai, slot, reason);
if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason);
}
+ ki.mStartedState = KeepaliveInfo.NOT_STARTED;
}
}
@@ -437,6 +505,7 @@ public class KeepaliveTracker {
* {@link android.net.SocketKeepalive}.
**/
public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
+ @Nullable FileDescriptor fd,
int intervalSeconds,
@NonNull ISocketKeepaliveCallback cb,
@NonNull String srcAddrString,
@@ -465,8 +534,15 @@ public class KeepaliveTracker {
notifyErrorCallback(cb, e.error);
return;
}
- KeepaliveInfo ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_NATT, null);
+ KeepaliveInfo ki = null;
+ try {
+ ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
+ KeepaliveInfo.TYPE_NATT, fd);
+ } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+ Log.e(TAG, "Fail to construct keepalive", e);
+ notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
+ return;
+ }
Log.d(TAG, "Created keepalive: " + ki.toString());
mConnectivityServiceHandler.obtainMessage(
NetworkAgent.CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
@@ -498,9 +574,15 @@ public class KeepaliveTracker {
notifyErrorCallback(cb, e.error);
return;
}
-
- KeepaliveInfo ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_TCP, fd);
+ KeepaliveInfo ki = null;
+ try {
+ ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
+ KeepaliveInfo.TYPE_TCP, fd);
+ } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+ Log.e(TAG, "Fail to construct keepalive e=" + e);
+ notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
+ return;
+ }
Log.d(TAG, "Created keepalive: " + ki.toString());
mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
}
@@ -535,7 +617,7 @@ public class KeepaliveTracker {
}
// Forward request to old API.
- startNattKeepalive(nai, intervalSeconds, cb, srcAddrString, srcPort,
+ startNattKeepalive(nai, fd, intervalSeconds, cb, srcAddrString, srcPort,
dstAddrString, dstPort);
}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 262ba7a475bb..66bd27c1a76b 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
import android.net.INetd;
import android.net.InetAddresses;
import android.net.InterfaceConfiguration;
@@ -65,6 +66,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
NetworkInfo.State.SUSPENDED,
};
+ private final IDnsResolver mDnsResolver;
private final INetd mNetd;
private final INetworkManagementService mNMService;
@@ -84,7 +86,9 @@ public class Nat464Xlat extends BaseNetworkObserver {
private Inet6Address mIPv6Address;
private State mState = State.IDLE;
- public Nat464Xlat(NetworkAgentInfo nai, INetd netd, INetworkManagementService nmService) {
+ public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
+ INetworkManagementService nmService) {
+ mDnsResolver = dnsResolver;
mNetd = netd;
mNMService = nmService;
mNetwork = nai;
@@ -269,7 +273,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
private void startPrefixDiscovery() {
try {
- mNetd.resolverStartPrefix64Discovery(getNetId());
+ mDnsResolver.startPrefix64Discovery(getNetId());
mState = State.DISCOVERING;
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
@@ -278,7 +282,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
private void stopPrefixDiscovery() {
try {
- mNetd.resolverStopPrefix64Discovery(getNetId());
+ mDnsResolver.stopPrefix64Discovery(getNetId());
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 8f2825ca72d8..e3fdbe84a1d3 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import android.content.Context;
+import android.net.IDnsResolver;
import android.net.INetd;
import android.net.INetworkMonitor;
import android.net.LinkProperties;
@@ -255,7 +256,7 @@ 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,
NetworkMisc misc, ConnectivityService connService, INetd netd,
- INetworkManagementService nms, int factorySerialNumber) {
+ IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
this.messenger = messenger;
asyncChannel = ac;
network = net;
@@ -263,7 +264,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
linkProperties = lp;
networkCapabilities = nc;
currentScore = score;
- clatd = new Nat464Xlat(this, netd, nms);
+ clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
mConnService = connService;
mContext = context;
mHandler = handler;
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 828a1e58868a..ac3d6def6f80 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -19,6 +19,7 @@ package com.android.server.connectivity;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import android.app.Notification;
import android.app.NotificationManager;
@@ -26,9 +27,12 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.net.NetworkSpecifier;
+import android.net.StringNetworkSpecifier;
import android.net.wifi.WifiInfo;
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Slog;
@@ -195,7 +199,20 @@ public class NetworkNotificationManager {
title = r.getString(R.string.network_available_sign_in, 0);
// TODO: Change this to pull from NetworkInfo once a printable
// name has been added to it
- details = mTelephonyManager.getNetworkOperatorName();
+ NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
+ int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ if (specifier instanceof StringNetworkSpecifier) {
+ try {
+ subId = Integer.parseInt(
+ ((StringNetworkSpecifier) specifier).specifier);
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "NumberFormatException on "
+ + ((StringNetworkSpecifier) specifier).specifier);
+ }
+ }
+
+ details = mTelephonyManager.createForSubscriptionId(subId)
+ .getNetworkOperatorName();
break;
default:
title = r.getString(R.string.network_available_sign_in, 0);
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 123564eb4fdb..0c559346bc42 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.os.Process.INVALID_UID;
@@ -42,13 +43,15 @@ import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.ArraySet;
import android.util.Log;
-import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
import java.util.ArrayList;
import java.util.HashMap;
@@ -83,41 +86,32 @@ public class PermissionMonitor {
private final Map<Integer, Boolean> mApps = new HashMap<>();
private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
- @Override
- public void onPackageAdded(String packageName, int uid) {
- final PackageInfo app = getPackageInfo(packageName);
- if (app == null) {
- Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
- return;
- }
- if (uid == INVALID_UID) {
- Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
- + "uid: " + uid);
- return;
- }
- if (app.requestedPermissions == null) {
- return;
- }
- sendPackagePermissionsForUid(uid,
- getNetdPermissionMask(app.requestedPermissions));
- }
- @Override
- public void onPackageRemoved(String packageName, int uid) {
+ private int getPermissionForUid(int uid) {
int permission = 0;
- // If there are still packages remain under the same uid, check the permission of the
- // remaining packages. We only remove the permission for a given uid when all packages
- // for that uid no longer have that permission.
+ // Check all the packages for this UID. The UID has the permission if any of the
+ // packages in it has the permission.
String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages != null && packages.length > 0) {
for (String name : packages) {
final PackageInfo app = getPackageInfo(name);
if (app != null && app.requestedPermissions != null) {
- permission |= getNetdPermissionMask(app.requestedPermissions);
+ permission |= getNetdPermissionMask(app.requestedPermissions,
+ app.requestedPermissionsFlags);
}
}
}
- sendPackagePermissionsForUid(uid, permission);
+ return permission;
+ }
+
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
}
}
@@ -167,12 +161,9 @@ public class PermissionMonitor {
}
//TODO: unify the management of the permissions into one codepath.
- if (app.requestedPermissions != null) {
- int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
- if (otherNetdPerms != 0) {
- netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
- }
- }
+ int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
+ app.requestedPermissionsFlags);
+ netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
}
List<UserInfo> users = mUserManager.getUsers(true); // exclude dying users
@@ -182,6 +173,23 @@ public class PermissionMonitor {
}
}
+ final SparseArray<ArraySet<String>> systemPermission =
+ SystemConfig.getInstance().getSystemPermissions();
+ for (int i = 0; i < systemPermission.size(); i++) {
+ ArraySet<String> perms = systemPermission.valueAt(i);
+ int uid = systemPermission.keyAt(i);
+ int netdPermission = 0;
+ // Get the uids of native services that have UPDATE_DEVICE_STATS permission.
+ if (perms != null) {
+ netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
+ ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
+ }
+ // For internet permission, the native services have their own selinux domains and
+ // sepolicy will control the socket creation during run time. netd cannot block the
+ // socket creation based on the permission information here.
+ netdPermission |= INetd.PERMISSION_INTERNET;
+ netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
+ }
log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
update(mUsers, mApps, true);
sendPackagePermissionsToNetd(netdPermsUids);
@@ -403,13 +411,17 @@ public class PermissionMonitor {
}
}
- private static int getNetdPermissionMask(String[] requestedPermissions) {
+ private static int getNetdPermissionMask(String[] requestedPermissions,
+ int[] requestedPermissionsFlags) {
int permissions = 0;
- for (String permissionName : requestedPermissions) {
- if (permissionName.equals(INTERNET)) {
+ if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
+ for (int i = 0; i < requestedPermissions.length; i++) {
+ if (requestedPermissions[i].equals(INTERNET)
+ && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
permissions |= INetd.PERMISSION_INTERNET;
}
- if (permissionName.equals(UPDATE_DEVICE_STATS)) {
+ if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
+ && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
}
}
diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
index f4d9006a7068..e570ef1e9bf2 100644
--- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
+++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
@@ -16,14 +16,17 @@
package com.android.server.connectivity;
import static android.net.SocketKeepalive.DATA_RECEIVED;
-import static android.net.SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE;
+import static android.net.SocketKeepalive.ERROR_UNSUPPORTED;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
import static android.system.OsConstants.ENOPROTOOPT;
import static android.system.OsConstants.FIONREAD;
+import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IP_TOS;
+import static android.system.OsConstants.IP_TTL;
import static android.system.OsConstants.TIOCOUTQ;
import android.annotation.NonNull;
@@ -193,12 +196,18 @@ public class TcpKeepaliveController {
trw = NetworkUtils.getTcpRepairWindow(fd);
tcpDetails.rcvWnd = trw.rcvWnd;
tcpDetails.rcvWndScale = trw.rcvWndScale;
+ if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
+ // Query TOS.
+ tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
+ // Query TTL.
+ tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
+ }
} catch (ErrnoException e) {
Log.e(TAG, "Exception reading TCP state from socket", e);
if (e.errno == ENOPROTOOPT) {
// ENOPROTOOPT may happen in kernel version lower than 4.8.
- // Treat it as ERROR_HARDWARE_UNSUPPORTED.
- throw new InvalidSocketException(ERROR_HARDWARE_UNSUPPORTED, e);
+ // Treat it as ERROR_UNSUPPORTED.
+ throw new InvalidSocketException(ERROR_UNSUPPORTED, e);
} else {
throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 35704d404ff3..99868099ad4d 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -82,7 +82,6 @@ import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
-import android.os.Parcel;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -230,8 +229,15 @@ public class Tethering extends BaseNetworkObserver {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
- mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM,
- mLog, systemProperties);
+ // 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, systemProperties);
+ mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
+ mLog.log("OBSERVED UiEnitlementFailed");
+ stopTethering(downstream);
+ });
+
mCarrierConfigChange = new VersionedBroadcastListener(
"CarrierConfigChangeListener", mContext, mHandler, filter,
(Intent ignored) -> {
@@ -247,7 +253,14 @@ public class Tethering extends BaseNetworkObserver {
(Intent ignored) -> {
mLog.log("OBSERVED default data subscription change");
updateConfiguration();
- mEntitlementMgr.reevaluateSimCardProvisioning();
+ // To avoid launch unexpected provisioning checks, ignore re-provisioning when
+ // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
+ // triggered again when CarrierConfig is loaded.
+ if (mEntitlementMgr.getCarrierConfig() != null) {
+ mEntitlementMgr.reevaluateSimCardProvisioning();
+ } else {
+ mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
+ }
});
mStateReceiver = new StateReceiver();
@@ -356,55 +369,28 @@ public class Tethering extends BaseNetworkObserver {
}
public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
- mEntitlementMgr.startTethering(type);
- if (!mEntitlementMgr.isTetherProvisioningRequired()) {
- enableTetheringInternal(type, true, receiver);
- return;
- }
-
- final ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
- if (showProvisioningUi) {
- mEntitlementMgr.runUiTetherProvisioningAndEnable(type, proxyReceiver);
- } else {
- mEntitlementMgr.runSilentTetherProvisioningAndEnable(type, proxyReceiver);
- }
+ mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi);
+ enableTetheringInternal(type, true /* enabled */, receiver);
}
public void stopTethering(int type) {
- enableTetheringInternal(type, false, null);
- mEntitlementMgr.stopTethering(type);
- if (mEntitlementMgr.isTetherProvisioningRequired()) {
- // There are lurking bugs where the notion of "provisioning required" or
- // "tethering supported" may change without notifying tethering properly, then
- // tethering can't shutdown correctly.
- // TODO: cancel re-check all the time
- if (mDeps.isTetheringSupported()) {
- mEntitlementMgr.cancelTetherProvisioningRechecks(type);
- }
- }
+ enableTetheringInternal(type, false /* disabled */, null);
+ mEntitlementMgr.stopProvisioningIfNeeded(type);
}
/**
- * Enables or disables tethering for the given type. This should only be called once
- * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
- * for the specified interface.
+ * Enables or disables tethering for the given type. If provisioning is required, it will
+ * schedule provisioning rechecks for the specified interface.
*/
private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
- boolean isProvisioningRequired = enable && mEntitlementMgr.isTetherProvisioningRequired();
int result;
switch (type) {
case TETHERING_WIFI:
result = setWifiTethering(enable);
- if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
- mEntitlementMgr.scheduleProvisioningRechecks(type);
- }
sendTetherResult(receiver, result);
break;
case TETHERING_USB:
result = setUsbTethering(enable);
- if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
- mEntitlementMgr.scheduleProvisioningRechecks(type);
- }
sendTetherResult(receiver, result);
break;
case TETHERING_BLUETOOTH:
@@ -462,46 +448,11 @@ public class Tethering extends BaseNetworkObserver {
? TETHER_ERROR_NO_ERROR
: TETHER_ERROR_MASTER_ERROR;
sendTetherResult(receiver, result);
- if (enable && mEntitlementMgr.isTetherProvisioningRequired()) {
- mEntitlementMgr.scheduleProvisioningRechecks(TETHERING_BLUETOOTH);
- }
adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
}
}, BluetoothProfile.PAN);
}
- /**
- * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result
- * is successful before firing back up to the wrapped receiver.
- *
- * @param type The type of tethering being enabled.
- * @param receiver A ResultReceiver which will be called back with an int resultCode.
- * @return The proxy receiver.
- */
- private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) {
- ResultReceiver rr = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- // If provisioning is successful, enable tethering, otherwise just send the error.
- if (resultCode == TETHER_ERROR_NO_ERROR) {
- enableTetheringInternal(type, true, receiver);
- } else {
- sendTetherResult(receiver, resultCode);
- }
- mEntitlementMgr.updateEntitlementCacheValue(type, resultCode);
- }
- };
-
- // The following is necessary to avoid unmarshalling issues when sending the receiver
- // across processes.
- Parcel parcel = Parcel.obtain();
- rr.writeToParcel(parcel,0);
- parcel.setDataPosition(0);
- ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
- parcel.recycle();
- return receiverForSending;
- }
-
public int tether(String iface) {
return tether(iface, IpServer.STATE_TETHERED);
}
@@ -780,6 +731,7 @@ public class Tethering extends BaseNetworkObserver {
if (!usbConnected && mRndisEnabled) {
// Turn off tethering if it was enabled and there is a disconnect.
tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
+ mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
} else if (usbConfigured && rndisEnabled) {
// Tether if rndis is enabled and usb is configured.
tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
@@ -806,6 +758,7 @@ public class Tethering extends BaseNetworkObserver {
case WifiManager.WIFI_AP_STATE_FAILED:
default:
disableWifiIpServingLocked(ifname, curState);
+ mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
break;
}
}
@@ -1083,6 +1036,8 @@ public class Tethering extends BaseNetworkObserver {
// we treated the error and want now to clear it
static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
+ // Events from EntitlementManager to choose upstream again.
+ static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
private final State mInitialState;
private final State mTetherModeAliveState;
@@ -1497,6 +1452,7 @@ public class Tethering extends BaseNetworkObserver {
}
break;
}
+ case EVENT_UPSTREAM_PERMISSION_CHANGED:
case CMD_UPSTREAM_CHANGED:
updateUpstreamWanted();
if (!mUpstreamWanted) break;
@@ -1687,7 +1643,8 @@ public class Tethering extends BaseNetworkObserver {
}
public void systemReady() {
- mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest());
+ mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
+ mEntitlementMgr);
}
/** Get the latest value of the tethering entitlement check. */
@@ -1748,6 +1705,11 @@ public class Tethering extends BaseNetworkObserver {
cfg.dump(pw);
pw.decreaseIndent();
+ pw.println("Entitlement:");
+ pw.increaseIndent();
+ mEntitlementMgr.dump(pw);
+ pw.decreaseIndent();
+
synchronized (mPublicSync) {
pw.println("Tether state:");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
index 65cc51610e72..764a6ebc2d98 100644
--- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
+++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
@@ -18,9 +18,11 @@ package com.android.server.connectivity.tethering;
import static android.net.ConnectivityManager.EXTRA_ADD_TETHER_TYPE;
import static android.net.ConnectivityManager.EXTRA_PROVISION_CALLBACK;
-import static android.net.ConnectivityManager.EXTRA_REM_TETHER_TYPE;
import static android.net.ConnectivityManager.EXTRA_RUN_PROVISION;
-import static android.net.ConnectivityManager.EXTRA_SET_ALARM;
+import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
+import static android.net.ConnectivityManager.TETHERING_INVALID;
+import static android.net.ConnectivityManager.TETHERING_USB;
+import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
@@ -28,17 +30,24 @@ import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
import static com.android.internal.R.string.config_wifi_tether_enable;
import android.annotation.Nullable;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.util.SharedLog;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.Parcel;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
@@ -46,48 +55,93 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.SparseIntArray;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.StateMachine;
import com.android.server.connectivity.MockableSystemProperties;
+import java.io.PrintWriter;
+
/**
- * This class encapsulates entitlement/provisioning mechanics
- * provisioning check only applies to the use of the mobile network as an upstream
+ * Re-check tethering provisioning for enabled downstream tether types.
+ * Reference ConnectivityManager.TETHERING_{@code *} for each tether type.
*
+ * All methods of this class must be accessed from the thread of tethering
+ * state machine.
* @hide
*/
public class EntitlementManager {
private static final String TAG = EntitlementManager.class.getSimpleName();
private static final boolean DBG = false;
+ @VisibleForTesting
+ protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
+ private static final String ACTION_PROVISIONING_ALARM =
+ "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM";
+
// {@link ComponentName} of the Service used to run tether provisioning.
private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(
Resources.getSystem().getString(config_wifi_tether_enable));
- protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
+ private static final int MS_PER_HOUR = 60 * 60 * 1000;
+ private static final int EVENT_START_PROVISIONING = 0;
+ private static final int EVENT_STOP_PROVISIONING = 1;
+ private static final int EVENT_UPSTREAM_CHANGED = 2;
+ private static final int EVENT_MAYBE_RUN_PROVISIONING = 3;
+ private static final int EVENT_GET_ENTITLEMENT_VALUE = 4;
+
// The ArraySet contains enabled downstream types, ex:
// {@link ConnectivityManager.TETHERING_WIFI}
// {@link ConnectivityManager.TETHERING_USB}
// {@link ConnectivityManager.TETHERING_BLUETOOTH}
- @GuardedBy("mCurrentTethers")
private final ArraySet<Integer> mCurrentTethers;
private final Context mContext;
+ private final int mPermissionChangeMessageCode;
private final MockableSystemProperties mSystemProperties;
private final SharedLog mLog;
- private final Handler mMasterHandler;
private final SparseIntArray mEntitlementCacheValue;
- @Nullable
- private TetheringConfiguration mConfig;
+ private final EntitlementHandler mHandler;
+ private @Nullable TetheringConfiguration mConfig;
+ private final StateMachine mTetherMasterSM;
+ // Key: ConnectivityManager.TETHERING_*(downstream).
+ // Value: ConnectivityManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
+ private final SparseIntArray mCellularPermitted;
+ private PendingIntent mProvisioningRecheckAlarm;
+ private boolean mCellularUpstreamPermitted = true;
+ private boolean mUsingCellularAsUpstream = false;
+ private boolean mNeedReRunProvisioningUi = false;
+ private OnUiEntitlementFailedListener mListener;
public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
- MockableSystemProperties systemProperties) {
+ int permissionChangeMessageCode, MockableSystemProperties systemProperties) {
+
mContext = ctx;
mLog = log.forSubComponent(TAG);
mCurrentTethers = new ArraySet<Integer>();
+ mCellularPermitted = new SparseIntArray();
mSystemProperties = systemProperties;
mEntitlementCacheValue = new SparseIntArray();
- mMasterHandler = tetherMasterSM.getHandler();
+ mTetherMasterSM = tetherMasterSM;
+ mPermissionChangeMessageCode = permissionChangeMessageCode;
+ final Handler masterHandler = tetherMasterSM.getHandler();
+ // Create entitlement's own handler which is associated with TetherMaster thread
+ // let all entitlement processes run in the same thread.
+ mHandler = new EntitlementHandler(masterHandler.getLooper());
+ mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM),
+ null, mHandler);
+ }
+
+ public void setOnUiEntitlementFailedListener(final OnUiEntitlementFailedListener listener) {
+ mListener = listener;
+ }
+
+ /** Callback fired when UI entitlement failed. */
+ public interface OnUiEntitlementFailedListener {
+ /**
+ * Ui entitlement check fails in |downstream|.
+ *
+ * @param downstream tethering type from ConnectivityManager.TETHERING_{@code *}.
+ */
+ void onUiEntitlementFailed(int downstream);
}
/**
@@ -99,24 +153,118 @@ public class EntitlementManager {
}
/**
- * Tell EntitlementManager that a given type of tethering has been enabled
+ * Check if cellular upstream is permitted.
+ */
+ public boolean isCellularUpstreamPermitted() {
+ return mCellularUpstreamPermitted;
+ }
+
+ /**
+ * This is called when tethering starts.
+ * Launch provisioning app if upstream is cellular.
*
- * @param type Tethering type
+ * @param downstreamType tethering type from ConnectivityManager.TETHERING_{@code *}
+ * @param showProvisioningUi a boolean indicating whether to show the
+ * provisioning app UI if there is one.
*/
- public void startTethering(int type) {
- synchronized (mCurrentTethers) {
- mCurrentTethers.add(type);
+ public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_START_PROVISIONING,
+ downstreamType, encodeBool(showProvisioningUi)));
+ }
+
+ private void handleStartProvisioningIfNeeded(int type, boolean showProvisioningUi) {
+ if (!isValidDownstreamType(type)) return;
+
+ if (!mCurrentTethers.contains(type)) mCurrentTethers.add(type);
+
+ if (isTetherProvisioningRequired()) {
+ // 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(type);
+ } else {
+ runSilentTetherProvisioning(type);
+ }
+ mNeedReRunProvisioningUi = false;
+ } else {
+ mNeedReRunProvisioningUi |= showProvisioningUi;
+ }
+ } else {
+ mCellularUpstreamPermitted = true;
}
}
/**
* Tell EntitlementManager that a given type of tethering has been disabled
*
- * @param type Tethering type
+ * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+ */
+ public void stopProvisioningIfNeeded(int type) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_STOP_PROVISIONING, type, 0));
+ }
+
+ private void handleStopProvisioningIfNeeded(int type) {
+ if (!isValidDownstreamType(type)) return;
+
+ mCurrentTethers.remove(type);
+ // 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);
+ }
+
+ /**
+ * Notify EntitlementManager if upstream is cellular or not.
+ *
+ * @param isCellular whether tethering upstream is cellular.
*/
- public void stopTethering(int type) {
- synchronized (mCurrentTethers) {
- mCurrentTethers.remove(type);
+ public void notifyUpstream(boolean isCellular) {
+ mHandler.sendMessage(mHandler.obtainMessage(
+ EVENT_UPSTREAM_CHANGED, encodeBool(isCellular), 0));
+ }
+
+ private void handleNotifyUpstream(boolean isCellular) {
+ if (DBG) {
+ Log.d(TAG, "notifyUpstream: " + isCellular
+ + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted
+ + ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
+ }
+ mUsingCellularAsUpstream = isCellular;
+
+ if (mUsingCellularAsUpstream) {
+ handleMaybeRunProvisioning();
+ }
+ }
+
+ /** Run provisioning if needed */
+ public void maybeRunProvisioning() {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_MAYBE_RUN_PROVISIONING));
+ }
+
+ private void handleMaybeRunProvisioning() {
+ if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired()) {
+ return;
+ }
+
+ // Whenever any entitlement value changes, all downstreams will re-evaluate whether they
+ // 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) {
+ if (mNeedReRunProvisioningUi) {
+ mNeedReRunProvisioningUi = false;
+ runUiTetherProvisioning(downstream);
+ } else {
+ runSilentTetherProvisioning(downstream);
+ }
+ }
}
}
@@ -138,24 +286,48 @@ public class EntitlementManager {
}
/**
- * Re-check tethering provisioning for enabled downstream tether types.
+ * Re-check tethering provisioning for all enabled tether types.
* Reference ConnectivityManager.TETHERING_{@code *} for each tether type.
+ *
+ * Note: this method is only called from TetherMaster on the handler thread.
+ * If there are new callers from different threads, the logic should move to
+ * masterHandler to avoid race conditions.
*/
public void reevaluateSimCardProvisioning() {
- synchronized (mEntitlementCacheValue) {
- mEntitlementCacheValue.clear();
+ if (DBG) Log.d(TAG, "reevaluateSimCardProvisioning");
+
+ if (!mHandler.getLooper().isCurrentThread()) {
+ // Except for test, this log should not appear in normal flow.
+ mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
}
+ mEntitlementCacheValue.clear();
+ mCellularPermitted.clear();
- if (!mConfig.hasMobileHotspotProvisionApp()) return;
- if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
+ // TODO: refine provisioning check to isTetherProvisioningRequired() ??
+ if (!mConfig.hasMobileHotspotProvisionApp()
+ || carrierConfigAffirmsEntitlementCheckNotRequired()) {
+ evaluateCellularPermission();
+ return;
+ }
- final ArraySet<Integer> reevaluateType;
- synchronized (mCurrentTethers) {
- reevaluateType = new ArraySet<Integer>(mCurrentTethers);
+ if (mUsingCellularAsUpstream) {
+ handleMaybeRunProvisioning();
}
- for (Integer type : reevaluateType) {
- startProvisionIntent(type);
+ }
+
+ /** Get carrier configuration bundle. */
+ public PersistableBundle getCarrierConfig() {
+ final CarrierConfigManager configManager = (CarrierConfigManager) mContext
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager == null) return null;
+
+ final PersistableBundle carrierConfig = configManager.getConfig();
+
+ if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
+ return carrierConfig;
}
+
+ return null;
}
// The logic here is aimed solely at confirming that a CarrierConfig exists
@@ -165,11 +337,7 @@ public class EntitlementManager {
// entirely so that this is more intuitive.
private boolean carrierConfigAffirmsEntitlementCheckNotRequired() {
// Check carrier config for entitlement checks
- final CarrierConfigManager configManager = (CarrierConfigManager) mContext
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager == null) return false;
-
- final PersistableBundle carrierConfig = configManager.getConfig();
+ final PersistableBundle carrierConfig = getCarrierConfig();
if (carrierConfig == null) return false;
// A CarrierConfigManager was found and it has a config.
@@ -178,7 +346,16 @@ public class EntitlementManager {
return !isEntitlementCheckRequired;
}
- public void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+ /**
+ * Run no UI tethering provisioning check.
+ * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+ */
+ protected void runSilentTetherProvisioning(int type) {
+ if (DBG) Log.d(TAG, "runSilentTetherProvisioning: " + type);
+ // For silent provisioning, settings would stop tethering when entitlement fail.
+ ResultReceiver receiver = buildProxyReceiver(type,
+ false/* notifyFail */, null);
+
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_RUN_PROVISION, true);
@@ -192,12 +369,21 @@ public class EntitlementManager {
}
}
- public void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+ /**
+ * Run the UI-enabled tethering provisioning check.
+ * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+ */
+ @VisibleForTesting
+ protected void runUiTetherProvisioning(int type) {
+ ResultReceiver receiver = buildProxyReceiver(type,
+ true/* notifyFail */, null);
runUiTetherProvisioning(type, receiver);
}
@VisibleForTesting
protected void runUiTetherProvisioning(int type, ResultReceiver receiver) {
+ if (DBG) Log.d(TAG, "runUiTetherProvisioning: " + type);
+
Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING);
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
@@ -210,56 +396,210 @@ public class EntitlementManager {
}
}
- // Used by the SIM card change observation code.
- // TODO: De-duplicate with above code, where possible.
- private void startProvisionIntent(int tetherType) {
- final Intent startProvIntent = new Intent();
- startProvIntent.putExtra(EXTRA_ADD_TETHER_TYPE, tetherType);
- startProvIntent.putExtra(EXTRA_RUN_PROVISION, true);
- startProvIntent.setComponent(TETHER_SERVICE);
- mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT);
+ // Not needed to check if this don't run on the handler thread because it's private.
+ private void scheduleProvisioningRechecks() {
+ if (mProvisioningRecheckAlarm == null) {
+ final int period = mConfig.provisioningCheckPeriod;
+ if (period <= 0) return;
+
+ Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
+ mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+ AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
+ Context.ALARM_SERVICE);
+ long periodMs = period * MS_PER_HOUR;
+ long firstAlarmTime = SystemClock.elapsedRealtime() + periodMs;
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstAlarmTime, periodMs,
+ mProvisioningRecheckAlarm);
+ }
+ }
+
+ private void cancelTetherProvisioningRechecks() {
+ if (mProvisioningRecheckAlarm != null) {
+ AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
+ Context.ALARM_SERVICE);
+ alarmManager.cancel(mProvisioningRecheckAlarm);
+ mProvisioningRecheckAlarm = null;
+ }
}
- public void scheduleProvisioningRechecks(int type) {
- Intent intent = new Intent();
- intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
- intent.putExtra(EXTRA_SET_ALARM, true);
- intent.setComponent(TETHER_SERVICE);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.startServiceAsUser(intent, UserHandle.CURRENT);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ private void evaluateCellularPermission() {
+ final boolean oldPermitted = mCellularUpstreamPermitted;
+ mCellularUpstreamPermitted = (!isTetherProvisioningRequired()
+ || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1);
+
+ if (DBG) {
+ Log.d(TAG, "Cellular permission change from " + oldPermitted
+ + " to " + mCellularUpstreamPermitted);
+ }
+
+ if (mCellularUpstreamPermitted != oldPermitted) {
+ mLog.log("Cellular permission change: " + mCellularUpstreamPermitted);
+ mTetherMasterSM.sendMessage(mPermissionChangeMessageCode);
+ }
+ // Only schedule periodic re-check when tether is provisioned
+ // and the result is ok.
+ if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) {
+ scheduleProvisioningRechecks();
+ } else {
+ cancelTetherProvisioningRechecks();
}
}
- public void cancelTetherProvisioningRechecks(int type) {
- Intent intent = new Intent();
- intent.putExtra(EXTRA_REM_TETHER_TYPE, type);
- intent.setComponent(TETHER_SERVICE);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.startServiceAsUser(intent, UserHandle.CURRENT);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ /**
+ * Add the mapping between provisioning result and tethering type.
+ * Notify UpstreamNetworkMonitor if Cellular permission changes.
+ *
+ * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+ * @param resultCode Provisioning result
+ */
+ protected void addDownstreamMapping(int type, int resultCode) {
+ if (DBG) {
+ Log.d(TAG, "addDownstreamMapping: " + type + ", result: " + resultCode
+ + " ,TetherTypeRequested: " + mCurrentTethers.contains(type));
}
+ if (!mCurrentTethers.contains(type)) return;
+
+ mCellularPermitted.put(type, resultCode);
+ evaluateCellularPermission();
}
- private ResultReceiver buildProxyReceiver(int type, final ResultReceiver receiver) {
- ResultReceiver rr = new ResultReceiver(mMasterHandler) {
+ /**
+ * Remove the mapping for input tethering type.
+ * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+ */
+ protected void removeDownstreamMapping(int type) {
+ if (DBG) Log.d(TAG, "removeDownstreamMapping: " + type);
+ mCellularPermitted.delete(type);
+ evaluateCellularPermission();
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) {
+ mLog.log("Received provisioning alarm");
+ reevaluateSimCardProvisioning();
+ }
+ }
+ };
+
+ private class EntitlementHandler extends Handler {
+ EntitlementHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_START_PROVISIONING:
+ handleStartProvisioningIfNeeded(msg.arg1, toBool(msg.arg2));
+ break;
+ case EVENT_STOP_PROVISIONING:
+ handleStopProvisioningIfNeeded(msg.arg1);
+ break;
+ case EVENT_UPSTREAM_CHANGED:
+ handleNotifyUpstream(toBool(msg.arg1));
+ break;
+ case EVENT_MAYBE_RUN_PROVISIONING:
+ handleMaybeRunProvisioning();
+ break;
+ case EVENT_GET_ENTITLEMENT_VALUE:
+ handleGetLatestTetheringEntitlementValue(msg.arg1, (ResultReceiver) msg.obj,
+ toBool(msg.arg2));
+ break;
+ default:
+ mLog.log("Unknown event: " + msg.what);
+ break;
+ }
+ }
+ }
+
+ private static boolean toBool(int encodedBoolean) {
+ return encodedBoolean != 0;
+ }
+
+ private static int encodeBool(boolean b) {
+ return b ? 1 : 0;
+ }
+
+ private static boolean isValidDownstreamType(int type) {
+ switch (type) {
+ case TETHERING_BLUETOOTH:
+ case TETHERING_USB:
+ case TETHERING_WIFI:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Dump the infromation of 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");
+ }
+ }
+ }
+
+ private static String typeString(int type) {
+ switch (type) {
+ case TETHERING_BLUETOOTH: return "TETHERING_BLUETOOTH";
+ case TETHERING_INVALID: return "TETHERING_INVALID";
+ case TETHERING_USB: return "TETHERING_USB";
+ case TETHERING_WIFI: return "TETHERING_WIFI";
+ default:
+ return String.format("TETHERING UNKNOWN TYPE (%d)", type);
+ }
+ }
+
+ private static String errorString(int value) {
+ switch (value) {
+ case TETHER_ERROR_ENTITLEMENT_UNKONWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN";
+ case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR";
+ case TETHER_ERROR_PROVISION_FAILED: return "TETHER_ERROR_PROVISION_FAILED";
+ default:
+ return String.format("UNKNOWN ERROR (%d)", value);
+ }
+ }
+
+ private ResultReceiver buildProxyReceiver(int type, boolean notifyFail,
+ final ResultReceiver receiver) {
+ ResultReceiver rr = new ResultReceiver(mHandler) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
int updatedCacheValue = updateEntitlementCacheValue(type, resultCode);
- receiver.send(updatedCacheValue, null);
+ addDownstreamMapping(type, updatedCacheValue);
+ if (updatedCacheValue == TETHER_ERROR_PROVISION_FAILED && notifyFail) {
+ mListener.onUiEntitlementFailed(type);
+ }
+ if (receiver != null) receiver.send(updatedCacheValue, null);
}
};
return writeToParcel(rr);
}
+ // Instances of ResultReceiver need to be public classes for remote processes to be able
+ // to load them (otherwise, ClassNotFoundException). For private classes, this method
+ // performs a trick : round-trip parceling any instance of ResultReceiver will return a
+ // vanilla instance of ResultReceiver sharing the binder token with the original receiver.
+ // The binder token has a reference to the original instance of the private class and will
+ // still call its methods, and can be sent over. However it cannot be used for anything
+ // else than sending over a Binder call.
+ // While round-trip parceling is not great, there is currently no other way of generating
+ // a vanilla instance of ResultReceiver because all its fields are private.
private ResultReceiver writeToParcel(final ResultReceiver receiver) {
- // This is necessary to avoid unmarshalling issues when sending the receiver
- // across processes.
Parcel parcel = Parcel.obtain();
receiver.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
@@ -275,38 +615,41 @@ public class EntitlementManager {
* @param resultCode last entitlement value
* @return the last updated entitlement value
*/
- public int updateEntitlementCacheValue(int type, int resultCode) {
+ private int updateEntitlementCacheValue(int type, int resultCode) {
if (DBG) {
Log.d(TAG, "updateEntitlementCacheValue: " + type + ", result: " + resultCode);
}
- synchronized (mEntitlementCacheValue) {
- if (resultCode == TETHER_ERROR_NO_ERROR) {
- mEntitlementCacheValue.put(type, resultCode);
- return resultCode;
- } else {
- mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED);
- return TETHER_ERROR_PROVISION_FAILED;
- }
+ if (resultCode == TETHER_ERROR_NO_ERROR) {
+ mEntitlementCacheValue.put(type, resultCode);
+ return resultCode;
+ } else {
+ mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED);
+ return TETHER_ERROR_PROVISION_FAILED;
}
}
/** Get the last value of the tethering entitlement check. */
public void getLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver,
boolean showEntitlementUi) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ENTITLEMENT_VALUE,
+ downstream, encodeBool(showEntitlementUi), receiver));
+
+ }
+
+ private void handleGetLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver,
+ boolean showEntitlementUi) {
+
if (!isTetherProvisioningRequired()) {
receiver.send(TETHER_ERROR_NO_ERROR, null);
return;
}
- final int cacheValue;
- synchronized (mEntitlementCacheValue) {
- cacheValue = mEntitlementCacheValue.get(
+ final int cacheValue = mEntitlementCacheValue.get(
downstream, TETHER_ERROR_ENTITLEMENT_UNKONWN);
- }
if (cacheValue == TETHER_ERROR_NO_ERROR || !showEntitlementUi) {
receiver.send(cacheValue, null);
} else {
- ResultReceiver proxy = buildProxyReceiver(downstream, receiver);
+ ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
runUiTetherProvisioning(downstream, proxy);
}
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 935b79546d63..8427b6eceab9 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -30,6 +30,7 @@ import static com.android.internal.R.array.config_tether_upstream_types;
import static com.android.internal.R.array.config_tether_usb_regexs;
import static com.android.internal.R.array.config_tether_wifi_regexs;
import static com.android.internal.R.bool.config_tether_upstream_automatic;
+import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period;
import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
import android.content.ContentResolver;
@@ -94,6 +95,7 @@ public class TetheringConfiguration {
public final String[] provisioningApp;
public final String provisioningAppNoUi;
+ public final int provisioningCheckPeriod;
public final int subId;
@@ -121,6 +123,9 @@ public class TetheringConfiguration {
provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app);
provisioningAppNoUi = getProvisioningAppNoUi(res);
+ provisioningCheckPeriod = getResourceInteger(res,
+ config_mobile_hotspot_provision_check_period,
+ 0 /* No periodic re-check */);
configLog.log(toString());
}
@@ -311,6 +316,14 @@ public class TetheringConfiguration {
}
}
+ private static int getResourceInteger(Resources res, int resId, int defaultValue) {
+ try {
+ return res.getInteger(resId);
+ } catch (Resources.NotFoundException e404) {
+ return defaultValue;
+ }
+ }
+
private static boolean getEnableLegacyDhcpServer(Context ctx) {
final ContentResolver cr = ctx.getContentResolver();
final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
index 173d7860e4ac..a0aad7c50481 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -83,8 +83,8 @@ public class TetheringDependencies {
* Get a reference to the EntitlementManager to be used by tethering.
*/
public EntitlementManager getEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, MockableSystemProperties systemProperties) {
- return new EntitlementManager(ctx, target, log, systemProperties);
+ SharedLog log, int what, MockableSystemProperties systemProperties) {
+ return new EntitlementManager(ctx, target, log, what, systemProperties);
}
/**
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 3ac311b3e13a..3a9e21f943d8 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -16,36 +16,32 @@
package com.android.server.connectivity.tethering;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
+import static android.net.ConnectivityManager.TYPE_NONE;
+import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IpPrefix;
-import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkState;
-import android.net.util.NetworkConstants;
import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.Process;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.StateMachine;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -97,10 +93,13 @@ public class UpstreamNetworkMonitor {
private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
private HashSet<IpPrefix> mLocalPrefixes;
private ConnectivityManager mCM;
+ private EntitlementManager mEntitlementMgr;
private NetworkCallback mListenAllCallback;
private NetworkCallback mDefaultNetworkCallback;
private NetworkCallback mMobileNetworkCallback;
private boolean mDunRequired;
+ // Whether the current default upstream is mobile or not.
+ private boolean mIsDefaultCellularUpstream;
// The current system default network (not really used yet).
private Network mDefaultInternetNetwork;
// The current upstream network used for tethering.
@@ -113,6 +112,7 @@ public class UpstreamNetworkMonitor {
mLog = log.forSubComponent(TAG);
mWhat = what;
mLocalPrefixes = new HashSet<>();
+ mIsDefaultCellularUpstream = false;
}
@VisibleForTesting
@@ -122,7 +122,15 @@ public class UpstreamNetworkMonitor {
mCM = cm;
}
- public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest) {
+ /**
+ * Tracking the system default network. This method should be called when system is ready.
+ *
+ * @param defaultNetworkRequest should be the same as ConnectivityService default request
+ * @param entitle a EntitlementManager object to communicate between EntitlementManager and
+ * UpstreamNetworkMonitor
+ */
+ public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest,
+ EntitlementManager entitle) {
// This is not really a "request", just a way of tracking the system default network.
// It's guaranteed not to actually bring up any networks because it's the same request
// as the ConnectivityService default request, and thus shares fate with it. We can't
@@ -133,6 +141,9 @@ public class UpstreamNetworkMonitor {
mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET);
cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler);
}
+ if (mEntitlementMgr == null) {
+ mEntitlementMgr = entitle;
+ }
}
public void startObserveAllNetworks() {
@@ -168,11 +179,15 @@ public class UpstreamNetworkMonitor {
}
public void registerMobileNetworkRequest() {
+ if (!isCellularUpstreamPermitted()) {
+ mLog.i("registerMobileNetworkRequest() is not permitted");
+ releaseMobileNetworkRequest();
+ return;
+ }
if (mMobileNetworkCallback != null) {
mLog.e("registerMobileNetworkRequest() already registered");
return;
}
-
// The following use of the legacy type system cannot be removed until
// after upstream selection no longer finds networks by legacy type.
// See also http://b/34364553 .
@@ -206,29 +221,32 @@ public class UpstreamNetworkMonitor {
// becomes available and useful we (a) file a request to keep it up as
// necessary and (b) change all upstream tracking state accordingly (by
// passing LinkProperties up to Tethering).
- //
- // Next TODO: return NetworkState instead of just the type.
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
- mNetworkMap.values(), preferredTypes);
+ mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
mLog.log("preferred upstream type: " + getNetworkTypeName(typeStatePair.type));
switch (typeStatePair.type) {
case TYPE_MOBILE_DUN:
case TYPE_MOBILE_HIPRI:
+ // Tethering just selected mobile upstream in spite of the default network being
+ // not mobile. This can happen because of the priority list.
+ // Notify EntitlementManager to check permission for using mobile upstream.
+ if (!mIsDefaultCellularUpstream) {
+ mEntitlementMgr.maybeRunProvisioning();
+ }
// If we're on DUN, put our own grab on it.
registerMobileNetworkRequest();
break;
case TYPE_NONE:
+ // If we found NONE and mobile upstream is permitted we don't want to do this
+ // as we want any previous requests to keep trying to bring up something we can use.
+ if (!isCellularUpstreamPermitted()) releaseMobileNetworkRequest();
break;
default:
- /* If we've found an active upstream connection that's not DUN/HIPRI
- * we should stop any outstanding DUN/HIPRI requests.
- *
- * If we found NONE we don't want to do this as we want any previous
- * requests to keep trying to bring up something we can use.
- */
+ // If we've found an active upstream connection that's not DUN/HIPRI
+ // we should stop any outstanding DUN/HIPRI requests.
releaseMobileNetworkRequest();
break;
}
@@ -241,10 +259,12 @@ public class UpstreamNetworkMonitor {
final NetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
: null;
- if (!mDunRequired) return dfltState;
-
if (isNetworkUsableAndNotCellular(dfltState)) return dfltState;
+ if (!isCellularUpstreamPermitted()) return null;
+
+ if (!mDunRequired) return dfltState;
+
// Find a DUN network. Note that code in Tethering causes a DUN request
// to be filed, but this might be moved into this class in future.
return findFirstDunNetwork(mNetworkMap.values());
@@ -258,6 +278,15 @@ public class UpstreamNetworkMonitor {
return (Set<IpPrefix>) mLocalPrefixes.clone();
}
+ private boolean isCellularUpstreamPermitted() {
+ if (mEntitlementMgr != null) {
+ return mEntitlementMgr.isCellularUpstreamPermitted();
+ } else {
+ // This flow should only happens in testing.
+ return true;
+ }
+ }
+
private void handleAvailable(Network network) {
if (mNetworkMap.containsKey(network)) return;
@@ -388,8 +417,14 @@ public class UpstreamNetworkMonitor {
public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
mDefaultInternetNetwork = network;
+ final boolean newIsCellular = isCellular(newNc);
+ if (mIsDefaultCellularUpstream != newIsCellular) {
+ mIsDefaultCellularUpstream = newIsCellular;
+ mEntitlementMgr.notifyUpstream(newIsCellular);
+ }
return;
}
+
handleNetCap(network, newNc);
}
@@ -424,8 +459,11 @@ public class UpstreamNetworkMonitor {
public void onLost(Network network) {
if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
mDefaultInternetNetwork = null;
+ mIsDefaultCellularUpstream = false;
+ mEntitlementMgr.notifyUpstream(false);
return;
}
+
handleLost(network);
// Any non-LISTEN_ALL callback will necessarily concern a network that will
// also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
@@ -454,7 +492,8 @@ public class UpstreamNetworkMonitor {
}
private static TypeStatePair findFirstAvailableUpstreamByType(
- Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes) {
+ Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes,
+ boolean isCellularUpstreamPermitted) {
final TypeStatePair result = new TypeStatePair();
for (int type : preferredTypes) {
@@ -466,6 +505,10 @@ public class UpstreamNetworkMonitor {
ConnectivityManager.getNetworkTypeName(type));
continue;
}
+ if (!isCellularUpstreamPermitted && isCellular(nc)) {
+ continue;
+ }
+
nc.setSingleUid(Process.myUid());
for (NetworkState value : netStates) {
diff --git a/services/core/java/com/android/server/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS
new file mode 100644
index 000000000000..7e7335d68d3b
--- /dev/null
+++ b/services/core/java/com/android/server/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index a2e7e0cae96b..bdff50053fae 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -41,10 +41,10 @@ import com.android.internal.net.VpnInfo;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
-import libcore.io.IoUtils;
-
import com.google.android.collect.Sets;
+import libcore.io.IoUtils;
+
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -234,7 +234,7 @@ public class NetworkStatsRecorder {
if (vpnArray != null) {
for (VpnInfo info : vpnArray) {
- delta.migrateTun(info.ownerUid, info.vpnIface, info.primaryUnderlyingIface);
+ delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
}
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 8fa435cd9381..4c076781731c 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -292,6 +292,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** Data layer operation counters for splicing into other structures. */
private NetworkStats mUidOperations = new NetworkStats(0L, 10);
+ /**
+ * Snapshot containing most recent network stats for all UIDs across all interfaces and tags
+ * since boot.
+ *
+ * <p>Maintains migrated VPN stats which are result of performing TUN migration on {@link
+ * #mLastUidDetailSnapshot}.
+ */
+ @GuardedBy("mStatsLock")
+ private NetworkStats mTunAdjustedStats;
+ /**
+ * Used by {@link #mTunAdjustedStats} to migrate VPN traffic over delta between this snapshot
+ * and latest snapshot.
+ */
+ @GuardedBy("mStatsLock")
+ private NetworkStats mLastUidDetailSnapshot;
+
/** Must be set in factory by calling #setHandler. */
private Handler mHandler;
private Handler.Callback mHandlerCallback;
@@ -805,15 +821,39 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
try {
+ // Get the latest snapshot from NetworkStatsFactory.
+ // TODO: Querying for INTERFACES_ALL may incur performance penalty. Consider restricting
+ // this to limited set of ifaces.
+ NetworkStats uidDetailStats = getNetworkStatsUidDetail(INTERFACES_ALL);
+
+ // Migrate traffic from VPN UID over delta and update mTunAdjustedStats.
+ NetworkStats result;
+ synchronized (mStatsLock) {
+ migrateTunTraffic(uidDetailStats, mVpnInfos);
+ result = mTunAdjustedStats.clone();
+ }
+
+ // Apply filter based on ifacesToQuery.
final String[] ifacesToQuery =
NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
- return getNetworkStatsUidDetail(ifacesToQuery);
+ result.filter(UID_ALL, ifacesToQuery, TAG_ALL);
+ return result;
} catch (RemoteException e) {
Log.wtf(TAG, "Error compiling UID stats", e);
return new NetworkStats(0L, 0);
}
}
+ @VisibleForTesting
+ NetworkStats getTunAdjustedStats() {
+ synchronized (mStatsLock) {
+ if (mTunAdjustedStats == null) {
+ return null;
+ }
+ return mTunAdjustedStats.clone();
+ }
+ }
+
@Override
public String[] getMobileIfaces() {
return mMobileIfaces;
@@ -1288,6 +1328,34 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// a race condition between the service handler thread and the observer's
mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
+
+ migrateTunTraffic(uidSnapshot, vpnArray);
+ }
+
+ /**
+ * Updates {@link #mTunAdjustedStats} with the delta containing traffic migrated off of VPNs.
+ */
+ @GuardedBy("mStatsLock")
+ private void migrateTunTraffic(NetworkStats uidDetailStats, VpnInfo[] vpnInfoArray) {
+ if (mTunAdjustedStats == null) {
+ // Either device booted or system server restarted, hence traffic cannot be migrated
+ // correctly without knowing the past state of VPN's underlying networks.
+ mTunAdjustedStats = uidDetailStats;
+ mLastUidDetailSnapshot = uidDetailStats;
+ return;
+ }
+ // Migrate delta traffic from VPN to other apps.
+ NetworkStats delta = uidDetailStats.subtract(mLastUidDetailSnapshot);
+ for (VpnInfo info : vpnInfoArray) {
+ delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
+ }
+ // Filter out debug entries as that may lead to over counting.
+ delta.filterDebugEntries();
+ // Update #mTunAdjustedStats with migrated delta.
+ mTunAdjustedStats.combineAllValues(delta);
+ mTunAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
+ // Update last snapshot.
+ mLastUidDetailSnapshot = uidDetailStats;
}
/**
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index da6e9c02c96a..abd85cd35f57 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -1401,11 +1401,14 @@ public class RankingHelper implements RankingConfig {
}
// Package upgrade
try {
- Record fullRecord = getRecord(pkg,
- mPm.getPackageUidAsUser(pkg, changeUserId));
- if (fullRecord != null) {
- createDefaultChannelIfNeeded(fullRecord);
- deleteDefaultChannelIfNeeded(fullRecord);
+ synchronized (mRecords) {
+ final String key = recordKey(pkg,
+ mPm.getPackageUidAsUser(pkg, changeUserId));
+ Record fullRecord = mRecords.get(key);
+ if (fullRecord != null) {
+ createDefaultChannelIfNeeded(fullRecord);
+ deleteDefaultChannelIfNeeded(fullRecord);
+ }
}
} catch (NameNotFoundException e) {}
}
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index 5c0874d7977a..c98a79ad4ed9 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -174,7 +174,11 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
ds.startBugreport(callingUid, callingPackage,
bugreportFd, screenshotFd, bugreportMode, myListener);
} catch (RemoteException e) {
- reportError(listener, IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR);
+ // bugreportd service is already started now. We need to kill it to manage the
+ // lifecycle correctly. If we don't subsequent callers will get
+ // BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS error.
+ // Note that listener will be notified by the death recipient below.
+ cancelBugreport();
}
}
diff --git a/services/core/java/com/android/server/policy/EventLogTags.logtags b/services/core/java/com/android/server/policy/EventLogTags.logtags
new file mode 100644
index 000000000000..75633820d01f
--- /dev/null
+++ b/services/core/java/com/android/server/policy/EventLogTags.logtags
@@ -0,0 +1,8 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.server.policy
+
+
+# 0 for screen off, 1 for screen on
+70000 screen_toggled (screen_state|1|5)
+70001 intercept_power (action|3),(mPowerKeyHandled|1),(mPowerKeyPressCounter|1)
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9a741bcfc3d6..0149d30da6bd 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -225,7 +225,6 @@ import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import android.util.DisplayMetrics;
-import android.util.EventLog;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.MutableBoolean;
@@ -270,12 +269,11 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
-import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.policy.PhoneWindow;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.ScreenshotHelper;
import com.android.internal.util.ScreenShapeHelper;
+import com.android.internal.util.ScreenshotHelper;
import com.android.internal.widget.PointerLocationView;
import com.android.server.GestureLauncherService;
import com.android.server.LocalServices;
@@ -6247,6 +6245,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
case KeyEvent.KEYCODE_POWER: {
+ EventLogTags.writeInterceptPower(
+ KeyEvent.actionToString(event.getAction()),
+ mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
@@ -6785,7 +6786,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the PowerManager's Notifier thread.
@Override
public void finishedGoingToSleep(int why) {
- EventLog.writeEvent(70000, 0);
+ EventLogTags.writeScreenToggled(0);
if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
@@ -6810,7 +6811,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the PowerManager's Notifier thread.
@Override
public void startedWakingUp() {
- EventLog.writeEvent(70000, 1);
+ EventLogTags.writeScreenToggled(1);
if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
// Since goToSleep performs these functions synchronously, we must
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index bf349efba11f..c62be3ba2a05 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -32,6 +32,7 @@ import android.content.IntentSender;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.net.INetworkStatsService;
import android.net.NetworkStats;
import android.net.wifi.IWifiManager;
import android.net.wifi.WifiActivityEnergyInfo;
@@ -63,7 +64,6 @@ import android.util.Slog;
import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.os.KernelCpuSpeedReader;
import com.android.internal.os.KernelUidCpuTimeReader;
import com.android.internal.os.KernelUidCpuClusterTimeReader;
@@ -123,6 +123,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private final Context mContext;
private final AlarmManager mAlarmManager;
+ private final INetworkStatsService mNetworkStatsService;
@GuardedBy("sStatsdLock")
private static IStatsManager sStatsd;
private static final Object sStatsdLock = new Object();
@@ -162,6 +163,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
super();
mContext = context;
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ mNetworkStatsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
mAnomalyAlarmIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent(mContext, AnomalyAlarmReceiver.class), 0);
@@ -651,13 +654,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
if (ifaces.length == 0) {
return;
}
- NetworkStatsFactory nsf = new NetworkStatsFactory();
+ if (mNetworkStatsService == null) {
+ Slog.e(TAG, "NetworkStats Service is not available!");
+ return;
+ }
// Combine all the metrics per Uid into one record.
- NetworkStats stats =
- nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
- .groupedByUid();
+ NetworkStats stats = mNetworkStatsService.getDetailedUidStats(ifaces).groupedByUid();
addNetworkStats(tagId, pulledData, stats, false);
- } catch (java.io.IOException e) {
+ } catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for wifi bytes has error", e);
} finally {
Binder.restoreCallingIdentity(token);
@@ -672,11 +676,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
if (ifaces.length == 0) {
return;
}
- NetworkStatsFactory nsf = new NetworkStatsFactory();
+ if (mNetworkStatsService == null) {
+ Slog.e(TAG, "NetworkStats Service is not available!");
+ return;
+ }
NetworkStats stats = rollupNetworkStatsByFGBG(
- nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
+ mNetworkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(tagId, pulledData, stats, true);
- } catch (java.io.IOException e) {
+ } catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
} finally {
Binder.restoreCallingIdentity(token);
@@ -691,13 +698,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
if (ifaces.length == 0) {
return;
}
- NetworkStatsFactory nsf = new NetworkStatsFactory();
+ if (mNetworkStatsService == null) {
+ Slog.e(TAG, "NetworkStats Service is not available!");
+ return;
+ }
// Combine all the metrics per Uid into one record.
- NetworkStats stats =
- nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
- .groupedByUid();
+ NetworkStats stats = mNetworkStatsService.getDetailedUidStats(ifaces).groupedByUid();
addNetworkStats(tagId, pulledData, stats, false);
- } catch (java.io.IOException e) {
+ } catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes has error", e);
} finally {
Binder.restoreCallingIdentity(token);
@@ -726,11 +734,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
if (ifaces.length == 0) {
return;
}
- NetworkStatsFactory nsf = new NetworkStatsFactory();
+ if (mNetworkStatsService == null) {
+ Slog.e(TAG, "NetworkStats Service is not available!");
+ return;
+ }
NetworkStats stats = rollupNetworkStatsByFGBG(
- nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
+ mNetworkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(tagId, pulledData, stats, true);
- } catch (java.io.IOException e) {
+ } catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
} finally {
Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 22ac65df4337..1fb28e1969a8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3703,13 +3703,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
.show(mSplitScreenDividerAnchor);
scheduleAnimation();
} else {
- mAppAnimationLayer.destroy();
+ // At this time mBoostedAppAnimationLayer may be used for animating,
+ // and ResizeableActivity is in it. mBoostedAppAnimationLayer.destroy()
+ // can also destroy the surface of ResizeableActivity, but the surface will
+ // be used after. So change to use transaction to call destroy to delay it,
+ // and ResizeableActivity is not in mBoostedAppAnimationLayer.
+ getPendingTransaction()
+ .destroy(mAppAnimationLayer)
+ .destroy(mBoostedAppAnimationLayer)
+ .destroy(mHomeAppAnimationLayer)
+ .destroy(mSplitScreenDividerAnchor);
mAppAnimationLayer = null;
- mBoostedAppAnimationLayer.destroy();
mBoostedAppAnimationLayer = null;
- mHomeAppAnimationLayer.destroy();
mHomeAppAnimationLayer = null;
- mSplitScreenDividerAnchor.destroy();
mSplitScreenDividerAnchor = null;
}
}
diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp
index 5e1ea897b86e..98e4343e6e57 100644
--- a/services/core/xsd/Android.bp
+++ b/services/core/xsd/Android.bp
@@ -2,5 +2,5 @@ xsd_config {
name: "default-permissions",
srcs: ["default-permissions.xsd"],
api_dir: "schema",
- package_name: "com.android.server.pm.permission",
+ package_name: "com.android.server.pm.permission.configfile",
}
diff --git a/services/core/xsd/default-permissions.xsd b/services/core/xsd/default-permissions.xsd
index d800a26cdceb..2e32be0009ba 100644
--- a/services/core/xsd/default-permissions.xsd
+++ b/services/core/xsd/default-permissions.xsd
@@ -27,7 +27,7 @@
</xs:element>
<xs:complexType name="exception">
<xs:sequence>
- <xs:element name="permission" type="permission"/>
+ <xs:element name="permission" type="permission" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="package" type="xs:string"/>
<xs:attribute name="sha256-cert-digest" type="xs:string"/>
diff --git a/services/core/xsd/schema/current.txt b/services/core/xsd/schema/current.txt
index 4e67e5c235a0..a2092e3a99dc 100644
--- a/services/core/xsd/schema/current.txt
+++ b/services/core/xsd/schema/current.txt
@@ -1,21 +1,20 @@
// Signature format: 2.0
-package com.android.server.pm.permission {
+package com.android.server.pm.permission.configfile {
public class Exception {
ctor public Exception();
method public String getBrand();
- method public com.android.server.pm.permission.Permission getPermission();
+ method public java.util.List<com.android.server.pm.permission.configfile.Permission> getPermission();
method public String getSha256CertDigest();
method public String get_package();
method public void setBrand(String);
- method public void setPermission(com.android.server.pm.permission.Permission);
method public void setSha256CertDigest(String);
method public void set_package(String);
}
public class Exceptions {
ctor public Exceptions();
- method public java.util.List<com.android.server.pm.permission.Exception> getException();
+ method public java.util.List<com.android.server.pm.permission.configfile.Exception> getException();
}
public class Permission {
@@ -28,7 +27,7 @@ package com.android.server.pm.permission {
public class XmlParser {
ctor public XmlParser();
- method public static com.android.server.pm.permission.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static com.android.server.pm.permission.configfile.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
}
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 9e1d44b9faff..8f48f5b3d292 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -25,7 +25,6 @@ aidl_interface {
local_include_dir: "java",
include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
srcs: [
- "java/android/net/ApfCapabilitiesParcelable.aidl",
"java/android/net/DhcpResultsParcelable.aidl",
"java/android/net/IIpMemoryStore.aidl",
"java/android/net/IIpMemoryStoreCallbacks.aidl",
@@ -36,7 +35,6 @@ aidl_interface {
"java/android/net/InitialConfigurationParcelable.aidl",
"java/android/net/PrivateDnsConfigParcel.aidl",
"java/android/net/ProvisioningConfigurationParcelable.aidl",
- "java/android/net/StaticIpConfigurationParcelable.aidl",
"java/android/net/TcpKeepalivePacketDataParcelable.aidl",
"java/android/net/dhcp/DhcpServingParamsParcel.aidl",
"java/android/net/dhcp/IDhcpServer.aidl",
@@ -60,6 +58,7 @@ java_library_static {
name: "services.net",
srcs: ["java/**/*.java"],
static_libs: [
+ "dnsresolver_aidl_interface-java",
"netd_aidl_interface-java",
"networkstack-aidl-interfaces-java",
]
@@ -71,7 +70,7 @@ java_library_static {
srcs: [
":framework-annotations",
"java/android/net/IpMemoryStoreClient.java",
- "java/android/net/ipmemorystore/**.java",
+ "java/android/net/ipmemorystore/**/*.java",
],
static_libs: [
"ipmemorystore-aidl-interfaces-java",
diff --git a/services/net/java/android/net/DhcpResultsParcelable.aidl b/services/net/java/android/net/DhcpResultsParcelable.aidl
index cf5629b6f792..978638b51ad1 100644
--- a/services/net/java/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/java/android/net/DhcpResultsParcelable.aidl
@@ -16,10 +16,10 @@
package android.net;
-import android.net.StaticIpConfigurationParcelable;
+import android.net.StaticIpConfiguration;
parcelable DhcpResultsParcelable {
- StaticIpConfigurationParcelable baseConfiguration;
+ StaticIpConfiguration baseConfiguration;
int leaseDuration;
int mtu;
String serverAddress;
diff --git a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
index 5b46d7f55ee3..99606fb4b7a2 100644
--- a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
@@ -17,10 +17,10 @@
package android.net;
-import android.net.ApfCapabilitiesParcelable;
import android.net.InitialConfigurationParcelable;
import android.net.Network;
-import android.net.StaticIpConfigurationParcelable;
+import android.net.StaticIpConfiguration;
+import android.net.apf.ApfCapabilities;
parcelable ProvisioningConfigurationParcelable {
boolean enableIPv4;
@@ -29,8 +29,8 @@ parcelable ProvisioningConfigurationParcelable {
boolean usingIpReachabilityMonitor;
int requestedPreDhcpActionMs;
InitialConfigurationParcelable initialConfig;
- StaticIpConfigurationParcelable staticIpConfig;
- ApfCapabilitiesParcelable apfCapabilities;
+ StaticIpConfiguration staticIpConfig;
+ ApfCapabilities apfCapabilities;
int provisioningTimeoutMs;
int ipv6AddrGenMode;
Network network;
diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java
index d79ad1fe41a9..7f2f499ab21f 100644
--- a/services/net/java/android/net/TcpKeepalivePacketData.java
+++ b/services/net/java/android/net/TcpKeepalivePacketData.java
@@ -38,7 +38,7 @@ import java.util.Objects;
public class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
private static final String TAG = "TcpKeepalivePacketData";
- /** TCP sequence number. */
+ /** TCP sequence number. */
public final int tcpSeq;
/** TCP ACK number. */
@@ -50,6 +50,12 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
/** TCP RCV window scale. */
public final int tcpWndScale;
+ /** IP TOS. */
+ public final int ipTos;
+
+ /** IP TTL. */
+ public final int ipTtl;
+
private static final int IPV4_HEADER_LENGTH = 20;
private static final int IPV6_HEADER_LENGTH = 40;
private static final int TCP_HEADER_LENGTH = 20;
@@ -65,6 +71,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
// In the packet, the window is shifted right by the window scale.
tcpWnd = tcpDetails.rcvWnd;
tcpWndScale = tcpDetails.rcvWndScale;
+ ipTos = tcpDetails.tos;
+ ipTtl = tcpDetails.ttl;
}
/**
@@ -98,12 +106,11 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
ByteBuffer buf = ByteBuffer.allocate(length);
buf.order(ByteOrder.BIG_ENDIAN);
- // IP version and TOS. TODO : fetch this from getsockopt(SOL_IP, IP_TOS)
- buf.putShort((short) 0x4500);
+ buf.put((byte) 0x45); // IP version and IHL
+ buf.put((byte) tcpDetails.tos); // TOS
buf.putShort((short) length);
- buf.putInt(0x4000); // ID, flags=DF, offset
- // TODO : fetch TTL from getsockopt(SOL_IP, IP_TTL)
- buf.put((byte) 64);
+ buf.putInt(0x00004000); // ID, flags=DF, offset
+ buf.put((byte) tcpDetails.ttl); // TTL
buf.put((byte) OsConstants.IPPROTO_TCP);
final int ipChecksumOffset = buf.position();
buf.putShort((short) 0); // IP checksum
@@ -117,7 +124,9 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size
final int tcpChecksumOffset = buf.position();
buf.putShort((short) 0); // TCP checksum
- // URG is not set therefore the urgent pointer is not included
+ // URG is not set therefore the urgent pointer is zero.
+ buf.putShort((short) 0); // Urgent pointer
+
buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum(
buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH));
@@ -138,13 +147,15 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
&& this.tcpAck == other.tcpAck
&& this.tcpSeq == other.tcpSeq
&& this.tcpWnd == other.tcpWnd
- && this.tcpWndScale == other.tcpWndScale;
+ && this.tcpWndScale == other.tcpWndScale
+ && this.ipTos == other.ipTos
+ && this.ipTtl == other.ipTtl;
}
@Override
public int hashCode() {
return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
- tcpWndScale);
+ tcpWndScale, ipTos, ipTtl);
}
/**
@@ -164,6 +175,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
out.writeInt(tcpAck);
out.writeInt(tcpWnd);
out.writeInt(tcpWndScale);
+ out.writeInt(ipTos);
+ out.writeInt(ipTtl);
}
private TcpKeepalivePacketData(Parcel in) {
@@ -172,6 +185,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
tcpAck = in.readInt();
tcpWnd = in.readInt();
tcpWndScale = in.readInt();
+ ipTos = in.readInt();
+ ipTtl = in.readInt();
}
/** Parcelable Creator. */
@@ -200,6 +215,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
parcel.ack = tcpAck;
parcel.rcvWnd = tcpWnd;
parcel.rcvWndScale = tcpWndScale;
+ parcel.tos = ipTos;
+ parcel.ttl = ipTtl;
return parcel;
}
@@ -212,6 +229,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
+ " seq: " + tcpSeq
+ " ack: " + tcpAck
+ " wnd: " + tcpWnd
- + " wndScale: " + tcpWndScale;
+ + " wndScale: " + tcpWndScale
+ + " tos: " + ipTos
+ + " ttl: " + ipTtl;
}
}
diff --git a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
index d66b6ae3ab54..e25168d588e7 100644
--- a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -25,4 +25,6 @@ parcelable TcpKeepalivePacketDataParcelable {
int ack;
int rcvWnd;
int rcvWndScale;
+ int tos;
+ int ttl;
}
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
index 6b5826f8b095..44d8e0ce3635 100644
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
@@ -16,17 +16,10 @@
package android.net.shared;
-import static android.net.shared.ParcelableUtil.fromParcelableArray;
-import static android.net.shared.ParcelableUtil.toParcelableArray;
-
import android.annotation.Nullable;
-import android.net.ApfCapabilitiesParcelable;
import android.net.DhcpResults;
import android.net.DhcpResultsParcelable;
import android.net.InetAddresses;
-import android.net.StaticIpConfiguration;
-import android.net.StaticIpConfigurationParcelable;
-import android.net.apf.ApfCapabilities;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -38,44 +31,12 @@ import java.net.InetAddress;
*/
public final class IpConfigurationParcelableUtil {
/**
- * Convert a StaticIpConfiguration to a StaticIpConfigurationParcelable.
- */
- public static StaticIpConfigurationParcelable toStableParcelable(
- @Nullable StaticIpConfiguration config) {
- if (config == null) return null;
- final StaticIpConfigurationParcelable p = new StaticIpConfigurationParcelable();
- p.ipAddress = config.getIpAddress();
- p.gateway = parcelAddress(config.getGateway());
- p.dnsServers = toParcelableArray(
- config.getDnsServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
- p.domains = config.getDomains();
- return p;
- }
-
- /**
- * Convert a StaticIpConfigurationParcelable to a StaticIpConfiguration.
- */
- public static StaticIpConfiguration fromStableParcelable(
- @Nullable StaticIpConfigurationParcelable p) {
- if (p == null) return null;
- final StaticIpConfiguration config = new StaticIpConfiguration();
- config.setIpAddress(p.ipAddress);
- config.setGateway(unparcelAddress(p.gateway));
- for (InetAddress addr : fromParcelableArray(
- p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress)) {
- config.addDnsServer(addr);
- }
- config.setDomains(p.domains);
- return config;
- }
-
- /**
* Convert DhcpResults to a DhcpResultsParcelable.
*/
public static DhcpResultsParcelable toStableParcelable(@Nullable DhcpResults results) {
if (results == null) return null;
final DhcpResultsParcelable p = new DhcpResultsParcelable();
- p.baseConfiguration = toStableParcelable(results.toStaticIpConfiguration());
+ p.baseConfiguration = results.toStaticIpConfiguration();
p.leaseDuration = results.leaseDuration;
p.mtu = results.mtu;
p.serverAddress = parcelAddress(results.serverAddress);
@@ -88,7 +49,7 @@ public final class IpConfigurationParcelableUtil {
*/
public static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
if (p == null) return null;
- final DhcpResults results = new DhcpResults(fromStableParcelable(p.baseConfiguration));
+ final DhcpResults results = new DhcpResults(p.baseConfiguration);
results.leaseDuration = p.leaseDuration;
results.mtu = p.mtu;
results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
@@ -97,27 +58,6 @@ public final class IpConfigurationParcelableUtil {
}
/**
- * Convert ApfCapabilities to ApfCapabilitiesParcelable.
- */
- public static ApfCapabilitiesParcelable toStableParcelable(@Nullable ApfCapabilities caps) {
- if (caps == null) return null;
- final ApfCapabilitiesParcelable p = new ApfCapabilitiesParcelable();
- p.apfVersionSupported = caps.apfVersionSupported;
- p.maximumApfProgramSize = caps.maximumApfProgramSize;
- p.apfPacketFormat = caps.apfPacketFormat;
- return p;
- }
-
- /**
- * Convert ApfCapabilitiesParcelable toApfCapabilities.
- */
- public static ApfCapabilities fromStableParcelable(@Nullable ApfCapabilitiesParcelable p) {
- if (p == null) return null;
- return new ApfCapabilities(
- p.apfVersionSupported, p.maximumApfProgramSize, p.apfPacketFormat);
- }
-
- /**
* Convert InetAddress to String.
* TODO: have an InetAddressParcelable
*/
diff --git a/services/net/java/android/net/shared/NetworkMonitorUtils.java b/services/net/java/android/net/shared/NetworkMonitorUtils.java
index 3d2a2de45539..a17cb4647158 100644
--- a/services/net/java/android/net/shared/NetworkMonitorUtils.java
+++ b/services/net/java/android/net/shared/NetworkMonitorUtils.java
@@ -44,18 +44,14 @@ public class NetworkMonitorUtils {
public static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
"android.permission.ACCESS_NETWORK_CONDITIONS";
- // TODO: once the URL is a resource overlay, remove and have the resource define the default
- private static final String DEFAULT_HTTP_URL =
- "http://connectivitycheck.gstatic.com/generate_204";
-
/**
* Get the captive portal server HTTP URL that is configured on the device.
*/
- public static String getCaptivePortalServerHttpUrl(Context context) {
+ public static String getCaptivePortalServerHttpUrl(Context context, String defaultUrl) {
final String settingUrl = Settings.Global.getString(
context.getContentResolver(),
Settings.Global.CAPTIVE_PORTAL_HTTP_URL);
- return settingUrl != null ? settingUrl : DEFAULT_HTTP_URL;
+ return settingUrl != null ? settingUrl : defaultUrl;
}
/**
diff --git a/services/net/java/android/net/shared/ProvisioningConfiguration.java b/services/net/java/android/net/shared/ProvisioningConfiguration.java
index 0aceb2278660..6f9c2949d864 100644
--- a/services/net/java/android/net/shared/ProvisioningConfiguration.java
+++ b/services/net/java/android/net/shared/ProvisioningConfiguration.java
@@ -235,8 +235,10 @@ public class ProvisioningConfiguration {
p.usingIpReachabilityMonitor = mUsingIpReachabilityMonitor;
p.requestedPreDhcpActionMs = mRequestedPreDhcpActionMs;
p.initialConfig = mInitialConfig == null ? null : mInitialConfig.toStableParcelable();
- p.staticIpConfig = IpConfigurationParcelableUtil.toStableParcelable(mStaticIpConfig);
- p.apfCapabilities = IpConfigurationParcelableUtil.toStableParcelable(mApfCapabilities);
+ p.staticIpConfig = mStaticIpConfig == null
+ ? null
+ : new StaticIpConfiguration(mStaticIpConfig);
+ p.apfCapabilities = mApfCapabilities; // ApfCapabilities is immutable
p.provisioningTimeoutMs = mProvisioningTimeoutMs;
p.ipv6AddrGenMode = mIPv6AddrGenMode;
p.network = mNetwork;
@@ -257,10 +259,10 @@ public class ProvisioningConfiguration {
config.mUsingIpReachabilityMonitor = p.usingIpReachabilityMonitor;
config.mRequestedPreDhcpActionMs = p.requestedPreDhcpActionMs;
config.mInitialConfig = InitialConfiguration.fromStableParcelable(p.initialConfig);
- config.mStaticIpConfig = IpConfigurationParcelableUtil.fromStableParcelable(
- p.staticIpConfig);
- config.mApfCapabilities = IpConfigurationParcelableUtil.fromStableParcelable(
- p.apfCapabilities);
+ config.mStaticIpConfig = p.staticIpConfig == null
+ ? null
+ : new StaticIpConfiguration(p.staticIpConfig);
+ config.mApfCapabilities = p.apfCapabilities; // ApfCapabilities is immutable
config.mProvisioningTimeoutMs = p.provisioningTimeoutMs;
config.mIPv6AddrGenMode = p.ipv6AddrGenMode;
config.mNetwork = p.network;
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
index d75a3fc8d20b..01644737f55f 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
@@ -43,8 +43,11 @@ import org.junit.runner.RunWith;
/**
* Tests for exercising resizing bounds due to activity options.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:ActivityLaunchParamsModifierTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index 5ee7477b486c..af0aaf31cd59 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -30,16 +30,15 @@ import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
-import static junit.framework.TestCase.assertNotNull;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -62,8 +61,11 @@ import org.mockito.invocation.InvocationOnMock;
/**
* Tests for the {@link ActivityRecord} class.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:com.android.server.am.ActivityRecordTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index f36c57973240..b0f949132c3e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -27,15 +27,14 @@ import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
-import static com.android.server.am.ActivityStackSupervisor
- .MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -62,8 +61,11 @@ import java.util.ArrayList;
/**
* Tests for the {@link ActivityStackSupervisor} class.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index be0c689ab89f..d89bc976e73f 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -33,7 +33,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -51,8 +51,11 @@ import org.junit.runner.RunWith;
/**
* Tests for the {@link ActivityStack} class.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@SmallTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index 3464ac2a3044..e84e354dbb8f 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -19,8 +19,8 @@ package com.android.server.am;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -43,8 +43,11 @@ import java.util.Random;
/**
* Tests for the {@link ActivityStartController} class.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:ActivityStartControllerTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@SmallTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index d1550d736e0b..1c83ded3cb9e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -55,8 +55,11 @@ import org.mockito.MockitoAnnotations;
/**
* Unit tests for {@link ActivityStartInterceptorTest}.
*
- * Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:ActivityStartInterceptorTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@SmallTest
public class ActivityStartInterceptorTest {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index f956a364315b..1e127a9863e6 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -39,14 +39,14 @@ import static com.android.server.am.ActivityManagerService.ANIMATE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyObject;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -80,8 +80,11 @@ import org.junit.runner.RunWith;
/**
* Tests for the {@link ActivityStarter} class.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:ActivityStarterTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@SmallTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index d985364a7cee..2e1155e0a905 100644
--- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -64,7 +64,11 @@ import java.util.concurrent.TimeUnit;
* Note: Currently, we only support fetching the screenshot for the current application, so the
* screenshot checks are hardcoded accordingly.
*
- * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:AssistDataRequesterTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@FlakyTest(bugId = 113616538)
diff --git a/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
index b4ad183db386..f882b63acfce 100644
--- a/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
@@ -16,6 +16,15 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link ClientLifecycleManager}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:ClientLifecycleManagerTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
index 8d675dd3032d..d24991ebc539 100644
--- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -24,10 +24,10 @@ import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -51,8 +51,11 @@ import org.junit.runner.RunWith;
/**
* Tests for exercising {@link LaunchParamsController}.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:LaunchParamsControllerTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
index f5f507f8b210..b52ce1702488 100644
--- a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
@@ -38,7 +38,13 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
- * atest PendingRemoteAnimationRegistryTest
+ * Tests for {@link PendingRemoteAnimationRegistry}.
+ *
+ * <p>Build/Install/Run:
+ * atest PendingRemoteAnimationRegistryTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@SmallTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index aa9123b16aa7..c61054099282 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -76,7 +76,13 @@ import java.util.Random;
import java.util.Set;
/**
- * atest FrameworksServicesTests:RecentTasksTest
+ * Tests for {@link RecentTasks}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:RecentTasksTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
index fa6a95ce275c..edc623589f4b 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
@@ -22,9 +22,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
-import static org.mockito.Mockito.any;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -46,7 +46,13 @@ import org.junit.Test;
import org.junit.runner.RunWith;
/**
- * atest FrameworksServicesTests:RecentsAnimationTest
+ * Tests for recent tasks animation.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:RecentsAnimationTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
index 19288a9c28d7..c38a594c1038 100644
--- a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
@@ -43,7 +43,13 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
/**
- * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
+ * Tests for {@link RunningTasks}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:RunningTasksTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
@@ -124,4 +130,4 @@ public class RunningTasksTest extends ActivityTestsBase {
.build();
return task;
}
-} \ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
index 8e4e7e6b63c3..03d17375298f 100644
--- a/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
@@ -28,6 +28,15 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link SafeActivityOptions}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:SafeActivityOptionsTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@MediumTest
@Presubmit
@FlakyTest
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
index eec55b162b3e..fc9db14d5834 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
@@ -38,8 +38,11 @@ import org.junit.runner.RunWith;
/**
* Tests for exercising resizing task bounds.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:TaskLaunchParamsModifierTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
index 9e6055d55e0f..976e8355128e 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -30,7 +30,13 @@ import java.io.File;
import java.util.Random;
/**
- * atest FrameworksServicesTests:TaskPersisterTest
+ * Tests for {@link TaskPersister}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:TaskPersisterTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
public class TaskPersisterTest extends AndroidTestCase {
private static final String TEST_USER_NAME = "AM-Test-User";
@@ -85,4 +91,4 @@ public class TaskPersisterTest extends AndroidTestCase {
fail("Error while removing the test user: " + TEST_USER_NAME);
}
}
-} \ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
index 5aecec005fdb..eada2ce4f004 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -59,8 +59,11 @@ import java.util.ArrayList;
/**
* Tests for exercising {@link TaskRecord}.
*
- * Build/Install/Run:
+ * <p>Build/Install/Run:
* atest FrameworksServicesTests:com.android.server.am.TaskRecordTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
*/
@MediumTest
@Presubmit
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index 9406160b52ca..814071445df8 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -52,6 +52,15 @@ import org.junit.runner.RunWith;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+/**
+ * Tests for {@link TaskStackListener}.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksServicesTests:TaskStackChangedListenerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class TaskStackChangedListenerTest {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index da682c6df621..e949e7490230 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -855,7 +855,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
&& status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE,
UsbPort.DATA_ROLE_DEVICE)
&& status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
- UsbPort.DATA_ROLE_HOST);
+ UsbPort.DATA_ROLE_DEVICE);
args.recycle();
updateUsbNotification(false);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 558d8d495d5c..06c85d27d880 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -33,7 +33,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -45,7 +44,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.Executor;
/**
* Provides access to information about active calls and registration/call-management functionality.
@@ -477,6 +475,12 @@ public class TelecomManager {
"android.telecom.extra.START_CALL_WITH_RTT";
/**
+ * A boolean extra set to indicate whether an app is eligible to be bound to when there are
+ * ongoing calls on the device.
+ */
+ public static final String EXTRA_IS_ENABLED = "android.telecom.extra.IS_ENABLED";
+
+ /**
* A boolean meta-data value indicating whether an {@link InCallService} implements an
* in-call user interface. Dialer implementations (see {@link #getDefaultDialerPackage()}) which
* would also like to replace the in-call interface should set this meta-data to {@code true} in
@@ -487,9 +491,7 @@ public class TelecomManager {
/**
* A boolean meta-data value indicating whether an {@link InCallService} implements an
* in-call user interface to be used while the device is in car-mode (see
- * {@link android.content.res.Configuration.UI_MODE_TYPE_CAR}).
- *
- * @hide
+ * {@link android.content.res.Configuration#UI_MODE_TYPE_CAR}).
*/
public static final String METADATA_IN_CALL_SERVICE_CAR_MODE_UI =
"android.telecom.IN_CALL_SERVICE_CAR_MODE_UI";
@@ -2041,7 +2043,6 @@ public class TelecomManager {
} catch (RemoteException e) {
Log.e(TAG, "RemoteException handleCallIntent: " + e);
}
-
}
private ITelecomService getTelecomService() {
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 81553a3bc0f8..afa35b4d4de3 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -18,6 +18,7 @@ package android.telephony;
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -51,6 +52,7 @@ public final class AccessNetworkConstants {
* @hide
*/
@SystemApi
+ @TestApi
public static final int TRANSPORT_TYPE_WWAN = 1;
/**
@@ -58,6 +60,7 @@ public final class AccessNetworkConstants {
* @hide
*/
@SystemApi
+ @TestApi
public static final int TRANSPORT_TYPE_WLAN = 2;
/** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5e9d33a86760..4776aa179478 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1844,6 +1844,14 @@ public class CarrierConfigManager {
"editable_wfc_roaming_mode_bool";
/**
+ * Flag specifying wether to show blocking pay phone option in blocked numbers screen. Only show
+ * the option if payphone call presentation represents in the carrier's region.
+ * @hide
+ */
+ public static final java.lang.String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL =
+ "show_blocking_pay_phone_option_bool";
+
+ /**
* Flag specifying whether the carrier will use the WFC home network mode in roaming network.
* {@code false} - roaming preference can be selected separately from the home preference.
* {@code true} - roaming preference is the same as home preference and
@@ -2482,6 +2490,18 @@ public class CarrierConfigManager {
"emergency_number_prefix_string_array";
/**
+ * Indicates when a carrier has a primary subscription and an opportunistic subscription active,
+ * and when Internet data is switched to opportunistic network, whether to still show
+ * signal bar of primary network. By default it will be false, meaning whenever data
+ * is going over opportunistic network, signal bar will reflect signal strength and rat
+ * icon of that network.
+ *
+ * @hide
+ */
+ public static final String KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN =
+ "always_show_primary_signal_bar_in_opportunistic_network_boolean";
+
+ /**
* Determines whether the carrier wants to cancel the cs reject notification automatically
* when the voice registration state changes.
* If true, the notification will be automatically removed
@@ -2826,6 +2846,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
+ sDefaults.putBoolean(KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL, false);
sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
sDefaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true);
@@ -2894,14 +2915,14 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_DIALER_SHORTCUT_BOOL, true);
sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false);
- /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */
- sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108);
/* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */
- sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -118);
- /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_GOOD */
- sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 45);
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -118);
+ /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_POOR */
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -128);
/* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_MODERATE */
- sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 10);
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 10);
+ /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_POOR */
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, -30);
/* Default value is 1024 kbps */
sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_BANDWIDTH_INT, 1024);
/* Default value is 10 seconds */
@@ -2916,6 +2937,8 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING,
"connected_mmwave:None,connected:5G,not_restricted:None,restricted:None");
sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
+ sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
+ false);
}
/**
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index c3387f3f112d..fbf488e590fd 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -1,7 +1,24 @@
+/*
+ * Copyright 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.
+ */
+
package android.telephony;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -13,7 +30,8 @@ import java.util.Objects;
* @hide
*/
@SystemApi
-public final class DataSpecificRegistrationStates implements Parcelable{
+@TestApi
+public final class DataSpecificRegistrationInfo implements Parcelable {
/**
* @hide
* The maximum number of simultaneous Data Calls that
@@ -53,27 +71,27 @@ public final class DataSpecificRegistrationStates implements Parcelable{
/**
* Provides network support info for LTE VoPS and LTE Emergency bearer support
*/
- private final LteVopsSupportInfo lteVopsSupportInfo;
+ private final LteVopsSupportInfo mLteVopsSupportInfo;
/**
* @hide
*/
- DataSpecificRegistrationStates(
+ DataSpecificRegistrationInfo(
int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
boolean isEnDcAvailable, LteVopsSupportInfo lteVops) {
this.maxDataCalls = maxDataCalls;
this.isDcNrRestricted = isDcNrRestricted;
this.isNrAvailable = isNrAvailable;
this.isEnDcAvailable = isEnDcAvailable;
- this.lteVopsSupportInfo = lteVops;
+ this.mLteVopsSupportInfo = lteVops;
}
- private DataSpecificRegistrationStates(Parcel source) {
+ private DataSpecificRegistrationInfo(Parcel source) {
maxDataCalls = source.readInt();
isDcNrRestricted = source.readBoolean();
isNrAvailable = source.readBoolean();
isEnDcAvailable = source.readBoolean();
- lteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+ mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
}
@Override
@@ -82,7 +100,7 @@ public final class DataSpecificRegistrationStates implements Parcelable{
dest.writeBoolean(isDcNrRestricted);
dest.writeBoolean(isNrAvailable);
dest.writeBoolean(isEnDcAvailable);
- lteVopsSupportInfo.writeToParcel(dest, flags);
+ mLteVopsSupportInfo.writeToParcel(dest, flags);
}
@Override
@@ -98,7 +116,7 @@ public final class DataSpecificRegistrationStates implements Parcelable{
.append(" isDcNrRestricted = " + isDcNrRestricted)
.append(" isNrAvailable = " + isNrAvailable)
.append(" isEnDcAvailable = " + isEnDcAvailable)
- .append(lteVopsSupportInfo.toString())
+ .append(mLteVopsSupportInfo.toString())
.append(" }")
.toString();
}
@@ -106,41 +124,41 @@ public final class DataSpecificRegistrationStates implements Parcelable{
@Override
public int hashCode() {
return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
- lteVopsSupportInfo);
+ mLteVopsSupportInfo);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof DataSpecificRegistrationStates)) return false;
+ if (!(o instanceof DataSpecificRegistrationInfo)) return false;
- DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
+ DataSpecificRegistrationInfo other = (DataSpecificRegistrationInfo) o;
return this.maxDataCalls == other.maxDataCalls
&& this.isDcNrRestricted == other.isDcNrRestricted
&& this.isNrAvailable == other.isNrAvailable
&& this.isEnDcAvailable == other.isEnDcAvailable
- && this.lteVopsSupportInfo.equals(other.lteVopsSupportInfo);
+ && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo);
}
- public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
- new Parcelable.Creator<DataSpecificRegistrationStates>() {
+ public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
+ new Parcelable.Creator<DataSpecificRegistrationInfo>() {
@Override
- public DataSpecificRegistrationStates createFromParcel(Parcel source) {
- return new DataSpecificRegistrationStates(source);
+ public DataSpecificRegistrationInfo createFromParcel(Parcel source) {
+ return new DataSpecificRegistrationInfo(source);
}
@Override
- public DataSpecificRegistrationStates[] newArray(int size) {
- return new DataSpecificRegistrationStates[size];
+ public DataSpecificRegistrationInfo[] newArray(int size) {
+ return new DataSpecificRegistrationInfo[size];
}
};
/**
- * @return LteVopsSupportInfo
+ * @return The LTE VOPS (Voice over Packet Switched) support information
*/
@NonNull
public LteVopsSupportInfo getLteVopsSupportInfo() {
- return lteVopsSupportInfo;
+ return mLteVopsSupportInfo;
}
}
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index 0ae85c0dfa6c..fda20bd4cf12 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -18,6 +18,7 @@ package android.telephony;
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,6 +31,7 @@ import java.util.Objects;
* @hide
*/
@SystemApi
+@TestApi
public final class LteVopsSupportInfo implements Parcelable {
/**@hide*/
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 9145b2532817..1dc29979dc61 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
@@ -38,6 +39,7 @@ import java.util.stream.Collectors;
* @hide
*/
@SystemApi
+@TestApi
public final class NetworkRegistrationInfo implements Parcelable {
/**
* Network domain
@@ -174,10 +176,10 @@ public final class NetworkRegistrationInfo implements Parcelable {
private CellIdentity mCellIdentity;
@Nullable
- private VoiceSpecificRegistrationStates mVoiceSpecificStates;
+ private VoiceSpecificRegistrationInfo mVoiceSpecificInfo;
@Nullable
- private DataSpecificRegistrationStates mDataSpecificStates;
+ private DataSpecificRegistrationInfo mDataSpecificInfo;
/**
* @param domain Network domain. Must be a {@link Domain}. For transport type
@@ -234,7 +236,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
emergencyOnly, availableServices, cellIdentity);
- mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
+ mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
systemIsInPrl, defaultRoamingIndicator);
}
@@ -253,9 +255,9 @@ public final class NetworkRegistrationInfo implements Parcelable {
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
emergencyOnly, availableServices, cellIdentity);
- mDataSpecificStates = new DataSpecificRegistrationStates(
+ mDataSpecificInfo = new DataSpecificRegistrationInfo(
maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
- updateNrState(mDataSpecificStates);
+ updateNrState(mDataSpecificInfo);
}
private NetworkRegistrationInfo(Parcel source) {
@@ -269,10 +271,10 @@ public final class NetworkRegistrationInfo implements Parcelable {
mAvailableServices = new ArrayList<>();
source.readList(mAvailableServices, Integer.class.getClassLoader());
mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
- mVoiceSpecificStates = source.readParcelable(
- VoiceSpecificRegistrationStates.class.getClassLoader());
- mDataSpecificStates = source.readParcelable(
- DataSpecificRegistrationStates.class.getClassLoader());
+ mVoiceSpecificInfo = source.readParcelable(
+ VoiceSpecificRegistrationInfo.class.getClassLoader());
+ mDataSpecificInfo = source.readParcelable(
+ DataSpecificRegistrationInfo.class.getClassLoader());
mNrState = source.readInt();
}
@@ -389,16 +391,16 @@ public final class NetworkRegistrationInfo implements Parcelable {
* @hide
*/
@Nullable
- public VoiceSpecificRegistrationStates getVoiceSpecificStates() {
- return mVoiceSpecificStates;
+ public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
+ return mVoiceSpecificInfo;
}
/**
* @return Data registration related info
*/
@Nullable
- public DataSpecificRegistrationStates getDataSpecificStates() {
- return mDataSpecificStates;
+ public DataSpecificRegistrationInfo getDataSpecificInfo() {
+ return mDataSpecificInfo;
}
@Override
@@ -474,8 +476,8 @@ public final class NetworkRegistrationInfo implements Parcelable {
? mAvailableServices.stream().map(type -> serviceTypeToString(type))
.collect(Collectors.joining(",")) : null) + "]")
.append(" cellIdentity=").append(mCellIdentity)
- .append(" voiceSpecificStates=").append(mVoiceSpecificStates)
- .append(" dataSpecificStates=").append(mDataSpecificStates)
+ .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
+ .append(" dataSpecificInfo=").append(mDataSpecificInfo)
.append(" nrState=").append(nrStateToString(mNrState))
.append("}").toString();
}
@@ -484,7 +486,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
public int hashCode() {
return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
- mCellIdentity, mVoiceSpecificStates, mDataSpecificStates, mNrState);
+ mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
}
@Override
@@ -505,8 +507,8 @@ public final class NetworkRegistrationInfo implements Parcelable {
&& mEmergencyOnly == other.mEmergencyOnly
&& mAvailableServices.equals(other.mAvailableServices)
&& Objects.equals(mCellIdentity, other.mCellIdentity)
- && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates)
- && Objects.equals(mDataSpecificStates, other.mDataSpecificStates)
+ && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
+ && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
&& mNrState == other.mNrState;
}
@@ -521,8 +523,8 @@ public final class NetworkRegistrationInfo implements Parcelable {
dest.writeBoolean(mEmergencyOnly);
dest.writeList(mAvailableServices);
dest.writeParcelable(mCellIdentity, 0);
- dest.writeParcelable(mVoiceSpecificStates, 0);
- dest.writeParcelable(mDataSpecificStates, 0);
+ dest.writeParcelable(mVoiceSpecificInfo, 0);
+ dest.writeParcelable(mDataSpecificInfo, 0);
dest.writeInt(mNrState);
}
@@ -543,7 +545,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
*
* @param state data specific registration state contains the 5G NR indicators.
*/
- private void updateNrState(DataSpecificRegistrationStates state) {
+ private void updateNrState(DataSpecificRegistrationInfo state) {
mNrState = NR_STATE_NONE;
if (state.isEnDcAvailable) {
if (!state.isDcNrRestricted && state.isNrAvailable) {
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index a500eba9fa2b..caf27b79dc13 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1132,7 +1132,7 @@ public class ServiceState implements Parcelable {
}
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @TestApi
public void setVoiceRoamingType(@RoamingType int type) {
NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1153,7 +1153,7 @@ public class ServiceState implements Parcelable {
}
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @TestApi
public void setDataRoamingType(@RoamingType int type) {
NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1855,6 +1855,7 @@ public class ServiceState implements Parcelable {
/**
* @hide
*/
+ @TestApi
public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
if (regState == null) return;
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index c39f1f5613b0..4d1b89c0e8ce 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -22,10 +22,6 @@ import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.PendingIntent;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothMapClient;
-import android.bluetooth.BluetoothProfile;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.Context;
@@ -36,7 +32,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.telecom.PhoneAccount;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -66,7 +61,6 @@ import java.util.Map;
*/
public final class SmsManager {
private static final String TAG = "SmsManager";
- private static final boolean DBG = false;
/**
* A psuedo-subId that represents the default subId at any given time. The actual subId it
@@ -347,42 +341,11 @@ public final class SmsManager {
throw new IllegalArgumentException("Invalid message body");
}
- // A Manager code accessing another manager is *not* acceptable, in Android.
- // In this particular case, it is unavoidable because of the following:
- // If the subscription for this SmsManager instance belongs to a remote SIM
- // then a listener to get BluetoothMapClient proxy needs to be started up.
- // Doing that is possible only in a foreground thread or as a system user.
- // i.e., Can't be done in ISms service.
- // For that reason, SubscriptionManager needs to be accessed here to determine
- // if the subscription belongs to a remote SIM.
- // Ideally, there should be another API in ISms to service messages going thru
- // remote SIM subscriptions (and ISms should be tweaked to be able to access
- // BluetoothMapClient proxy)
- Context context = ActivityThread.currentApplication().getApplicationContext();
- SubscriptionManager manager = (SubscriptionManager) context
- .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- int subId = getSubscriptionId();
- SubscriptionInfo info = manager.getActiveSubscriptionInfo(subId);
- if (DBG) {
- Log.d(TAG, "for subId: " + subId + ", subscription-info: " + info);
- }
-
- /* If the Subscription associated with this SmsManager instance belongs to a remote-sim,
- * then send the message thru the remote-sim subscription.
- */
- if (info != null
- && info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM) {
- if (DBG) Log.d(TAG, "sending message thru bluetooth");
- sendTextMessageBluetooth(destinationAddress, scAddress, text, sentIntent,
- deliveryIntent, info);
- return;
- }
-
try {
// If the subscription is invalid or default, we will use the default phone to send the
// SMS and possibly fail later in the SMS sending process.
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendTextForSubscriber(subId, ActivityThread.currentPackageName(),
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendTextForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
destinationAddress,
scAddress, text, sentIntent, deliveryIntent,
persistMessage);
@@ -391,82 +354,6 @@ public final class SmsManager {
}
}
- private void sendTextMessageBluetooth(String destAddr, String scAddress,
- String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
- SubscriptionInfo info) {
- BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
- if (btAdapter == null) {
- // No bluetooth service on this platform?
- sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
- return;
- }
- BluetoothDevice device = btAdapter.getRemoteDevice(info.getIccId());
- if (device == null) {
- if (DBG) Log.d(TAG, "Bluetooth device addr invalid: " + info.getIccId());
- sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
- return;
- }
- btAdapter.getProfileProxy(ActivityThread.currentApplication().getApplicationContext(),
- new MapMessageSender(destAddr, text, device, sentIntent, deliveryIntent),
- BluetoothProfile.MAP_CLIENT);
- }
-
- private class MapMessageSender implements BluetoothProfile.ServiceListener {
- final Uri[] mDestAddr;
- private String mMessage;
- final BluetoothDevice mDevice;
- final PendingIntent mSentIntent;
- final PendingIntent mDeliveryIntent;
- MapMessageSender(final String destAddr, final String message, final BluetoothDevice device,
- final PendingIntent sentIntent, final PendingIntent deliveryIntent) {
- super();
- mDestAddr = new Uri[] {new Uri.Builder()
- .appendPath(destAddr)
- .scheme(PhoneAccount.SCHEME_TEL)
- .build()};
- mMessage = message;
- mDevice = device;
- mSentIntent = sentIntent;
- mDeliveryIntent = deliveryIntent;
- }
-
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (DBG) Log.d(TAG, "Service connected");
- if (profile != BluetoothProfile.MAP_CLIENT) return;
- BluetoothMapClient mapProfile = (BluetoothMapClient) proxy;
- if (mMessage != null) {
- if (DBG) Log.d(TAG, "Sending message thru bluetooth");
- mapProfile.sendMessage(mDevice, mDestAddr, mMessage, mSentIntent, mDeliveryIntent);
- mMessage = null;
- }
- BluetoothAdapter.getDefaultAdapter()
- .closeProfileProxy(BluetoothProfile.MAP_CLIENT, mapProfile);
- }
-
- @Override
- public void onServiceDisconnected(int profile) {
- if (mMessage != null) {
- if (DBG) Log.d(TAG, "Bluetooth disconnected before sending the message");
- sendErrorInPendingIntent(mSentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
- mMessage = null;
- }
- }
- }
-
- private void sendErrorInPendingIntent(PendingIntent intent, int errorCode) {
- if (intent == null) {
- return;
- }
- try {
- intent.send(errorCode);
- } catch (PendingIntent.CanceledException e) {
- // PendingIntent is cancelled. ignore sending this error code back to
- // caller.
- if (DBG) Log.d(TAG, "PendingIntent.CanceledException: " + e.getMessage());
- }
- }
-
/**
* Send a text based SMS without writing it into the SMS Provider.
*
@@ -516,8 +403,8 @@ public final class SmsManager {
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(),
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(),
ActivityThread.currentPackageName(),
destinationAddress,
scAddress, text, sentIntent, deliveryIntent, persistMessage);
@@ -600,9 +487,9 @@ public final class SmsManager {
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- if (iccISms != null) {
- iccISms.sendTextForSubscriberWithOptions(getSubscriptionId(),
+ ISms iSms = getISmsServiceOrThrow();
+ if (iSms != null) {
+ iSms.sendTextForSubscriberWithOptions(getSubscriptionId(),
ActivityThread.currentPackageName(), destinationAddress, scAddress, text,
sentIntent, deliveryIntent, persistMessage, priority, expectMore,
validityPeriod);
@@ -661,9 +548,9 @@ public final class SmsManager {
"Invalid pdu format. format must be either 3gpp or 3gpp2");
}
try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- iccISms.injectSmsPduForSubscriber(
+ ISms iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iSms != null) {
+ iSms.injectSmsPduForSubscriber(
getSubscriptionId(), pdu, format, receivedIntent);
}
} catch (RemoteException ex) {
@@ -749,8 +636,8 @@ public final class SmsManager {
if (parts.size() > 1) {
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendMultipartTextForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendMultipartTextForSubscriber(getSubscriptionId(),
ActivityThread.currentPackageName(),
destinationAddress, scAddress, parts,
sentIntents, deliveryIntents, persistMessage);
@@ -881,9 +768,9 @@ public final class SmsManager {
if (parts.size() > 1) {
try {
- ISms iccISms = getISmsServiceOrThrow();
- if (iccISms != null) {
- iccISms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
+ ISms iSms = getISmsServiceOrThrow();
+ if (iSms != null) {
+ iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
ActivityThread.currentPackageName(), destinationAddress, scAddress,
parts, sentIntents, deliveryIntents, persistMessage, priority,
expectMore, validityPeriod);
@@ -969,8 +856,8 @@ public final class SmsManager {
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendDataForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendDataForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
destinationAddress, scAddress, destinationPort & 0xFFFF,
data, sentIntent, deliveryIntent);
} catch (RemoteException ex) {
@@ -996,8 +883,8 @@ public final class SmsManager {
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(),
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(),
ActivityThread.currentPackageName(), destinationAddress, scAddress,
destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
} catch (RemoteException ex) {
@@ -1059,9 +946,9 @@ public final class SmsManager {
boolean isSmsSimPickActivityNeeded = false;
final Context context = ActivityThread.currentApplication().getApplicationContext();
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- isSmsSimPickActivityNeeded = iccISms.isSmsSimPickActivityNeeded(subId);
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ isSmsSimPickActivityNeeded = iSms.isSmsSimPickActivityNeeded(subId);
}
} catch (RemoteException ex) {
Log.e(TAG, "Exception in getSubscriptionId");
@@ -1092,11 +979,11 @@ public final class SmsManager {
* the service does not exist.
*/
private static ISms getISmsServiceOrThrow() {
- ISms iccISms = getISmsService();
- if (iccISms == null) {
+ ISms iSms = getISmsService();
+ if (iSms == null) {
throw new UnsupportedOperationException("Sms is not supported");
}
- return iccISms;
+ return iSms;
}
private static ISms getISmsService() {
@@ -1125,9 +1012,9 @@ public final class SmsManager {
throw new IllegalArgumentException("pdu is NULL");
}
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
ActivityThread.currentPackageName(),
status, pdu, smsc);
}
@@ -1156,9 +1043,9 @@ public final class SmsManager {
Arrays.fill(pdu, (byte)0xff);
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
ActivityThread.currentPackageName(),
messageIndex, STATUS_ON_ICC_FREE, pdu);
}
@@ -1188,9 +1075,9 @@ public final class SmsManager {
boolean success = false;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
ActivityThread.currentPackageName(),
messageIndex, newStatus, pdu);
}
@@ -1215,9 +1102,9 @@ public final class SmsManager {
List<SmsRawData> records = null;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- records = iccISms.getAllMessagesFromIccEfForSubscriber(
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ records = iSms.getAllMessagesFromIccEfForSubscriber(
getSubscriptionId(),
ActivityThread.currentPackageName());
}
@@ -1252,9 +1139,9 @@ public final class SmsManager {
boolean success = false;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.enableCellBroadcastForSubscriber(
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.enableCellBroadcastForSubscriber(
getSubscriptionId(), messageIdentifier, ranType);
}
} catch (RemoteException ex) {
@@ -1288,9 +1175,9 @@ public final class SmsManager {
boolean success = false;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.disableCellBroadcastForSubscriber(
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.disableCellBroadcastForSubscriber(
getSubscriptionId(), messageIdentifier, ranType);
}
} catch (RemoteException ex) {
@@ -1331,9 +1218,9 @@ public final class SmsManager {
throw new IllegalArgumentException("endMessageId < startMessageId");
}
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(),
startMessageId, endMessageId, ranType);
}
} catch (RemoteException ex) {
@@ -1374,9 +1261,9 @@ public final class SmsManager {
throw new IllegalArgumentException("endMessageId < startMessageId");
}
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- success = iccISms.disableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ success = iSms.disableCellBroadcastRangeForSubscriber(getSubscriptionId(),
startMessageId, endMessageId, ranType);
}
} catch (RemoteException ex) {
@@ -1426,9 +1313,9 @@ public final class SmsManager {
public boolean isImsSmsSupported() {
boolean boSupported = false;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- boSupported = iccISms.isImsSmsSupportedForSubscriber(getSubscriptionId());
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ boSupported = iSms.isImsSmsSupportedForSubscriber(getSubscriptionId());
}
} catch (RemoteException ex) {
// ignore it
@@ -1451,9 +1338,9 @@ public final class SmsManager {
public String getImsSmsFormat() {
String format = com.android.internal.telephony.SmsConstants.FORMAT_UNKNOWN;
try {
- ISms iccISms = getISmsService();
- if (iccISms != null) {
- format = iccISms.getImsSmsFormatForSubscriber(getSubscriptionId());
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ format = iSms.getImsSmsFormatForSubscriber(getSubscriptionId());
}
} catch (RemoteException ex) {
// ignore it
@@ -1467,10 +1354,10 @@ public final class SmsManager {
* @return the default SMS subscription id
*/
public static int getDefaultSmsSubscriptionId() {
- ISms iccISms = null;
+ ISms iSms = null;
try {
- iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- return iccISms.getPreferredSmsSubscription();
+ iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ return iSms.getPreferredSmsSubscription();
} catch (RemoteException ex) {
return -1;
} catch (NullPointerException ex) {
@@ -1486,10 +1373,10 @@ public final class SmsManager {
*/
@UnsupportedAppUsage
public boolean isSMSPromptEnabled() {
- ISms iccISms = null;
+ ISms iSms = null;
try {
- iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- return iccISms.isSMSPromptEnabled();
+ iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ return iSms.isSMSPromptEnabled();
} catch (RemoteException ex) {
return false;
} catch (NullPointerException ex) {
@@ -1966,8 +1853,8 @@ public final class SmsManager {
throw new IllegalArgumentException("Empty message URI");
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendStoredText(
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendStoredText(
getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,
scAddress, sentIntent, deliveryIntent);
} catch (RemoteException ex) {
@@ -2014,8 +1901,8 @@ public final class SmsManager {
throw new IllegalArgumentException("Empty message URI");
}
try {
- ISms iccISms = getISmsServiceOrThrow();
- iccISms.sendStoredMultipartText(
+ ISms iSms = getISmsServiceOrThrow();
+ iSms.sendStoredMultipartText(
getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,
scAddress, sentIntents, deliveryIntents);
} catch (RemoteException ex) {
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 58f12e2c427a..b781b109bdcc 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -467,7 +467,7 @@ public class SubscriptionInfo implements Parcelable {
* @return group UUID a String of group UUID if it belongs to a group. Otherwise
* it will return null.
*/
- public String getGroupUuid() {
+ public @Nullable String getGroupUuid() {
return mGroupUUID;
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 0bbf054d7563..d5862280b3b1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -63,6 +63,7 @@ import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1075,7 +1076,8 @@ public class SubscriptionManager {
* @param listener that is to be unregistered.
*/
public void removeOnOpportunisticSubscriptionsChangedListener(
- OnOpportunisticSubscriptionsChangedListener listener) {
+ @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
+ Preconditions.checkNotNull(listener, "listener cannot be null");
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
@@ -1269,7 +1271,7 @@ public class SubscriptionManager {
if (!userVisibleOnly || activeList == null) {
return activeList;
} else {
- return activeList.stream().filter(subInfo -> !shouldHideSubscription(subInfo))
+ return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
.collect(Collectors.toList());
}
}
@@ -2699,7 +2701,8 @@ public class SubscriptionManager {
* @param callbackIntent pending intent that will be sent after operation is done.
*/
@RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
- public void switchToSubscription(int subId, PendingIntent callbackIntent) {
+ public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
+ Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
EuiccManager euiccManager = new EuiccManager(mContext);
euiccManager.switchToSubscription(subId, callbackIntent);
}
@@ -2874,32 +2877,27 @@ public class SubscriptionManager {
}
/**
- * Whether system UI should hide a subscription. If it's a bundled opportunistic
- * subscription, it shouldn't show up in anywhere in Settings app, dialer app,
- * or status bar. Exception is if caller is carrier app, in which case they will
+ * Whether a subscription is visible to API caller. If it's a bundled opportunistic
+ * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
+ * Exception is if caller owns carrier privilege, in which case they will
* want to see their own hidden subscriptions.
*
* @param info the subscriptionInfo to check against.
- * @return true if this subscription should be hidden.
+ * @return true if this subscription should be visible to the API caller.
*
- * @hide
*/
- public boolean shouldHideSubscription(SubscriptionInfo info) {
+ private boolean isSubscriptionVisible(SubscriptionInfo info) {
if (info == null) return false;
- // If hasCarrierPrivileges or canManageSubscription returns true, it means caller
- // has carrier privilege.
- boolean hasCarrierPrivilegePermission = (info.isEmbedded() && canManageSubscription(info))
- || TelephonyManager.from(mContext).hasCarrierPrivileges(info.getSubscriptionId());
-
- return isInvisibleSubscription(info) && !hasCarrierPrivilegePermission;
- }
+ // If subscription is NOT grouped opportunistic subscription, it's visible.
+ if (TextUtils.isEmpty(info.getGroupUuid()) || !info.isOpportunistic()) return true;
- /**
- * @hide
- */
- public static boolean isInvisibleSubscription(SubscriptionInfo info) {
- return info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic();
+ // If the caller is the carrier app and owns the subscription, it should be visible
+ // to the caller.
+ boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
+ .hasCarrierPrivileges(info.getSubscriptionId())
+ || (info.isEmbedded() && canManageSubscription(info));
+ return hasCarrierPrivilegePermission;
}
/**
@@ -2927,7 +2925,7 @@ public class SubscriptionManager {
for (SubscriptionInfo info : availableList) {
// Opportunistic subscriptions are considered invisible
// to users so they should never be returned.
- if (isInvisibleSubscription(info)) continue;
+ if (!isSubscriptionVisible(info)) continue;
String groupUuid = info.getGroupUuid();
if (groupUuid == null) {
@@ -2949,7 +2947,7 @@ public class SubscriptionManager {
}
/**
- * Enabled or disable a subscription. This is currently used in the settings page.
+ * Enables or disables a subscription. This is currently used in the settings page.
*
* <p>
* Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 857b4973dbd2..955977d63413 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4755,22 +4755,18 @@ public class TelephonyManager {
* Registers a listener object to receive notification of changes
* in specified telephony states.
* <p>
- * To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony
- * state of interest in the events argument.
- *
- * At registration, and when a specified telephony state changes, the telephony manager invokes
- * the appropriate callback method on the listener object and passes the current (updated)
- * values.
+ * To register a listener, pass a {@link PhoneStateListener}
+ * and specify at least one telephony state of interest in
+ * the events argument.
+ *
+ * At registration, and when a specified telephony state
+ * changes, the telephony manager invokes the appropriate
+ * callback method on the listener object and passes the
+ * current (updated) values.
* <p>
- * To un-register a listener, pass the listener object and set the events argument to
+ * To unregister a listener, pass the listener object and set the
+ * events argument to
* {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
- *
- * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
- * applies to the given subId. Otherwise, applies to
- * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds,
- * pass a separate listener object to each TelephonyManager object created with
- * {@link #createForSubscriptionId}.
- *
* Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
* call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
* {@link SecurityException} will be thrown otherwise.
@@ -4785,18 +4781,17 @@ public class TelephonyManager {
if (mContext == null) return;
try {
boolean notifyNow = (getITelephony() != null);
+ // If the listener has not explicitly set the subId (for example, created with the
+ // default constructor), replace the subId so it will listen to the account the
+ // telephony manager is created with.
+ if (listener.mSubId == null) {
+ listener.mSubId = mSubId;
+ }
+
ITelephonyRegistry registry = getTelephonyRegistry();
if (registry != null) {
- // listen to the subId the telephony manager is created with. Ignore subId in
- // PhoneStateListener.
- registry.listenForSubscriber(mSubId, getOpPackageName(),
+ registry.listenForSubscriber(listener.mSubId, getOpPackageName(),
listener.callback, events, notifyNow);
- // TODO: remove this once we remove PhoneStateListener constructor with subId.
- if (events == PhoneStateListener.LISTEN_NONE) {
- listener.mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- } else {
- listener.mSubId = mSubId;
- }
} else {
Rlog.w(TAG, "telephony registry not ready.");
}
@@ -7107,10 +7102,21 @@ public class TelephonyManager {
* @hide
*/
public boolean getTetherApnRequired() {
+ return getTetherApnRequired(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+ }
+
+ /**
+ * Check whether DUN APN is required for tethering with subId.
+ *
+ * @param subId the id of the subscription to require tethering.
+ * @return {@code true} if DUN APN is required for tethering.
+ * @hide
+ */
+ public boolean getTetherApnRequired(int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.getTetherApnRequired();
+ return telephony.getTetherApnRequiredForSubscriber(subId);
} catch (RemoteException ex) {
Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex);
} catch (NullPointerException ex) {
diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
index 871ee4d9f0a1..18a533a46273 100644
--- a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright 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.
+ */
+
package android.telephony;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
@@ -10,14 +27,14 @@ import java.util.Objects;
* Class that stores information specific to voice network registration.
* @hide
*/
-public class VoiceSpecificRegistrationStates implements Parcelable{
+public class VoiceSpecificRegistrationInfo implements Parcelable{
/**
* oncurrent services support indicator. if
* registered on a CDMA system.
* false - Concurrent services not supported,
* true - Concurrent services supported
*/
- public final boolean cssSupported;
+ public final boolean cssSupported;
/**
* TSB-58 Roaming Indicator if registered
@@ -40,15 +57,15 @@ public class VoiceSpecificRegistrationStates implements Parcelable{
*/
public final int defaultRoamingIndicator;
- VoiceSpecificRegistrationStates(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
- int defaultRoamingIndicator) {
+ VoiceSpecificRegistrationInfo(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
+ int defaultRoamingIndicator) {
this.cssSupported = cssSupported;
this.roamingIndicator = roamingIndicator;
this.systemIsInPrl = systemIsInPrl;
this.defaultRoamingIndicator = defaultRoamingIndicator;
}
- private VoiceSpecificRegistrationStates(Parcel source) {
+ private VoiceSpecificRegistrationInfo(Parcel source) {
this.cssSupported = source.readBoolean();
this.roamingIndicator = source.readInt();
this.systemIsInPrl = source.readInt();
@@ -70,7 +87,7 @@ public class VoiceSpecificRegistrationStates implements Parcelable{
@Override
public String toString() {
- return "VoiceSpecificRegistrationStates {"
+ return "VoiceSpecificRegistrationInfo {"
+ " mCssSupported=" + cssSupported
+ " mRoamingIndicator=" + roamingIndicator
+ " mSystemIsInPrl=" + systemIsInPrl
@@ -87,11 +104,11 @@ public class VoiceSpecificRegistrationStates implements Parcelable{
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || !(o instanceof VoiceSpecificRegistrationStates)) {
+ if (o == null || !(o instanceof VoiceSpecificRegistrationInfo)) {
return false;
}
- VoiceSpecificRegistrationStates other = (VoiceSpecificRegistrationStates) o;
+ VoiceSpecificRegistrationInfo other = (VoiceSpecificRegistrationInfo) o;
return this.cssSupported == other.cssSupported
&& this.roamingIndicator == other.roamingIndicator
&& this.systemIsInPrl == other.systemIsInPrl
@@ -99,16 +116,16 @@ public class VoiceSpecificRegistrationStates implements Parcelable{
}
- public static final Parcelable.Creator<VoiceSpecificRegistrationStates> CREATOR =
- new Parcelable.Creator<VoiceSpecificRegistrationStates>() {
+ public static final @NonNull Parcelable.Creator<VoiceSpecificRegistrationInfo> CREATOR =
+ new Parcelable.Creator<VoiceSpecificRegistrationInfo>() {
@Override
- public VoiceSpecificRegistrationStates createFromParcel(Parcel source) {
- return new VoiceSpecificRegistrationStates(source);
+ public VoiceSpecificRegistrationInfo createFromParcel(Parcel source) {
+ return new VoiceSpecificRegistrationInfo(source);
}
@Override
- public VoiceSpecificRegistrationStates[] newArray(int size) {
- return new VoiceSpecificRegistrationStates[size];
+ public VoiceSpecificRegistrationInfo[] newArray(int size) {
+ return new VoiceSpecificRegistrationInfo[size];
}
};
-} \ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index ae2c1d1f1e72..4b9abc1e6f33 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -17,6 +17,7 @@ package android.telephony.data;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ContentValues;
import android.database.Cursor;
import android.hardware.radio.V1_4.ApnTypes;
@@ -1620,7 +1621,7 @@ public class ApnSetting implements Parcelable {
* @param mvnoMatchData the MVNO match data for the APN
* @hide
*/
- public Builder setMvnoMatchData(String mvnoMatchData) {
+ public Builder setMvnoMatchData(@Nullable String mvnoMatchData) {
this.mMvnoMatchData = mvnoMatchData;
return this;
}
@@ -1642,7 +1643,7 @@ public class ApnSetting implements Parcelable {
* @param entryName the entry name to set for the APN
*/
@NonNull
- public Builder setEntryName(String entryName) {
+ public Builder setEntryName(@Nullable String entryName) {
this.mEntryName = entryName;
return this;
}
@@ -1653,7 +1654,7 @@ public class ApnSetting implements Parcelable {
* @param apnName the name to set for the APN
*/
@NonNull
- public Builder setApnName(String apnName) {
+ public Builder setApnName(@Nullable String apnName) {
this.mApnName = apnName;
return this;
}
@@ -1684,7 +1685,7 @@ public class ApnSetting implements Parcelable {
* @param proxy the proxy address to set for the APN
*/
@NonNull
- public Builder setProxyAddress(String proxy) {
+ public Builder setProxyAddress(@Nullable String proxy) {
this.mProxyAddress = proxy;
return this;
}
@@ -1706,7 +1707,7 @@ public class ApnSetting implements Parcelable {
* @param mmsc the MMSC Uri to set for the APN
*/
@NonNull
- public Builder setMmsc(Uri mmsc) {
+ public Builder setMmsc(@Nullable Uri mmsc) {
this.mMmsc = mmsc;
return this;
}
@@ -1738,7 +1739,7 @@ public class ApnSetting implements Parcelable {
* @param mmsProxy the MMS proxy address to set for the APN
*/
@NonNull
- public Builder setMmsProxyAddress(String mmsProxy) {
+ public Builder setMmsProxyAddress(@Nullable String mmsProxy) {
this.mMmsProxyAddress = mmsProxy;
return this;
}
@@ -1760,7 +1761,7 @@ public class ApnSetting implements Parcelable {
* @param user the APN username to set for the APN
*/
@NonNull
- public Builder setUser(String user) {
+ public Builder setUser(@Nullable String user) {
this.mUser = user;
return this;
}
@@ -1772,7 +1773,7 @@ public class ApnSetting implements Parcelable {
* @param password the APN password to set for the APN
*/
@NonNull
- public Builder setPassword(String password) {
+ public Builder setPassword(@Nullable String password) {
this.mPassword = password;
return this;
}
@@ -1813,7 +1814,7 @@ public class ApnSetting implements Parcelable {
* @param operatorNumeric the numeric operator ID to set for this entry
*/
@NonNull
- public Builder setOperatorNumeric(String operatorNumeric) {
+ public Builder setOperatorNumeric(@Nullable String operatorNumeric) {
this.mOperatorNumeric = operatorNumeric;
return this;
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 209d35efe03e..c8dab272de3e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -788,12 +788,13 @@ interface ITelephony {
int getPreferredNetworkType(int subId);
/**
- * Check whether DUN APN is required for tethering.
+ * Check whether DUN APN is required for tethering with subId.
*
+ * @param subId the id of the subscription to require tethering.
* @return {@code true} if DUN APN is required for tethering.
* @hide
*/
- boolean getTetherApnRequired();
+ boolean getTetherApnRequiredForSubscriber(int subId);
/**
* Enables framework IMS and triggers IMS Registration.
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index b5b0384ca599..c16a0f446651 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -569,7 +569,7 @@ public class NetworkStatsTest {
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
- assertTrue(delta.toString(), delta.migrateTun(tunUid, tunIface, underlyingIface));
+ delta.migrateTun(tunUid, tunIface, new String[] {underlyingIface});
assertEquals(20, delta.size());
// tunIface and TEST_IFACE entries are not changed.
@@ -650,7 +650,7 @@ public class NetworkStatsTest {
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
- assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
+ delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
assertEquals(9, delta.size());
// tunIface entries should not be changed.
@@ -813,6 +813,37 @@ public class NetworkStatsTest {
}
@Test
+ public void testFilterDebugEntries() {
+ NetworkStats.Entry entry1 = new NetworkStats.Entry(
+ "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
+
+ NetworkStats.Entry entry2 = new NetworkStats.Entry(
+ "test2", 10101, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
+
+ NetworkStats.Entry entry3 = new NetworkStats.Entry(
+ "test2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
+
+ NetworkStats.Entry entry4 = new NetworkStats.Entry(
+ "test2", 10101, SET_DBG_VPN_OUT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
+
+ NetworkStats stats = new NetworkStats(TEST_START, 4)
+ .addValues(entry1)
+ .addValues(entry2)
+ .addValues(entry3)
+ .addValues(entry4);
+
+ stats.filterDebugEntries();
+
+ assertEquals(2, stats.size());
+ assertEquals(entry1, stats.getValues(0, null));
+ assertEquals(entry3, stats.getValues(1, null));
+ }
+
+ @Test
public void testApply464xlatAdjustments() {
final String v4Iface = "v4-wlan0";
final String baseIface = "wlan0";
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 372ffcd057b4..e0b722761c34 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -48,6 +48,8 @@ public final class TcpKeepalivePacketDataTest {
final int ack = 0x22222222;
final int wnd = 8000;
final int wndScale = 2;
+ final int tos = 4;
+ final int ttl = 64;
TcpKeepalivePacketData resultData = null;
final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
@@ -58,6 +60,8 @@ public final class TcpKeepalivePacketDataTest {
testInfo.ack = ack;
testInfo.rcvWnd = wnd;
testInfo.rcvWndScale = wndScale;
+ testInfo.tos = tos;
+ testInfo.ttl = ttl;
try {
resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
} catch (InvalidPacketException e) {
@@ -72,16 +76,21 @@ public final class TcpKeepalivePacketDataTest {
assertEquals(testInfo.ack, resultData.tcpAck);
assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);
+ assertEquals(testInfo.tos, resultData.ipTos);
+ assertEquals(testInfo.ttl, resultData.ipTtl);
TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
final byte[] packet = resultData.getPacket();
- // IP version and TOS.
- ByteBuffer buf = ByteBuffer.wrap(packet);
- assertEquals(buf.getShort(), 0x4500);
+ // IP version and IHL
+ assertEquals(packet[0], 0x45);
+ // TOS
+ assertEquals(packet[1], tos);
+ // TTL
+ assertEquals(packet[8], ttl);
// Source IP address.
byte[] ip = new byte[4];
- buf = ByteBuffer.wrap(packet, 12, 4);
+ ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4);
buf.get(ip);
assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR);
// Destination IP address.
@@ -113,6 +122,8 @@ public final class TcpKeepalivePacketDataTest {
final int ack = 0x22222222;
final int wnd = 48_000;
final int wndScale = 2;
+ final int tos = 4;
+ final int ttl = 64;
final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
testInfo.srcPort = srcPort;
@@ -122,6 +133,8 @@ public final class TcpKeepalivePacketDataTest {
testInfo.ack = ack;
testInfo.rcvWnd = wnd;
testInfo.rcvWndScale = wndScale;
+ testInfo.tos = tos;
+ testInfo.ttl = ttl;
TcpKeepalivePacketData testData = null;
TcpKeepalivePacketDataParcelable resultData = null;
testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
@@ -134,5 +147,7 @@ public final class TcpKeepalivePacketDataTest {
assertEquals(resultData.ack, ack);
assertEquals(resultData.rcvWnd, wnd);
assertEquals(resultData.rcvWndScale, wndScale);
+ assertEquals(resultData.tos, tos);
+ assertEquals(resultData.ttl, ttl);
}
}
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index 3e86e77183ec..21a4988950db 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -25,8 +25,6 @@ import static org.junit.Assert.assertEquals;
import android.net.DhcpResults;
import android.net.LinkAddress;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -43,21 +41,16 @@ import java.net.Inet4Address;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class IpConfigurationParcelableUtilTest {
- private StaticIpConfiguration mStaticIpConfiguration;
private DhcpResults mDhcpResults;
@Before
public void setUp() {
- mStaticIpConfiguration = new StaticIpConfiguration();
- mStaticIpConfiguration.ipAddress = new LinkAddress(parseNumericAddress("2001:db8::42"), 64);
- mStaticIpConfiguration.gateway = parseNumericAddress("192.168.42.42");
- mStaticIpConfiguration.dnsServers.add(parseNumericAddress("2001:db8::43"));
- mStaticIpConfiguration.dnsServers.add(parseNumericAddress("192.168.43.43"));
- mStaticIpConfiguration.domains = "example.com";
- // Any added StaticIpConfiguration field must be included in equals() to be tested properly
- assertFieldCountEquals(4, StaticIpConfiguration.class);
-
- mDhcpResults = new DhcpResults(mStaticIpConfiguration);
+ mDhcpResults = new DhcpResults();
+ mDhcpResults.ipAddress = new LinkAddress(parseNumericAddress("2001:db8::42"), 64);
+ mDhcpResults.gateway = parseNumericAddress("192.168.42.42");
+ mDhcpResults.dnsServers.add(parseNumericAddress("2001:db8::43"));
+ mDhcpResults.dnsServers.add(parseNumericAddress("192.168.43.43"));
+ mDhcpResults.domains = "example.com";
mDhcpResults.serverAddress = (Inet4Address) parseNumericAddress("192.168.44.44");
mDhcpResults.vendorInfo = "TEST_VENDOR_INFO";
mDhcpResults.leaseDuration = 3600;
@@ -67,42 +60,31 @@ public class IpConfigurationParcelableUtilTest {
}
@Test
- public void testParcelUnparcelStaticConfiguration() {
- doStaticConfigurationParcelUnparcelTest();
- }
-
- @Test
- public void testParcelUnparcelStaticConfiguration_NullIpAddress() {
- mStaticIpConfiguration.ipAddress = null;
- doStaticConfigurationParcelUnparcelTest();
+ public void testParcelUnparcelDhcpResults() {
+ doDhcpResultsParcelUnparcelTest();
}
@Test
- public void testParcelUnparcelStaticConfiguration_NullGateway() {
- mStaticIpConfiguration.gateway = null;
- doStaticConfigurationParcelUnparcelTest();
+ public void testParcelUnparcelDhcpResults_NullIpAddress() {
+ mDhcpResults.ipAddress = null;
+ doDhcpResultsParcelUnparcelTest();
}
@Test
- public void testParcelUnparcelStaticConfiguration_NullDomains() {
- mStaticIpConfiguration.domains = null;
- doStaticConfigurationParcelUnparcelTest();
+ public void testParcelUnparcelDhcpResults_NullGateway() {
+ mDhcpResults.gateway = null;
+ doDhcpResultsParcelUnparcelTest();
}
@Test
- public void testParcelUnparcelStaticConfiguration_EmptyDomains() {
- mStaticIpConfiguration.domains = "";
- doStaticConfigurationParcelUnparcelTest();
- }
-
- private void doStaticConfigurationParcelUnparcelTest() {
- final StaticIpConfiguration unparceled =
- fromStableParcelable(toStableParcelable(mStaticIpConfiguration));
- assertEquals(mStaticIpConfiguration, unparceled);
+ public void testParcelUnparcelDhcpResults_NullDomains() {
+ mDhcpResults.domains = null;
+ doDhcpResultsParcelUnparcelTest();
}
@Test
- public void testParcelUnparcelDhcpResults() {
+ public void testParcelUnparcelDhcpResults_EmptyDomains() {
+ mDhcpResults.domains = "";
doDhcpResultsParcelUnparcelTest();
}
@@ -122,10 +104,4 @@ public class IpConfigurationParcelableUtilTest {
final DhcpResults unparceled = fromStableParcelable(toStableParcelable(mDhcpResults));
assertEquals(mDhcpResults, unparceled);
}
-
- @Test
- public void testParcelUnparcelApfCapabilities() {
- final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
- assertEquals(caps, fromStableParcelable(toStableParcelable(caps)));
- }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index d3616aa89f74..afefd5e4e6a9 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -104,6 +104,7 @@ import android.net.ConnectivityManager.PacketKeepalive;
import android.net.ConnectivityManager.PacketKeepaliveCallback;
import android.net.ConnectivityManager.TooManyRequestsException;
import android.net.ConnectivityThread;
+import android.net.IDnsResolver;
import android.net.INetd;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
@@ -144,12 +145,14 @@ import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
+import android.system.Os;
import android.test.mock.MockContentResolver;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -188,6 +191,8 @@ import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.stubbing.Answer;
+import java.io.IOException;
+import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -208,7 +213,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
import java.util.function.Predicate;
/**
@@ -237,6 +241,7 @@ public class ConnectivityServiceTest {
private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
private static final String WIFI_IFNAME = "test_wlan0";
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
private MockContext mServiceContext;
private WrappedConnectivityService mService;
@@ -253,6 +258,7 @@ public class ConnectivityServiceTest {
@Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService;
@Mock INetworkPolicyManager mNpm;
+ @Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
@@ -421,7 +427,7 @@ public class ConnectivityServiceTest {
private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
private int mScore;
private NetworkAgent mNetworkAgent;
- private int mStartKeepaliveError = SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
+ private int mStartKeepaliveError = SocketKeepalive.ERROR_UNSUPPORTED;
private int mStopKeepaliveError = SocketKeepalive.NO_KEEPALIVE;
private Integer mExpectedKeepaliveSlot = null;
// Contains the redirectUrl from networkStatus(). Before reading, wait for
@@ -495,7 +501,6 @@ public class ConnectivityServiceTest {
try {
doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected();
doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
- doAnswer(validateAnswer).when(mNetworkMonitor).setAcceptPartialConnectivity();
} catch (RemoteException e) {
fail(e.getMessage());
}
@@ -1051,8 +1056,8 @@ public class ConnectivityServiceTest {
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
- IpConnectivityLog log, INetd netd) {
- super(context, netManager, statsService, policyManager, log);
+ IpConnectivityLog log, INetd netd, IDnsResolver dnsResolver) {
+ super(context, netManager, statsService, policyManager, dnsResolver, log);
mNetd = netd;
mLingerDelayMs = TEST_LINGER_DELAY_MS;
}
@@ -1216,7 +1221,8 @@ public class ConnectivityServiceTest {
mStatsService,
mNpm,
mock(IpConnectivityLog.class),
- mMockNetd);
+ mMockNetd,
+ mMockDnsResolver);
final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
ArgumentCaptor.forClass(INetworkPolicyListener.class);
@@ -2550,8 +2556,7 @@ public class ConnectivityServiceTest {
verifyActiveNetwork(TRANSPORT_CELLULAR);
}
- // TODO(b/128426024): deflake and re-enable
- // @Test
+ @Test
public void testPartialConnectivity() {
// Register network callback.
NetworkRequest request = new NetworkRequest.Builder()
@@ -2575,20 +2580,24 @@ public class ConnectivityServiceTest {
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.assertNoCallback();
+ // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
+ // probe.
+ mWiFiNetworkAgent.setNetworkValid();
// If the user chooses yes to use this partial connectivity wifi, switch the default
// network to wifi and check if wifi becomes valid or not.
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
false /* always */);
- // With https probe disabled, NetworkMonitor should pass the network validation with http
- // probe.
- mWiFiNetworkAgent.setNetworkValid();
+ // If user accepts partial connectivity network,
+ // NetworkMonitor#setAcceptPartialConnectivity() should be called too.
waitForIdle();
try {
- verify(mWiFiNetworkAgent.mNetworkMonitor,
- timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
} catch (RemoteException e) {
fail(e.getMessage());
}
+ // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+ // validated.
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
mWiFiNetworkAgent);
@@ -2618,6 +2627,15 @@ public class ConnectivityServiceTest {
// acceptUnvalidated is also used as setting for accepting partial networks.
mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
mWiFiNetworkAgent.connect(true);
+ // If user accepted partial connectivity network before,
+ // NetworkMonitor#setAcceptPartialConnectivity() will be called in
+ // ConnectivityService#updateNetworkInfo().
+ waitForIdle();
+ try {
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
+ } catch (RemoteException e) {
+ fail(e.getMessage());
+ }
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
@@ -2632,23 +2650,33 @@ public class ConnectivityServiceTest {
// NET_CAPABILITY_PARTIAL_CONNECTIVITY.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
+ // Current design cannot send multi-testResult from NetworkMonitor to ConnectivityService.
+ // So, if user accepts partial connectivity, NetworkMonitor will send PARTIAL_CONNECTIVITY
+ // to ConnectivityService first then send VALID. Once NetworkMonitor support
+ // multi-testResult, this test case also need to be changed to meet the new design.
mWiFiNetworkAgent.connectWithPartialConnectivity();
- callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
- // NetworkMonitor detects partial connectivity
- assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- mWiFiNetworkAgent.setNetworkValid();
+ // If user accepted partial connectivity network before,
+ // NetworkMonitor#setAcceptPartialConnectivity() will be called in
+ // ConnectivityService#updateNetworkInfo().
waitForIdle();
try {
- verify(mWiFiNetworkAgent.mNetworkMonitor,
- timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
} catch (RemoteException e) {
fail(e.getMessage());
}
+ callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
- callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
- // Wifi should be the default network.
+ // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
+ // NetworkMonitor detects partial connectivity
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
+ mWiFiNetworkAgent.setNetworkValid();
+ // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+ // validated.
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ mWiFiNetworkAgent.disconnect();
+ callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
}
@Test
@@ -4018,8 +4046,13 @@ public class ConnectivityServiceTest {
callback3.expectStopped();
}
+ @FunctionalInterface
+ private interface ThrowingConsumer<T> {
+ void accept(T t) throws Exception;
+ }
+
// Helper method to prepare the executor and run test
- private void runTestWithSerialExecutors(Consumer<Executor> functor) {
+ private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
final Executor executorInline = (Runnable r) -> r.run();
functor.accept(executorSingleThread);
@@ -4028,20 +4061,15 @@ public class ConnectivityServiceTest {
}
@Test
- public void testNattSocketKeepalives() {
- runTestWithSerialExecutors(executor -> {
- try {
- doTestNattSocketKeepalivesWithExecutor(executor);
- } catch (Exception e) {
- fail(e.getMessage());
- }
- });
+ public void testNattSocketKeepalives() throws Exception {
+ runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor));
+ runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor));
}
private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception {
// TODO: 1. Move this outside of ConnectivityServiceTest.
// 2. Make test to verify that Nat-T keepalive socket is created by IpSecService.
- final int srcPort = 12345;
+ // 3. Mock ipsec service.
final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
@@ -4052,7 +4080,8 @@ public class ConnectivityServiceTest {
final int invalidKaInterval = 9;
final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
- final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort);
+ final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
+ final int srcPort = testSocket.getPort();
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("wlan12");
@@ -4065,89 +4094,106 @@ public class ConnectivityServiceTest {
Network myNet = connectKeepaliveNetwork(lp);
TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor);
- SocketKeepalive ka;
// Attempt to start keepalives with invalid parameters and check for errors.
// Invalid network.
- ka = mCm.createSocketKeepalive(notMyNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+ }
// Invalid interval.
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(invalidKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(invalidKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL);
+ }
// Invalid destination.
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv6, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv6, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ }
// Invalid source;
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv6, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv6, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ }
// NAT-T is only supported for IPv4.
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv6, dstIPv6, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv6, dstIPv6, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ }
// Sanity check before testing started keepalive.
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED);
+ }
// Check that a started keepalive can be stopped.
mWiFiNetworkAgent.setStartKeepaliveError(SocketKeepalive.SUCCESS);
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectStarted();
- mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS);
- ka.stop();
- callback.expectStopped();
-
- // Check that keepalive could be restarted.
- ka.start(validKaInterval);
- callback.expectStarted();
- ka.stop();
- callback.expectStopped();
-
- // Check that keepalive can be restarted without waiting for callback.
- ka.start(validKaInterval);
- callback.expectStarted();
- ka.stop();
- ka.start(validKaInterval);
- callback.expectStopped();
- callback.expectStarted();
- ka.stop();
- callback.expectStopped();
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS);
+ ka.stop();
+ callback.expectStopped();
+
+ // Check that keepalive could be restarted.
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ ka.stop();
+ callback.expectStopped();
+
+ // Check that keepalive can be restarted without waiting for callback.
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ ka.stop();
+ ka.start(validKaInterval);
+ callback.expectStopped();
+ callback.expectStarted();
+ ka.stop();
+ callback.expectStopped();
+ }
// Check that deleting the IP address stops the keepalive.
LinkProperties bogusLp = new LinkProperties(lp);
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectStarted();
- bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
- bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
- mWiFiNetworkAgent.sendLinkProperties(bogusLp);
- callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
- mWiFiNetworkAgent.sendLinkProperties(lp);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
+ bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
+ mWiFiNetworkAgent.sendLinkProperties(bogusLp);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ mWiFiNetworkAgent.sendLinkProperties(lp);
+ }
// Check that a started keepalive is stopped correctly when the network disconnects.
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectStarted();
- mWiFiNetworkAgent.disconnect();
- waitFor(mWiFiNetworkAgent.getDisconnectedCV());
- callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ mWiFiNetworkAgent.disconnect();
+ waitFor(mWiFiNetworkAgent.getDisconnectedCV());
+ callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
- // ... and that stopping it after that has no adverse effects.
- waitForIdle();
- final Network myNetAlias = myNet;
- assertNull(mCm.getNetworkCapabilities(myNetAlias));
- ka.stop();
- callback.assertNoCallback();
+ // ... and that stopping it after that has no adverse effects.
+ waitForIdle();
+ final Network myNetAlias = myNet;
+ assertNull(mCm.getNetworkCapabilities(myNetAlias));
+ ka.stop();
+ callback.assertNoCallback();
+ }
// Reconnect.
myNet = connectKeepaliveNetwork(lp);
@@ -4155,27 +4201,36 @@ public class ConnectivityServiceTest {
// Check that keepalive slots start from 1 and increment. The first one gets slot 1.
mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
- ka = mCm.createSocketKeepalive(myNet, testSocket, myIPv4, dstIPv4, executor, callback);
- ka.start(validKaInterval);
- callback.expectStarted();
-
- // The second one gets slot 2.
- mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
- final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789);
- TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor);
- SocketKeepalive ka2 =
- mCm.createSocketKeepalive(myNet, testSocket2, myIPv4, dstIPv4, executor, callback2);
- ka2.start(validKaInterval);
- callback2.expectStarted();
-
- ka.stop();
- callback.expectStopped();
-
- ka2.stop();
- callback2.expectStopped();
+ int srcPort2 = 0;
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectStarted();
+
+ // The second one gets slot 2.
+ mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
+ final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket();
+ srcPort2 = testSocket2.getPort();
+ TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor);
+ try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
+ myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) {
+ ka2.start(validKaInterval);
+ callback2.expectStarted();
+
+ ka.stop();
+ callback.expectStopped();
+
+ ka2.stop();
+ callback2.expectStopped();
+
+ testSocket.close();
+ testSocket2.close();
+ }
+ }
- testSocket.close();
- testSocket2.close();
+ // Check that there is no port leaked after all keepalives and sockets are closed.
+ assertFalse(isUdpPortInUse(srcPort));
+ assertFalse(isUdpPortInUse(srcPort2));
mWiFiNetworkAgent.disconnect();
waitFor(mWiFiNetworkAgent.getDisconnectedCV());
@@ -4183,14 +4238,8 @@ public class ConnectivityServiceTest {
}
@Test
- public void testTcpSocketKeepalives() {
- runTestWithSerialExecutors(executor -> {
- try {
- doTestTcpSocketKeepalivesWithExecutor(executor);
- } catch (Exception e) {
- fail(e.getMessage());
- }
- });
+ public void testTcpSocketKeepalives() throws Exception {
+ runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor));
}
private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception {
@@ -4200,7 +4249,6 @@ public class ConnectivityServiceTest {
final InetAddress myIPv6 = InetAddress.getByName("::1");
final int validKaInterval = 15;
- final int invalidKaInterval = 9;
final LinkProperties lp = new LinkProperties();
lp.setInterfaceName("wlan12");
@@ -4216,37 +4264,46 @@ public class ConnectivityServiceTest {
final Socket testSocketV6 = new Socket();
TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor);
- SocketKeepalive ka;
// Attempt to start Tcp keepalives with invalid parameters and check for errors.
// Invalid network.
- ka = mCm.createSocketKeepalive(notMyNet, testSocketV4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ notMyNet, testSocketV4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+ }
// Invalid Socket (socket is not bound with IPv4 address).
- ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocketV4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ }
// Invalid Socket (socket is not bound with IPv6 address).
- ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocketV6, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ }
// Bind the socket address
testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4));
testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6));
// Invalid Socket (socket is bound with IPv4 address).
- ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocketV4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ }
// Invalid Socket (socket is bound with IPv6 address).
- ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback);
- ka.start(validKaInterval);
- callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ try (SocketKeepalive ka = mCm.createSocketKeepalive(
+ myNet, testSocketV6, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ }
testSocketV4.close();
testSocketV6.close();
@@ -4256,6 +4313,66 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent = null;
}
+ private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception {
+ final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
+ final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0");
+ final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
+ final int validKaInterval = 15;
+
+ // Prepare the target network.
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName("wlan12");
+ lp.addLinkAddress(new LinkAddress(myIPv4, 25));
+ lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
+ Network myNet = connectKeepaliveNetwork(lp);
+ mWiFiNetworkAgent.setStartKeepaliveError(SocketKeepalive.SUCCESS);
+ mWiFiNetworkAgent.setStopKeepaliveError(SocketKeepalive.SUCCESS);
+
+ TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor);
+
+ // Prepare the target file descriptor, keep only one instance.
+ final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
+ final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
+ final int srcPort = testSocket.getPort();
+ final ParcelFileDescriptor testPfd =
+ ParcelFileDescriptor.dup(testSocket.getFileDescriptor());
+ testSocket.close();
+ assertTrue(isUdpPortInUse(srcPort));
+
+ // Start keepalive and explicit make the variable goes out of scope with try-with-resources
+ // block.
+ try (SocketKeepalive ka = mCm.createNattKeepalive(
+ myNet, testPfd, myIPv4, dstIPv4, executor, callback)) {
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ ka.stop();
+ callback.expectStopped();
+ }
+
+ // Check that the ParcelFileDescriptor is still valid after keepalive stopped,
+ // ErrnoException with EBADF will be thrown if the socket is closed when checking local
+ // address.
+ assertTrue(isUdpPortInUse(srcPort));
+ final InetSocketAddress sa =
+ (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor());
+ assertEquals(anyIPv4, sa.getAddress());
+
+ testPfd.close();
+ assertFalse(isUdpPortInUse(srcPort));
+
+ mWiFiNetworkAgent.disconnect();
+ waitFor(mWiFiNetworkAgent.getDisconnectedCV());
+ mWiFiNetworkAgent = null;
+ }
+
+ private static boolean isUdpPortInUse(int port) {
+ try (DatagramSocket ignored = new DatagramSocket(port)) {
+ return false;
+ } catch (IOException ignored) {
+ return true;
+ }
+ }
+
@Test
public void testGetCaptivePortalServerUrl() throws Exception {
String url = mCm.getCaptivePortalServerUrl();
@@ -4664,14 +4781,14 @@ public class ConnectivityServiceTest {
ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
// Clear any interactions that occur as a result of CS starting up.
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
- final String[] EMPTY_STRING_ARRAY = new String[0];
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
waitForIdle();
- verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
- verifyNoMoreInteractions(mNetworkManagementService);
+ verify(mMockDnsResolver, never()).setResolverConfiguration(
+ anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+ eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verifyNoMoreInteractions(mMockDnsResolver);
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
@@ -4688,28 +4805,29 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.connect(false);
waitForIdle();
// CS tells netd about the empty DNS config for this network.
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
- reset(mNetworkManagementService);
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
+ anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+ eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ reset(mMockDnsResolver);
cellLp.addDnsServer(InetAddress.getByName("2001:db8::1"));
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture());
+ eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
assertEquals(1, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1"));
// Opportunistic mode.
assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1"));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
cellLp.addDnsServer(InetAddress.getByName("192.0.2.1"));
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture());
+ eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
assertEquals(2, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
@@ -4717,7 +4835,7 @@ public class ConnectivityServiceTest {
assertEquals(2, tlsServers.getValue().length);
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
final String TLS_SPECIFIER = "tls.example.com";
final String TLS_SERVER6 = "2001:db8:53::53";
@@ -4727,22 +4845,21 @@ public class ConnectivityServiceTest {
new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel());
waitForIdle();
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(TLS_SPECIFIER), eq(TLS_SERVERS));
+ eq(TLS_SPECIFIER), eq(TLS_SERVERS), eq(EMPTY_STRING_ARRAY));
assertEquals(2, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
}
@Test
public void testPrivateDnsSettingsChange() throws Exception {
- final String[] EMPTY_STRING_ARRAY = new String[0];
ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
// Clear any interactions that occur as a result of CS starting up.
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
// The default on Android is opportunistic mode ("Automatic").
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
@@ -4755,9 +4872,10 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
waitForIdle();
// CS tells netd about the empty DNS config for this network.
- verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
- verifyNoMoreInteractions(mNetworkManagementService);
+ verify(mMockDnsResolver, never()).setResolverConfiguration(
+ anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+ eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verifyNoMoreInteractions(mMockDnsResolver);
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
@@ -4776,9 +4894,9 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(false);
waitForIdle();
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture());
+ eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
assertEquals(2, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
@@ -4786,7 +4904,7 @@ public class ConnectivityServiceTest {
assertEquals(2, tlsServers.getValue().length);
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
mCellNetworkAgent);
@@ -4798,26 +4916,26 @@ public class ConnectivityServiceTest {
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
- verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, times(1)).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), eq(EMPTY_STRING_ARRAY));
+ eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
assertEquals(2, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
- verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture());
+ eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
assertEquals(2, mStringArrayCaptor.getValue().length);
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
assertEquals(2, tlsServers.getValue().length);
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
new String[]{"2001:db8::1", "192.0.2.1"}));
- reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
@@ -5648,6 +5766,7 @@ public class ConnectivityServiceTest {
cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
reset(mNetworkManagementService);
+ reset(mMockDnsResolver);
when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
.thenReturn(getClatInterfaceConfig(myIpv4));
@@ -5655,7 +5774,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
- verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
// Switching default network updates TCP buffer sizes.
verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES);
@@ -5665,17 +5784,22 @@ public class ConnectivityServiceTest {
cellLp.addLinkAddress(myIpv4);
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
- verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
+ eq(cellNetId), eq(EMPTY_STRING_ARRAY), any(), any(),
+ eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
verifyNoMoreInteractions(mMockNetd);
+ verifyNoMoreInteractions(mMockDnsResolver);
reset(mMockNetd);
+ reset(mMockDnsResolver);
// Remove IPv4 address. Expect prefix discovery to be started again.
cellLp.removeLinkAddress(myIpv4);
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
- verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
@@ -5705,6 +5829,12 @@ public class ConnectivityServiceTest {
assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST);
assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
+ verify(mMockDnsResolver, times(1)).setResolverConfiguration(
+ eq(cellNetId), mStringArrayCaptor.capture(), any(), any(),
+ eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ assertEquals(1, mStringArrayCaptor.getValue().length);
+ assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "8.8.8.8"));
+
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
// linkproperties are cleaned up.
cellLp.addLinkAddress(myIpv4);
@@ -5712,7 +5842,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
- verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
// As soon as stop is called, the linkproperties lose the stacked interface.
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
@@ -5727,7 +5857,9 @@ public class ConnectivityServiceTest {
networkCallback.assertNoCallback();
verifyNoMoreInteractions(mMockNetd);
+ verifyNoMoreInteractions(mMockDnsResolver);
reset(mMockNetd);
+ reset(mMockDnsResolver);
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
@@ -5741,7 +5873,7 @@ public class ConnectivityServiceTest {
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
- verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+ verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
kNat64PrefixString, 96);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
@@ -5824,6 +5956,7 @@ public class ConnectivityServiceTest {
// Disconnect cell
reset(mNetworkManagementService);
+ reset(mMockNetd);
mCellNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
// LOST callback is triggered earlier than removing idle timer. Broadcast should also be
@@ -5831,8 +5964,9 @@ public class ConnectivityServiceTest {
// unexpectedly before network being removed.
waitForIdle();
verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
- verify(mNetworkManagementService, times(1)).removeNetwork(
- eq(mCellNetworkAgent.getNetwork().netId));
+ verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
+ verify(mMockDnsResolver, times(1))
+ .clearResolverConfiguration(eq(mCellNetworkAgent.getNetwork().netId));
// Disconnect wifi
ConditionVariable cv = waitForConnectivityBroadcasts(1);
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 15ba43df832f..8fa0ab979a54 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -29,13 +29,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.net.IDnsResolver;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.RouteInfo;
import android.net.shared.PrivateDnsConfig;
-import android.os.INetworkManagementService;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
@@ -73,7 +73,7 @@ public class DnsManagerTest {
MockContentResolver mContentResolver;
@Mock Context mCtx;
- @Mock INetworkManagementService mNMService;
+ @Mock IDnsResolver mMockDnsResolver;
@Mock MockableSystemProperties mSystemProperties;
@Before
@@ -83,7 +83,7 @@ public class DnsManagerTest {
mContentResolver.addProvider(Settings.AUTHORITY,
new FakeSettingsProvider());
when(mCtx.getContentResolver()).thenReturn(mContentResolver);
- mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
+ mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties);
// Clear the private DNS settings
Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 6de4aa1be1ea..142769f61335 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -32,6 +32,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
import android.net.INetd;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -69,6 +70,7 @@ public class LingerMonitorTest {
LingerMonitor mMonitor;
@Mock ConnectivityService mConnService;
+ @Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
@Mock INetworkManagementService mNMS;
@Mock Context mCtx;
@@ -353,7 +355,7 @@ public class LingerMonitorTest {
caps.addCapability(0);
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
- caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS,
+ caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
NetworkFactory.SerialNumber.NONE);
nai.everValidated = true;
return nai;
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index cc09fb7ba66f..b709af1a02f1 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
import android.net.INetd;
import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
@@ -63,6 +64,7 @@ public class Nat464XlatTest {
@Mock ConnectivityService mConnectivity;
@Mock NetworkMisc mMisc;
+ @Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
@Mock INetworkManagementService mNms;
@Mock InterfaceConfiguration mConfig;
@@ -72,7 +74,7 @@ public class Nat464XlatTest {
Handler mHandler;
Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNai, mNetd, mNms) {
+ return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
@Override protected int getNetId() {
return NETID;
}
@@ -205,7 +207,7 @@ public class Nat464XlatTest {
verify(mNms).unregisterObserver(eq(nat));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
- verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+ verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
// Stacked interface removed notification arrives and is ignored.
@@ -331,7 +333,7 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
verify(mNms).unregisterObserver(eq(nat));
- verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+ verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
assertIdle(nat);
@@ -358,7 +360,7 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mNms).unregisterObserver(eq(nat));
- verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+ verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
// In-flight interface up notification arrives: no-op
@@ -390,7 +392,7 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mNms).unregisterObserver(eq(nat));
- verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+ verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
index 3944fad2ac9e..d28ab708f051 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity.tethering;
+import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
@@ -30,6 +31,8 @@ import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
@@ -72,12 +75,14 @@ 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";
@Mock private CarrierConfigManager mCarrierConfigManager;
@Mock private Context mContext;
@Mock private MockableSystemProperties mSystemProperties;
@Mock private Resources mResources;
@Mock private SharedLog mLog;
+ @Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
// Like so many Android system APIs, these cannot be mocked because it is marked final.
// We have to use the real versions.
@@ -107,18 +112,31 @@ public final class EntitlementManagerTest {
public class WrappedEntitlementManager extends EntitlementManager {
public int fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
- public boolean everRunUiEntitlement = false;
+ public int uiProvisionCount = 0;
+ public int silentProvisionCount = 0;
public WrappedEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, MockableSystemProperties systemProperties) {
- super(ctx, target, log, systemProperties);
+ SharedLog log, int what, MockableSystemProperties systemProperties) {
+ super(ctx, target, log, what, systemProperties);
+ }
+
+ public void reset() {
+ fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
+ uiProvisionCount = 0;
+ silentProvisionCount = 0;
}
@Override
protected void runUiTetherProvisioning(int type, ResultReceiver receiver) {
- everRunUiEntitlement = true;
+ uiProvisionCount++;
receiver.send(fakeEntitlementResult, null);
}
+
+ @Override
+ protected void runSilentTetherProvisioning(int type) {
+ silentProvisionCount++;
+ addDownstreamMapping(type, fakeEntitlementResult);
+ }
}
@Before
@@ -141,7 +159,9 @@ public final class EntitlementManagerTest {
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
mMockContext = new MockContext(mContext);
mSM = new TestStateMachine();
- mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties);
+ mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE,
+ mSystemProperties);
+ mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
}
@@ -158,7 +178,9 @@ public final class EntitlementManagerTest {
// Produce some acceptable looking provision app setting if requested.
when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
.thenReturn(PROVISIONING_APP_NAME);
- // Don't disable tethering provisioning unless requested.
+ when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
+ .thenReturn(PROVISIONING_NO_UI_APP_NAME);
+ // Don't disable tethering provisioning unless requested.
when(mSystemProperties.getBoolean(eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY),
anyBoolean())).thenReturn(false);
// Act like the CarrierConfigManager is present and ready unless told otherwise.
@@ -166,6 +188,7 @@ public final class EntitlementManagerTest {
.thenReturn(mCarrierConfigManager);
when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig);
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
}
@Test
@@ -199,6 +222,16 @@ public final class EntitlementManagerTest {
}
@Test
+ public void toleratesCarrierConfigNotLoaded() {
+ setupForRequiredProvisioning();
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
+ mEnMgr.updateConfiguration(
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
+ // We still have a provisioning app configured, so still require provisioning.
+ assertTrue(mEnMgr.isTetherProvisioningRequired());
+ }
+
+ @Test
public void provisioningNotRequiredWhenAppNotFound() {
setupForRequiredProvisioning();
when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
@@ -218,7 +251,6 @@ public final class EntitlementManagerTest {
final CountDownLatch mCallbacklatch = new CountDownLatch(1);
// 1. Entitlement check is not required.
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.everRunUiEntitlement = false;
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -227,14 +259,15 @@ public final class EntitlementManagerTest {
}
};
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
+ mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertFalse(mEnMgr.everRunUiEntitlement);
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
setupForRequiredProvisioning();
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
INVALID_SUBSCRIPTION_ID));
// 2. No cache value and don't need to run entitlement check.
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -243,11 +276,12 @@ public final class EntitlementManagerTest {
}
};
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
+ mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertFalse(mEnMgr.everRunUiEntitlement);
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
// 3. No cache value and ui entitlement check is needed.
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -258,10 +292,10 @@ public final class EntitlementManagerTest {
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertTrue(mEnMgr.everRunUiEntitlement);
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
// 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check.
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -270,11 +304,12 @@ public final class EntitlementManagerTest {
}
};
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
+ mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertFalse(mEnMgr.everRunUiEntitlement);
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
// 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed.
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -285,10 +320,10 @@ public final class EntitlementManagerTest {
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertTrue(mEnMgr.everRunUiEntitlement);
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
// 6. Cache value is TETHER_ERROR_NO_ERROR.
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -297,10 +332,11 @@ public final class EntitlementManagerTest {
}
};
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
+ mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertFalse(mEnMgr.everRunUiEntitlement);
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
// 7. Test get value for other downstream type.
- mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -309,19 +345,152 @@ public final class EntitlementManagerTest {
}
};
mEnMgr.getLatestTetheringEntitlementResult(TETHERING_USB, receiver, false);
+ mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
- assertFalse(mEnMgr.everRunUiEntitlement);
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ mEnMgr.reset();
}
void callbackTimeoutHelper(final CountDownLatch latch) throws Exception {
if (!latch.await(1, TimeUnit.SECONDS)) {
- fail("Timout, fail to recieve callback");
+ fail("Timout, fail to receive callback");
}
}
+
+ @Test
+ public void verifyPermissionResult() {
+ setupForRequiredProvisioning();
+ mEnMgr.notifyUpstream(true);
+ mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+ INVALID_SUBSCRIPTION_ID));
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+ mLooper.dispatchAll();
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ }
+
+ @Test
+ public void verifyPermissionIfAllNotApproved() {
+ setupForRequiredProvisioning();
+ mEnMgr.notifyUpstream(true);
+ mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+ INVALID_SUBSCRIPTION_ID));
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ }
+
+ @Test
+ public void verifyPermissionIfAnyApproved() {
+ setupForRequiredProvisioning();
+ mEnMgr.notifyUpstream(true);
+ mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+ INVALID_SUBSCRIPTION_ID));
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+ mLooper.dispatchAll();
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ mLooper.dispatchAll();
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+ mLooper.dispatchAll();
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
+ }
+
+ @Test
+ public void testRunTetherProvisioning() {
+ setupForRequiredProvisioning();
+ mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+ INVALID_SUBSCRIPTION_ID));
+ // 1. start ui provisioning, upstream is mobile
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+ mEnMgr.notifyUpstream(true);
+ mLooper.dispatchAll();
+ mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+ mLooper.dispatchAll();
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ assertEquals(0, mEnMgr.silentProvisionCount);
+ 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);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.reset();
+ // 3. tear down mobile, then start ui provisioning
+ mEnMgr.notifyUpstream(false);
+ mLooper.dispatchAll();
+ mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
+ mLooper.dispatchAll();
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ assertEquals(0, mEnMgr.silentProvisionCount);
+ 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);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ mEnMgr.reset();
+ // 5. tear down mobile, then switch SIM
+ mEnMgr.notifyUpstream(false);
+ mLooper.dispatchAll();
+ mEnMgr.reevaluateSimCardProvisioning();
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ assertEquals(0, mEnMgr.silentProvisionCount);
+ mEnMgr.reset();
+ // 6. switch upstream back to mobile again
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.notifyUpstream(true);
+ mLooper.dispatchAll();
+ assertEquals(0, mEnMgr.uiProvisionCount);
+ assertEquals(3, mEnMgr.silentProvisionCount);
+ mEnMgr.reset();
+ }
+
+ @Test
+ public void testCallStopTetheringWhenUiProvisioningFail() {
+ setupForRequiredProvisioning();
+ mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+ INVALID_SUBSCRIPTION_ID));
+ verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI);
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+ mEnMgr.notifyUpstream(true);
+ mLooper.dispatchAll();
+ mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+ mLooper.dispatchAll();
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ 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();
+ private final State
+ mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState();
class LoggingState extends State {
@Override public void enter() {
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index 5a1f853e75a9..0d276cbd1b85 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -90,6 +90,7 @@ public class UpstreamNetworkMonitorTest {
private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
@Mock private Context mContext;
+ @Mock private EntitlementManager mEntitleMgr;
@Mock private IConnectivityManager mCS;
@Mock private SharedLog mLog;
@@ -103,6 +104,7 @@ public class UpstreamNetworkMonitorTest {
reset(mCS);
reset(mLog);
when(mLog.forSubComponent(anyString())).thenReturn(mLog);
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
mCM = spy(new TestConnectivityManager(mContext, mCS));
mSM = new TestStateMachine();
@@ -138,7 +140,7 @@ public class UpstreamNetworkMonitorTest {
@Test
public void testDefaultNetworkIsTracked() throws Exception {
assertTrue(mCM.hasNoCallbacks());
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertEquals(1, mCM.trackingDefault.size());
@@ -151,7 +153,7 @@ public class UpstreamNetworkMonitorTest {
public void testListensForAllNetworks() throws Exception {
assertTrue(mCM.listening.isEmpty());
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertFalse(mCM.listening.isEmpty());
assertTrue(mCM.isListeningForAll());
@@ -162,7 +164,7 @@ public class UpstreamNetworkMonitorTest {
@Test
public void testCallbacksRegistered() {
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
verify(mCM, times(1)).requestNetwork(
eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
mUNM.startObserveAllNetworks();
@@ -285,7 +287,7 @@ public class UpstreamNetworkMonitorTest {
final Collection<Integer> preferredTypes = new ArrayList<>();
preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// There are no networks, so there is nothing to select.
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -319,6 +321,14 @@ public class UpstreamNetworkMonitorTest {
NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
assertFalse(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
+ // mobile is not permitted, we should not use HIPRI.
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+ assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
+ assertEquals(0, mCM.requested.size());
+ // mobile change back to permitted, HIRPI should come back
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+ assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
+ mUNM.selectPreferredUpstreamType(preferredTypes));
wifiAgent.fakeConnect();
// WiFi is up, and we should prefer it over cell.
@@ -347,11 +357,19 @@ public class UpstreamNetworkMonitorTest {
netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
+ // mobile is not permitted, we should not use DUN.
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+ assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
+ assertEquals(0, mCM.requested.size());
+ // mobile change back to permitted, DUN should come back
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+ assertSatisfiesLegacyType(TYPE_MOBILE_DUN,
+ mUNM.selectPreferredUpstreamType(preferredTypes));
}
@Test
public void testGetCurrentPreferredUpstream() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
mUNM.updateMobileRequiresDun(false);
@@ -361,37 +379,46 @@ public class UpstreamNetworkMonitorTest {
mCM.makeDefaultNetwork(cellAgent);
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- // [1] WiFi connects but not validated/promoted to default -> mobile selected.
+ // [1] Mobile connects but not permitted -> null selected
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+ assertEquals(null, mUNM.getCurrentPreferredUpstream());
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+
+ // [2] WiFi connects but not validated/promoted to default -> mobile selected.
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
wifiAgent.fakeConnect();
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- // [2] WiFi validates and is promoted to the default network -> WiFi selected.
+ // [3] WiFi validates and is promoted to the default network -> WiFi selected.
mCM.makeDefaultNetwork(wifiAgent);
assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- // [3] DUN required, no other changes -> WiFi still selected
+ // [4] DUN required, no other changes -> WiFi still selected
mUNM.updateMobileRequiresDun(true);
assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- // [4] WiFi no longer validated, mobile becomes default, DUN required -> null selected.
+ // [5] WiFi no longer validated, mobile becomes default, DUN required -> null selected.
mCM.makeDefaultNetwork(cellAgent);
assertEquals(null, mUNM.getCurrentPreferredUpstream());
// TODO: make sure that a DUN request has been filed. This is currently
// triggered by code over in Tethering, but once that has been moved
// into UNM we should test for this here.
- // [5] DUN network arrives -> DUN selected
+ // [6] DUN network arrives -> DUN selected
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
dunAgent.fakeConnect();
assertEquals(dunAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
+
+ // [7] Mobile is not permitted -> null selected
+ when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+ assertEquals(null, mUNM.getCurrentPreferredUpstream());
}
@Test
public void testLocalPrefixes() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// [0] Test minimum set of local prefixes.
@@ -492,6 +519,26 @@ public class UpstreamNetworkMonitorTest {
assertTrue(local.isEmpty());
}
+ @Test
+ public void testSelectMobileWhenMobileIsNotDefault() {
+ final Collection<Integer> preferredTypes = new ArrayList<>();
+ // Mobile has higher pirority than wifi.
+ preferredTypes.add(TYPE_MOBILE_HIPRI);
+ preferredTypes.add(TYPE_WIFI);
+ mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startObserveAllNetworks();
+ // Setup wifi and make wifi as default network.
+ final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+ wifiAgent.fakeConnect();
+ mCM.makeDefaultNetwork(wifiAgent);
+ // Setup mobile network.
+ final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ cellAgent.fakeConnect();
+
+ assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
+ mUNM.selectPreferredUpstreamType(preferredTypes));
+ verify(mEntitleMgr, times(1)).maybeRunProvisioning();
+ }
private void assertSatisfiesLegacyType(int legacyType, NetworkState ns) {
if (legacyType == TYPE_NONE) {
assertTrue(ns == null);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index bce526d3ae29..e35c34affd1a 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -57,6 +57,7 @@ import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_PO
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -216,11 +217,16 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats());
expectSystemReady();
+ assertNull(mService.getTunAdjustedStats());
mService.systemReady();
+ // Verify that system ready fetches realtime stats and initializes tun adjusted stats.
+ verify(mNetManager).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
+ assertNotNull("failed to initialize TUN adjusted stats", mService.getTunAdjustedStats());
+ assertEquals(0, mService.getTunAdjustedStats().size());
+
mSession = mService.openSession();
assertNotNull("openSession() failed", mSession);
-
// catch INetworkManagementEventObserver during systemReady()
ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
@@ -733,11 +739,13 @@ public class NetworkStatsServiceTest {
NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
- verify(mNetManager, times(1)).getNetworkStatsUidDetail(eq(UID_ALL), argThat(ifaces ->
- ifaces != null && ifaces.length == 2
- && ArrayUtils.contains(ifaces, TEST_IFACE)
- && ArrayUtils.contains(ifaces, stackedIface)));
-
+ // mNetManager#getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL) has following invocations:
+ // 1) NetworkStatsService#systemReady from #setUp.
+ // 2) mService#forceUpdateIfaces in the test above.
+ // 3) Finally, mService#getDetailedUidStats.
+ verify(mNetManager, times(3)).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
+ assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
+ assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
assertEquals(2, stats.size());
assertEquals(uidStats, stats.getValues(0, null));
assertEquals(tetheredStats1, stats.getValues(1, null));
@@ -927,7 +935,7 @@ public class NetworkStatsServiceTest {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
expectDefaultSettings();
NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
@@ -947,8 +955,10 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
.addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 500L, 50L, 500L, 50L, 1L)
- .addValues(
- TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1650L, 150L, 1650L, 150L, 2L));
+ // VPN received 1650 bytes over WiFi in background (SET_DEFAULT).
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1650L, 150L, 0L, 0L, 1L)
+ // VPN sent 1650 bytes over WiFi in foreground (SET_FOREGROUND).
+ .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 1650L, 150L, 1L));
forcePollAndWaitForIdle();
@@ -962,7 +972,7 @@ public class NetworkStatsServiceTest {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
expectDefaultSettings();
NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
@@ -993,6 +1003,132 @@ public class NetworkStatsServiceTest {
}
@Test
+ public void vpnWithTwoUnderlyingIfaces_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.
+ expectDefaultSettings();
+ NetworkState[] networkStates =
+ new NetworkState[] {
+ buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
+ };
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ expectBandwidthControlCheck();
+
+ mService.forceUpdateIfaces(
+ new Network[] {WIFI_NETWORK, VPN_NETWORK},
+ vpnInfos,
+ networkStates,
+ getActiveIface(networkStates));
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN.
+ // VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total).
+ // Of 8800 bytes over WiFi/Cell, expect:
+ // - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE.
+ // - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
+ .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L)
+ .addValues(
+ TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L));
+
+ forcePollAndWaitForIdle();
+
+ assertUidTotal(sTemplateWifi, UID_RED, 500L, 50L, 500L, 50L, 1);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
+ assertUidTotal(sTemplateWifi, UID_VPN, 1200L, 100L, 1200L, 100L, 2);
+
+ assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 500L, 50L, 500L, 50L, 1);
+ assertUidTotal(buildTemplateMobileWildcard(), UID_BLUE, 500L, 50L, 500L, 50L, 1);
+ assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1200L, 100L, 1200L, 100L, 2);
+ }
+
+ @Test
+ public void vpnWithTwoUnderlyingIfaces_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.
+ expectDefaultSettings();
+ NetworkState[] networkStates =
+ new NetworkState[] {
+ buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
+ };
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ expectBandwidthControlCheck();
+
+ mService.forceUpdateIfaces(
+ new Network[] {WIFI_NETWORK, VPN_NETWORK},
+ vpnInfos,
+ networkStates,
+ getActiveIface(networkStates));
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+ // VPN sent/received 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell.
+ // For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for both
+ // rx/tx.
+ // For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for both rx/tx.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 660L, 60L, 660L, 60L, 1L)
+ .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 440L, 40L, 440L, 40L, 1L));
+
+ forcePollAndWaitForIdle();
+
+ assertUidTotal(sTemplateWifi, UID_RED, 600L, 60L, 600L, 60L, 1);
+ assertUidTotal(sTemplateWifi, UID_VPN, 60L, 0L, 60L, 0L, 1);
+
+ assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 400L, 40L, 400L, 40L, 1);
+ assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 40L, 0L, 40L, 0L, 1);
+ }
+
+ @Test
+ public void vpnWithTwoUnderlyingIfaces_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.
+ expectDefaultSettings();
+ NetworkState[] networkStates =
+ new NetworkState[] {
+ buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
+ };
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ expectBandwidthControlCheck();
+
+ mService.forceUpdateIfaces(
+ new Network[] {WIFI_NETWORK, VPN_NETWORK},
+ vpnInfos,
+ networkStates,
+ getActiveIface(networkStates));
+ // create some traffic (assume 10 bytes of MTU for VPN interface:
+ // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+ // VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell.
+ // For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both
+ // rx/tx.
+ // UID_VPN gets nothing attributed to it (avoiding negative stats).
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 600L, 60L, 600L, 60L, 0L)
+ .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 200L, 20L, 200L, 20L, 0L));
+
+ forcePollAndWaitForIdle();
+
+ assertUidTotal(sTemplateWifi, UID_RED, 600L, 60L, 600L, 60L, 0);
+ assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
+
+ assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 200L, 20L, 200L, 20L, 0);
+ assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 0L, 0L, 0L, 0L, 0);
+ }
+
+ @Test
public void vpnWithIncorrectUnderlyingIface() 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.
@@ -1001,7 +1137,7 @@ public class NetworkStatsServiceTest {
new NetworkState[] {
buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
};
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
@@ -1030,6 +1166,134 @@ public class NetworkStatsServiceTest {
}
@Test
+ public void recordSnapshot_migratesTunTrafficAndUpdatesTunAdjustedStats() throws Exception {
+ assertEquals(0, mService.getTunAdjustedStats().size());
+ // VPN using WiFi (TEST_IFACE).
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ expectBandwidthControlCheck();
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
+ // VPN received 1100 bytes (100 packets) over WiFi.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
+
+ // this should lead to NSS#recordSnapshotLocked
+ mService.forceUpdateIfaces(
+ new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
+
+ // Verify TUN adjusted stats have traffic migrated correctly.
+ // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
+ // bytes attributed to UID_VPN.
+ NetworkStats tunAdjStats = mService.getTunAdjustedStats();
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
+ }
+
+ @Test
+ public void getDetailedUidStats_migratesTunTrafficAndUpdatesTunAdjustedStats()
+ throws Exception {
+ assertEquals(0, mService.getTunAdjustedStats().size());
+ // VPN using WiFi (TEST_IFACE).
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ expectBandwidthControlCheck();
+ mService.forceUpdateIfaces(
+ new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
+ // VPN received 1100 bytes (100 packets) over WiFi.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
+
+ mService.getDetailedUidStats(INTERFACES_ALL);
+
+ // Verify internally maintained TUN adjusted stats
+ NetworkStats tunAdjStats = mService.getTunAdjustedStats();
+ // Verify stats for TEST_IFACE (WiFi):
+ // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
+ // bytes attributed to UID_VPN.
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
+ // Verify stats for TUN_IFACE; only UID_RED should have usage on it.
+ assertValues(
+ tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
+ assertValues(
+ tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
+
+ // lets assume that since last time, VPN received another 1100 bytes (same assumptions as
+ // before i.e. UID_RED downloaded another 1000 bytes).
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ // Note - NetworkStatsFactory returns counters that are monotonically increasing.
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 0L, 0L, 0L));
+
+ mService.getDetailedUidStats(INTERFACES_ALL);
+
+ tunAdjStats = mService.getTunAdjustedStats();
+ // verify TEST_IFACE stats:
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
+ assertValues(
+ tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 200L, 0L, 0L, 0L, 0);
+ // verify TUN_IFACE stats:
+ assertValues(
+ tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
+ assertValues(
+ tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
+ }
+
+ @Test
+ public void getDetailedUidStats_returnsCorrectStatsWithVpnRunning() throws Exception {
+ // VPN using WiFi (TEST_IFACE).
+ VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ expectBandwidthControlCheck();
+ mService.forceUpdateIfaces(
+ new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
+ // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+ // overhead per packet):
+ // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
+ // VPN received 1100 bytes (100 packets) over WiFi.
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
+
+ // Query realtime stats for TEST_IFACE.
+ NetworkStats queriedStats =
+ mService.getDetailedUidStats(new String[] {TEST_IFACE});
+
+ assertEquals(HOUR_IN_MILLIS, queriedStats.getElapsedRealtime());
+ // verify that returned stats are only for TEST_IFACE and VPN traffic is migrated correctly.
+ assertEquals(new String[] {TEST_IFACE}, queriedStats.getUniqueIfaces());
+ assertValues(
+ queriedStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
+ assertValues(
+ queriedStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
+ }
+
+ @Test
public void testRegisterUsageCallback() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
@@ -1382,11 +1646,11 @@ public class NetworkStatsServiceTest {
return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
}
- private static VpnInfo createVpnInfo(String underlyingIface) {
+ private static VpnInfo createVpnInfo(String[] underlyingIfaces) {
VpnInfo info = new VpnInfo();
info.ownerUid = UID_VPN;
info.vpnIface = TUN_IFACE;
- info.primaryUnderlyingIface = underlyingIface;
+ info.underlyingIfaces = underlyingIfaces;
return info;
}
diff --git a/tests/utils/testutils/Android.bp b/tests/utils/testutils/Android.bp
index 0a9e964d8d8d..f71be7b0b7d3 100644
--- a/tests/utils/testutils/Android.bp
+++ b/tests/utils/testutils/Android.bp
@@ -19,7 +19,10 @@ java_library {
srcs: ["java/**/*.java"],
- static_libs: ["junit"],
+ static_libs: [
+ "junit",
+ "hamcrest-library",
+ ],
libs: [
"android.test.runner",
diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
new file mode 100644
index 000000000000..2ce1fc68e1ce
--- /dev/null
+++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.test.filters;
+
+import android.os.Bundle;
+
+import com.android.test.filters.SelectTest;
+
+/**
+ * JUnit test filter that select Window Manager Service related tests from FrameworksCoreTests.
+ *
+ * <p>Use this filter when running FrameworksCoreTests as
+ * <pre>
+ * adb shell am instrument -w \
+ * -e filter com.android.server.wm.test.filters.FrameworksTestsFilter \
+ * -e selectTest_verbose true \
+ * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
+ * </pre>
+ */
+public final class FrameworksTestsFilter extends SelectTest {
+
+ private static final String[] SELECTED_TESTS = {
+ // Test specifications for FrameworksCoreTests.
+ "android.app.servertransaction.", // all tests under the package.
+ "android.view.DisplayCutoutTest",
+ // Test specifications for FrameworksServicesTests.
+ "com.android.server.policy.", // all tests under the package.
+ "com.android.server.am.ActivityLaunchParamsModifierTests",
+ "com.android.server.am.ActivityRecordTests",
+ "com.android.server.am.ActivityStackSupervisorTests",
+ "com.android.server.am.ActivityStackTests",
+ "com.android.server.am.ActivityStartControllerTests",
+ "com.android.server.am.ActivityStarterTests",
+ "com.android.server.am.ActivityStartInterceptorTest",
+ "com.android.server.am.AssistDataRequesterTest",
+ "com.android.server.am.ClientLifecycleManagerTests",
+ "com.android.server.am.LaunchParamsControllerTests",
+ "com.android.server.am.PendingRemoteAnimationRegistryTest",
+ "com.android.server.am.RecentsAnimationTest",
+ "com.android.server.am.RecentTasksTest",
+ "com.android.server.am.RunningTasksTest",
+ "com.android.server.am.SafeActivityOptionsTest",
+ "com.android.server.am.TaskLaunchParamsModifierTests",
+ "com.android.server.am.TaskPersisterTest",
+ "com.android.server.am.TaskRecordTests",
+ "com.android.server.am.TaskStackChangedListenerTest",
+ };
+
+ public FrameworksTestsFilter(Bundle testArgs) {
+ super(addSelectTest(testArgs, SELECTED_TESTS));
+ }
+}
diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
index d0350aff5ef5..d5b14c58512e 100644
--- a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
+++ b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
@@ -26,10 +26,12 @@ import com.android.internal.annotations.VisibleForTesting;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
@@ -131,7 +133,8 @@ public class SelectTest extends Filter {
*
* @param testArgs instrumentation test arguments.
* @param selectTests array of class name to be selected to run.
- * @return modified instrumentation test arguments.
+ * @return modified instrumentation test arguments. if {@link #OPTION_SELECT_TEST} argument
+ * already exists in {@code testArgs}, those are prepended before {@code selectTests}.
*/
@NonNull
protected static Bundle addSelectTest(
@@ -139,7 +142,13 @@ public class SelectTest extends Filter {
if (selectTests.length == 0) {
return testArgs;
}
- testArgs.putString(OPTION_SELECT_TEST, join(Arrays.asList(selectTests)));
+ final List<String> selectedTestList = new ArrayList<>();
+ final String selectTestArgs = testArgs.getString(OPTION_SELECT_TEST);
+ if (selectTestArgs != null) {
+ selectedTestList.addAll(Arrays.asList(selectTestArgs.split(ARGUMENT_ITEM_SEPARATOR)));
+ }
+ selectedTestList.addAll(Arrays.asList(selectTests));
+ testArgs.putString(OPTION_SELECT_TEST, join(selectedTestList));
return testArgs;
}
diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
index 163b00abafcd..df18985f77bf 100644
--- a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
+++ b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
@@ -19,7 +19,11 @@ package com.android.test.filters;
import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST;
import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST_VERBOSE;
+import static org.hamcrest.collection.IsArrayContaining.hasItemInArray;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import android.os.Bundle;
@@ -146,6 +150,45 @@ public class SelectTestTests {
}
@Test
+ public void testAddSelectTest() {
+ final Bundle testArgs = new Bundle();
+
+ final Bundle modifiedTestArgs =
+ SelectTest.addSelectTest(testArgs, PACKAGE_A, CLASS_B3, METHOD_C5X);
+ assertSame(testArgs, modifiedTestArgs);
+
+ final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST);
+ assertNotNull(selectTestArgs);
+ final String[] selectedTests = selectTestArgs.split(",");
+ assertThat(selectedTests, hasItemInArray(PACKAGE_A));
+ assertThat(selectedTests, hasItemInArray(CLASS_B3));
+ assertThat(selectedTests, hasItemInArray(METHOD_C5X));
+ }
+
+ @Test
+ public void testAddSelectTest_prependExistingTestArg() {
+ final Bundle testArgs = new Bundle();
+ testArgs.putString(OPTION_SELECT_TEST, new StringJoiner(",")
+ .add(PACKAGE_A)
+ .add(CLASS_B3)
+ .add(METHOD_C5X)
+ .toString());
+
+ final Bundle modifiedTestArgs =
+ SelectTest.addSelectTest(testArgs, PACKAGE_B, CLASS_B4, METHOD_C6Y);
+
+ final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST);
+ assertNotNull(selectTestArgs);
+ final String[] selectedTests = selectTestArgs.split(",");
+ assertThat(selectedTests, hasItemInArray(PACKAGE_A));
+ assertThat(selectedTests, hasItemInArray(CLASS_B3));
+ assertThat(selectedTests, hasItemInArray(METHOD_C5X));
+ assertThat(selectedTests, hasItemInArray(PACKAGE_B));
+ assertThat(selectedTests, hasItemInArray(CLASS_B4));
+ assertThat(selectedTests, hasItemInArray(METHOD_C6Y));
+ }
+
+ @Test
public void testFilterDisabled() {
final Filter filter = mBuilder.build();
acceptTests(filter, TEST_ALL);