summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rwxr-xr-xapi/current.txt9
-rw-r--r--api/system-current.txt6
-rw-r--r--api/test-current.txt69
-rw-r--r--cmds/statsd/src/atoms.proto4
-rw-r--r--config/hiddenapi-greylist.txt269
-rw-r--r--core/java/android/net/ConnectivityManager.java3
-rw-r--r--core/java/android/net/DnsResolver.java62
-rw-r--r--core/java/android/net/NetworkStats.java351
-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/res/AndroidManifest.xml15
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java54
-rw-r--r--core/xsd/permission.xsd8
-rw-r--r--data/etc/privapp-permissions-platform.xml2
-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.bp3
-rw-r--r--packages/NetworkStack/proguard.flags9
-rw-r--r--packages/NetworkStack/src/android/net/dhcp/DhcpClient.java7
-rw-r--r--packages/NetworkStack/src/android/net/ip/IpClient.java1
-rw-r--r--packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java4
-rw-r--r--packages/Shell/AndroidManifest.xml2
-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/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.java51
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java29
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java5
-rw-r--r--services/core/java/com/android/server/connectivity/DnsManager.java24
-rw-r--r--services/core/java/com/android/server/connectivity/KeepaliveTracker.java19
-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/Tethering.java99
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java492
-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/net/NetworkStatsRecorder.java6
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java70
-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/net/Android.bp3
-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.java26
-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.java1
-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.java41
-rw-r--r--telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java (renamed from telephony/java/android/telephony/VoiceSpecificRegistrationStates.java)47
-rw-r--r--tests/net/java/android/net/NetworkStatsTest.java35
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java120
-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.java204
-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
147 files changed, 2657 insertions, 1203 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 76011b52fd90..37a542d80b34 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";
@@ -41958,6 +41959,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";
@@ -41969,6 +41971,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
@@ -42961,7 +42964,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();
@@ -43002,7 +43005,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);
@@ -43011,7 +43014,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";
diff --git a/api/system-current.txt b/api/system-current.txt
index a2f83fd7783f..1717382272f3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5916,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 {
@@ -6029,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 bb1a957da589..ca7410931a50 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1484,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";
}
@@ -1500,7 +1524,52 @@ 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);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 9ab7c215d82d..564e9186b868 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -3061,7 +3061,9 @@ message ProcessStartTime {
* frameworks/base/packages/NetworkStack/
*/
message NetworkStackReported {
- optional int32 eventId = 1;
+ // 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/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ae93cf019776..4a64128f146b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1934,6 +1934,8 @@ public class ConnectivityManager {
@NonNull Callback 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
@@ -1975,6 +1977,7 @@ public class ConnectivityManager {
@NonNull Callback 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
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 59802514c7a3..f9e0af227ac3 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -205,6 +205,7 @@ public final class DnsResolver {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
+ final Object lock = new Object();
final FileDescriptor queryfd;
try {
queryfd = resNetworkSend((network != null
@@ -214,8 +215,8 @@ public final class DnsResolver {
return;
}
- maybeAddCancellationSignal(cancellationSignal, queryfd);
- registerFDListener(executor, queryfd, callback);
+ maybeAddCancellationSignal(cancellationSignal, queryfd, lock);
+ registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
}
/**
@@ -242,6 +243,7 @@ public final class DnsResolver {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
+ final Object lock = new Object();
final FileDescriptor queryfd;
try {
queryfd = resNetworkQuery((network != null
@@ -251,31 +253,37 @@ public final class DnsResolver {
return;
}
- maybeAddCancellationSignal(cancellationSignal, queryfd);
- registerFDListener(executor, queryfd, callback);
+ maybeAddCancellationSignal(cancellationSignal, queryfd, lock);
+ registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
}
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);
+ } 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
@@ -284,14 +292,16 @@ public final class DnsResolver {
}
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) {
+ if (!queryfd.valid()) return;
+ Looper.getMainLooper().getQueue()
+ .removeOnFileDescriptorEventListener(queryfd);
+ resNetworkCancel(queryfd);
+ }
+ });
}
private static class DnsAddressAnswer extends DnsPacket {
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/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/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/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/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/xsd/permission.xsd b/core/xsd/permission.xsd
index d90863b2c716..12281242e9f7 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"/>
@@ -124,7 +124,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 +136,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 +151,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/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 9decd086972a..d44f5a934280 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -262,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/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 52534a8fbae7..0bd5c5f59133 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -49,6 +49,9 @@ java_defaults {
// 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"],
}
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/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 346ac68407de..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;
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
index 3aa6933fe8f2..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
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/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/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 bca2df47cd22..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();
@@ -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);
}
@@ -4299,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) {
@@ -4311,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 };
+ }
+ }
+ 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());
+ }
}
- } else if (underlyingNetworks.length > 0) {
- LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
- if (linkProperties != null) {
- info.primaryUnderlyingIface = linkProperties.getInterfaceName();
+ if (!interfaces.isEmpty()) {
+ info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
}
}
- return info.primaryUnderlyingIface == null ? null : info;
+ return info.underlyingIfaces == null ? null : info;
}
/**
@@ -5372,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();
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 4a4b6254ffa7..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)) {
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 ce887eb4f0fe..d7a57b992eef 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -154,12 +154,19 @@ public class KeepaliveTracker {
// 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.
- // TODO: don't accept null fd after legacy packetKeepalive API is removed.
try {
if (fd != null) {
mFd = Os.dup(fd);
} else {
- Log.d(TAG, "uid/pid " + mUid + "/" + mPid + " calls with null fd");
+ 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) {
@@ -480,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());
@@ -490,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;
}
}
@@ -531,7 +538,8 @@ public class KeepaliveTracker {
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
KeepaliveInfo.TYPE_NATT, fd);
- } catch (InvalidSocketException e) {
+ } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+ Log.e(TAG, "Fail to construct keepalive", e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
return;
}
@@ -570,7 +578,8 @@ public class KeepaliveTracker {
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
KeepaliveInfo.TYPE_TCP, fd);
- } catch (InvalidSocketException e) {
+ } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+ Log.e(TAG, "Fail to construct keepalive e=" + e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
return;
}
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/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 37fe3d094179..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) -> {
@@ -363,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:
@@ -469,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);
}
@@ -787,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);
@@ -813,6 +758,7 @@ public class Tethering extends BaseNetworkObserver {
case WifiManager.WIFI_AP_STATE_FAILED:
default:
disableWifiIpServingLocked(ifname, curState);
+ mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
break;
}
}
@@ -1090,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;
@@ -1504,6 +1452,7 @@ public class Tethering extends BaseNetworkObserver {
}
break;
}
+ case EVENT_UPSTREAM_PERMISSION_CHANGED:
case CMD_UPSTREAM_CHANGED:
updateUpstreamWanted();
if (!mUpstreamWanted) break;
@@ -1694,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. */
@@ -1755,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 70ab38983446..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 stopTethering(int type) {
- synchronized (mCurrentTethers) {
- mCurrentTethers.remove(type);
+ 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 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,23 +286,32 @@ 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 (!mConfig.hasMobileHotspotProvisionApp()) return;
- if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
+ 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();
- final ArraySet<Integer> reevaluateType;
- synchronized (mCurrentTethers) {
- reevaluateType = new ArraySet<Integer>(mCurrentTethers);
+ // TODO: refine provisioning check to isTetherProvisioningRequired() ??
+ if (!mConfig.hasMobileHotspotProvisionApp()
+ || carrierConfigAffirmsEntitlementCheckNotRequired()) {
+ evaluateCellularPermission();
+ return;
}
- for (Integer type : reevaluateType) {
- startProvisionIntent(type);
+
+ if (mUsingCellularAsUpstream) {
+ handleMaybeRunProvisioning();
}
}
@@ -189,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);
@@ -203,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);
@@ -221,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);
+ }
}
- 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 cancelTetherProvisioningRechecks() {
+ if (mProvisioningRecheckAlarm != null) {
+ AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
+ Context.ALARM_SERVICE);
+ alarmManager.cancel(mProvisioningRecheckAlarm);
+ mProvisioningRecheckAlarm = null;
}
}
- 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);
+ 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();
+ }
+ }
+
+ /**
+ * 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);
@@ -286,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/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/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/net/Android.bp b/services/net/Android.bp
index 67fbdc4d95f2..8f48f5b3d292 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -58,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",
]
@@ -69,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/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 47bf48f09b25..4776aa179478 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2490,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
@@ -2903,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 */
@@ -2925,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 b0417b328f0e..caf27b79dc13 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -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 f5ae945e5174..5e0a7a69854e 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.");
}
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/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/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a95db2242371..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;
@@ -240,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;
@@ -256,6 +258,7 @@ public class ConnectivityServiceTest {
@Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService;
@Mock INetworkPolicyManager mNpm;
+ @Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
@@ -1053,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;
}
@@ -1218,7 +1221,8 @@ public class ConnectivityServiceTest {
mStatsService,
mNpm,
mock(IpConnectivityLog.class),
- mMockNetd);
+ mMockNetd,
+ mMockDnsResolver);
final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
ArgumentCaptor.forClass(INetworkPolicyListener.class);
@@ -4066,8 +4070,6 @@ public class ConnectivityServiceTest {
// TODO: 1. Move this outside of ConnectivityServiceTest.
// 2. Make test to verify that Nat-T keepalive socket is created by IpSecService.
// 3. Mock ipsec service.
- // 4. Find a free port instead of a fixed port.
- final int srcPort = 12345;
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");
@@ -4078,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");
@@ -4198,6 +4201,7 @@ public class ConnectivityServiceTest {
// Check that keepalive slots start from 1 and increment. The first one gets slot 1.
mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
+ int srcPort2 = 0;
try (SocketKeepalive ka = mCm.createSocketKeepalive(
myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
ka.start(validKaInterval);
@@ -4205,7 +4209,8 @@ public class ConnectivityServiceTest {
// The second one gets slot 2.
mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
- final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789);
+ final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket();
+ srcPort2 = testSocket2.getPort();
TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor);
try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) {
@@ -4223,6 +4228,10 @@ public class ConnectivityServiceTest {
}
}
+ // 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());
mWiFiNetworkAgent = null;
@@ -4305,7 +4314,6 @@ public class ConnectivityServiceTest {
}
private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception {
- final int srcPort = 12345;
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");
@@ -4324,7 +4332,8 @@ public class ConnectivityServiceTest {
// Prepare the target file descriptor, keep only one instance.
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();
final ParcelFileDescriptor testPfd =
ParcelFileDescriptor.dup(testSocket.getFileDescriptor());
testSocket.close();
@@ -4772,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);
@@ -4796,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"}));
@@ -4825,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";
@@ -4835,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");
@@ -4863,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);
@@ -4884,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"}));
@@ -4894,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);
@@ -4906,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");
@@ -5756,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));
@@ -5763,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);
@@ -5773,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);
@@ -5813,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);
@@ -5820,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);
@@ -5835,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 */,
@@ -5849,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);
@@ -5932,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
@@ -5939,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 bac509802258..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.
@@ -229,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) {
@@ -238,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) {
@@ -254,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) {
@@ -269,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) {
@@ -281,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) {
@@ -296,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) {
@@ -308,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) {
@@ -320,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;
}