diff options
442 files changed, 6229 insertions, 2599 deletions
diff --git a/Android.bp b/Android.bp index afc728f25ad9..b782fec455cb 100644 --- a/Android.bp +++ b/Android.bp @@ -464,7 +464,8 @@ java_library { "framework-minus-apex", "updatable_media_stubs", "framework-sdkextensions-stubs-systemapi", - // TODO(jiyong): add more stubs for APEXes here + // TODO(b/147200698): should be the stub of framework-tethering + "framework-tethering", ], sdk_version: "core_platform", apex_available: ["//apex_available:platform"], @@ -587,6 +588,15 @@ java_library { } filegroup { + name: "framework-ike-shared-srcs", + visibility: ["//frameworks/opt/net/ike"], + srcs: [ + "core/java/android/net/annotations/PolicyDirection.java", + "telephony/java/android/telephony/Annotation.java", + ], +} + +filegroup { name: "framework-networkstack-shared-srcs", srcs: [ // TODO: remove these annotations as soon as we can use andoid.support.annotations.* diff --git a/apex/sdkextensions/TEST_MAPPING b/apex/sdkextensions/TEST_MAPPING index 7e7762337afc..4e1883382e2c 100644 --- a/apex/sdkextensions/TEST_MAPPING +++ b/apex/sdkextensions/TEST_MAPPING @@ -1,7 +1,7 @@ { "presubmit": [ { - "name": "CtsSdkExtTestCases" + "name": "CtsSdkExtensionsTestCases" }, { "name": "apiextensions_e2e_tests" diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp index 5504f4e5dd8e..dd174734df6d 100644 --- a/apex/sdkextensions/framework/Android.bp +++ b/apex/sdkextensions/framework/Android.bp @@ -36,6 +36,11 @@ java_library { "//frameworks/base/apex/sdkextensions", "//frameworks/base/apex/sdkextensions/testing", ], + hostdex: true, // for hiddenapi check + apex_available: [ + "com.android.sdkext", + "test_com.android.sdkext", + ], } droidstubs { diff --git a/api/current.txt b/api/current.txt index cf9a2927bf01..5295b474066a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -112,6 +112,7 @@ package android { field public static final String READ_LOGS = "android.permission.READ_LOGS"; field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"; field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; + field public static final String READ_PRECISE_PHONE_STATE = "android.permission.READ_PRECISE_PHONE_STATE"; field public static final String READ_SMS = "android.permission.READ_SMS"; field public static final String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS"; field public static final String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS"; @@ -28796,6 +28797,7 @@ package android.net { ctor public DhcpInfo(); method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR; field public int dns1; field public int dns2; field public int gateway; @@ -45415,6 +45417,7 @@ package android.telephony { method public long getDataLimitBytes(); method public long getDataUsageBytes(); method public long getDataUsageTime(); + method @Nullable public int[] getNetworkTypes(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); @@ -45434,6 +45437,7 @@ package android.telephony { method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); + method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]); method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); } @@ -45505,12 +45509,12 @@ package android.telephony { method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle); method public boolean hasCarrierPrivileges(); method public boolean hasIccCard(); - method public boolean iccCloseLogicalChannel(int); - method public byte[] iccExchangeSimIO(int, int, int, int, int, String); + method @Deprecated public boolean iccCloseLogicalChannel(int); + method @Deprecated public byte[] iccExchangeSimIO(int, int, int, int, int, String); method @Deprecated public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String); - method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String, int); - method public String iccTransmitApduBasicChannel(int, int, int, int, int, String); - method public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String); + method @Deprecated public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String, int); + method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String); + method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String); method public boolean isConcurrentVoiceAndDataSupported(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled(); @@ -45528,7 +45532,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); method public void sendDialerSpecialCode(String); - method public String sendEnvelopeWithStatus(String); + method @Deprecated public String sendEnvelopeWithStatus(String); method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler); method public void sendVisualVoicemailSms(String, int, String, android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean); diff --git a/api/system-current.txt b/api/system-current.txt index 2e81c7078fbb..52a86c1719a1 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -181,6 +181,7 @@ package android { field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; + field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED"; field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY"; field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; @@ -1413,6 +1414,10 @@ package android.bluetooth { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); } + public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile { + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + } + public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile { method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); @@ -1421,12 +1426,20 @@ package android.bluetooth { field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; } + public final class BluetoothMap implements android.bluetooth.BluetoothProfile { + method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int); + field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; + } + public final class BluetoothPan implements android.bluetooth.BluetoothProfile { method protected void finalize(); method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice); method public boolean isTetheringOn(); method public void setBluetoothTethering(boolean); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED"; field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE"; field public static final int LOCAL_NAP_ROLE = 1; // 0x1 @@ -4255,6 +4268,7 @@ package android.net { method @Deprecated @RequiresPermission("android.permission.NETWORK_SETTINGS") public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi(); @@ -4262,6 +4276,7 @@ package android.net { method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback); field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; @@ -4288,6 +4303,14 @@ package android.net { method public void onUpstreamChanged(@Nullable android.net.Network); } + public class InvalidPacketException extends java.lang.Exception { + ctor public InvalidPacketException(int); + field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb + field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9 + field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea + field public final int error; + } + public final class IpConfiguration implements android.os.Parcelable { ctor public IpConfiguration(); ctor public IpConfiguration(@NonNull android.net.IpConfiguration); @@ -4338,6 +4361,15 @@ package android.net { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecTransform buildTunnelModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; } + public class KeepalivePacketData { + ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException; + method @NonNull public byte[] getPacket(); + field @NonNull public final java.net.InetAddress dstAddress; + field public final int dstPort; + field @NonNull public final java.net.InetAddress srcAddress; + field public final int srcPort; + } + public class LinkAddress implements android.os.Parcelable { ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int); ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int); @@ -4396,6 +4428,7 @@ package android.net { } public final class NetworkCapabilities implements android.os.Parcelable { + method public boolean deduceRestrictedCapability(); method @NonNull public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String); @@ -4415,6 +4448,17 @@ package android.net { field public final android.net.WifiKey wifiKey; } + public class NetworkProvider { + ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest); + method @Nullable public android.os.Messenger getMessenger(); + method @NonNull public String getName(); + method public int getProviderId(); + method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int); + method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest); + field public static final int ID_NONE = -1; // 0xffffffff + } + public abstract class NetworkRecommendationProvider { ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor); method public final android.os.IBinder getBinder(); @@ -5076,6 +5120,25 @@ package android.net.metrics { } +package android.net.netstats.provider { + + public abstract class AbstractNetworkStatsProvider { + ctor public AbstractNetworkStatsProvider(); + method public abstract void requestStatsUpdate(int); + method public abstract void setAlert(long); + method public abstract void setLimit(@NonNull String, long); + field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff + } + + public class NetworkStatsProviderCallback { + method public void onAlertReached(); + method public void onLimitReached(); + method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); + method public void unregister(); + } + +} + package android.net.util { public final class SocketUtils { @@ -6175,7 +6238,7 @@ package android.os { ctor public UpdateEngine(); method @NonNull public android.os.UpdateEngine.AllocateSpaceResult allocateSpace(@NonNull String, @NonNull String[]); method public void applyPayload(String, long, long, String[]); - method public void applyPayload(@NonNull android.os.ParcelFileDescriptor, long, long, @NonNull String[]); + method public void applyPayload(@NonNull android.content.res.AssetFileDescriptor, @NonNull String[]); method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler); method public boolean bind(android.os.UpdateEngineCallback); method public void cancel(); @@ -6721,6 +6784,7 @@ package android.provider { } public final class Settings { + method public static boolean checkAndNoteWriteSettingsOperation(@NonNull android.content.Context, int, @NonNull String, boolean); field public static final String ACTION_ACCESSIBILITY_DETAILS_SETTINGS = "android.settings.ACCESSIBILITY_DETAILS_SETTINGS"; field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS"; @@ -8094,6 +8158,34 @@ package android.telephony { field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService"; } + public abstract class CellIdentity implements android.os.Parcelable { + method @NonNull public abstract android.telephony.CellLocation asCellLocation(); + } + + public final class CellIdentityCdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation(); + } + + public final class CellIdentityGsm extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + } + + public final class CellIdentityLte extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + } + + public final class CellIdentityNr extends android.telephony.CellIdentity { + method @NonNull public android.telephony.CellLocation asCellLocation(); + } + + public final class CellIdentityTdscdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + } + + public final class CellIdentityWcdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + } + public final class DataFailCause { field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab field public static final int ACCESS_BLOCK = 2087; // 0x827 @@ -9076,10 +9168,10 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); - method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); + method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); method public boolean isDataConnectivityPossible(); diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 8944dedd6c96..da1a76f8169d 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -138,11 +138,57 @@ cc_defaults { "android.hardware.power@1.1", "android.hardware.power.stats@1.0", "libpackagelistparser", + "libstatsmetadata", "libsysutils", "libcutils", ], } +// ================ +// libstatsmetadata +// ================ + +genrule { + name: "atoms_info.h", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoHeader $(genDir)/atoms_info.h", + out: [ + "atoms_info.h", + ], +} + +genrule { + name: "atoms_info.cpp", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoCpp $(genDir)/atoms_info.cpp", + out: [ + "atoms_info.cpp", + ], +} + +cc_library_shared { + name: "libstatsmetadata", + host_supported: true, + generated_sources: [ + "atoms_info.cpp", + ], + generated_headers: [ + "atoms_info.h", + ], + cflags: [ + "-Wall", + "-Werror", + ], + export_generated_headers: [ + "atoms_info.h", + ], + shared_libs: [ + "libcutils", + "libstatslog", + ], +} + + // ========= // statsd // ========= diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 13f5c8ae5fd8..320a32ab4648 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "math.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index ff7416c4b9e0..c9e026bf231c 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -23,6 +23,7 @@ #include <frameworks/base/cmds/statsd/src/active_config_list.pb.h> #include "StatsLogProcessor.h" #include "android-base/stringprintf.h" +#include "atoms_info.h" #include "external/StatsPullerManager.h" #include "guardrail/StatsdStats.h" #include "metrics/CountMetricProducer.h" diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp index b142caca3acc..dc69b78f0329 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.cpp +++ b/cmds/statsd/src/external/PowerStatsPuller.cpp @@ -22,6 +22,7 @@ #include <vector> #include "PowerStatsPuller.h" +#include "statslog.h" #include "stats_log_util.h" using android::hardware::hidl_vec; diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index 0b9b6abfd6d6..ccfd666573c4 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "StatsPullerManager.h" +#include "atoms_info.h" #include "puller_util.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 23d2aceb4fc3..564b9ee8051c 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -16,7 +16,7 @@ #pragma once #include "config/ConfigKey.h" -#include "statslog.h" +#include "atoms_info.h" #include <gtest/gtest_prod.h> #include <log/log_time.h> diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 963205ee56f4..7b7d0cac0d30 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -19,6 +19,7 @@ #include "statslog.h" #include "CountMetricProducer.h" +#include "atoms_info.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" #include "guardrail/StatsdStats.h" diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 5cfb1239d30e..46442b57126c 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -32,8 +32,8 @@ #include "../metrics/GaugeMetricProducer.h" #include "../metrics/ValueMetricProducer.h" +#include "atoms_info.h" #include "stats_util.h" -#include "statslog.h" #include <inttypes.h> diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h index bfb84cf4d1b9..a28165d09cdf 100644 --- a/cmds/statsd/src/stats_log_util.h +++ b/cmds/statsd/src/stats_log_util.h @@ -19,9 +19,9 @@ #include <android/util/ProtoOutputStream.h> #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "guardrail/StatsdStats.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp index bdc52b0af34c..32409184b02f 100644 --- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp +++ b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp @@ -24,6 +24,7 @@ #include <log/log.h> #include "src/external/GpuStatsPuller.h" +#include "statslog.h" #ifdef __ANDROID__ diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 266ea351b5d4..673082834e18 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -17,6 +17,7 @@ #include <gtest/gtest.h> #include <stdio.h> #include <vector> +#include "statslog.h" #include "../metrics/metrics_test_helper.h" #ifdef __ANDROID__ diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 90b80e73c323..842c3ef7dcdc 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -21,8 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.UnsupportedAppUsage; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index cf24b8e1ffa6..8e1ac7623e45 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -20,7 +20,7 @@ import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import android.annotation.IntDef; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index c822d20445ec..9a18880a353b 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -18,7 +18,7 @@ package android.accounts; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/accounts/AccountAndUser.java b/core/java/android/accounts/AccountAndUser.java index b0d53438d97c..fd6739410ce2 100644 --- a/core/java/android/accounts/AccountAndUser.java +++ b/core/java/android/accounts/AccountAndUser.java @@ -16,7 +16,7 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Used to store the Account and the UserId this account is associated with. diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java index bb2e327a9be8..a2a57990297c 100644 --- a/core/java/android/accounts/AccountAuthenticatorResponse.java +++ b/core/java/android/accounts/AccountAuthenticatorResponse.java @@ -16,10 +16,10 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index c80be8e5c3fa..7ecaacae6b09 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -25,8 +25,8 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.Size; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java index 555639445e85..b7bf11d4d5b6 100644 --- a/core/java/android/accounts/AuthenticatorDescription.java +++ b/core/java/android/accounts/AuthenticatorDescription.java @@ -16,10 +16,10 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; /** * A {@link Parcelable} value type that contains information about an account authenticator. diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 17d54d2455fe..3cdd691fd5dd 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -17,7 +17,7 @@ package android.animation; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ConstantState; diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java index 5b69d18a8386..9519ddde86f4 100644 --- a/core/java/android/animation/ArgbEvaluator.java +++ b/core/java/android/animation/ArgbEvaluator.java @@ -16,7 +16,7 @@ package android.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * This evaluator can be used to perform type interpolation between integer diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index c7537102d40c..21f0b6b2ae62 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -16,7 +16,7 @@ package android.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.view.View; import android.view.ViewGroup; diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 764e5992fbd9..ca37e9b107a0 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -19,7 +19,7 @@ package android.animation; import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Looper; import android.os.Trace; diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index e57327991a82..504364c8c1d9 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -22,7 +22,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index bf7b2f8b7be4..b6f61a2b8f01 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -33,10 +33,10 @@ import android.annotation.RequiresPermission; import android.annotation.StyleRes; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.VoiceInteractor.Request; import android.app.admin.DevicePolicyManager; import android.app.assist.AssistContent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java index d4aa01b8f43e..cb06eea2059e 100644 --- a/core/java/android/app/ActivityGroup.java +++ b/core/java/android/app/ActivityGroup.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Bundle; diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index e8e4085f731d..726a6195efc5 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -27,7 +27,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 607ef185ae60..b9eb95739aa1 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -15,7 +15,7 @@ */ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.IBinder; diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 926044bffdd0..10bee4013de0 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -25,7 +25,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 4ef554dc64cc..28d4c7f8a448 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4e8bee24052e..c4281f0b8d28 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -32,7 +32,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; @@ -46,6 +45,7 @@ import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.PendingTransactionActions.StopInfo; import android.app.servertransaction.TransactionExecutor; import android.app.servertransaction.TransactionExecutorHelper; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 3a34b7926611..a0040ffd13fa 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -21,7 +21,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.os.Build; diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java index bfc216a24c1b..4c347373d642 100644 --- a/core/java/android/app/AlertDialog.java +++ b/core/java/android/app/AlertDialog.java @@ -21,7 +21,7 @@ import android.annotation.AttrRes; import android.annotation.DrawableRes; import android.annotation.StringRes; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.res.ResourceId; diff --git a/core/java/android/app/AppGlobals.java b/core/java/android/app/AppGlobals.java index 1f737b60964c..552d6e9334e2 100644 --- a/core/java/android/app/AppGlobals.java +++ b/core/java/android/app/AppGlobals.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.IPackageManager; /** diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 33d83f9b123b..7d3cd28c22d6 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -25,8 +25,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.usage.UsageStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java index e12942f248d4..941467fad736 100644 --- a/core/java/android/app/Application.java +++ b/core/java/android/app/Application.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks; import android.content.ComponentCallbacks2; import android.content.Context; diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index 2e59b903f06d..bac432e42318 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.SharedLibraryInfo; import android.os.Build; import android.os.GraphicsEnvironment; diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 835769f69951..1158c44e63c0 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -20,9 +20,9 @@ import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/app/ContentProviderHolder.java b/core/java/android/app/ContentProviderHolder.java index 004dca1a708f..3d745831ce1c 100644 --- a/core/java/android/app/ContentProviderHolder.java +++ b/core/java/android/app/ContentProviderHolder.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderNative; import android.content.IContentProvider; import android.content.pm.ProviderInfo; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index d317c34c6518..ce4d312318d4 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.BroadcastReceiver; import android.content.ComponentName; diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index 9d82ffa838ca..195c3e1c296a 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 088c245c9c2c..10525f7afc54 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -24,7 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java index bfc15c221702..e4c84d7e7997 100644 --- a/core/java/android/app/DialogFragment.java +++ b/core/java/android/app/DialogFragment.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 77a777024a21..bcc08e9a96fb 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -22,7 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 4f121aa35f7c..c6a0de458df0 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -21,7 +21,7 @@ import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/FragmentController.java b/core/java/android/app/FragmentController.java index 9316be7a7968..f021f7690283 100644 --- a/core/java/android/app/FragmentController.java +++ b/core/java/android/app/FragmentController.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java index 26b4a11f4c10..9e887b88c407 100644 --- a/core/java/android/app/FragmentHostCallback.java +++ b/core/java/android/app/FragmentHostCallback.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.IntentSender; diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 68daf44b19a5..904c4735e0ff 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -22,7 +22,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Configuration; diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 9720e9f47f83..cff6411c882c 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java index 74fb99a0909f..71b28fba6019 100644 --- a/core/java/android/app/IntentService.java +++ b/core/java/android/app/IntentService.java @@ -16,9 +16,9 @@ package android.app; -import android.annotation.UnsupportedAppUsage; -import android.annotation.WorkerThread; import android.annotation.Nullable; +import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 667758755c99..376acfaa6d90 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -23,8 +23,8 @@ import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.trust.ITrustManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 4efaaad91eb6..2a72d43eccad 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java index 19575b2b36ba..1d27f8fb6dbc 100644 --- a/core/java/android/app/LocalActivityManager.java +++ b/core/java/android/app/LocalActivityManager.java @@ -16,9 +16,9 @@ package android.app; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread.ActivityClientRecord; import android.app.servertransaction.PendingTransactionActions; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Binder; diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index 25eb958b61e3..74bc9e215106 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 412ef04c2284..cefec441e702 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -33,7 +33,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.LocusId; diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 69ec831b5d1d..b1d791b58a79 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -15,13 +15,11 @@ */ package android.app; -import static android.app.NotificationManager.IMPORTANCE_HIGH; - import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager.Importance; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java index a8ee414cac0a..afbd0b5afe1c 100644 --- a/core/java/android/app/NotificationChannelGroup.java +++ b/core/java/android/app/NotificationChannelGroup.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index c6aa4fd86594..e25558f16f26 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -23,8 +23,8 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Notification.Builder; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java index b7b0b192e7ae..d8803aa13e42 100644 --- a/core/java/android/app/PackageDeleteObserver.java +++ b/core/java/android/app/PackageDeleteObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.IPackageDeleteObserver2; diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java index 50031e0e4d35..0820367db1f8 100644 --- a/core/java/android/app/PackageInstallObserver.java +++ b/core/java/android/app/PackageInstallObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.IPackageInstallObserver2; import android.os.Bundle; diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 6f7a0607cbdb..6acbf21e5602 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.IIntentReceiver; import android.content.IIntentSender; diff --git a/core/java/android/app/PictureInPictureArgs.java b/core/java/android/app/PictureInPictureArgs.java index 3ee51739e455..9d49d107c99e 100644 --- a/core/java/android/app/PictureInPictureArgs.java +++ b/core/java/android/app/PictureInPictureArgs.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index cb72d4d5dc2c..f864fb57d00a 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -20,24 +20,24 @@ import static android.content.Context.DISPLAY_SERVICE; import static android.content.Context.WINDOW_SERVICE; import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java index 3193eb89ac80..432fae5e9033 100644 --- a/core/java/android/app/ProgressDialog.java +++ b/core/java/android/app/ProgressDialog.java @@ -16,9 +16,7 @@ package android.app; -import com.android.internal.R; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -34,6 +32,8 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; +import com.android.internal.R; + import java.text.NumberFormat; /** diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java index 76265390fe1a..82cc2c4daa0b 100644 --- a/core/java/android/app/QueuedWork.java +++ b/core/java/android/app/QueuedWork.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index e9ae60f23cf2..7d742f7e11eb 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -20,7 +20,7 @@ import static android.app.ActivityThread.DEBUG_CONFIGURATION; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.res.ApkAssets; diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java index 9ee0f3126432..979d3dbf36a7 100644 --- a/core/java/android/app/ResultInfo.java +++ b/core/java/android/app/ResultInfo.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 8493fb25b8a5..9fe894b75455 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -17,7 +17,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index acca6fc177b8..93107ad4bfcb 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java index a01cec7aa944..83eb2ee1da14 100644 --- a/core/java/android/app/SearchableInfo.java +++ b/core/java/android/app/SearchableInfo.java @@ -16,17 +16,14 @@ package android.app; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ProviderInfo; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Parcel; @@ -38,6 +35,9 @@ import android.util.Log; import android.util.Xml; import android.view.inputmethod.EditorInfo; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.util.HashMap; diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 9b62e3b3af98..dc8269f900b7 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -21,7 +21,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index 0f8976fe924a..3783d1c52ab1 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.SharedPreferences; import android.os.FileUtils; import android.os.Looper; diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index dc24467406cf..078e4538c66b 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index de64db9def64..fe9c64038909 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.content.res.Configuration; diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index 50130400deab..6247187bbfab 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -16,8 +16,8 @@ package android.app; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager.TaskSnapshot; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index 1b281d521957..c529297b14db 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 3935628b707f..20e31cab4b00 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -24,7 +24,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index f251b3eb4a15..5f89e5c2a9b0 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -19,6 +19,7 @@ package android.app; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.IPackageManager; import android.graphics.Bitmap; @@ -40,8 +41,6 @@ import android.view.WindowContentFrameStats; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; -import dalvik.annotation.compat.UnsupportedAppUsage; - import libcore.io.IoUtils; import java.io.FileInputStream; diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index 83247875c8a5..6582d240554b 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.os.RemoteException; diff --git a/core/java/android/app/UserSwitchObserver.java b/core/java/android/app/UserSwitchObserver.java index 2f8ee744bfd6..6abc4f09ba38 100644 --- a/core/java/android/app/UserSwitchObserver.java +++ b/core/java/android/app/UserSwitchObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IRemoteCallback; import android.os.RemoteException; diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java index c74f8c389c20..08a210b069b9 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -6,7 +6,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.os.RemoteException; diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 325a54bffbfb..102de950a129 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -26,7 +26,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 74237b4bfcb1..f4240b1c8a46 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -26,6 +26,7 @@ import static android.view.Surface.rotationToString; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Parcel; @@ -35,8 +36,6 @@ import android.util.proto.ProtoOutputStream; import android.util.proto.WireTypeMismatchException; import android.view.DisplayInfo; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.IOException; /** diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index 00903c43b291..3cc7f1e5df42 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -17,7 +17,7 @@ package android.app.admin; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index a17b2ddd7215..12d3c59c2bbb 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -33,13 +33,13 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.Activity; import android.app.IServiceConnection; import android.app.KeyguardManager; import android.app.admin.SecurityLog.SecurityEvent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 972762152d3a..f0b87a8e2561 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -18,7 +18,7 @@ package android.app.admin; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java index db6ae4f2260a..e5316bc05749 100644 --- a/core/java/android/app/assist/AssistContent.java +++ b/core/java/android/app/assist/AssistContent.java @@ -1,6 +1,6 @@ package android.app.assist; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.Intent; import android.net.Uri; diff --git a/core/java/android/app/backup/BackupDataInput.java b/core/java/android/app/backup/BackupDataInput.java index 2a98ca715a26..d1383c8d0a6a 100644 --- a/core/java/android/app/backup/BackupDataInput.java +++ b/core/java/android/app/backup/BackupDataInput.java @@ -17,7 +17,7 @@ package android.app.backup; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.FileDescriptor; import java.io.IOException; diff --git a/core/java/android/app/backup/BackupDataInputStream.java b/core/java/android/app/backup/BackupDataInputStream.java index 08880665d921..11a3d0c3d725 100644 --- a/core/java/android/app/backup/BackupDataInputStream.java +++ b/core/java/android/app/backup/BackupDataInputStream.java @@ -16,9 +16,10 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; -import java.io.InputStream; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.IOException; +import java.io.InputStream; /** * Provides an {@link java.io.InputStream}-like interface for accessing an diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java index 01961e78777f..fb161d41acd2 100644 --- a/core/java/android/app/backup/BackupDataOutput.java +++ b/core/java/android/app/backup/BackupDataOutput.java @@ -17,7 +17,7 @@ package android.app.backup; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; import java.io.FileDescriptor; diff --git a/core/java/android/app/backup/BackupHelperDispatcher.java b/core/java/android/app/backup/BackupHelperDispatcher.java index e9acdbfb61b9..6faa887206c1 100644 --- a/core/java/android/app/backup/BackupHelperDispatcher.java +++ b/core/java/android/app/backup/BackupHelperDispatcher.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; import android.util.Log; diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index 25caaaa6e5ad..dc815b631e46 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/backup/FileBackupHelperBase.java b/core/java/android/app/backup/FileBackupHelperBase.java index 0caab983448b..5ad5d0865e56 100644 --- a/core/java/android/app/backup/FileBackupHelperBase.java +++ b/core/java/android/app/backup/FileBackupHelperBase.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.ParcelFileDescriptor; import android.util.Log; diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index 9a595b2da59f..587e883edaf2 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java index 0ce86534afdd..d8fa0f586b7a 100644 --- a/core/java/android/app/backup/FullBackupDataOutput.java +++ b/core/java/android/app/backup/FullBackupDataOutput.java @@ -1,6 +1,6 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; /** diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java index a8f89df8058c..72eea849cbf4 100644 --- a/core/java/android/app/job/JobInfo.java +++ b/core/java/android/app/job/JobInfo.java @@ -29,7 +29,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ComponentName; import android.net.NetworkRequest; diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java index dadfe3d3746a..763520272e2e 100644 --- a/core/java/android/app/job/JobParameters.java +++ b/core/java/android/app/job/JobParameters.java @@ -18,8 +18,7 @@ package android.app.job; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.app.job.IJobCallback; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.net.Network; import android.net.Uri; diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java index a055ab48c766..237c5071a130 100644 --- a/core/java/android/app/job/JobWorkItem.java +++ b/core/java/android/app/job/JobWorkItem.java @@ -19,7 +19,7 @@ package android.app.job; import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN; import android.annotation.BytesLong; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java index 52ec3e60a9c7..4e743caccad6 100644 --- a/core/java/android/app/servertransaction/ActivityResultItem.java +++ b/core/java/android/app/servertransaction/ActivityResultItem.java @@ -18,9 +18,9 @@ package android.app.servertransaction; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; import android.app.ResultInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index b08e5973faa2..4d2e9a503ac5 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -17,9 +17,9 @@ package android.app.servertransaction; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; import android.app.IApplicationThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index 1236e0ac7401..6d674ae7df14 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -18,11 +18,11 @@ package android.app.servertransaction; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.app.ProfilerInfo; import android.app.ResultInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.CompatibilityInfo; diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java index bb775fc4a5fb..6a4996da38ca 100644 --- a/core/java/android/app/servertransaction/NewIntentItem.java +++ b/core/java/android/app/servertransaction/NewIntentItem.java @@ -19,8 +19,8 @@ package android.app.servertransaction; import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME; import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java index 55f92be14cd0..50de73855511 100644 --- a/core/java/android/app/timedetector/ManualTimeSuggestion.java +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java index 4c55ba12d881..17e9c5a79fa5 100644 --- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java +++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.java b/core/java/android/app/timedetector/PhoneTimeSuggestion.java index 4a89a1245473..479e4b4efb4c 100644 --- a/core/java/android/app/timedetector/PhoneTimeSuggestion.java +++ b/core/java/android/app/timedetector/PhoneTimeSuggestion.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Collections; diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java index af9ece00f491..54dd1bed5361 100644 --- a/core/java/android/app/timedetector/TimeDetector.java +++ b/core/java/android/app/timedetector/TimeDetector.java @@ -24,8 +24,8 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemClock; +import android.os.TimestampedValue; import android.util.Log; -import android.util.TimestampedValue; /** * The interface through which system components can send signals to the TimeDetectorService. diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 27abdcfbefc9..65b2775fd66b 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -19,7 +19,7 @@ package android.app.trust; import android.Manifest; import android.annotation.RequiresPermission; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; diff --git a/core/java/android/app/usage/ConfigurationStats.java b/core/java/android/app/usage/ConfigurationStats.java index da3b76972ced..8a7107de8363 100644 --- a/core/java/android/app/usage/ConfigurationStats.java +++ b/core/java/android/app/usage/ConfigurationStats.java @@ -15,7 +15,7 @@ */ package android.app.usage; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 6bade901826a..74129702b487 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -21,8 +21,8 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.usage.NetworkStats.Bucket; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.ConnectivityManager; import android.net.DataUsageRequest; diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 84c68552c40a..c646fc69702d 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -18,7 +18,7 @@ package android.app.usage; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java index 2c021cc42cb5..3550ebd24026 100644 --- a/core/java/android/app/usage/UsageStats.java +++ b/core/java/android/app/usage/UsageStats.java @@ -29,7 +29,7 @@ import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 92e1b30793c9..102a08d17deb 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -23,9 +23,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.Build; diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index f003d4bea028..f61d35bc7d33 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -18,8 +18,8 @@ package android.appwidget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.IntentSender; diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 85f0e2342412..09d56ec70e56 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -16,9 +16,9 @@ package android.appwidget; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityOptions; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index dbc1c199cb4d..6dea1c69ce86 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -23,9 +23,9 @@ import android.annotation.RequiresFeature; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.IServiceConnection; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 2faa9007fc29..130a20dfb07b 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -18,8 +18,8 @@ package android.appwidget; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 291d1d99fdc9..220b77b299a4 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -2670,6 +2670,9 @@ public final class BluetoothAdapter { } else if (profile == BluetoothProfile.PAN) { BluetoothPan pan = new BluetoothPan(context, listener); return true; + } else if (profile == BluetoothProfile.PBAP) { + BluetoothPbap pbap = new BluetoothPbap(context, listener); + return true; } else if (profile == BluetoothProfile.HEALTH) { Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated"); return false; @@ -2742,6 +2745,10 @@ public final class BluetoothAdapter { BluetoothPan pan = (BluetoothPan) proxy; pan.close(); break; + case BluetoothProfile.PBAP: + BluetoothPbap pbap = (BluetoothPbap) proxy; + pbap.close(); + break; case BluetoothProfile.GATT: BluetoothGatt gatt = (BluetoothGatt) proxy; gatt.close(); diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java index e9b0be2c4cd6..a923be62fbce 100644 --- a/core/java/android/bluetooth/BluetoothHidDevice.java +++ b/core/java/android/bluetooth/BluetoothHidDevice.java @@ -16,8 +16,12 @@ package android.bluetooth; +import android.Manifest; +import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -36,6 +40,7 @@ import java.util.concurrent.Executor; */ public final class BluetoothHidDevice implements BluetoothProfile { private static final String TAG = BluetoothHidDevice.class.getSimpleName(); + private static final boolean DBG = false; /** * Intent used to broadcast the change in connection state of the Input Host profile. @@ -682,4 +687,62 @@ public final class BluetoothHidDevice implements BluetoothProfile { return result; } + + /** + * Connects Hid Device if connectionPolicy is {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} + * and disconnects Hid device if connectionPolicy is + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}. + * + * <p> The device should already be paired. + * Connection policy can be one of: + * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, + * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + * + * @param device Paired bluetooth device + * @param connectionPolicy determines whether hid device should be connected or disconnected + * @return true if hid device is connected or disconnected, false otherwise + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, + @ConnectionPolicy int connectionPolicy) { + log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); + try { + final IBluetoothHidDevice service = getService(); + if (service != null && isEnabled() + && isValidDevice(device)) { + if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN + && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) { + return false; + } + return service.setConnectionPolicy(device, connectionPolicy); + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } + } + + private boolean isEnabled() { + if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; + return false; + } + + private boolean isValidDevice(BluetoothDevice device) { + if (device == null) return false; + + if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; + return false; + } + + private static void log(String msg) { + if (DBG) { + Log.d(TAG, msg); + } + } } diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java index 979dfd4e3ba5..f2ceabcc7d75 100644 --- a/core/java/android/bluetooth/BluetoothMap.java +++ b/core/java/android/bluetooth/BluetoothMap.java @@ -17,7 +17,10 @@ package android.bluetooth; import android.Manifest; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.content.Context; @@ -35,21 +38,35 @@ import java.util.List; * * @hide */ +@SystemApi public final class BluetoothMap implements BluetoothProfile { private static final String TAG = "BluetoothMap"; private static final boolean DBG = true; private static final boolean VDBG = false; + /** @hide */ + @SuppressLint("ActionValue") + @SystemApi public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; - /** There was an error trying to obtain the state */ + /** + * There was an error trying to obtain the state + * + * @hide + */ public static final int STATE_ERROR = -1; + /** @hide */ public static final int RESULT_FAILURE = 0; + /** @hide */ public static final int RESULT_SUCCESS = 1; - /** Connection canceled before completion. */ + /** + * Connection canceled before completion. + * + * @hide + */ public static final int RESULT_CANCELED = 2; private BluetoothAdapter mAdapter; @@ -71,6 +88,7 @@ public final class BluetoothMap implements BluetoothProfile { mProfileConnector.connect(context, listener); } + @SuppressLint("GenericException") protected void finalize() throws Throwable { try { close(); @@ -84,6 +102,8 @@ public final class BluetoothMap implements BluetoothProfile { * Other public functions of BluetoothMap will return default error * results once close() has been called. Multiple invocations of close() * are ok. + * + * @hide */ public synchronized void close() { mProfileConnector.disconnect(); @@ -98,6 +118,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not * connected to the Map service. + * + * @hide */ public int getState() { if (VDBG) log("getState()"); @@ -120,6 +142,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @return The remote Bluetooth device, or null if not in connected or connecting state, or if * this proxy object is not connected to the Map service. + * + * @hide */ public BluetoothDevice getClient() { if (VDBG) log("getClient()"); @@ -141,6 +165,8 @@ public final class BluetoothMap implements BluetoothProfile { * Returns true if the specified Bluetooth device is connected. * Returns false if not connected, or if this proxy object is not * currently connected to the Map service. + * + * @hide */ public boolean isConnected(BluetoothDevice device) { if (VDBG) log("isConnected(" + device + ")"); @@ -161,6 +187,8 @@ public final class BluetoothMap implements BluetoothProfile { /** * Initiate connection. Initiation of outgoing connections is not * supported for MAP server. + * + * @hide */ public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")" + "not supported for MAPS"); @@ -172,6 +200,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @param device Remote Bluetooth Device * @return false on error, true otherwise + * + * @hide */ @UnsupportedAppUsage public boolean disconnect(BluetoothDevice device) { @@ -196,6 +226,8 @@ public final class BluetoothMap implements BluetoothProfile { * devices. It tries to err on the side of false positives. * * @return True if this device might support Map. + * + * @hide */ public static boolean doesClassMatchSink(BluetoothClass btClass) { // TODO optimize the rule @@ -214,8 +246,11 @@ public final class BluetoothMap implements BluetoothProfile { * Get the list of connected devices. Currently at most one. * * @return list of connected devices + * + * @hide */ - public List<BluetoothDevice> getConnectedDevices() { + @SystemApi + public @NonNull List<BluetoothDevice> getConnectedDevices() { if (DBG) log("getConnectedDevices()"); final IBluetoothMap service = getService(); if (service != null && isEnabled()) { @@ -234,6 +269,8 @@ public final class BluetoothMap implements BluetoothProfile { * Get the list of devices matching specified states. Currently at most one. * * @return list of matching devices + * + * @hide */ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { if (DBG) log("getDevicesMatchingStates()"); @@ -254,6 +291,8 @@ public final class BluetoothMap implements BluetoothProfile { * Get connection state of device * * @return device connection state + * + * @hide */ public int getConnectionState(BluetoothDevice device) { if (DBG) log("getConnectionState(" + device + ")"); @@ -301,7 +340,7 @@ public final class BluetoothMap implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { + public boolean setConnectionPolicy(@Nullable BluetoothDevice device, int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothMap service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { @@ -349,7 +388,7 @@ public final class BluetoothMap implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH) - public int getConnectionPolicy(BluetoothDevice device) { + public int getConnectionPolicy(@Nullable BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothMap service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index 4e9762737c07..f5de4addb072 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -16,9 +16,11 @@ package android.bluetooth; +import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SuppressLint; @@ -256,6 +258,41 @@ public final class BluetoothPan implements BluetoothProfile { } /** + * Set connection policy of the profile + * + * <p> The device should already be paired. + * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED}, + * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN} + * + * @param device Paired bluetooth device + * @param connectionPolicy is the connection policy to set to for this profile + * @return true if connectionPolicy is set, false on error + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, + @ConnectionPolicy int connectionPolicy) { + if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); + try { + final IBluetoothPan service = getService(); + if (service != null && isEnabled() + && isValidDevice(device)) { + if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN + && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) { + return false; + } + return service.setConnectionPolicy(device, connectionPolicy); + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } + } + + /** * {@inheritDoc} */ @Override diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 291015070385..74ee2c3fba01 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -274,15 +274,15 @@ public class BluetoothPbap implements BluetoothProfile { } /** - * Pbap does not store connection policy, so this function only disconnects Pbap if - * connectionPolicy is CONNECTION_POLICY_FORBIDDEN. + * Pbap does not store connection policy, so this function only disconnects pbap if + * connectionPolicy is {@link #CONNECTION_POLICY_FORBIDDEN}. * * <p> The device should already be paired. * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED}, * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device - * @param connectionPolicy is the connection policy to set to for this profile + * @param connectionPolicy determines whether to disconnect the device * @return true if pbap is successfully disconnected, false otherwise * @hide */ diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 2e4bff0c66f5..3c85649690ef 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3107,6 +3107,61 @@ public class ConnectivityManager { } } + /** + * Registers the specified {@link NetworkProvider}. + * Each listener must only be registered once. The listener can be unregistered with + * {@link #unregisterNetworkProvider}. + * + * @param provider the provider to register + * @return the ID of the provider. This ID must be used by the provider when registering + * {@link android.net.NetworkAgent}s. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public int registerNetworkProvider(@NonNull NetworkProvider provider) { + if (provider.getProviderId() != NetworkProvider.ID_NONE) { + throw new IllegalStateException("NetworkProviders can only be registered once"); + } + + try { + int providerId = mService.registerNetworkProvider(provider.getMessenger(), + provider.getName()); + provider.setProviderId(providerId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return provider.getProviderId(); + } + + /** + * Unregisters the specified NetworkProvider. + * + * @param provider the provider to unregister + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void unregisterNetworkProvider(@NonNull NetworkProvider provider) { + try { + mService.unregisterNetworkProvider(provider.getMessenger()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + provider.setProviderId(NetworkProvider.ID_NONE); + } + + + /** @hide exposed via the NetworkProvider class. */ + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { + try { + mService.declareNetworkRequestUnfulfillable(request); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this // temporarily helps with the process of going through with all these dependent changes across @@ -3119,8 +3174,7 @@ public class ConnectivityManager { @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, NetworkCapabilities nc, int score, NetworkMisc misc) { - return registerNetworkAgent(messenger, ni, lp, nc, score, misc, - NetworkFactory.SerialNumber.NONE); + return registerNetworkAgent(messenger, ni, lp, nc, score, misc, NetworkProvider.ID_NONE); } /** @@ -3130,10 +3184,9 @@ public class ConnectivityManager { */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkMisc misc, int factorySerialNumber) { + NetworkCapabilities nc, int score, NetworkMisc misc, int providerId) { try { - return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc, - factorySerialNumber); + return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc, providerId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java index 98bab44e19fb..912df67a0b45 100644 --- a/core/java/android/net/DhcpInfo.java +++ b/core/java/android/net/DhcpInfo.java @@ -16,8 +16,8 @@ package android.net; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; /** * A simple object for retrieving the results of a DHCP request. @@ -67,12 +67,12 @@ public class DhcpInfo implements Parcelable { buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress()); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(ipAddress); dest.writeInt(gateway); @@ -83,7 +83,7 @@ public class DhcpInfo implements Parcelable { dest.writeInt(leaseDuration); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final @android.annotation.NonNull Creator<DhcpInfo> CREATOR = new Creator<DhcpInfo>() { public DhcpInfo createFromParcel(Parcel in) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 09c02efbcfc4..e6a0379ff629 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -142,12 +142,16 @@ interface IConnectivityManager void setAirplaneMode(boolean enable); - int registerNetworkFactory(in Messenger messenger, in String name); - boolean requestBandwidthUpdate(in Network network); + int registerNetworkFactory(in Messenger messenger, in String name); void unregisterNetworkFactory(in Messenger messenger); + int registerNetworkProvider(in Messenger messenger, in String name); + void unregisterNetworkProvider(in Messenger messenger); + + void declareNetworkRequestUnfulfillable(in NetworkRequest request); + int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber); diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index 106b7be5c8d3..fe9141cb6a20 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -15,6 +15,7 @@ */ package android.net; +import android.telephony.SubscriptionPlan; /** {@hide} */ oneway interface INetworkPolicyListener { @@ -22,5 +23,6 @@ oneway interface INetworkPolicyListener { void onMeteredIfacesChanged(in String[] meteredIfaces); void onRestrictBackgroundChanged(boolean restrictBackground); void onUidPoliciesChanged(int uid, int uidPolicies); - void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask); + void onSubscriptionOverride(int subId, int overrideMask, int overrideValue); + void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans); } diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl index 90327663e34b..385cb1d68b57 100644 --- a/core/java/android/net/INetworkPolicyManager.aidl +++ b/core/java/android/net/INetworkPolicyManager.aidl @@ -76,7 +76,7 @@ interface INetworkPolicyManager { SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage); void setSubscriptionPlans(int subId, in SubscriptionPlan[] plans, String callingPackage); String getSubscriptionPlansOwner(int subId); - void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask, long timeoutMillis, String callingPackage); + void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long timeoutMillis, String callingPackage); void factoryReset(String subscriber); diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java new file mode 100644 index 000000000000..909998d4562c --- /dev/null +++ b/core/java/android/net/InvalidPacketException.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.annotation.IntDef; +import android.annotation.SystemApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Thrown when a packet is invalid. + * @hide + */ +@SystemApi +public class InvalidPacketException extends Exception { + public final int error; + + // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS. + /** Invalid IP address. */ + public static final int ERROR_INVALID_IP_ADDRESS = -21; + + // Must match SocketKeepalive#ERROR_INVALID_PORT. + /** Invalid port number. */ + public static final int ERROR_INVALID_PORT = -22; + + // Must match SocketKeepalive#ERROR_INVALID_LENGTH. + /** Invalid packet length. */ + public static final int ERROR_INVALID_LENGTH = -23; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "ERROR_" }, value = { + ERROR_INVALID_IP_ADDRESS, + ERROR_INVALID_PORT, + ERROR_INVALID_LENGTH + }) + public @interface ErrorCode {} + + /** + * This packet is invalid. + * See the error code for details. + */ + public InvalidPacketException(@ErrorCode final int error) { + this.error = error; + } +} diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 45d0c7313fca..09ec6c35fcb9 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -17,7 +17,6 @@ package android.net; import static com.android.internal.util.Preconditions.checkNotNull; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; @@ -26,6 +25,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; import android.content.pm.PackageManager; +import android.net.annotations.PolicyDirection; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -41,8 +41,6 @@ import dalvik.system.CloseGuard; import java.io.FileDescriptor; import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.Socket; @@ -78,11 +76,6 @@ public final class IpSecManager { */ public static final int DIRECTION_OUT = 1; - /** @hide */ - @IntDef(value = {DIRECTION_IN, DIRECTION_OUT}) - @Retention(RetentionPolicy.SOURCE) - public @interface PolicyDirection {} - /** * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index. * diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java index 9b8b7322cd23..2b8b7e69dec9 100644 --- a/core/java/android/net/KeepalivePacketData.java +++ b/core/java/android/net/KeepalivePacketData.java @@ -16,13 +16,13 @@ package android.net; -import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; -import static android.net.SocketKeepalive.ERROR_INVALID_PORT; +import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS; +import static android.net.InvalidPacketException.ERROR_INVALID_PORT; -import android.net.SocketKeepalive.InvalidPacketException; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.net.util.IpUtils; import android.os.Parcel; -import android.os.Parcelable; import android.util.Log; import java.net.InetAddress; @@ -33,13 +33,16 @@ import java.net.InetAddress; * * @hide */ -public class KeepalivePacketData implements Parcelable { +@SystemApi +public class KeepalivePacketData { private static final String TAG = "KeepalivePacketData"; /** Source IP address */ + @NonNull public final InetAddress srcAddress; /** Destination IP address */ + @NonNull public final InetAddress dstAddress; /** Source port */ @@ -51,13 +54,14 @@ public class KeepalivePacketData implements Parcelable { /** Packet data. A raw byte string of packet data, not including the link-layer header. */ private final byte[] mPacket; - protected static final int IPV4_HEADER_LENGTH = 20; - protected static final int UDP_HEADER_LENGTH = 8; - // This should only be constructed via static factory methods, such as - // nattKeepalivePacket - protected KeepalivePacketData(InetAddress srcAddress, int srcPort, - InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException { + // nattKeepalivePacket. + /** + * A holding class for data necessary to build a keepalive packet. + */ + protected KeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort, + @NonNull InetAddress dstAddress, int dstPort, + @NonNull byte[] data) throws InvalidPacketException { this.srcAddress = srcAddress; this.dstAddress = dstAddress; this.srcPort = srcPort; @@ -78,16 +82,12 @@ public class KeepalivePacketData implements Parcelable { } } + @NonNull public byte[] getPacket() { return mPacket.clone(); } - /* Parcelable Implementation */ - public int describeContents() { - return 0; - } - - /** Write to parcel */ + /** @hide */ public void writeToParcel(Parcel out, int flags) { out.writeString(srcAddress.getHostAddress()); out.writeString(dstAddress.getHostAddress()); @@ -96,6 +96,7 @@ public class KeepalivePacketData implements Parcelable { out.writeByteArray(mPacket); } + /** @hide */ protected KeepalivePacketData(Parcel in) { srcAddress = NetworkUtils.numericToInetAddress(in.readString()); dstAddress = NetworkUtils.numericToInetAddress(in.readString()); @@ -103,17 +104,4 @@ public class KeepalivePacketData implements Parcelable { dstPort = in.readInt(); mPacket = in.createByteArray(); } - - /** Parcelable Creator */ - public static final @android.annotation.NonNull Parcelable.Creator<KeepalivePacketData> CREATOR = - new Parcelable.Creator<KeepalivePacketData>() { - public KeepalivePacketData createFromParcel(Parcel in) { - return new KeepalivePacketData(in); - } - - public KeepalivePacketData[] newArray(int size) { - return new KeepalivePacketData[size]; - } - }; - } diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java index a77c244d6b40..3fb52f12a88d 100644 --- a/core/java/android/net/NattKeepalivePacketData.java +++ b/core/java/android/net/NattKeepalivePacketData.java @@ -19,7 +19,6 @@ package android.net; import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import static android.net.SocketKeepalive.ERROR_INVALID_PORT; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; @@ -32,6 +31,9 @@ import java.nio.ByteOrder; /** @hide */ public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable { + private static final int IPV4_HEADER_LENGTH = 20; + private static final int UDP_HEADER_LENGTH = 8; + // This should only be constructed via static factory methods, such as // nattKeepalivePacket private NattKeepalivePacketData(InetAddress srcAddress, int srcPort, diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 60bd5730f8cf..5f6cc6eced5d 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -58,7 +58,7 @@ public abstract class NetworkAgent extends Handler { private static final long BW_REFRESH_MIN_WIN_MS = 500; private boolean mPollLceScheduled = false; private AtomicBoolean mPollLcePending = new AtomicBoolean(false); - public final int mFactorySerialNumber; + public final int mProviderId; private static final int BASE = Protocol.BASE_NETWORK_AGENT; @@ -219,25 +219,25 @@ public abstract class NetworkAgent extends Handler { // the entire tree. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score) { - this(looper, context, logTag, ni, nc, lp, score, null, NetworkFactory.SerialNumber.NONE); + this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) { - this(looper, context, logTag, ni, nc, lp, score, misc, NetworkFactory.SerialNumber.NONE); + this(looper, context, logTag, ni, nc, lp, score, misc, NetworkProvider.ID_NONE); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, - NetworkCapabilities nc, LinkProperties lp, int score, int factorySerialNumber) { - this(looper, context, logTag, ni, nc, lp, score, null, factorySerialNumber); + NetworkCapabilities nc, LinkProperties lp, int score, int providerId) { + this(looper, context, logTag, ni, nc, lp, score, null, providerId); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc, - int factorySerialNumber) { + int providerId) { super(looper); LOG_TAG = logTag; mContext = context; - mFactorySerialNumber = factorySerialNumber; + mProviderId = providerId; if (ni == null || nc == null || lp == null) { throw new IllegalArgumentException(); } @@ -246,8 +246,7 @@ public abstract class NetworkAgent extends Handler { ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( Context.CONNECTIVITY_SERVICE); netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), - new LinkProperties(lp), new NetworkCapabilities(nc), score, misc, - factorySerialNumber); + new LinkProperties(lp), new NetworkCapabilities(nc), score, misc, providerId); } @Override diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index a5e567d274c1..f43385d1f2e0 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -587,15 +587,14 @@ public final class NetworkCapabilities implements Parcelable { } /** - * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are - * typically provided by restricted networks. + * Deduces that all the capabilities it provides are typically provided by restricted networks + * or not. * - * TODO: consider: - * - Renaming it to guessRestrictedCapability and make it set the - * restricted capability bit in addition to clearing it. + * @return {@code true} if the network should be restricted. * @hide */ - public void maybeMarkCapabilitiesRestricted() { + @SystemApi + public boolean deduceRestrictedCapability() { // Check if we have any capability that forces the network to be restricted. final boolean forceRestrictedCapability = (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0; @@ -609,8 +608,17 @@ public final class NetworkCapabilities implements Parcelable { final boolean hasRestrictedCapabilities = (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0; - if (forceRestrictedCapability - || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities)) { + return forceRestrictedCapability + || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities); + } + + /** + * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if deducing the network is restricted. + * + * @hide + */ + public void maybeMarkCapabilitiesRestricted() { + if (deduceRestrictedCapability()) { removeCapability(NET_CAPABILITY_NOT_RESTRICTED); } } diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java index 42ab9256a6ab..824ddb8dd260 100644 --- a/core/java/android/net/NetworkFactory.java +++ b/core/java/android/net/NetworkFactory.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; @@ -27,7 +28,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.AsyncChannel; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Protocol; @@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide **/ public class NetworkFactory extends Handler { - /** @hide */ + /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ public static class SerialNumber { // Guard used by no network factory. public static final int NONE = -1; @@ -91,8 +91,8 @@ public class NetworkFactory extends Handler { * with the same NetworkRequest but an updated score. * Also, network conditions may change for this bearer * allowing for a better score in the future. - * msg.arg2 = the serial number of the factory currently responsible for the - * NetworkAgent handling this request, or SerialNumber.NONE if none. + * msg.arg2 = the ID of the NetworkProvider currently responsible for the + * NetworkAgent handling this request, or NetworkProvider.ID_NONE if none. */ public static final int CMD_REQUEST_NETWORK = BASE; @@ -124,7 +124,6 @@ public class NetworkFactory extends Handler { private final Context mContext; private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>(); - private AsyncChannel mAsyncChannel; private final String LOG_TAG; private final SparseArray<NetworkRequestInfo> mNetworkRequests = @@ -135,7 +134,8 @@ public class NetworkFactory extends Handler { private int mRefCount = 0; private Messenger mMessenger = null; - private int mSerialNumber; + private NetworkProvider mProvider = null; + private int mProviderId; @UnsupportedAppUsage public NetworkFactory(Looper looper, Context context, String logTag, @@ -147,55 +147,43 @@ public class NetworkFactory extends Handler { } public void register() { - if (DBG) log("Registering NetworkFactory"); - if (mMessenger == null) { - mMessenger = new Messenger(this); - mSerialNumber = ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, - LOG_TAG); + if (mProvider != null) { + Log.e(LOG_TAG, "Ignoring attempt to register already-registered NetworkFactory"); + return; } + if (DBG) log("Registering NetworkFactory"); + + mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) { + @Override + public void onNetworkRequested(@NonNull NetworkRequest request, int score, + int servingProviderId) { + handleAddRequest((NetworkRequest) request, score, servingProviderId); + } + + @Override + public void onRequestWithdrawn(@NonNull NetworkRequest request) { + handleRemoveRequest(request); + } + }; + + mMessenger = new Messenger(this); + mProviderId = ConnectivityManager.from(mContext).registerNetworkProvider(mProvider); } public void unregister() { - if (DBG) log("Unregistering NetworkFactory"); - if (mMessenger != null) { - ConnectivityManager.from(mContext).unregisterNetworkFactory(mMessenger); - mMessenger = null; + if (mProvider == null) { + Log.e(LOG_TAG, "Ignoring attempt to unregister unregistered NetworkFactory"); + return; } + if (DBG) log("Unregistering NetworkFactory"); + + ConnectivityManager.from(mContext).unregisterNetworkProvider(mProvider); + mProvider = null; } @Override public void handleMessage(Message msg) { switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { - if (mAsyncChannel != null) { - log("Received new connection while already connected!"); - break; - } - if (VDBG) log("NetworkFactory fully connected"); - AsyncChannel ac = new AsyncChannel(); - ac.connected(null, this, msg.replyTo); - ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, - AsyncChannel.STATUS_SUCCESSFUL); - mAsyncChannel = ac; - for (Message m : mPreConnectedQueue) { - ac.sendMessage(m); - } - mPreConnectedQueue.clear(); - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECT: { - if (VDBG) log("CMD_CHANNEL_DISCONNECT"); - if (mAsyncChannel != null) { - mAsyncChannel.disconnect(); - mAsyncChannel = null; - } - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { - if (DBG) log("NetworkFactory channel lost"); - mAsyncChannel = null; - break; - } case CMD_REQUEST_NETWORK: { handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2); break; @@ -219,13 +207,13 @@ public class NetworkFactory extends Handler { public final NetworkRequest request; public int score; public boolean requested; // do we have a request outstanding, limited by score - public int factorySerialNumber; + public int providerId; - NetworkRequestInfo(NetworkRequest request, int score, int factorySerialNumber) { + NetworkRequestInfo(NetworkRequest request, int score, int providerId) { this.request = request; this.score = score; this.requested = false; - this.factorySerialNumber = factorySerialNumber; + this.providerId = providerId; } @Override @@ -240,8 +228,6 @@ public class NetworkFactory extends Handler { * * @param request the request to handle. * @param score the score of the NetworkAgent currently satisfying this request. - * @param servingFactorySerialNumber the serial number of the NetworkFactory that - * created the NetworkAgent currently satisfying this request. */ // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this @@ -249,7 +235,7 @@ public class NetworkFactory extends Handler { // the entire tree. @VisibleForTesting protected void handleAddRequest(NetworkRequest request, int score) { - handleAddRequest(request, score, SerialNumber.NONE); + handleAddRequest(request, score, NetworkProvider.ID_NONE); } /** @@ -258,27 +244,26 @@ public class NetworkFactory extends Handler { * * @param request the request to handle. * @param score the score of the NetworkAgent currently satisfying this request. - * @param servingFactorySerialNumber the serial number of the NetworkFactory that - * created the NetworkAgent currently satisfying this request. + * @param servingProviderId the ID of the NetworkProvider that created the NetworkAgent + * currently satisfying this request. */ @VisibleForTesting - protected void handleAddRequest(NetworkRequest request, int score, - int servingFactorySerialNumber) { + protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) { NetworkRequestInfo n = mNetworkRequests.get(request.requestId); if (n == null) { if (DBG) { log("got request " + request + " with score " + score - + " and serial " + servingFactorySerialNumber); + + " and providerId " + servingProviderId); } - n = new NetworkRequestInfo(request, score, servingFactorySerialNumber); + n = new NetworkRequestInfo(request, score, servingProviderId); mNetworkRequests.put(n.request.requestId, n); } else { if (VDBG) { log("new score " + score + " for exisiting request " + request - + " with serial " + servingFactorySerialNumber); + + " and providerId " + servingProviderId); } n.score = score; - n.factorySerialNumber = servingFactorySerialNumber; + n.providerId = servingProviderId; } if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter); @@ -333,8 +318,8 @@ public class NetworkFactory extends Handler { log(" n.requests = " + n.requested); log(" n.score = " + n.score); log(" mScore = " + mScore); - log(" n.factorySerialNumber = " + n.factorySerialNumber); - log(" mSerialNumber = " + mSerialNumber); + log(" n.providerId = " + n.providerId); + log(" mProviderId = " + mProviderId); } if (shouldNeedNetworkFor(n)) { if (VDBG) log(" needNetworkFor"); @@ -355,7 +340,7 @@ public class NetworkFactory extends Handler { // If the score of this request is higher or equal to that of this factory and some // other factory is responsible for it, then this factory should not track the request // because it has no hope of satisfying it. - && (n.score < mScore || n.factorySerialNumber == mSerialNumber) + && (n.score < mScore || n.providerId == mProviderId) // If this factory can't satisfy the capability needs of this request, then it // should not be tracked. && n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter) @@ -373,7 +358,7 @@ public class NetworkFactory extends Handler { // assigned to the factory // - This factory can't satisfy the capability needs of the request // - The concrete implementation of the factory rejects the request - && ((n.score > mScore && n.factorySerialNumber != mSerialNumber) + && ((n.score > mScore && n.providerId != mProviderId) || !n.request.networkCapabilities.satisfiedByNetworkCapabilities( mCapabilityFilter) || !acceptRequest(n.request, n.score)); @@ -408,12 +393,7 @@ public class NetworkFactory extends Handler { protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) { post(() -> { if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r); - Message msg = obtainMessage(EVENT_UNFULFILLABLE_REQUEST, r); - if (mAsyncChannel != null) { - mAsyncChannel.sendMessage(msg); - } else { - mPreConnectedQueue.add(msg); - } + ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(r); }); } @@ -444,8 +424,13 @@ public class NetworkFactory extends Handler { return mNetworkRequests.size(); } + /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ public int getSerialNumber() { - return mSerialNumber; + return mProviderId; + } + + public int getProviderId() { + return mProviderId; } protected void log(String s) { @@ -465,8 +450,8 @@ public class NetworkFactory extends Handler { @Override public String toString() { - StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mSerialNumber=") - .append(mSerialNumber).append(", ScoreFilter=") + StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mProviderId=") + .append(mProviderId).append(", ScoreFilter=") .append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=") .append(mNetworkRequests.size()).append(", refCount=").append(mRefCount) .append("}"); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 53854c23baac..de962f8f25e3 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -31,6 +31,7 @@ import android.net.wifi.WifiInfo; import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; +import android.telephony.SubscriptionPlan; import android.util.DebugUtils; import android.util.Pair; import android.util.Range; @@ -380,7 +381,8 @@ public class NetworkPolicyManager { @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { } @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { } @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { } - @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, - long networkTypeMask) { } + @Override public void onSubscriptionOverride(int subId, int overrideMask, + int overrideValue) { } + @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { } } } diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java new file mode 100644 index 000000000000..2c0e4aa700b1 --- /dev/null +++ b/core/java/android/net/NetworkProvider.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.Messenger; +import android.util.Log; + +/** + * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device + * to networks and makes them available to to the core network stack by creating + * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted + * with via networking APIs such as {@link ConnectivityManager}. + * + * Subclasses should implement {@link #onNetworkRequested} and {@link #onRequestWithdrawn} to + * receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the + * best (highest-scoring) network for any request is generally not used by the system, and torn + * down. + * + * @hide + */ +@SystemApi +public class NetworkProvider { + /** + * {@code providerId} value that indicates the absence of a provider. It is the providerId of + * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not + * currently being satisfied by a network. + */ + public static final int ID_NONE = -1; + + /** + * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any + * provider, so they use this constant for clarity instead of NONE. + * @hide only used by ConnectivityService. + */ + public static final int ID_VPN = -2; + + /** + * The first providerId value that will be allocated. + * @hide only used by ConnectivityService. + */ + public static final int FIRST_PROVIDER_ID = 1; + + /** @hide only used by ConnectivityService */ + public static final int CMD_REQUEST_NETWORK = 1; + /** @hide only used by ConnectivityService */ + public static final int CMD_CANCEL_REQUEST = 2; + + private final Messenger mMessenger; + private final String mName; + private final ConnectivityManager mCm; + + private int mProviderId = ID_NONE; + + /** + * Constructs a new NetworkProvider. + * + * @param looper the Looper on which to run {@link #onNetworkRequested} and + * {@link #onRequestWithdrawn}. + * @param name the name of the listener, used only for debugging. + * + * @hide + */ + @SystemApi + public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { + mCm = ConnectivityManager.from(context); + + Handler handler = new Handler(looper) { + @Override + public void handleMessage(Message m) { + switch (m.what) { + case CMD_REQUEST_NETWORK: + onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); + break; + case CMD_CANCEL_REQUEST: + onRequestWithdrawn((NetworkRequest) m.obj); + break; + default: + Log.e(mName, "Unhandled message: " + m.what); + } + } + }; + mMessenger = new Messenger(handler); + mName = name; + } + + // TODO: consider adding a register() method so ConnectivityManager does not need to call this. + public @Nullable Messenger getMessenger() { + return mMessenger; + } + + public @NonNull String getName() { + return mName; + } + + /** + * Returns the ID of this provider. This is known only once the provider is registered via + * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. + * This ID must be used when registering any {@link NetworkAgent}s. + */ + public int getProviderId() { + return mProviderId; + } + + /** @hide */ + public void setProviderId(int providerId) { + mProviderId = providerId; + } + + /** + * Called when a NetworkRequest is received. The request may be a new request or an existing + * request with a different score. + * + * @param request the NetworkRequest being received + * @param score the score of the network currently satisfying the request, or 0 if none. + * @param providerId the ID of the provider that created the network currently satisfying this + * request, or {@link #ID_NONE} if none. + * + * @hide + */ + @SystemApi + public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {} + + /** + * Called when a NetworkRequest is withdrawn. + * @hide + */ + @SystemApi + public void onRequestWithdrawn(@NonNull NetworkRequest request) {} + + /** + * Asserts that no provider will ever be able to satisfy the specified request. The provider + * must only call this method if it knows that it is the only provider on the system capable of + * satisfying this request, and that the request cannot be satisfied. The application filing the + * request will receive an {@link NetworkCallback#onUnavailable()} callback. + * + * @param request the request that cannot be fulfilled + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { + mCm.declareNetworkRequestUnfulfillable(request); + } +} diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java index ec73866a647d..fb224fbe1318 100644 --- a/core/java/android/net/SocketKeepalive.java +++ b/core/java/android/net/SocketKeepalive.java @@ -147,17 +147,6 @@ public abstract class SocketKeepalive implements AutoCloseable { } } - /** - * This packet is invalid. - * See the error code for details. - * @hide - */ - public static class InvalidPacketException extends ErrorCodeException { - public InvalidPacketException(final int error) { - super(error); - } - } - @NonNull final IConnectivityManager mService; @NonNull final Network mNetwork; @NonNull final ParcelFileDescriptor mPfd; diff --git a/core/java/android/net/annotations/PolicyDirection.java b/core/java/android/net/annotations/PolicyDirection.java new file mode 100644 index 000000000000..febd9b406111 --- /dev/null +++ b/core/java/android/net/annotations/PolicyDirection.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.annotations; + +import android.annotation.IntDef; +import android.net.IpSecManager; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * IPsec traffic direction. + * + * <p>Mainline modules cannot reference hidden @IntDef. Moving this annotation to a separate class + * to allow others to statically include it. + * + * @hide + */ +@IntDef(value = {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT}) +@Retention(RetentionPolicy.SOURCE) +public @interface PolicyDirection {} diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java new file mode 100644 index 000000000000..740aa92ad484 --- /dev/null +++ b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.NetworkStats; + +/** + * A base class that allows external modules to implement a custom network statistics provider. + * @hide + */ +@SystemApi +public abstract class AbstractNetworkStatsProvider { + /** + * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit. + */ + public static final int QUOTA_UNLIMITED = -1; + + /** + * Called by {@code NetworkStatsService} when global polling is needed. Custom + * implementation of providers MUST respond to it by calling + * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding + * later than this may cause the stats to be dropped. + * + * @param token a positive number identifying the new state of the system under which + * {@link NetworkStats} have to be gathered from now on. When this is called, + * custom implementations of providers MUST report the latest stats with the + * previous token, under which stats were being gathered so far. + */ + public abstract void requestStatsUpdate(int token); + + /** + * Called by {@code NetworkStatsService} when setting the interface quota for the specified + * upstream interface. When this is called, the custom implementation should block all egress + * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have + * been reached, and MUST respond to it by calling + * {@link NetworkStatsProviderCallback#onLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + */ + public abstract void setLimit(@NonNull String iface, long quotaBytes); + + /** + * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations + * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes + * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should + * not block all egress packets. + * + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. + */ + public abstract void setAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl new file mode 100644 index 000000000000..55b3d4edb157 --- /dev/null +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats.provider; + +/** + * Interface for NetworkStatsService to query network statistics and set data limits. + * + * @hide + */ +oneway interface INetworkStatsProvider { + void requestStatsUpdate(int token); + void setLimit(String iface, long quotaBytes); + void setAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl new file mode 100644 index 000000000000..3ea9318f10d4 --- /dev/null +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats.provider; + +import android.net.NetworkStats; + +/** + * Interface for implementor of {@link INetworkStatsProviderCallback} to push events + * such as network statistics update or notify limit reached. + * @hide + */ +oneway interface INetworkStatsProviderCallback { + void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); + void onAlertReached(); + void onLimitReached(); + void unregister(); +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java new file mode 100644 index 000000000000..e17a8eee7ff0 --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.net.NetworkStats; +import android.os.RemoteException; + +/** + * A callback class that allows callers to report events to the system. + * @hide + */ +@SystemApi +@SuppressLint("CallbackMethodName") +public class NetworkStatsProviderCallback { + @NonNull private final INetworkStatsProviderCallback mBinder; + + /** @hide */ + public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) { + mBinder = binder; + } + + /** + * Notify the system of new network statistics. + * + * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be + * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)} + * being called. The provider can also call this whenever it wants to reports new stats for any + * reason. Note that the system will not necessarily immediately propagate the statistics to + * reflect the update. + * + * @param token the token under which these stats were gathered. Providers can call this method + * with the current token as often as they want, until the token changes. + * {@see AbstractNetworkStatsProvider#requestStatsUpdate()} + * @param ifaceStats the {@link NetworkStats} per interface to be reported. + * The provider should not include any traffic that is already counted by + * kernel interface counters. + * @param uidStats the same stats as above, but counts {@link NetworkStats} + * per uid. + */ + public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats, + @NonNull NetworkStats uidStats) { + try { + mBinder.onStatsUpdated(token, ifaceStats, uidStats); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code setAlert} has been reached. + */ + public void onAlertReached() { + try { + mBinder.onAlertReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code setLimit} has been reached. + */ + public void onLimitReached() { + try { + mBinder.onLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Unregister the provider and the referencing callback. + */ + public void unregister() { + try { + mBinder.unregister(); + } catch (RemoteException e) { + // Ignore error. + } + } +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java new file mode 100644 index 000000000000..4bf7c9bc086e --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats.provider; + +import android.annotation.NonNull; + +/** + * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing + * to outer world. + * + * @hide + */ +public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub { + @NonNull final AbstractNetworkStatsProvider mProvider; + + public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) { + mProvider = provider; + } + + @Override + public void requestStatsUpdate(int token) { + mProvider.requestStatsUpdate(token); + } + + @Override + public void setLimit(@NonNull String iface, long quotaBytes) { + mProvider.setLimit(iface, quotaBytes); + } + + @Override + public void setAlert(long quotaBytes) { + mProvider.setAlert(quotaBytes); + } +} diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 1130f1db6256..c94c74a4ce22 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -740,11 +740,12 @@ public class Process { /** * Set the priority of a thread, based on Linux priorities. - * - * @param tid The identifier of the thread/process to change. + * + * @param tid The identifier of the thread/process to change. It should be + * the native thread id but not the managed id of {@link java.lang.Thread}. * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/os/TimestampedValue.java index 45056730b08b..348574ed43c7 100644 --- a/core/java/android/util/TimestampedValue.java +++ b/core/java/android/os/TimestampedValue.java @@ -14,13 +14,10 @@ * limitations under the License. */ -package android.util; +package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; import java.util.Objects; diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java index 16f7b398731c..73e1adf134f2 100644 --- a/core/java/android/os/UpdateEngine.java +++ b/core/java/android/os/UpdateEngine.java @@ -19,6 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.content.res.AssetFileDescriptor; import android.os.IUpdateEngine; import android.os.IUpdateEngineCallback; import android.os.RemoteException; @@ -349,16 +350,17 @@ public class UpdateEngine { } /** - * Applies the payload passed as ParcelFileDescriptor {@code pfd} instead of - * using the {@code file://} scheme. + * Applies the payload passed as AssetFileDescriptor {@code assetFd} + * instead of using the {@code file://} scheme. * * <p>See {@link #applyPayload(String)} for {@code offset}, {@code size} and * {@code headerKeyValuePairs} parameters. */ - public void applyPayload(@NonNull ParcelFileDescriptor pfd, long offset, long size, + public void applyPayload(@NonNull AssetFileDescriptor assetFd, @NonNull String[] headerKeyValuePairs) { try { - mUpdateEngine.applyPayloadFd(pfd, offset, size, headerKeyValuePairs); + mUpdateEngine.applyPayloadFd(assetFd.getParcelFileDescriptor(), + assetFd.getStartOffset(), assetFd.getLength(), headerKeyValuePairs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 26222544ffb5..c7e714559d05 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -15268,8 +15268,9 @@ public final class Settings { * current time. * @hide */ - public static boolean checkAndNoteWriteSettingsOperation(Context context, int uid, - String callingPackage, boolean throwException) { + @SystemApi + public static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, + @NonNull String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_WRITE_SETTINGS, true); diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java index d646e23d230a..00060ab8ef4a 100644 --- a/core/java/android/se/omapi/SEService.java +++ b/core/java/android/se/omapi/SEService.java @@ -22,14 +22,11 @@ package android.se.omapi; -import android.app.ActivityThread; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -143,10 +140,6 @@ public final class SEService { throw new NullPointerException("Arguments must not be null"); } - if (!hasOMAPIReaders()) { - throw new UnsupportedOperationException("Device does not support any OMAPI reader"); - } - mContext = context; mSEListener.mListener = listener; mSEListener.mExecutor = executor; @@ -277,23 +270,4 @@ public final class SEService { throw new IllegalStateException(e.getMessage()); } } - - /** - * Helper to check if this device support any OMAPI readers - */ - private static boolean hasOMAPIReaders() { - IPackageManager pm = ActivityThread.getPackageManager(); - if (pm == null) { - Log.e(TAG, "Cannot get package manager, assuming OMAPI readers supported"); - return true; - } - try { - return pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_UICC, 0) - || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_ESE, 0) - || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_SD, 0); - } catch (RemoteException e) { - Log.e(TAG, "Package manager query failed, assuming OMAPI readers supported", e); - return true; - } - } } diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 146c1c3b6123..7841f991c4bc 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -24,7 +24,6 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Build; -import android.os.Bundle; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; @@ -984,8 +983,11 @@ public class PhoneStateListener { () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); } - public void onCellLocationChanged(Bundle bundle) { - CellLocation location = CellLocation.newFromBundle(bundle); + public void onCellLocationChanged(CellIdentity cellIdentity) { + // There is no system/public API to create an CellIdentity in system server, + // so the server pass a null to indicate an empty initial location. + CellLocation location = + cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation(); PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java index ec2050fb1a44..28a5c2086ede 100644 --- a/core/java/android/telephony/SubscriptionPlan.java +++ b/core/java/android/telephony/SubscriptionPlan.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; import android.util.Range; import android.util.RecurrenceRule; @@ -33,6 +34,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Period; import java.time.ZonedDateTime; +import java.util.Arrays; import java.util.Iterator; import java.util.Objects; @@ -42,6 +44,14 @@ import java.util.Objects; * as explaining how much mobile data they have remaining, and what will happen * when they run out. * + * If specifying network types, the developer must supply at least one plan + * that applies to all network types (default), and all additional plans + * may not include a particular network type more than once. + * This is enforced by {@link SubscriptionManager} when setting the plans. + * + * Plan selection will prefer plans that have specific network types defined + * over plans that apply to all network types. + * * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) * @see SubscriptionManager#getSubscriptionPlans(int) */ @@ -80,6 +90,8 @@ public final class SubscriptionPlan implements Parcelable { private int dataLimitBehavior = LIMIT_BEHAVIOR_UNKNOWN; private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; + private @NetworkType int[] networkTypes; + private long networkTypesBitMask; private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); @@ -93,6 +105,7 @@ public final class SubscriptionPlan implements Parcelable { dataLimitBehavior = source.readInt(); dataUsageBytes = source.readLong(); dataUsageTime = source.readLong(); + networkTypes = source.createIntArray(); } @Override @@ -109,6 +122,7 @@ public final class SubscriptionPlan implements Parcelable { dest.writeInt(dataLimitBehavior); dest.writeLong(dataUsageBytes); dest.writeLong(dataUsageTime); + dest.writeIntArray(networkTypes); } @Override @@ -121,13 +135,14 @@ public final class SubscriptionPlan implements Parcelable { .append(" dataLimitBehavior=").append(dataLimitBehavior) .append(" dataUsageBytes=").append(dataUsageBytes) .append(" dataUsageTime=").append(dataUsageTime) + .append(" networkTypes=").append(Arrays.toString(networkTypes)) .append("}").toString(); } @Override public int hashCode() { return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior, - dataUsageBytes, dataUsageTime); + dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes)); } @Override @@ -140,7 +155,8 @@ public final class SubscriptionPlan implements Parcelable { && dataLimitBytes == other.dataLimitBytes && dataLimitBehavior == other.dataLimitBehavior && dataUsageBytes == other.dataUsageBytes - && dataUsageTime == other.dataUsageTime; + && dataUsageTime == other.dataUsageTime + && Arrays.equals(networkTypes, other.networkTypes); } return false; } @@ -204,6 +220,32 @@ public final class SubscriptionPlan implements Parcelable { } /** + * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to. + * A null value means this SubscriptionPlan applies to all network types. + */ + public @Nullable @NetworkType int[] getNetworkTypes() { + return networkTypes; + } + + /** + * Return the networkTypes array converted to a {@link TelephonyManager.NetworkTypeBitMask} + * @hide + */ + public long getNetworkTypesBitMask() { + // calculate bitmask the first time and save for future calls + if (networkTypesBitMask == 0) { + if (networkTypes == null) { + networkTypesBitMask = ~0; + } else { + for (int networkType : networkTypes) { + networkTypesBitMask |= TelephonyManager.getBitMaskForNetworkType(networkType); + } + } + } + return networkTypesBitMask; + } + + /** * Return an iterator that will return all valid data usage cycles based on * any recurrence rules. The iterator starts from the currently active cycle * and walks backwards through time. @@ -335,5 +377,17 @@ public final class SubscriptionPlan implements Parcelable { plan.dataUsageTime = dataUsageTime; return this; } + + /** + * Set the network types this SubscriptionPlan applies to. + * + * @param networkTypes a set of all {@link NetworkType}s that apply to this plan. + * A null value means the plan applies to all network types, + * and an empty array means the plan applies to no network types. + */ + public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) { + plan.networkTypes = networkTypes; + return this; + } } } diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 8507e1207393..bfff3de75813 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -22,9 +22,6 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerExecutor; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Annotation.CallState; @@ -642,10 +639,14 @@ public class TelephonyRegistryManager { } /** - * TODO change from bundle to CellLocation? + * Notify {@link android.telephony.CellLocation} changed. + * + * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is + * parcelable, and convert to CellLocation in client code. + * * @hide */ - public void notifyCellLocation(int subId, Bundle cellLocation) { + public void notifyCellLocation(int subId, CellIdentity cellLocation) { try { sRegistry.notifyCellLocationForSubscriber(subId, cellLocation); } catch (RemoteException ex) { diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index 507790313bc2..0dd7338a5e3e 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -387,6 +387,25 @@ public final class Log { public static native int println_native(int bufID, int priority, String tag, String msg); /** + * Send a log message to the "radio" log buffer, which can be dumped with + * {@code adb logcat -b radio}. + * + * <p>Only the telephony mainline module should use it. + * + * <p>Note ART will protect {@code MODULE_LIBRARIES} system APIs from regular app code. + * + * @param priority Log priority. + * @param tag Used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param message The message you would like logged. + * @hide + */ + public static int logToRadioBuffer(@Level int priority, @Nullable String tag, + @Nullable String message) { + return println_native(LOG_ID_RADIO, priority, tag, message); + } + + /** * Return the maximum payload the log daemon accepts without truncation. * @return LOGGER_ENTRY_MAX_PAYLOAD. */ diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index ea294f010791..1b951a564628 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -25,6 +25,7 @@ import android.net.Network; import android.net.NetworkInfo; import android.net.SntpClient; import android.os.SystemClock; +import android.os.TimestampedValue; import android.provider.Settings; import android.text.TextUtils; diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java new file mode 100644 index 000000000000..c7659457bdf9 --- /dev/null +++ b/core/java/android/util/StatsEvent.java @@ -0,0 +1,829 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.SystemClock; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; + +/** + * StatsEvent builds and stores the buffer sent over the statsd socket. + * This class defines and encapsulates the socket protocol. + * + * <p>Usage:</p> + * <pre> + * // Pushed event + * StatsEvent statsEvent = StatsEvent.newBuilder() + * .setAtomId(atomId) + * .writeBoolean(false) + * .writeString("annotated String field") + * .addBooleanAnnotation(annotationId, true) + * .usePooledBuffer() + * .build(); + * StatsLog.write(statsEvent); + * + * // Pulled event + * StatsEvent statsEvent = StatsEvent.newBuilder() + * .setAtomId(atomId) + * .writeBoolean(false) + * .writeString("annotated String field") + * .addBooleanAnnotation(annotationId, true) + * .build(); + * </pre> + * @hide + **/ +public final class StatsEvent { + // Type Ids. + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_INT = 0x00; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_LONG = 0x01; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_STRING = 0x02; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_LIST = 0x03; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_FLOAT = 0x04; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_BOOLEAN = 0x05; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_BYTE_ARRAY = 0x06; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_OBJECT = 0x07; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_KEY_VALUE_PAIRS = 0x08; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_ATTRIBUTION_CHAIN = 0x09; + + /** + * @hide + **/ + @VisibleForTesting + public static final byte TYPE_ERRORS = 0x0F; + + // Error flags. + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_NO_TIMESTAMP = 0x1; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_NO_ATOM_ID = 0x2; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_OVERFLOW = 0x4; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_TOO_MANY_KEY_VALUE_PAIRS = 0x10; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x20; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_INVALID_ANNOTATION_ID = 0x40; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x80; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_TOO_MANY_ANNOTATIONS = 0x100; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_TOO_MANY_FIELDS = 0x200; + + /** + * @hide + **/ + @VisibleForTesting + public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000; + + // Size limits. + + /** + * @hide + **/ + @VisibleForTesting + public static final int MAX_ANNOTATION_COUNT = 15; + + /** + * @hide + **/ + @VisibleForTesting + public static final int MAX_ATTRIBUTION_NODES = 127; + + /** + * @hide + **/ + @VisibleForTesting + public static final int MAX_NUM_ELEMENTS = 127; + + /** + * @hide + **/ + @VisibleForTesting + public static final int MAX_KEY_VALUE_PAIRS = 127; + + private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068; + + // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag. + // See android_util_StatsLog.cpp. + private static final int MAX_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4; + + private final int mAtomId; + private final byte[] mPayload; + private Buffer mBuffer; + private final int mNumBytes; + + private StatsEvent(final int atomId, @Nullable final Buffer buffer, + @NonNull final byte[] payload, final int numBytes) { + mAtomId = atomId; + mBuffer = buffer; + mPayload = payload; + mNumBytes = numBytes; + } + + /** + * Returns a new StatsEvent.Builder for building StatsEvent object. + **/ + @NonNull + public static StatsEvent.Builder newBuilder() { + return new StatsEvent.Builder(Buffer.obtain()); + } + + /** + * Get the atom Id of the atom encoded in this StatsEvent object. + * + * @hide + **/ + public int getAtomId() { + return mAtomId; + } + + /** + * Get the byte array that contains the encoded payload that can be sent to statsd. + * + * @hide + **/ + @NonNull + public byte[] getBytes() { + return mPayload; + } + + /** + * Get the number of bytes used to encode the StatsEvent payload. + * + * @hide + **/ + public int getNumBytes() { + return mNumBytes; + } + + /** + * Recycle resources used by this StatsEvent object. + * No actions should be taken on this StatsEvent after release() is called. + **/ + public void release() { + if (mBuffer != null) { + mBuffer.release(); + mBuffer = null; + } + } + + /** + * Builder for constructing a StatsEvent object. + * + * <p>This class defines and encapsulates the socket encoding for the buffer. + * The write methods must be called in the same order as the order of fields in the + * atom definition.</p> + * + * <p>setAtomId() can be called anytime before build().</p> + * + * <p>Example:</p> + * <pre> + * // Atom definition. + * message MyAtom { + * optional int32 field1 = 1; + * optional int64 field2 = 2; + * optional string field3 = 3 [(annotation1) = true]; + * } + * + * // StatsEvent construction for pushed event. + * StatsEvent.newBuilder() + * StatsEvent statsEvent = StatsEvent.newBuilder() + * .setAtomId(atomId) + * .writeInt(3) // field1 + * .writeLong(8L) // field2 + * .writeString("foo") // field 3 + * .addBooleanAnnotation(annotation1Id, true) + * .usePooledBuffer() + * .build(); + * + * // StatsEvent construction for pulled event. + * StatsEvent.newBuilder() + * StatsEvent statsEvent = StatsEvent.newBuilder() + * .setAtomId(atomId) + * .writeInt(3) // field1 + * .writeLong(8L) // field2 + * .writeString("foo") // field 3 + * .addBooleanAnnotation(annotation1Id, true) + * .build(); + * </pre> + **/ + public static final class Builder { + // Fixed positions. + private static final int POS_NUM_ELEMENTS = 1; + private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES; + private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES; + + private final Buffer mBuffer; + private long mTimestampNs; + private int mAtomId; + private byte mCurrentAnnotationCount; + private int mPos; + private int mPosLastField; + private byte mLastType; + private int mNumElements; + private int mErrorMask; + private boolean mUsePooledBuffer = false; + + private Builder(final Buffer buffer) { + mBuffer = buffer; + mCurrentAnnotationCount = 0; + mAtomId = 0; + mTimestampNs = SystemClock.elapsedRealtimeNanos(); + mNumElements = 0; + + // Set mPos to 0 for writing TYPE_OBJECT at 0th position. + mPos = 0; + writeTypeId(TYPE_OBJECT); + + // Set mPos to after atom id's location in the buffer. + // First 2 elements in the buffer are event timestamp followed by the atom id. + mPos = POS_ATOM_ID + Byte.BYTES + Integer.BYTES; + mPosLastField = 0; + mLastType = 0; + } + + /** + * Sets the atom id for this StatsEvent. + **/ + @NonNull + public Builder setAtomId(final int atomId) { + mAtomId = atomId; + return this; + } + + /** + * Sets the timestamp in nanos for this StatsEvent. + **/ + @VisibleForTesting + @NonNull + public Builder setTimestampNs(final long timestampNs) { + mTimestampNs = timestampNs; + return this; + } + + /** + * Write a boolean field to this StatsEvent. + **/ + @NonNull + public Builder writeBoolean(final boolean value) { + // Write boolean typeId byte followed by boolean byte representation. + writeTypeId(TYPE_BOOLEAN); + mPos += mBuffer.putBoolean(mPos, value); + mNumElements++; + return this; + } + + /** + * Write an integer field to this StatsEvent. + **/ + @NonNull + public Builder writeInt(final int value) { + // Write integer typeId byte followed by 4-byte representation of value. + writeTypeId(TYPE_INT); + mPos += mBuffer.putInt(mPos, value); + mNumElements++; + return this; + } + + /** + * Write a long field to this StatsEvent. + **/ + @NonNull + public Builder writeLong(final long value) { + // Write long typeId byte followed by 8-byte representation of value. + writeTypeId(TYPE_LONG); + mPos += mBuffer.putLong(mPos, value); + mNumElements++; + return this; + } + + /** + * Write a float field to this StatsEvent. + **/ + @NonNull + public Builder writeFloat(final float value) { + // Write float typeId byte followed by 4-byte representation of value. + writeTypeId(TYPE_FLOAT); + mPos += mBuffer.putFloat(mPos, value); + mNumElements++; + return this; + } + + /** + * Write a String field to this StatsEvent. + **/ + @NonNull + public Builder writeString(@NonNull final String value) { + // Write String typeId byte, followed by 4-byte representation of number of bytes + // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value. + final byte[] valueBytes = stringToBytes(value); + writeByteArray(valueBytes, TYPE_STRING); + return this; + } + + /** + * Write a byte array field to this StatsEvent. + **/ + @NonNull + public Builder writeByteArray(@NonNull final byte[] value) { + // Write byte array typeId byte, followed by 4-byte representation of number of bytes + // in value, followed by the actual byte array. + writeByteArray(value, TYPE_BYTE_ARRAY); + return this; + } + + private void writeByteArray(@NonNull final byte[] value, final byte typeId) { + writeTypeId(typeId); + final int numBytes = value.length; + mPos += mBuffer.putInt(mPos, numBytes); + mPos += mBuffer.putByteArray(mPos, value); + mNumElements++; + } + + /** + * Write an attribution chain field to this StatsEvent. + * + * The sizes of uids and tags must be equal. The AttributionNode at position i is + * made up of uids[i] and tags[i]. + * + * @param uids array of uids in the attribution nodes. + * @param tags array of tags in the attribution nodes. + **/ + @NonNull + public Builder writeAttributionChain( + @NonNull final int[] uids, @NonNull final String[] tags) { + final byte numUids = (byte) uids.length; + final byte numTags = (byte) tags.length; + + if (numUids != numTags) { + mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL; + } else if (numUids > MAX_ATTRIBUTION_NODES) { + mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG; + } else { + // Write attribution chain typeId byte, followed by 1-byte representation of + // number of attribution nodes, followed by encoding of each attribution node. + writeTypeId(TYPE_ATTRIBUTION_CHAIN); + mPos += mBuffer.putByte(mPos, numUids); + for (int i = 0; i < numUids; i++) { + // Each uid is encoded as 4-byte representation of its int value. + mPos += mBuffer.putInt(mPos, uids[i]); + + // Each tag is encoded as 4-byte representation of number of bytes in its + // UTF-8 encoding, followed by the actual UTF-8 bytes. + final byte[] tagBytes = stringToBytes(tags[i]); + mPos += mBuffer.putInt(mPos, tagBytes.length); + mPos += mBuffer.putByteArray(mPos, tagBytes); + } + mNumElements++; + } + return this; + } + + /** + * Write KeyValuePairsAtom entries to this StatsEvent. + * + * @param intMap Integer key-value pairs. + * @param longMap Long key-value pairs. + * @param stringMap String key-value pairs. + * @param floatMap Float key-value pairs. + **/ + @NonNull + public Builder writeKeyValuePairs( + @NonNull final SparseIntArray intMap, + @NonNull final SparseLongArray longMap, + @NonNull final SparseArray<String> stringMap, + @NonNull final SparseArray<Float> floatMap) { + final int intMapSize = intMap.size(); + final int longMapSize = longMap.size(); + final int stringMapSize = stringMap.size(); + final int floatMapSize = floatMap.size(); + final int totalCount = intMapSize + longMapSize + stringMapSize + floatMapSize; + + if (totalCount > MAX_KEY_VALUE_PAIRS) { + mErrorMask |= ERROR_TOO_MANY_KEY_VALUE_PAIRS; + } else { + writeTypeId(TYPE_KEY_VALUE_PAIRS); + mPos += mBuffer.putByte(mPos, (byte) totalCount); + + for (int i = 0; i < intMapSize; i++) { + final int key = intMap.keyAt(i); + final int value = intMap.valueAt(i); + mPos += mBuffer.putInt(mPos, key); + writeTypeId(TYPE_INT); + mPos += mBuffer.putInt(mPos, value); + } + + for (int i = 0; i < longMapSize; i++) { + final int key = longMap.keyAt(i); + final long value = longMap.valueAt(i); + mPos += mBuffer.putInt(mPos, key); + writeTypeId(TYPE_LONG); + mPos += mBuffer.putLong(mPos, value); + } + + for (int i = 0; i < stringMapSize; i++) { + final int key = stringMap.keyAt(i); + final String value = stringMap.valueAt(i); + mPos += mBuffer.putInt(mPos, key); + writeTypeId(TYPE_STRING); + final byte[] valueBytes = stringToBytes(value); + mPos += mBuffer.putInt(mPos, valueBytes.length); + mPos += mBuffer.putByteArray(mPos, valueBytes); + } + + for (int i = 0; i < floatMapSize; i++) { + final int key = floatMap.keyAt(i); + final float value = floatMap.valueAt(i); + mPos += mBuffer.putInt(mPos, key); + writeTypeId(TYPE_FLOAT); + mPos += mBuffer.putFloat(mPos, value); + } + + mNumElements++; + } + + return this; + } + + /** + * Write a boolean annotation for the last field written. + **/ + @NonNull + public Builder addBooleanAnnotation( + final byte annotationId, final boolean value) { + // Ensure there's a field written to annotate. + if (0 == mPosLastField) { + mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD; + } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) { + mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS; + } else { + mPos += mBuffer.putByte(mPos, annotationId); + mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN); + mPos += mBuffer.putBoolean(mPos, value); + mCurrentAnnotationCount++; + writeAnnotationCount(); + } + return this; + } + + /** + * Write an integer annotation for the last field written. + **/ + @NonNull + public Builder addIntAnnotation(final byte annotationId, final int value) { + if (0 == mPosLastField) { + mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD; + } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) { + mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS; + } else { + mPos += mBuffer.putByte(mPos, annotationId); + mPos += mBuffer.putByte(mPos, TYPE_INT); + mPos += mBuffer.putInt(mPos, value); + mCurrentAnnotationCount++; + writeAnnotationCount(); + } + return this; + } + + /** + * Indicates to reuse Buffer's byte array as the underlying payload in StatsEvent. + * This should be called for pushed events to reduce memory allocations and garbage + * collections. + **/ + @NonNull + public Builder usePooledBuffer() { + mUsePooledBuffer = true; + return this; + } + + /** + * Builds a StatsEvent object with values entered in this Builder. + **/ + @NonNull + public StatsEvent build() { + if (0L == mTimestampNs) { + mErrorMask |= ERROR_NO_TIMESTAMP; + } + if (0 == mAtomId) { + mErrorMask |= ERROR_NO_ATOM_ID; + } + if (mBuffer.hasOverflowed()) { + mErrorMask |= ERROR_OVERFLOW; + } + if (mNumElements > MAX_NUM_ELEMENTS) { + mErrorMask |= ERROR_TOO_MANY_FIELDS; + } + + int size = mPos; + mPos = POS_TIMESTAMP_NS; + writeLong(mTimestampNs); + writeInt(mAtomId); + if (0 == mErrorMask) { + mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements); + } else { + mPos += mBuffer.putByte(mPos, TYPE_ERRORS); + mPos += mBuffer.putInt(mPos, mErrorMask); + mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3); + size = mPos; + } + + if (mUsePooledBuffer) { + return new StatsEvent(mAtomId, mBuffer, mBuffer.getBytes(), size); + } else { + // Create a copy of the buffer with the required number of bytes. + final byte[] payload = new byte[size]; + System.arraycopy(mBuffer.getBytes(), 0, payload, 0, size); + + // Return Buffer instance to the pool. + mBuffer.release(); + + return new StatsEvent(mAtomId, null, payload, size); + } + } + + private void writeTypeId(final byte typeId) { + mPosLastField = mPos; + mLastType = typeId; + mCurrentAnnotationCount = 0; + final byte encodedId = (byte) (typeId & 0x0F); + mPos += mBuffer.putByte(mPos, encodedId); + } + + private void writeAnnotationCount() { + // Use first 4 bits for annotation count and last 4 bits for typeId. + final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F)); + mBuffer.putByte(mPosLastField, encodedId); + } + + @NonNull + private static byte[] stringToBytes(@Nullable final String value) { + return (null == value ? "" : value).getBytes(UTF_8); + } + } + + private static final class Buffer { + private static Object sLock = new Object(); + + @GuardedBy("sLock") + private static Buffer sPool; + + private final byte[] mBytes = new byte[MAX_PAYLOAD_SIZE]; + private boolean mOverflow = false; + + @NonNull + private static Buffer obtain() { + final Buffer buffer; + synchronized (sLock) { + buffer = null == sPool ? new Buffer() : sPool; + sPool = null; + } + buffer.reset(); + return buffer; + } + + private Buffer() { + } + + @NonNull + private byte[] getBytes() { + return mBytes; + } + + private void release() { + synchronized (sLock) { + if (null == sPool) { + sPool = this; + } + } + } + + private void reset() { + mOverflow = false; + } + + private boolean hasOverflowed() { + return mOverflow; + } + + /** + * Checks for available space in the byte array. + * + * @param index starting position in the buffer to start the check. + * @param numBytes number of bytes to check from index. + * @return true if space is available, false otherwise. + **/ + private boolean hasEnoughSpace(final int index, final int numBytes) { + final boolean result = index + numBytes < MAX_PAYLOAD_SIZE; + if (!result) { + mOverflow = true; + } + return result; + } + + /** + * Writes a byte into the buffer. + * + * @param index position in the buffer where the byte is written. + * @param value the byte to write. + * @return number of bytes written to buffer from this write operation. + **/ + private int putByte(final int index, final byte value) { + if (hasEnoughSpace(index, Byte.BYTES)) { + mBytes[index] = (byte) (value); + return Byte.BYTES; + } + return 0; + } + + /** + * Writes a boolean into the buffer. + * + * @param index position in the buffer where the boolean is written. + * @param value the boolean to write. + * @return number of bytes written to buffer from this write operation. + **/ + private int putBoolean(final int index, final boolean value) { + return putByte(index, (byte) (value ? 1 : 0)); + } + + /** + * Writes an integer into the buffer. + * + * @param index position in the buffer where the integer is written. + * @param value the integer to write. + * @return number of bytes written to buffer from this write operation. + **/ + private int putInt(final int index, final int value) { + if (hasEnoughSpace(index, Integer.BYTES)) { + // Use little endian byte order. + mBytes[index] = (byte) (value); + mBytes[index + 1] = (byte) (value >> 8); + mBytes[index + 2] = (byte) (value >> 16); + mBytes[index + 3] = (byte) (value >> 24); + return Integer.BYTES; + } + return 0; + } + + /** + * Writes a long into the buffer. + * + * @param index position in the buffer where the long is written. + * @param value the long to write. + * @return number of bytes written to buffer from this write operation. + **/ + private int putLong(final int index, final long value) { + if (hasEnoughSpace(index, Long.BYTES)) { + // Use little endian byte order. + mBytes[index] = (byte) (value); + mBytes[index + 1] = (byte) (value >> 8); + mBytes[index + 2] = (byte) (value >> 16); + mBytes[index + 3] = (byte) (value >> 24); + mBytes[index + 4] = (byte) (value >> 32); + mBytes[index + 5] = (byte) (value >> 40); + mBytes[index + 6] = (byte) (value >> 48); + mBytes[index + 7] = (byte) (value >> 56); + return Long.BYTES; + } + return 0; + } + + /** + * Writes a float into the buffer. + * + * @param index position in the buffer where the float is written. + * @param value the float to write. + * @return number of bytes written to buffer from this write operation. + **/ + private int putFloat(final int index, final float value) { + return putInt(index, Float.floatToIntBits(value)); + } + + /** + * Copies a byte array into the buffer. + * + * @param index position in the buffer where the byte array is copied. + * @param value the byte array to copy. + * @return number of bytes written to buffer from this write operation. + **/ + private int putByteArray(final int index, @NonNull final byte[] value) { + final int numBytes = value.length; + if (hasEnoughSpace(index, numBytes)) { + System.arraycopy(value, 0, mBytes, index, numBytes); + return numBytes; + } + return 0; + } + } +} diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index ae9966b7b934..23fd4f2f61d3 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -244,6 +244,19 @@ public final class StatsLog extends StatsLogInternal { */ private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId); + /** + * Write an event to stats log using the raw format encapsulated in StatsEvent. + * After writing to stats log, release() is called on the StatsEvent object. + * No further action should be taken on the StatsEvent object following this call. + * + * @param statsEvent The StatsEvent object containing the encoded buffer of data to write. + * @hide + */ + public static void write(@NonNull final StatsEvent statsEvent) { + writeImpl(statsEvent.getBytes(), statsEvent.getNumBytes(), statsEvent.getAtomId()); + statsEvent.release(); + } + private static void enforceDumpCallingPermission(Context context) { context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission."); } diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 28eb79ae1f2a..5b4ff52376b3 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -16,12 +16,11 @@ package android.view; -import static android.view.DisplayEventReceiver.CONFIG_CHANGED_EVENT_SUPPRESS; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java index 696e048ffed8..876331b5c57f 100644 --- a/core/java/android/view/ContextThemeWrapper.java +++ b/core/java/android/view/ContextThemeWrapper.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.ContextWrapper; import android.content.res.AssetManager; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index b3d98b8de0a3..7a818ce78568 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -22,8 +22,8 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java index da4d92fa0c94..834dd7b6e7d8 100644 --- a/core/java/android/view/DisplayAdjustments.java +++ b/core/java/android/view/DisplayAdjustments.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 91acc4638c26..eaf297cc05d8 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 2efebf6457ab..f3b2800eef39 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -23,7 +23,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH; import static android.view.DisplayInfoProto.NAME; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Rect; diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java index 8e6e99a6d949..6035cbebb032 100644 --- a/core/java/android/view/DisplayListCanvas.java +++ b/core/java/android/view/DisplayListCanvas.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.BaseRecordingCanvas; import android.graphics.CanvasProperty; import android.graphics.Paint; diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index 2a43bcc00daf..35af0f252d2d 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; import android.os.Parcel; diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java index dcdef3eaa275..de4112cbf1e1 100644 --- a/core/java/android/view/FrameMetrics.java +++ b/core/java/android/view/FrameMetrics.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java index 0f38e847f4bd..e4197abf8088 100644 --- a/core/java/android/view/FrameMetricsObserver.java +++ b/core/java/android/view/FrameMetricsObserver.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java index 8fbbcf4b88c6..0fdbc9cf9e33 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -23,7 +23,7 @@ import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SC import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java index 3286bd623694..a72832760f96 100644 --- a/core/java/android/view/GhostView.java +++ b/core/java/android/view/GhostView.java @@ -15,7 +15,7 @@ */ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.RecordingCanvas; diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index ecb727c79016..67c8b15b2ca5 100644 --- a/core/java/android/view/InputChannel.java +++ b/core/java/android/view/InputChannel.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index e723f91887c1..360deddf544d 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputManager; diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index 4b88a6a54efe..5f9c4801ee66 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java index e4b1a8d855ec..c0a3cec4547a 100644 --- a/core/java/android/view/InputEventConsistencyVerifier.java +++ b/core/java/android/view/InputEventConsistencyVerifier.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.Log; diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index 7260a658a027..cab8bc549af6 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/InputEventSender.java b/core/java/android/view/InputEventSender.java index c5f4c23b7b15..86a309e3ed79 100644 --- a/core/java/android/view/InputEventSender.java +++ b/core/java/android/view/InputEventSender.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java index 3aaf31ef406f..36d558630da9 100644 --- a/core/java/android/view/InputFilter.java +++ b/core/java/android/view/InputFilter.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java index 69ebc46cb456..74ce6ac02db3 100644 --- a/core/java/android/view/InputQueue.java +++ b/core/java/android/view/InputQueue.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.LongSparseArray; diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index bd033480ea87..90e0f3f89a0f 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.input.InputManager; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 60db6a57d187..c638717b13c0 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -20,7 +20,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index 1fc7f0e36095..bf646c7cddb6 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; @@ -31,10 +31,7 @@ import android.graphics.Canvas; import android.os.Build; import android.os.Handler; import android.os.Message; -import android.os.SystemProperties; import android.os.Trace; -import android.provider.DeviceConfig; -import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 833e78ff5c71..70873d7db92a 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -22,7 +22,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index b2f3f5edcd20..232e0f6f9a14 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -17,9 +17,9 @@ package android.view; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.AppOpsManager; import android.app.Notification; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index dfe34c80bb8f..18d0d7b98a42 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -17,8 +17,8 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/android/view/RemoteAnimationAdapter.java b/core/java/android/view/RemoteAnimationAdapter.java index c686440171a2..166d3baa2fdf 100644 --- a/core/java/android/view/RemoteAnimationAdapter.java +++ b/core/java/android/view/RemoteAnimationAdapter.java @@ -16,8 +16,8 @@ package android.view; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityOptions; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/RemoteAnimationDefinition.java b/core/java/android/view/RemoteAnimationDefinition.java index da599efb6eee..c9bd92ae84ba 100644 --- a/core/java/android/view/RemoteAnimationDefinition.java +++ b/core/java/android/view/RemoteAnimationDefinition.java @@ -19,9 +19,9 @@ package android.view; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; import android.app.WindowConfiguration.ActivityType; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java index ae3e1d0a9691..2249966a6b2d 100644 --- a/core/java/android/view/RemoteAnimationTarget.java +++ b/core/java/android/view/RemoteAnimationTarget.java @@ -30,8 +30,8 @@ import static android.view.RemoteAnimationTargetProto.TASK_ID; import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; import android.graphics.Rect; import android.os.Parcel; diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 93f52a04d626..06cb51927ba8 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -19,7 +19,7 @@ package android.view; import android.animation.Animator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.CanvasProperty; import android.graphics.Paint; import android.graphics.RecordingCanvas; diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 1d721516a979..346f76cace7d 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 17f07b5a2ad4..3a6c8dd3720f 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo.Translator; import android.graphics.Canvas; import android.graphics.ColorSpace; diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 2313b13befad..2c48af04aa18 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -32,7 +32,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index 361ac932758e..0f851c1881f5 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An instance of this class represents a connection to the surface diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index d11548d687b1..ec2ab6a5a4be 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -20,7 +20,7 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLA import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.CompatibilityInfo.Translator; import android.graphics.BlendMode; diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 0175ba201dd1..2062bb0bc87f 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; diff --git a/core/java/android/view/TouchDelegate.java b/core/java/android/view/TouchDelegate.java index 2ea95e90a8bf..de0f9e5c5cf6 100644 --- a/core/java/android/view/TouchDelegate.java +++ b/core/java/android/view/TouchDelegate.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.graphics.Region; import android.util.ArrayMap; diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index 7154f2bdee42..a56633e3c5fa 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Pools.SynchronizedPool; /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 9d2040c5bdb4..3313537965c4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -43,7 +43,7 @@ import android.annotation.Size; import android.annotation.StyleRes; import android.annotation.TestApi; import android.annotation.UiThread; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.ClipData; import android.content.Context; diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 9e914d4e7d41..774a2dea6311 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -18,8 +18,8 @@ package android.view; import android.annotation.FloatRange; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index c67fca59fe97..dda7b260533e 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -19,7 +19,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 937bd1b34e61..6125aadc57b6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -24,7 +24,7 @@ import android.annotation.IdRes; import android.annotation.NonNull; import android.annotation.TestApi; import android.annotation.UiThread; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/view/ViewHierarchyEncoder.java b/core/java/android/view/ViewHierarchyEncoder.java index d5716bfaaf00..b0e0524a0d85 100644 --- a/core/java/android/view/ViewHierarchyEncoder.java +++ b/core/java/android/view/ViewHierarchyEncoder.java @@ -2,7 +2,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index e23c687af49b..7830c57e53ec 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -17,7 +17,7 @@ package android.view; import android.animation.LayoutTransition; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 57a01a32e1b8..1ab3d3ab4974 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -32,10 +32,10 @@ import android.animation.LayoutTransition; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ResourcesManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; import android.content.Context; diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index c72baca0b93b..d7b0afc89eaa 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.graphics.Region; diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 73e0e4b2eb8b..cdafa470a542 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -26,8 +26,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; diff --git a/core/java/android/view/WindowAnimationFrameStats.java b/core/java/android/view/WindowAnimationFrameStats.java index 399dfba64461..dfc4f0cd4dc6 100644 --- a/core/java/android/view/WindowAnimationFrameStats.java +++ b/core/java/android/view/WindowAnimationFrameStats.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/WindowContentFrameStats.java b/core/java/android/view/WindowContentFrameStats.java index 9fa5a005055d..217197c96793 100644 --- a/core/java/android/view/WindowContentFrameStats.java +++ b/core/java/android/view/WindowContentFrameStats.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index bcc6a552f569..87bc534da92f 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -34,7 +34,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.graphics.Insets; import android.graphics.Rect; diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 7433b6c8ce87..d9d92788a434 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -50,9 +50,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; import android.app.Presentation; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 379acbecb613..a930abe40341 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -18,8 +18,8 @@ package android.view; import android.animation.ValueAnimator; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index c3494432ebcb..cdeeaa438acb 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Region; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 2ac44d2fac22..2ba9f94869e4 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -17,7 +17,7 @@ package android.view.accessibility; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 4db6f4f808f2..723da77b6f7d 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -17,7 +17,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Build; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 2e9d881f72f9..747bd706f316 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -29,7 +29,7 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 3b310fc13ee3..8e61a5e7c44b 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -26,7 +26,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index b382a1863af3..37c3a1361de1 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -19,7 +19,7 @@ package android.view.accessibility; import static com.android.internal.util.CollectionUtils.isEmpty; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcelable; import android.view.View; diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java index c42e9fec91bf..3d68692a3b5c 100644 --- a/core/java/android/view/accessibility/CaptioningManager.java +++ b/core/java/android/view/accessibility/CaptioningManager.java @@ -19,7 +19,7 @@ package android.view.accessibility; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 3b60aee8f604..43dcafc9b9ce 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -19,7 +19,7 @@ package android.view.animation; import android.annotation.AnimRes; import android.annotation.ColorInt; import android.annotation.InterpolatorRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.RectF; diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index c877b9cec812..075b0ab728fa 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -19,7 +19,7 @@ package android.view.animation; import android.annotation.AnimRes; import android.annotation.InterpolatorRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java index 58da04d8d38f..cfc6e39da876 100644 --- a/core/java/android/view/animation/Transformation.java +++ b/core/java/android/view/animation/Transformation.java @@ -17,7 +17,7 @@ package android.view.animation; import android.annotation.FloatRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; import android.graphics.Rect; diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java index 6c040d4c61aa..ec55a0273999 100644 --- a/core/java/android/view/animation/TranslateAnimation.java +++ b/core/java/android/view/animation/TranslateAnimation.java @@ -16,7 +16,7 @@ package android.view.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/android/view/animation/TranslateYAnimation.java b/core/java/android/view/animation/TranslateYAnimation.java index a6e0ccb18805..1a1dfbfd6f05 100644 --- a/core/java/android/view/animation/TranslateYAnimation.java +++ b/core/java/android/view/animation/TranslateYAnimation.java @@ -16,7 +16,7 @@ package android.view.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; /** diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index fe07feef3bfa..34005ac02735 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -17,7 +17,7 @@ package android.view.inputmethod; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 032af1c5c7b5..d395f5294d6c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -26,9 +26,9 @@ import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -2830,7 +2830,7 @@ public final class InputMethodManager { } /** - * This is kept due to {@link android.annotation.UnsupportedAppUsage}. + * This is kept due to {@link android.compat.annotation.UnsupportedAppUsage}. * * <p>TODO(Bug 113914148): Check if we can remove this. We have accidentally exposed * WindowManagerInternal#getInputMethodWindowVisibleHeight to app developers and some of them diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java index 8dd0dcd45a1c..50e95c80cfed 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java +++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java @@ -16,7 +16,7 @@ package android.view.inputmethod; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.util.Slog; diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index 95ca9deb2871..526ac6fd3570 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -19,8 +19,8 @@ package android.view.textclassifier; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.ContentObserver; import android.os.ServiceManager; diff --git a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java index b530ddfe86d6..05d12ce17d8c 100644 --- a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java +++ b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java @@ -19,7 +19,7 @@ package android.view.textclassifier.logging; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.metrics.LogMaker; import android.util.Log; diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java index f553ca512881..afddaa2ff58a 100644 --- a/core/java/android/view/textservice/SpellCheckerSession.java +++ b/core/java/android/view/textservice/SpellCheckerSession.java @@ -16,7 +16,7 @@ package android.view.textservice; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java index 9ff64d9b268a..acb35d63df9d 100644 --- a/core/java/android/view/textservice/TextServicesManager.java +++ b/core/java/android/view/textservice/TextServicesManager.java @@ -18,8 +18,8 @@ package android.view.textservice; import android.annotation.NonNull; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Bundle; import android.os.RemoteException; diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 7e067197ced8..fafe81393888 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.File; import java.io.IOException; diff --git a/core/java/android/webkit/ConsoleMessage.java b/core/java/android/webkit/ConsoleMessage.java index e54849772f9a..5474557c9998 100644 --- a/core/java/android/webkit/ConsoleMessage.java +++ b/core/java/android/webkit/ConsoleMessage.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/webkit/JsResult.java b/core/java/android/webkit/JsResult.java index 5bf6aab3225d..448db58e2658 100644 --- a/core/java/android/webkit/JsResult.java +++ b/core/java/android/webkit/JsResult.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An instance of this class is passed as a parameter in various {@link WebChromeClient} action diff --git a/core/java/android/webkit/PluginData.java b/core/java/android/webkit/PluginData.java index 8aeeb1c53241..c9a196017a75 100644 --- a/core/java/android/webkit/PluginData.java +++ b/core/java/android/webkit/PluginData.java @@ -16,7 +16,8 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.InputStream; import java.util.Map; diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java index 5d704cb09dcb..844b156b84d3 100644 --- a/core/java/android/webkit/URLUtil.java +++ b/core/java/android/webkit/URLUtil.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.ParseException; import android.net.Uri; import android.net.WebAddress; diff --git a/core/java/android/webkit/UrlInterceptHandler.java b/core/java/android/webkit/UrlInterceptHandler.java index f23aae6be8c2..a48e10799be7 100644 --- a/core/java/android/webkit/UrlInterceptHandler.java +++ b/core/java/android/webkit/UrlInterceptHandler.java @@ -17,9 +17,8 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.webkit.CacheManager.CacheResult; -import android.webkit.PluginData; import java.util.Map; diff --git a/core/java/android/webkit/UrlInterceptRegistry.java b/core/java/android/webkit/UrlInterceptRegistry.java index eeb28d73be85..c9dee00942c3 100644 --- a/core/java/android/webkit/UrlInterceptRegistry.java +++ b/core/java/android/webkit/UrlInterceptRegistry.java @@ -17,10 +17,8 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.webkit.CacheManager.CacheResult; -import android.webkit.PluginData; -import android.webkit.UrlInterceptHandler; import java.util.Iterator; import java.util.LinkedList; diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java index 7c8f33e181d6..219523b15ab0 100644 --- a/core/java/android/webkit/WebResourceResponse.java +++ b/core/java/android/webkit/WebResourceResponse.java @@ -18,7 +18,7 @@ package android.webkit; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.InputStream; import java.io.StringBufferInputStream; diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 7282008f7e3a..8a5b64d95f19 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -19,7 +19,7 @@ package android.webkit; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import java.lang.annotation.ElementType; diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java index e44d6ebf37d1..7046c5108783 100644 --- a/core/java/android/webkit/WebSyncManager.java +++ b/core/java/android/webkit/WebSyncManager.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; /** diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 721ac2d9a6dc..271d5be3864e 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -21,8 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index f5657dff538f..df86926a95dc 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -19,10 +19,10 @@ package android.webkit; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; import android.app.ResourcesManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 678a25223ef5..941af6ef1d7a 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -17,10 +17,10 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; diff --git a/core/java/android/webkit/WebViewProviderInfo.java b/core/java/android/webkit/WebViewProviderInfo.java index 7e00cded2c5a..6629fdc4cdee 100644 --- a/core/java/android/webkit/WebViewProviderInfo.java +++ b/core/java/android/webkit/WebViewProviderInfo.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.Signature; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/webkit/WebViewProviderResponse.java b/core/java/android/webkit/WebViewProviderResponse.java index 5622abe0e99f..b58cc4bb1577 100644 --- a/core/java/android/webkit/WebViewProviderResponse.java +++ b/core/java/android/webkit/WebViewProviderResponse.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageInfo; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/webkit/WebViewUpdateService.java b/core/java/android/webkit/WebViewUpdateService.java index 12d3221fb7b5..9152b438618f 100644 --- a/core/java/android/webkit/WebViewUpdateService.java +++ b/core/java/android/webkit/WebViewUpdateService.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.RemoteException; /** diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 85e9e4950cba..2d99eab88dfc 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index bbcba2e12a2c..11a6acf5b934 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java index cfb93ec2321f..aa3590aaff0a 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -22,7 +22,7 @@ import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java index 7e58622db3b8..3a743562110f 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java index f5bf7598aa5a..d87bdf482e43 100644 --- a/core/java/android/widget/ActivityChooserModel.java +++ b/core/java/android/widget/ActivityChooserModel.java @@ -16,8 +16,8 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 89ea0747b532..aa18d576c8f4 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -17,7 +17,7 @@ package android.widget; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index c55f7d654548..52658404548c 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.DataSetObserver; import android.os.Build; diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java index 67a70b48b534..d165bd0f0fa7 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java index 2bf1ba5cf017..6c38c8b9a0f5 100644 --- a/core/java/android/widget/ArrayAdapter.java +++ b/core/java/android/widget/ArrayAdapter.java @@ -21,7 +21,7 @@ import android.annotation.IdRes; import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.util.Log; diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 8785251b0a64..8d9ae58be290 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/core/java/android/widget/BaseAdapter.java b/core/java/android/widget/BaseAdapter.java index 7b9365b08a41..27cf9a64a8d5 100644 --- a/core/java/android/widget/BaseAdapter.java +++ b/core/java/android/widget/BaseAdapter.java @@ -17,7 +17,7 @@ package android.widget; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.DataSetObservable; import android.database.DataSetObserver; import android.view.View; diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java index b552aa6c85c4..4b2f738ef7ab 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 8b70f41f050c..422d2d37321c 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -19,7 +19,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index cb67309ce74f..6c7e3dc84425 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -16,8 +16,8 @@ package com.android.internal.telephony; -import android.os.Bundle; import android.telephony.CallAttributes; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.PhoneCapability; @@ -37,8 +37,8 @@ oneway interface IPhoneStateListener { void onMessageWaitingIndicatorChanged(boolean mwi); void onCallForwardingIndicatorChanged(boolean cfi); - // we use bundle here instead of CellLocation so it can get the right subclass - void onCellLocationChanged(in Bundle location); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + void onCellLocationChanged(in CellIdentity location); void onCallStateChanged(int state, String incomingNumber); void onDataConnectionStateChanged(int state, int networkType); void onDataActivity(int direction); @@ -63,4 +63,3 @@ oneway interface IPhoneStateListener { void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); } - diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5228584610b9..29cd1879436c 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -19,8 +19,8 @@ package com.android.internal.telephony; import android.content.Intent; import android.net.LinkProperties; import android.net.NetworkCapabilities; -import android.os.Bundle; import android.telephony.CallQuality; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.ims.ImsReasonInfo; import android.telephony.PhoneCapability; @@ -67,9 +67,9 @@ interface ITelephonyRegistry { @UnsupportedAppUsage void notifyDataConnectionFailed(String apnType); void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + void notifyCellLocation(in CellIdentity cellLocation); + void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @UnsupportedAppUsage void notifyCellInfo(in List<CellInfo> cellInfo); void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 3fff5c233890..994a01c023d8 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -126,7 +126,9 @@ public class Preconditions { * @param reference an object reference * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null + * @deprecated - use {@link java.util.Objects.requireNonNull} instead. */ + @Deprecated @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference) { if (reference == null) { @@ -144,7 +146,9 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null + * @deprecated - use {@link java.util.Objects.requireNonNull} instead. */ + @Deprecated @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) { if (reference == null) { @@ -154,26 +158,6 @@ public class Preconditions { } /** - * Ensures that an object reference passed as a parameter to the calling - * method is not null. - * - * @param reference an object reference - * @param messageTemplate a printf-style message template to use if the check fails; will - * be converted to a string using {@link String#format(String, Object...)} - * @param messageArgs arguments for {@code messageTemplate} - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static @NonNull <T> T checkNotNull(final T reference, - final String messageTemplate, - final Object... messageArgs) { - if (reference == null) { - throw new NullPointerException(String.format(messageTemplate, messageArgs)); - } - return reference; - } - - /** * Ensures the truth of an expression involving the state of the calling * instance, but not involving any parameters to the calling method. * diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index a42ba17c100e..7d407b271884 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1777,6 +1777,11 @@ android:label="@string/permlab_preferredPaymentInfo" android:protectionLevel="normal" /> + <!-- @SystemApi Allows an internal user to use privileged SecureElement APIs. + @hide --> + <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED" + android:protectionLevel="signature|privileged" /> + <!-- @deprecated This permission used to allow too broad access to sensitive methods and all its uses have been replaced by a more appropriate permission. Most uses have been replaced with a NETWORK_STACK or NETWORK_SETTINGS check. Please look up the documentation of the @@ -2057,8 +2062,10 @@ android:protectionLevel="signature|privileged" /> <!-- Allows read only access to precise phone state. - @hide Pending API council approval --> + Allows reading of detailed information about phone state for special-use applications + such as dialers, carrier applications, or ims applications. --> <permission android:name="android.permission.READ_PRECISE_PHONE_STATE" + android:permissionGroup="android.permission-group.UNDEFINED" android:protectionLevel="signature|privileged" /> <!-- @SystemApi Allows read access to privileged phone state. diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java index f0a83678f70b..a296ca27e268 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java @@ -16,6 +16,7 @@ package com.android.connectivitymanagertest; +import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.LinkAddress; @@ -136,7 +137,7 @@ public class WifiConfigurationHelper { config.enterpriseConfig.setPhase2Method(phase2); config.enterpriseConfig.setIdentity(identity); config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity); - config.enterpriseConfig.setCaCertificateAlias(caCert); + config.enterpriseConfig.setCaCertificateAliases(new String[] {caCert}); config.enterpriseConfig.setClientCertificateAlias(clientCert); return config; } @@ -147,8 +148,12 @@ public class WifiConfigurationHelper { private static WifiConfiguration createGenericConfig(String ssid) { WifiConfiguration config = new WifiConfiguration(); config.SSID = quotedString(ssid); - config.setIpAssignment(IpAssignment.DHCP); - config.setProxySettings(ProxySettings.NONE); + + IpConfiguration ipConfiguration = config.getIpConfiguration(); + ipConfiguration.setIpAssignment(IpAssignment.DHCP); + ipConfiguration.setProxySettings(ProxySettings.NONE); + config.setIpConfiguration(ipConfiguration); + return config; } @@ -237,6 +242,7 @@ public class WifiConfigurationHelper { throw new IllegalArgumentException(); } + IpConfiguration ipConfiguration = config.getIpConfiguration(); if (jsonConfig.has("ip")) { StaticIpConfiguration staticIpConfig = new StaticIpConfiguration(); @@ -247,13 +253,14 @@ public class WifiConfigurationHelper { staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns1"))); staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns2"))); - config.setIpAssignment(IpAssignment.STATIC); - config.setStaticIpConfiguration(staticIpConfig); + ipConfiguration.setIpAssignment(IpAssignment.STATIC); + ipConfiguration.setStaticIpConfiguration(staticIpConfig); } else { - config.setIpAssignment(IpAssignment.DHCP); + ipConfiguration.setIpAssignment(IpAssignment.DHCP); } + ipConfiguration.setProxySettings(ProxySettings.NONE); + config.setIpConfiguration(ipConfiguration); - config.setProxySettings(ProxySettings.NONE); return config; } diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java index 68b9b0079761..f4709ff0bc00 100644 --- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java +++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java @@ -33,14 +33,15 @@ import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; +import android.support.test.uiautomator.UiDevice; import android.test.InstrumentationTestCase; import android.util.Log; -import libcore.io.Streams; - import com.google.mockwebserver.MockResponse; import com.google.mockwebserver.MockWebServer; +import libcore.io.Streams; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -63,6 +64,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { private static final String TAG = "DownloadManagerBaseTest"; protected DownloadManager mDownloadManager = null; private MockWebServer mServer = null; + private UiDevice mUiDevice = null; protected String mFileType = "text/plain"; protected Context mContext = null; protected MultipleDownloadsCompletedReceiver mReceiver = null; @@ -234,6 +236,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { @Override public void setUp() throws Exception { mContext = getInstrumentation().getContext(); + mUiDevice = UiDevice.getInstance(getInstrumentation()); mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); mServer = new MockWebServer(); mServer.play(); @@ -512,7 +515,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { Log.i(LOG_TAG, "Setting WiFi State to: " + enable); WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - manager.setWifiEnabled(enable); + mUiDevice.executeShellCommand("svc wifi " + (enable ? "enable" : "disable")); String timeoutMessage = "Timed out waiting for Wifi to be " + (enable ? "enabled!" : "disabled!"); diff --git a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java index de6f8f7231fa..750ffa1c9a54 100644 --- a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java index 9b3d0c9eaff6..b88c36f20bc6 100644 --- a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java index bee270e5f5c9..ba29a97b55ab 100644 --- a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/net/NetworkKeyTest.java b/core/tests/coretests/src/android/net/NetworkKeyTest.java index c6c0b46d0505..b13bcd1311f6 100644 --- a/core/tests/coretests/src/android/net/NetworkKeyTest.java +++ b/core/tests/coretests/src/android/net/NetworkKeyTest.java @@ -18,6 +18,7 @@ package android.net; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.net.wifi.ScanResult; @@ -107,7 +108,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_nullSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.BSSID = VALID_BSSID; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -115,7 +116,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_emptySsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = ""; scanResult.BSSID = VALID_BSSID; @@ -124,7 +125,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_noneSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = WifiManager.UNKNOWN_SSID; scanResult.BSSID = VALID_BSSID; @@ -133,7 +134,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_nullBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -141,7 +142,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_emptyBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = ""; @@ -150,7 +151,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_invalidBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = INVALID_BSSID; @@ -159,7 +160,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_validSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = VALID_BSSID; diff --git a/core/tests/coretests/src/android/util/TimestampedValueTest.java b/core/tests/coretests/src/android/os/TimestampedValueTest.java index 6fc2400316c2..f36d9e6b1eff 100644 --- a/core/tests/coretests/src/android/util/TimestampedValueTest.java +++ b/core/tests/coretests/src/android/os/TimestampedValueTest.java @@ -14,14 +14,12 @@ * limitations under the License. */ -package android.util; +package android.os; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; -import android.os.Parcel; - import androidx.test.runner.AndroidJUnit4; import org.junit.Test; diff --git a/core/tests/coretests/src/android/util/StatsEventTest.java b/core/tests/coretests/src/android/util/StatsEventTest.java new file mode 100644 index 000000000000..ac25e2734ac9 --- /dev/null +++ b/core/tests/coretests/src/android/util/StatsEventTest.java @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import android.os.SystemClock; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.google.common.collect.Range; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Internal tests for {@link StatsEvent}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class StatsEventTest { + + @Test + public void testNoFields() { + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder().usePooledBuffer().build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + final int expectedAtomId = 0; + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(3); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + assertWithMessage("Third element is not errors type") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS); + + final int errorMask = buffer.getInt(); + + assertWithMessage("ERROR_NO_ATOM_ID should be the only error in the error mask") + .that(errorMask).isEqualTo(StatsEvent.ERROR_NO_ATOM_ID); + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + @Test + public void testIntBooleanIntInt() { + final int expectedAtomId = 109; + final int field1 = 1; + final boolean field2 = true; + final int field3 = 3; + final int field4 = 4; + + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder() + .setAtomId(expectedAtomId) + .writeInt(field1) + .writeBoolean(field2) + .writeInt(field3) + .writeInt(field4) + .usePooledBuffer() + .build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(6); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + assertWithMessage("First field is not Int") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect field 1") + .that(buffer.getInt()).isEqualTo(field1); + + assertWithMessage("Second field is not Boolean") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN); + + assertWithMessage("Incorrect field 2") + .that(buffer.get()).isEqualTo(1); + + assertWithMessage("Third field is not Int") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect field 3") + .that(buffer.getInt()).isEqualTo(field3); + + assertWithMessage("Fourth field is not Int") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect field 4") + .that(buffer.getInt()).isEqualTo(field4); + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + @Test + public void testStringFloatByteArray() { + final int expectedAtomId = 109; + final String field1 = "Str 1"; + final float field2 = 9.334f; + final byte[] field3 = new byte[] { 56, 23, 89, -120 }; + + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder() + .setAtomId(expectedAtomId) + .writeString(field1) + .writeFloat(field2) + .writeByteArray(field3) + .usePooledBuffer() + .build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(5); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + assertWithMessage("First field is not String") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING); + + final String field1Actual = getStringFromByteBuffer(buffer); + assertWithMessage("Incorrect field 1") + .that(field1Actual).isEqualTo(field1); + + assertWithMessage("Second field is not Float") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT); + + assertWithMessage("Incorrect field 2") + .that(buffer.getFloat()).isEqualTo(field2); + + assertWithMessage("Third field is not byte array") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BYTE_ARRAY); + + final byte[] field3Actual = getByteArrayFromByteBuffer(buffer); + assertWithMessage("Incorrect field 3") + .that(field3Actual).isEqualTo(field3); + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + @Test + public void testAttributionChainLong() { + final int expectedAtomId = 109; + final int[] uids = new int[] { 1, 2, 3, 4, 5 }; + final String[] tags = new String[] { "1", "2", "3", "4", "5" }; + final long field2 = -230909823L; + + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder() + .setAtomId(expectedAtomId) + .writeAttributionChain(uids, tags) + .writeLong(field2) + .usePooledBuffer() + .build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(4); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + assertWithMessage("First field is not Attribution Chain") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ATTRIBUTION_CHAIN); + + assertWithMessage("Incorrect number of attribution nodes") + .that(buffer.get()).isEqualTo((byte) uids.length); + + for (int i = 0; i < tags.length; i++) { + assertWithMessage("Incorrect uid in Attribution Chain") + .that(buffer.getInt()).isEqualTo(uids[i]); + + final String tag = getStringFromByteBuffer(buffer); + assertWithMessage("Incorrect tag in Attribution Chain") + .that(tag).isEqualTo(tags[i]); + } + + assertWithMessage("Second field is not Long") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect field 2") + .that(buffer.getLong()).isEqualTo(field2); + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + @Test + public void testKeyValuePairs() { + final int expectedAtomId = 109; + final SparseIntArray intMap = new SparseIntArray(); + final SparseLongArray longMap = new SparseLongArray(); + final SparseArray<String> stringMap = new SparseArray<>(); + final SparseArray<Float> floatMap = new SparseArray<>(); + intMap.put(1, -1); + intMap.put(2, -2); + stringMap.put(3, "abc"); + stringMap.put(4, "2h"); + floatMap.put(9, -234.344f); + + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder() + .setAtomId(expectedAtomId) + .writeKeyValuePairs(intMap, longMap, stringMap, floatMap) + .usePooledBuffer() + .build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(3); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + assertWithMessage("First field is not KeyValuePairs") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_KEY_VALUE_PAIRS); + + assertWithMessage("Incorrect number of key value pairs") + .that(buffer.get()).isEqualTo( + (byte) (intMap.size() + longMap.size() + stringMap.size() + + floatMap.size())); + + for (int i = 0; i < intMap.size(); i++) { + assertWithMessage("Incorrect key in intMap") + .that(buffer.getInt()).isEqualTo(intMap.keyAt(i)); + assertWithMessage("The type id of the value should be TYPE_INT in intMap") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + assertWithMessage("Incorrect value in intMap") + .that(buffer.getInt()).isEqualTo(intMap.valueAt(i)); + } + + for (int i = 0; i < longMap.size(); i++) { + assertWithMessage("Incorrect key in longMap") + .that(buffer.getInt()).isEqualTo(longMap.keyAt(i)); + assertWithMessage("The type id of the value should be TYPE_LONG in longMap") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + assertWithMessage("Incorrect value in longMap") + .that(buffer.getLong()).isEqualTo(longMap.valueAt(i)); + } + + for (int i = 0; i < stringMap.size(); i++) { + assertWithMessage("Incorrect key in stringMap") + .that(buffer.getInt()).isEqualTo(stringMap.keyAt(i)); + assertWithMessage("The type id of the value should be TYPE_STRING in stringMap") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING); + final String value = getStringFromByteBuffer(buffer); + assertWithMessage("Incorrect value in stringMap") + .that(value).isEqualTo(stringMap.valueAt(i)); + } + + for (int i = 0; i < floatMap.size(); i++) { + assertWithMessage("Incorrect key in floatMap") + .that(buffer.getInt()).isEqualTo(floatMap.keyAt(i)); + assertWithMessage("The type id of the value should be TYPE_FLOAT in floatMap") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT); + assertWithMessage("Incorrect value in floatMap") + .that(buffer.getFloat()).isEqualTo(floatMap.valueAt(i)); + } + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + @Test + public void testSingleAnnotations() { + final int expectedAtomId = 109; + final int field1 = 1; + final byte field1AnnotationId = 45; + final boolean field1AnnotationValue = false; + final boolean field2 = true; + final byte field2AnnotationId = 1; + final int field2AnnotationValue = 23; + + final long minTimestamp = SystemClock.elapsedRealtimeNanos(); + final StatsEvent statsEvent = StatsEvent.newBuilder() + .setAtomId(expectedAtomId) + .writeInt(field1) + .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue) + .writeBoolean(field2) + .addIntAnnotation(field2AnnotationId, field2AnnotationValue) + .usePooledBuffer() + .build(); + final long maxTimestamp = SystemClock.elapsedRealtimeNanos(); + + assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId); + + final ByteBuffer buffer = + ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN); + + assertWithMessage("Root element in buffer is not TYPE_OBJECT") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT); + + assertWithMessage("Incorrect number of elements in root object") + .that(buffer.get()).isEqualTo(4); + + assertWithMessage("First element is not timestamp") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG); + + assertWithMessage("Incorrect timestamp") + .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp)); + + assertWithMessage("Second element is not atom id") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + + assertWithMessage("Incorrect atom id") + .that(buffer.getInt()).isEqualTo(expectedAtomId); + + final byte field1Header = buffer.get(); + final int field1AnnotationValueCount = field1Header >> 4; + final byte field1Type = (byte) (field1Header & 0x0F); + assertWithMessage("First field is not Int") + .that(field1Type).isEqualTo(StatsEvent.TYPE_INT); + assertWithMessage("First field annotation count is wrong") + .that(field1AnnotationValueCount).isEqualTo(1); + assertWithMessage("Incorrect field 1") + .that(buffer.getInt()).isEqualTo(field1); + assertWithMessage("First field's annotation id is wrong") + .that(buffer.get()).isEqualTo(field1AnnotationId); + assertWithMessage("First field's annotation type is wrong") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN); + assertWithMessage("First field's annotation value is wrong") + .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0); + + final byte field2Header = buffer.get(); + final int field2AnnotationValueCount = field2Header >> 4; + final byte field2Type = (byte) (field2Header & 0x0F); + assertWithMessage("Second field is not boolean") + .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN); + assertWithMessage("Second field annotation count is wrong") + .that(field2AnnotationValueCount).isEqualTo(1); + assertWithMessage("Incorrect field 2") + .that(buffer.get()).isEqualTo(field2 ? 1 : 0); + assertWithMessage("Second field's annotation id is wrong") + .that(buffer.get()).isEqualTo(field2AnnotationId); + assertWithMessage("Second field's annotation type is wrong") + .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT); + assertWithMessage("Second field's annotation value is wrong") + .that(buffer.getInt()).isEqualTo(field2AnnotationValue); + + assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position()); + + statsEvent.release(); + } + + private static byte[] getByteArrayFromByteBuffer(final ByteBuffer buffer) { + final int numBytes = buffer.getInt(); + byte[] bytes = new byte[numBytes]; + buffer.get(bytes); + return bytes; + } + + private static String getStringFromByteBuffer(final ByteBuffer buffer) { + final byte[] bytes = getByteArrayFromByteBuffer(buffer); + return new String(bytes, UTF_8); + } +} diff --git a/data/etc/OWNERS b/data/etc/OWNERS index ea66ee373785..70d467829269 100644 --- a/data/etc/OWNERS +++ b/data/etc/OWNERS @@ -1 +1 @@ -per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com +per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com, lorenzo@google.com diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 0756647d5774..3477aedefacf 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -238,6 +238,7 @@ applications that come with the platform <permission name="android.permission.MANAGE_USB"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> + <permission name="android.permission.TETHER_PRIVILEGED"/> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> </privapp-permissions> diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index f5fa8c546bed..e93e7dfbe22c 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 08409869c626..e70529b6cd1a 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -22,7 +22,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 090d915a2f67..51b299c9ee5e 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -17,7 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java index bad3791a9c24..3408b64e7536 100644 --- a/graphics/java/android/graphics/drawable/DrawableInflater.java +++ b/graphics/java/android/graphics/drawable/DrawableInflater.java @@ -16,19 +16,19 @@ package android.graphics.drawable; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.util.AttributeSet; import android.view.InflateException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index 64fc7042dfc7..e8cb42e75ea2 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index b9945cc735d8..b50ec0d5e3fd 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 3658f89abae1..63662099c4c8 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -21,7 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index bc8a4cbd7e9d..005a4d175fd5 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 760d554888ee..fb4146f04bc9 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 8561d95ddd88..99d27ba4c469 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 1540cc22e295..e5e4d4527fca 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index db5f082bd853..43766b636adb 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -16,22 +16,22 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.graphics.Canvas; -import android.graphics.Rect; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; -import android.util.AttributeSet; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index 91ed061e511d..af7eed4b3897 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -16,14 +16,9 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; @@ -34,6 +29,11 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; /** diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index f67188c22609..2920acbe514c 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index 276f3662189b..401e05ffc139 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources; import android.graphics.Canvas; diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index aa19b2a0e94c..e6fa866df3ab 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.ComplexColor; diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java index bcee559d8291..4e6580ea5f53 100644 --- a/graphics/java/android/graphics/fonts/FontVariationAxis.java +++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java @@ -18,7 +18,7 @@ package android.graphics.fonts; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java index bd1a49205fd5..54710e58687c 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -19,7 +19,7 @@ package android.graphics.pdf; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Matrix; @@ -29,7 +29,9 @@ import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; + import com.android.internal.util.Preconditions; + import dalvik.system.CloseGuard; import libcore.io.IoUtils; diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java index fad7d8062a22..7282bcfe4445 100644 --- a/keystore/java/android/security/Credentials.java +++ b/keystore/java/android/security/Credentials.java @@ -16,7 +16,7 @@ package android.security; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.org.bouncycastle.util.io.pem.PemObject; import com.android.org.bouncycastle.util.io.pem.PemReader; diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java index a50ff7984341..af188a95c929 100644 --- a/keystore/java/android/security/GateKeeper.java +++ b/keystore/java/android/security/GateKeeper.java @@ -16,7 +16,7 @@ package android.security; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index c0a04220cfe7..e9bc8026d25e 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -16,10 +16,10 @@ package android.security; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; @@ -31,7 +31,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.security.KeyStoreException; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java index 234615d9c81d..8be85d6827f4 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java @@ -17,7 +17,7 @@ package android.security.keystore; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.security.KeyStore; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index e3f43efff72b..630a6dd081a3 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -20,8 +20,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.security.GateKeeper; diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 219d04055eae..c21bdca3db77 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -219,7 +219,7 @@ Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info, BitmapPalette palette) : SkPixelRef(info.width(), info.height(), nullptr, - bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride()) + bytesPerPixel(buffer->getPixelFormat()) * (buffer->getStride() > 0 ? buffer->getStride() : buffer->getWidth())) , mInfo(validateAlpha(info)) , mPixelStorageType(PixelStorageType::Hardware) , mPalette(palette) diff --git a/location/java/android/location/Country.java b/location/java/android/location/Country.java index f3c2a1684cda..8c40338e80fc 100644 --- a/location/java/android/location/Country.java +++ b/location/java/android/location/Country.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; diff --git a/location/java/android/location/CountryDetector.java b/location/java/android/location/CountryDetector.java index ae139499eeb2..e344b820ca2a 100644 --- a/location/java/android/location/CountryDetector.java +++ b/location/java/android/location/CountryDetector.java @@ -16,10 +16,8 @@ package android.location; -import java.util.HashMap; - import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; @@ -27,6 +25,8 @@ import android.os.Looper; import android.os.RemoteException; import android.util.Log; +import java.util.HashMap; + /** * This class provides access to the system country detector service. This * service allows applications to obtain the country that the user is in. diff --git a/location/java/android/location/CountryListener.java b/location/java/android/location/CountryListener.java index 70a83c5acdd9..eb67205f4de9 100644 --- a/location/java/android/location/CountryListener.java +++ b/location/java/android/location/CountryListener.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The listener for receiving the notification when the country is detected or diff --git a/location/java/android/location/GeocoderParams.java b/location/java/android/location/GeocoderParams.java index 45d92ee7cc34..1c6e9b6e1836 100644 --- a/location/java/android/location/GeocoderParams.java +++ b/location/java/android/location/GeocoderParams.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java index 9570b26452e4..af57bfd30984 100644 --- a/location/java/android/location/Geofence.java +++ b/location/java/android/location/Geofence.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index 609a15e1be7e..8a5edc41a774 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.SparseArray; diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 9c36d76cf370..6f12c78e8621 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -18,7 +18,7 @@ package android.location; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 7b24f44823d0..f17f7483a838 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -30,8 +30,8 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index 0902acf176d4..adea73d25922 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index f9b2fe057995..9846436b3ac8 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -19,6 +19,7 @@ package com.android.internal.location; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -37,8 +38,6 @@ import com.android.internal.R; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.telephony.GsmAlphabet; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.UnsupportedEncodingException; import java.util.concurrent.TimeUnit; @@ -126,7 +125,7 @@ public class GpsNetInitiatedHandler { public static class GpsNiNotification { - @android.annotation.UnsupportedAppUsage + @android.compat.annotation.UnsupportedAppUsage public GpsNiNotification() { } public int notificationId; diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/com/android/internal/location/ProviderRequest.java index 155f788cb33e..c23f49976799 100644 --- a/location/java/com/android/internal/location/ProviderRequest.java +++ b/location/java/com/android/internal/location/ProviderRequest.java @@ -16,7 +16,7 @@ package com.android.internal.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.location.LocationRequest; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java index 5088798a2910..3cb224dd58cd 100644 --- a/media/java/android/media/AmrInputStream.java +++ b/media/java/android/media/AmrInputStream.java @@ -16,14 +16,14 @@ package android.media; -import java.io.InputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaCodec.BufferInfo; import android.util.Log; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + /** * DO NOT USE diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java index 8ac26553bab4..c3dc118fec7e 100644 --- a/media/java/android/media/AsyncPlayer.java +++ b/media/java/android/media/AsyncPlayer.java @@ -17,9 +17,8 @@ package android.media; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.media.PlayerBase; import android.net.Uri; import android.os.PowerManager; import android.os.SystemClock; diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 820d82dd3bd1..bb874045817e 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.audiopolicy.AudioProductStrategy; import android.os.Build; import android.os.Bundle; diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index 62b18cbafcb1..51909db11a09 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -16,8 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import android.media.AudioSystem; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioDevicePort is a specialized type of AudioPort diff --git a/media/java/android/media/AudioDevicePortConfig.java b/media/java/android/media/AudioDevicePortConfig.java index 0c647ea85c60..51b8037b82f8 100644 --- a/media/java/android/media/AudioDevicePortConfig.java +++ b/media/java/android/media/AudioDevicePortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioDevicePortConfig describes a possible configuration of an output or input device diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index e55585ada6eb..7ff15df2d65e 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/AudioGain.java b/media/java/android/media/AudioGain.java index dd129a26ee59..cae1b59d46a7 100644 --- a/media/java/android/media/AudioGain.java +++ b/media/java/android/media/AudioGain.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioGain describes a gain controller. Gain controllers are exposed by diff --git a/media/java/android/media/AudioGainConfig.java b/media/java/android/media/AudioGainConfig.java index f5ebef85d302..dfefa8621ef8 100644 --- a/media/java/android/media/AudioGainConfig.java +++ b/media/java/android/media/AudioGainConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioGainConfig is used by APIs setting or getting values on a given gain diff --git a/media/java/android/media/AudioHandle.java b/media/java/android/media/AudioHandle.java index 24f81f918af2..8fc834f8d0a9 100644 --- a/media/java/android/media/AudioHandle.java +++ b/media/java/android/media/AudioHandle.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioHandle is used by the audio framework implementation to diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f797da70e7d1..32eec0054d9b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -27,12 +27,12 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager; import android.app.PendingIntent; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java index c4a5c4d86a41..33d603f0b9da 100644 --- a/media/java/android/media/AudioMixPort.java +++ b/media/java/android/media/AudioMixPort.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioMixPort is a specialized type of AudioPort diff --git a/media/java/android/media/AudioMixPortConfig.java b/media/java/android/media/AudioMixPortConfig.java index 315e46b725ad..9d8120624a45 100644 --- a/media/java/android/media/AudioMixPortConfig.java +++ b/media/java/android/media/AudioMixPortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioMixPortConfig describes a possible configuration of an output or input mixer. diff --git a/media/java/android/media/AudioPatch.java b/media/java/android/media/AudioPatch.java index d1f800694f50..e5107d4e3309 100644 --- a/media/java/android/media/AudioPatch.java +++ b/media/java/android/media/AudioPatch.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java index 83eb240be743..7c3ca24e1c9a 100644 --- a/media/java/android/media/AudioPort.java +++ b/media/java/android/media/AudioPort.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An audio port is a node of the audio framework or hardware that can be connected to or diff --git a/media/java/android/media/AudioPortConfig.java b/media/java/android/media/AudioPortConfig.java index ac19bb167905..16fb5b80eb3e 100644 --- a/media/java/android/media/AudioPortConfig.java +++ b/media/java/android/media/AudioPortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioPortConfig contains a possible configuration of an audio port chosen diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java index 6d9d6265f5e7..14249cbe8945 100644 --- a/media/java/android/media/AudioPortEventHandler.java +++ b/media/java/android/media/AudioPortEventHandler.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index ce9b07dd0c0e..306999cef7e7 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaRecorder.Source; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java index 874a215e4975..5f32c0f3f4a8 100644 --- a/media/java/android/media/AudioRecordingConfiguration.java +++ b/media/java/android/media/AudioRecordingConfiguration.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.audiofx.AudioEffect; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 1033e56776b9..1ad61983904c 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -19,8 +19,8 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothCodecConfig; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 7cd09de41346..0ced68ef8695 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -23,7 +23,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 963b1d1504e2..e4bab7466a70 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Build; diff --git a/media/java/android/media/DecoderCapabilities.java b/media/java/android/media/DecoderCapabilities.java index df5e918ba8d5..ebfc63bd9bcd 100644 --- a/media/java/android/media/DecoderCapabilities.java +++ b/media/java/android/media/DecoderCapabilities.java @@ -16,9 +16,10 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import java.util.List; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; +import java.util.List; /** * {@hide} diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java index c09c5fae1213..67ce0f7cc0b9 100644 --- a/media/java/android/media/EncoderCapabilities.java +++ b/media/java/android/media/EncoderCapabilities.java @@ -16,9 +16,10 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import java.util.List; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; +import java.util.List; /** * The EncoderCapabilities class is used to retrieve the diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 5645ba5d7dac..b41792710cbf 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -20,7 +20,7 @@ import android.annotation.CurrentTimeMillisLong; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java index 70a343f4de01..b5acbd457db0 100644 --- a/media/java/android/media/Image.java +++ b/media/java/android/media/Image.java @@ -16,14 +16,13 @@ package android.media; -import java.nio.ByteBuffer; -import java.lang.AutoCloseable; - import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.hardware.HardwareBuffer; +import java.nio.ByteBuffer; + /** * <p>A single complete image buffer to use with a media source such as a * {@link MediaCodec} or a diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java index e85b3ff99104..84ee09b35b81 100644 --- a/media/java/android/media/JetPlayer.java +++ b/media/java/android/media/JetPlayer.java @@ -17,7 +17,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.os.Handler; import android.os.Looper; diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index c9d79784004c..e702f19903d0 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.ImageFormat; import android.graphics.Rect; import android.graphics.SurfaceTexture; diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index f304f7cc5981..f3752d56ea0f 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -22,7 +22,7 @@ import static android.media.Utils.sortDistinctRanges; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.SystemProperties; import android.util.Log; diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index a08aec3ed20c..ea9a373a19f2 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -21,17 +21,17 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; -import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; -import android.os.Message; import android.os.Parcel; import android.os.PersistableBundle; import android.util.Log; + import dalvik.system.CloseGuard; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java index c4eb0310f292..9908e042c6a4 100644 --- a/media/java/android/media/MediaFile.java +++ b/media/java/android/media/MediaFile.java @@ -20,7 +20,7 @@ import static android.content.ContentResolver.MIME_TYPE_DEFAULT; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.mtp.MtpConstants; import libcore.content.type.MimeMap; diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 8b667f772867..841799a58aa4 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java index 8ee929e77899..a17ff825e21b 100644 --- a/media/java/android/media/MediaHTTPConnection.java +++ b/media/java/android/media/MediaHTTPConnection.java @@ -18,13 +18,14 @@ package android.media; import static android.media.MediaPlayer.MEDIA_ERROR_UNSUPPORTED; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkUtils; import android.os.IBinder; import android.os.StrictMode; import android.util.Log; import com.android.internal.annotations.GuardedBy; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java index 97a0df799101..3008067daefb 100644 --- a/media/java/android/media/MediaHTTPService.java +++ b/media/java/android/media/MediaHTTPService.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.util.Log; diff --git a/media/java/android/media/MediaInserter.java b/media/java/android/media/MediaInserter.java index 0749f58e460d..ca7a01cb990d 100644 --- a/media/java/android/media/MediaInserter.java +++ b/media/java/android/media/MediaInserter.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentValues; import android.net.Uri; diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index 8512dbe8d224..a23191f36efc 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.StringDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index c43b78cf4fc7..a21a630e200a 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java index 0fb392bfc0fe..14a48d72f9bb 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -18,8 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; -import android.media.MediaCodec; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaCodec.BufferInfo; import dalvik.system.CloseGuard; diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 353e58e98efa..6b953ae932f0 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -19,8 +19,8 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 63b22df12953..c957a883be1a 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.os.Build; import android.os.Handler; diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index d72231f40dcf..9837e1cc62b3 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -22,8 +22,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 771628cf7b1e..317502d760a8 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java index 792a2ba678fd..ef17073654a6 100644 --- a/media/java/android/media/Metadata.java +++ b/media/java/android/media/Metadata.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.util.Log; import android.util.MathUtils; diff --git a/media/java/android/media/MicrophoneInfo.java b/media/java/android/media/MicrophoneInfo.java index f805975d53b0..876628fefff4 100644 --- a/media/java/android/media/MicrophoneInfo.java +++ b/media/java/android/media/MicrophoneInfo.java @@ -18,7 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Pair; import java.lang.annotation.Retention; diff --git a/media/java/android/media/PlaybackParams.java b/media/java/android/media/PlaybackParams.java index b4325b6ea53d..f24f831d0333 100644 --- a/media/java/android/media/PlaybackParams.java +++ b/media/java/android/media/PlaybackParams.java @@ -18,7 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 325420b06122..c5fd3c30236d 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -16,8 +16,8 @@ package android.media; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.graphics.Bitmap; diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index f70963a982e4..9e48f1e05391 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -16,8 +16,8 @@ package android.media; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.graphics.Bitmap; diff --git a/media/java/android/media/RemoteDisplay.java b/media/java/android/media/RemoteDisplay.java index 2be206f2f462..e529af9da935 100644 --- a/media/java/android/media/RemoteDisplay.java +++ b/media/java/android/media/RemoteDisplay.java @@ -16,12 +16,12 @@ package android.media; -import dalvik.system.CloseGuard; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.view.Surface; +import dalvik.system.CloseGuard; + /** * Listens for Wifi remote display connections managed by the media server. * diff --git a/media/java/android/media/RemoteDisplayState.java b/media/java/android/media/RemoteDisplayState.java index 2f4ace0c8fdd..fed361a960e6 100644 --- a/media/java/android/media/RemoteDisplayState.java +++ b/media/java/android/media/RemoteDisplayState.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index eb680c8377f4..d35bc4176cb3 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 435d8d766149..6fd47c42bcba 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -22,9 +22,9 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java index 1a241af7345d..48657a6c810f 100644 --- a/media/java/android/media/SubtitleController.java +++ b/media/java/android/media/SubtitleController.java @@ -16,10 +16,7 @@ package android.media; -import java.util.Locale; -import java.util.Vector; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.MediaPlayer.TrackInfo; import android.media.SubtitleTrack.RenderingWidget; @@ -28,6 +25,9 @@ import android.os.Looper; import android.os.Message; import android.view.accessibility.CaptioningManager; +import java.util.Locale; +import java.util.Vector; + /** * The subtitle controller provides the architecture to display subtitles for a * media source. It allows specifying which tracks to display, on which anchor diff --git a/media/java/android/media/SubtitleTrack.java b/media/java/android/media/SubtitleTrack.java index 0705d97a9edf..10669f466fe5 100644 --- a/media/java/android/media/SubtitleTrack.java +++ b/media/java/android/media/SubtitleTrack.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.media.MediaPlayer.TrackInfo; import android.os.Handler; diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java index 534d63b4cca0..cbdf9adfd0e1 100644 --- a/media/java/android/media/ThumbnailUtils.java +++ b/media/java/android/media/ThumbnailUtils.java @@ -24,7 +24,7 @@ import static android.os.Environment.MEDIA_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/TimedText.java b/media/java/android/media/TimedText.java index d8cdf9c12e09..120642a8e7cb 100644 --- a/media/java/android/media/TimedText.java +++ b/media/java/android/media/TimedText.java @@ -16,14 +16,15 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.os.Parcel; import android.util.Log; + +import java.util.ArrayList; import java.util.HashMap; -import java.util.Set; import java.util.List; -import java.util.ArrayList; +import java.util.Set; /** * Class to hold the timed text's metadata, including: diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java index c6d5ba3f9953..cc114a9092e1 100644 --- a/media/java/android/media/ToneGenerator.java +++ b/media/java/android/media/ToneGenerator.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; diff --git a/media/java/android/media/TtmlRenderer.java b/media/java/android/media/TtmlRenderer.java index 34154ce93a8c..e5782642f4eb 100644 --- a/media/java/android/media/TtmlRenderer.java +++ b/media/java/android/media/TtmlRenderer.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; @@ -27,6 +27,10 @@ import android.view.accessibility.CaptioningManager; import android.widget.LinearLayout; import android.widget.TextView; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; @@ -37,10 +41,6 @@ import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - /** @hide */ public class TtmlRenderer extends SubtitleController.Renderer { private final Context mContext; diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java index 663d564af23e..99dfe1e8e32f 100644 --- a/media/java/android/media/VolumeShaper.java +++ b/media/java/android/media/VolumeShaper.java @@ -19,13 +19,12 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.AutoCloseable; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Objects; diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java index 36458d7e1746..bc1429499e70 100644 --- a/media/java/android/media/WebVttRenderer.java +++ b/media/java/android/media/WebVttRenderer.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.text.Layout.Alignment; import android.text.SpannableStringBuilder; diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index 5b4bbce91784..4a40c627ecb0 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -19,8 +19,8 @@ package android.media.audiofx; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Handler; import android.os.Looper; diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java index 89a509f64a1b..392e8fe7543f 100644 --- a/media/java/android/media/audiofx/Visualizer.java +++ b/media/java/android/media/audiofx/Visualizer.java @@ -16,8 +16,8 @@ package android.media.audiofx; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index a82c78fad271..dd9877a9c706 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioSystem; diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index c4afd95be9ac..8c204d222cd4 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -19,7 +19,7 @@ package android.media.audiopolicy; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioAttributes; import android.os.Parcel; import android.util.Log; diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 1fc4f7d59ca5..a856653e8bc9 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -18,8 +18,8 @@ package android.media.session; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index e11715ff7299..5db4e8c1e3f7 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -19,9 +19,9 @@ package android.media.session; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index 123c4f75d5b6..0d506f0eb52c 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -16,9 +16,9 @@ package android.media.session; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -26,7 +26,6 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; -import android.media.AudioManager; import android.media.MediaMetadata; import android.media.MediaMetadataEditor; import android.media.MediaMetadataRetriever; diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index a89dc5f1d2af..aff725734ee1 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ParceledListSlice; diff --git a/mms/OWNERS b/mms/OWNERS index ba00d5d75010..befc320b949c 100644 --- a/mms/OWNERS +++ b/mms/OWNERS @@ -12,3 +12,5 @@ satk@google.com shuoq@google.com refuhoo@google.com nazaninb@google.com +sarahchin@google.com +dbright@google.com
\ No newline at end of file diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java index 69bd0ed0c59c..ff00fb3282b1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java @@ -16,8 +16,6 @@ package com.android.settingslib; -import static android.content.Context.TELEPHONY_SERVICE; - import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -172,36 +170,38 @@ public class DeviceInfoUtils { } } - public static String getFormattedPhoneNumber(Context context, SubscriptionInfo subscriptionInfo) { + /** + * Format a phone number. + * @param subscriptionInfo {@link SubscriptionInfo} subscription information. + * @return Returns formatted phone number. + */ + public static String getFormattedPhoneNumber(Context context, + SubscriptionInfo subscriptionInfo) { String formattedNumber = null; if (subscriptionInfo != null) { - final TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); - final String rawNumber = - telephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()); + final TelephonyManager telephonyManager = context.getSystemService( + TelephonyManager.class); + final String rawNumber = telephonyManager.createForSubscriptionId( + subscriptionInfo.getSubscriptionId()).getLine1Number(); if (!TextUtils.isEmpty(rawNumber)) { formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); } - } return formattedNumber; } public static String getFormattedPhoneNumbers(Context context, - List<SubscriptionInfo> subscriptionInfo) { + List<SubscriptionInfo> subscriptionInfoList) { StringBuilder sb = new StringBuilder(); - if (subscriptionInfo != null) { - final TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); - final int count = subscriptionInfo.size(); - for (int i = 0; i < count; i++) { - final String rawNumber = telephonyManager.getLine1Number( - subscriptionInfo.get(i).getSubscriptionId()); + if (subscriptionInfoList != null) { + final TelephonyManager telephonyManager = context.getSystemService( + TelephonyManager.class); + final int count = subscriptionInfoList.size(); + for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) { + final String rawNumber = telephonyManager.createForSubscriptionId( + subscriptionInfo.getSubscriptionId()).getLine1Number(); if (!TextUtils.isEmpty(rawNumber)) { - sb.append(PhoneNumberUtils.formatNumber(rawNumber)); - if (i < count - 1) { - sb.append("\n"); - } + sb.append(PhoneNumberUtils.formatNumber(rawNumber)).append("\n"); } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java index 23e2949372aa..d5ff1ee6512a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java @@ -38,7 +38,7 @@ public class DataUsageUtils { final SubscriptionManager subscriptionManager = context.getSystemService( SubscriptionManager.class); final NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll( - telephonyManager.getSubscriberId(subId)); + telephonyManager.createForSubscriptionId(subId).getSubscriberId()); if (!subscriptionManager.isActiveSubId(subId)) { Log.i(TAG, "Subscription is not active: " + subId); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index efd31ca6a86e..af2569dcb1f2 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -186,6 +186,9 @@ <uses-permission android:name="android.permission.MANAGE_APPOPS" /> + <!-- Permission required for storage tests - FuseDaemonHostTest --> + <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> + <!-- Permission needed to run network tests in CTS --> <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" /> <!-- Permission needed to test tcp keepalive offload. --> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 367a7bd4aed7..0ffe05de1357 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -26,8 +26,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; -import android.os.RemoteException; -import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -37,7 +35,6 @@ import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; @@ -254,27 +251,29 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { @Override public void run() { - try { - if (DEBUG) { - Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")"); - } - final int[] result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin); - if (DEBUG) { - Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]); - } + if (DEBUG) { + Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")"); + } + TelephonyManager telephonyManager = + ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) + .createForSubscriptionId(mSubId); + final int[] result = telephonyManager.supplyPinReportResult(mPin); + if (result == null || result.length == 0) { + Log.e(TAG, "Error result for supplyPinReportResult."); post(new Runnable() { @Override public void run() { - onSimCheckResponse(result[0], result[1]); + onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException for supplyPinReportResult:", e); + } else { + if (DEBUG) { + Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]); + } post(new Runnable() { @Override public void run() { - onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); + onSimCheckResponse(result[0], result[1]); } }); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 81f8c67605fe..abadcfd60a38 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -25,8 +25,6 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; -import android.os.RemoteException; -import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -36,7 +34,6 @@ import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; @@ -314,25 +311,27 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { @Override public void run() { - try { - if (DEBUG) Log.v(TAG, "call supplyPukReportResult()"); - final int[] result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPukReportResultForSubscriber(mSubId, mPuk, mPin); - if (DEBUG) { - Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]); - } + if (DEBUG) Log.v(TAG, "call supplyPukReportResult()"); + TelephonyManager telephonyManager = + ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) + .createForSubscriptionId(mSubId); + final int[] result = telephonyManager.supplyPukReportResult(mPuk, mPin); + if (result == null || result.length == 0) { + Log.e(TAG, "Error result for supplyPukReportResult."); post(new Runnable() { @Override public void run() { - onSimLockChangedResponse(result[0], result[1]); + onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException for supplyPukReportResult:", e); + } else { + if (DEBUG) { + Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]); + } post(new Runnable() { @Override public void run() { - onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); + onSimLockChangedResponse(result[0], result[1]); } }); } diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index e79986c4f6c6..8987b544779f 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -122,4 +122,5 @@ android_app { use_embedded_native_libs: true, // The permission configuration *must* be included to ensure security of the device required: ["NetworkPermissionConfig"], + apex_available: ["com.android.tethering"], } diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml index 87a8c3f5c68a..e99c2c529bd2 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -33,6 +33,7 @@ <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> + <uses-permission android:name="android.permission.TETHER_PRIVILEGED" /> <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp index 5785707cb9c5..264ce440f59f 100644 --- a/packages/Tethering/common/TetheringLib/Android.bp +++ b/packages/Tethering/common/TetheringLib/Android.bp @@ -47,6 +47,16 @@ java_library { libs: [ "android_system_stubs_current", ], + + hostdex: true, // for hiddenapi check + visibility: [ + "//frameworks/base/packages/Tethering:__subpackages__", + //TODO(b/147200698) remove below lines when the platform is built with stubs + "//frameworks/base", + "//frameworks/base/services", + "//frameworks/base/services/core", + ], + apex_available: ["com.android.tethering"], } filegroup { diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml index ca866a946ea2..792bce9fc334 100644 --- a/packages/Tethering/res/values/strings.xml +++ b/packages/Tethering/res/values/strings.xml @@ -1,4 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> <resources> <!-- Shown when the device is tethered --> <!-- Strings for tethered notification title [CHAR LIMIT=200] --> @@ -9,8 +23,11 @@ <!-- This notification is shown when tethering has been disabled on a user's device. The device is managed by the user's employer. Tethering can't be turned on unless the IT administrator allows it. The noun "admin" is another reference for "IT administrator." --> - <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> + <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> <string name="disable_tether_notification_title">Tethering is disabled</string> - <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> + <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> <string name="disable_tether_notification_message">Contact your admin for details</string> + + <!-- Strings for tether notification channel name [CHAR LIMIT=200] --> + <string name="notification_channel_tethering_status">Hotspot & tethering status</string> </resources>
\ No newline at end of file diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java index 2119791a2602..5b97f50f1208 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java @@ -50,6 +50,7 @@ import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANG import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; @@ -106,8 +107,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.State; @@ -663,19 +662,19 @@ public class Tethering { if (usbTethered) { if (wifiTethered || bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); + showTetheredNotification(R.drawable.stat_sys_tether_general); } else { - showTetheredNotification(SystemMessage.NOTE_TETHER_USB); + showTetheredNotification(R.drawable.stat_sys_tether_usb); } } else if (wifiTethered) { if (bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); + showTetheredNotification(R.drawable.stat_sys_tether_general); } else { /* We now have a status bar icon for WifiTethering, so drop the notification */ clearTetheredNotification(); } } else if (bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH); + showTetheredNotification(R.drawable.stat_sys_tether_bluetooth); } else { clearTetheredNotification(); } @@ -688,30 +687,22 @@ public class Tethering { @VisibleForTesting protected void showTetheredNotification(int id, boolean tetheringOn) { NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) + .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) { return; } - int icon = 0; - switch(id) { - case SystemMessage.NOTE_TETHER_USB: - icon = R.drawable.stat_sys_tether_usb; - break; - case SystemMessage.NOTE_TETHER_BLUETOOTH: - icon = R.drawable.stat_sys_tether_bluetooth; - break; - case SystemMessage.NOTE_TETHER_GENERAL: - default: - icon = R.drawable.stat_sys_tether_general; - break; - } + final NotificationChannel channel = new NotificationChannel( + "TETHERING_STATUS", + mContext.getResources().getString(R.string.notification_channel_tethering_status), + NotificationManager.IMPORTANCE_LOW); + notificationManager.createNotificationChannel(channel); if (mLastNotificationId != 0) { - if (mLastNotificationId == icon) { + if (mLastNotificationId == id) { return; } - notificationManager.cancelAsUser(null, mLastNotificationId, - UserHandle.ALL); + notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } @@ -719,8 +710,8 @@ public class Tethering { intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, - null, UserHandle.CURRENT); + PendingIntent pi = PendingIntent.getActivity( + mContext.createContextAsUser(UserHandle.CURRENT, 0), 0, intent, 0, null); Resources r = mContext.getResources(); final CharSequence title; @@ -735,32 +726,31 @@ public class Tethering { } if (mTetheredNotificationBuilder == null) { - mTetheredNotificationBuilder = new Notification.Builder(mContext, - SystemNotificationChannels.NETWORK_STATUS); + mTetheredNotificationBuilder = new Notification.Builder(mContext, channel.getId()); mTetheredNotificationBuilder.setWhen(0) .setOngoing(true) .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)) + android.R.color.system_notification_accent_color)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setCategory(Notification.CATEGORY_STATUS); } - mTetheredNotificationBuilder.setSmallIcon(icon) + mTetheredNotificationBuilder.setSmallIcon(id) .setContentTitle(title) .setContentText(message) .setContentIntent(pi); mLastNotificationId = id; - notificationManager.notifyAsUser(null, mLastNotificationId, - mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL); + notificationManager.notify(null, mLastNotificationId, + mTetheredNotificationBuilder.buildInto(new Notification())); } @VisibleForTesting protected void clearTetheredNotification() { NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) + .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mLastNotificationId != 0) { - notificationManager.cancelAsUser(null, mLastNotificationId, - UserHandle.ALL); + notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } } diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java index fe3f51700df9..5692a6fc5c80 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -16,9 +16,12 @@ package com.android.server.connectivity.tethering; +import static android.net.ConnectivityManager.TYPE_BLUETOOTH; +import static android.net.ConnectivityManager.TYPE_ETHERNET; +import static android.net.ConnectivityManager.TYPE_MOBILE; 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.TYPE_WIFI; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -35,8 +38,10 @@ import android.net.util.PrefixUtils; import android.net.util.SharedLog; import android.os.Handler; import android.util.Log; +import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; import com.android.internal.util.StateMachine; import java.util.HashMap; @@ -77,11 +82,25 @@ public class UpstreamNetworkMonitor { public static final int EVENT_ON_LINKPROPERTIES = 2; public static final int EVENT_ON_LOST = 3; public static final int NOTIFY_LOCAL_PREFIXES = 10; + // This value is used by deprecated preferredUpstreamIfaceTypes selection which is default + // disabled. + @VisibleForTesting + public static final int TYPE_NONE = -1; private static final int CALLBACK_LISTEN_ALL = 1; private static final int CALLBACK_DEFAULT_INTERNET = 2; private static final int CALLBACK_MOBILE_REQUEST = 3; + private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray(); + static { + sLegacyTypeToTransport.put(TYPE_MOBILE, NetworkCapabilities.TRANSPORT_CELLULAR); + sLegacyTypeToTransport.put(TYPE_MOBILE_DUN, NetworkCapabilities.TRANSPORT_CELLULAR); + sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR); + sLegacyTypeToTransport.put(TYPE_WIFI, NetworkCapabilities.TRANSPORT_WIFI); + sLegacyTypeToTransport.put(TYPE_BLUETOOTH, NetworkCapabilities.TRANSPORT_BLUETOOTH); + sLegacyTypeToTransport.put(TYPE_ETHERNET, NetworkCapabilities.TRANSPORT_ETHERNET); + } + private final Context mContext; private final SharedLog mLog; private final StateMachine mTarget; @@ -202,7 +221,7 @@ public class UpstreamNetworkMonitor { final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI; final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder() - .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType)) + .setCapabilities(networkCapabilitiesForType(legacyType)) .build(); // The existing default network and DUN callbacks will be notified. @@ -354,16 +373,6 @@ public class UpstreamNetworkMonitor { notifyTarget(EVENT_ON_LINKPROPERTIES, network); } - private void handleSuspended(Network network) { - if (!network.equals(mTetheringUpstreamNetwork)) return; - mLog.log("SUSPENDED current upstream: " + network); - } - - private void handleResumed(Network network) { - if (!network.equals(mTetheringUpstreamNetwork)) return; - mLog.log("RESUMED current upstream: " + network); - } - private void handleLost(Network network) { // There are few TODOs within ConnectivityService's rematching code // pertaining to spurious onLost() notifications. @@ -453,20 +462,6 @@ public class UpstreamNetworkMonitor { } @Override - public void onNetworkSuspended(Network network) { - if (mCallbackType == CALLBACK_LISTEN_ALL) { - handleSuspended(network); - } - } - - @Override - public void onNetworkResumed(Network network) { - if (mCallbackType == CALLBACK_LISTEN_ALL) { - handleResumed(network); - } - } - - @Override public void onLost(Network network) { if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { mDefaultInternetNetwork = null; @@ -510,7 +505,7 @@ public class UpstreamNetworkMonitor { for (int type : preferredTypes) { NetworkCapabilities nc; try { - nc = ConnectivityManager.networkCapabilitiesForType(type); + nc = networkCapabilitiesForType(type); } catch (IllegalArgumentException iae) { Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " + type); continue; @@ -572,4 +567,28 @@ public class UpstreamNetworkMonitor { return null; } + + /** + * Given a legacy type (TYPE_WIFI, ...) returns the corresponding NetworkCapabilities instance. + * This function is used for deprecated legacy type and be disabled by default. + */ + @VisibleForTesting + public static NetworkCapabilities networkCapabilitiesForType(int type) { + final NetworkCapabilities nc = new NetworkCapabilities(); + + // Map from type to transports. + final int notFound = -1; + final int transport = sLegacyTypeToTransport.get(type, notFound); + Preconditions.checkArgument(transport != notFound, "unknown legacy type: " + type); + nc.addTransportType(transport); + + if (type == TYPE_MOBILE_DUN) { + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); + // DUN is restricted network, see NetworkCapabilities#FORCE_RESTRICTED_CAPABILITIES. + nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); + } else { + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + } + return nc; + } } diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java index 5ca21f718f8e..4edde0a066aa 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java @@ -224,6 +224,11 @@ public class TetheringTest { if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; return super.getSystemServiceName(serviceClass); } + + @Override + public Context createContextAsUser(UserHandle user, int flags) { + return mContext; + } } public class MockIpServerDependencies extends IpServer.Dependencies { @@ -432,6 +437,7 @@ public class TetheringTest { .thenReturn(true); mServiceContext = new TestContext(mContext); + when(mContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(null); mContentResolver = new MockContentResolver(mServiceContext); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java index c90abbbedb5f..5ed75bf26f8b 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java @@ -18,13 +18,14 @@ package com.android.server.connectivity.tethering; 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.TYPE_WIFI; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static com.android.server.connectivity.tethering.UpstreamNetworkMonitor.TYPE_NONE; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -538,13 +539,15 @@ public class UpstreamNetworkMonitorTest { mUNM.selectPreferredUpstreamType(preferredTypes)); verify(mEntitleMgr, times(1)).maybeRunProvisioning(); } + private void assertSatisfiesLegacyType(int legacyType, UpstreamNetworkState ns) { if (legacyType == TYPE_NONE) { assertTrue(ns == null); return; } - final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType); + final NetworkCapabilities nc = + UpstreamNetworkMonitor.networkCapabilitiesForType(legacyType); assertTrue(nc.satisfiedByNetworkCapabilities(ns.networkCapabilities)); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 49cfa7b6de6d..3a8a73657f39 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -94,6 +94,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; +import android.net.NetworkProvider; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkScore; @@ -221,6 +222,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.atomic.AtomicInteger; /** * @hide @@ -364,10 +366,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_PROXY_HAS_CHANGED = 16; /** - * used internally when registering NetworkFactories - * obj = NetworkFactoryInfo + * used internally when registering NetworkProviders + * obj = NetworkProviderInfo */ - private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; + private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; /** * used internally when registering NetworkAgents @@ -403,10 +405,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; /** - * used internally when registering NetworkFactories + * used internally when registering NetworkProviders * obj = Messenger */ - private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23; + private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; /** * used internally to expire a wakelock when transitioning @@ -597,6 +599,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; + // Sequence number for NetworkProvider IDs. + private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( + NetworkProvider.FIRST_PROVIDER_ID); + // NetworkRequest activity String log entries. private static final int MAX_NETWORK_REQUEST_LOGS = 20; private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); @@ -2381,9 +2387,9 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } - pw.print("NetworkFactories for:"); - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - pw.print(" " + nfi.name); + pw.print("NetworkProviders for:"); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + pw.print(" " + npi.name); } pw.println(); pw.println(); @@ -2714,7 +2720,7 @@ public class ConnectivityService extends IConnectivityManager.Stub nai.lastValidated = valid; nai.everValidated |= valid; updateCapabilities(oldScore, nai, nai.networkCapabilities); - // If score has changed, rebroadcast to NetworkFactories. b/17726566 + // If score has changed, rebroadcast to NetworkProviders. b/17726566 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); if (valid) { handleFreshlyValidatedNetwork(nai); @@ -2829,6 +2835,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } + // TODO: delete when direct use of registerNetworkFactory is no longer supported. private boolean maybeHandleNetworkFactoryMessage(Message msg) { switch (msg.what) { default: @@ -3018,16 +3025,16 @@ public class ConnectivityService extends IConnectivityManager.Stub private void handleAsyncChannelHalfConnect(Message msg) { ensureRunningOnConnectivityServiceThread(); final AsyncChannel ac = (AsyncChannel) msg.obj; - if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { + if (mNetworkProviderInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (VDBG) log("NetworkFactory connected"); // Finish setting up the full connection - NetworkFactoryInfo nfi = mNetworkFactoryInfos.get(msg.replyTo); - nfi.completeConnection(); - sendAllRequestsToFactory(nfi); + NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo); + npi.completeConnection(); + sendAllRequestsToProvider(npi); } else { loge("Error connecting NetworkFactory"); - mNetworkFactoryInfos.remove(msg.obj); + mNetworkProviderInfos.remove(msg.obj); } } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { @@ -3059,8 +3066,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai != null) { disconnectAndDestroyNetwork(nai); } else { - NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); - if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); + NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo); + if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name); } } @@ -3143,7 +3150,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it // after we've rematched networks with requests which should make a potential // fallback network the default or requested a new network from the - // NetworkFactories, so network traffic isn't interrupted for an unnecessarily + // NetworkProviders, so network traffic isn't interrupted for an unnecessarily // long time. destroyNativeNetwork(nai); mDnsManager.removeNetwork(nai.network); @@ -3406,8 +3413,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - nfi.cancelRequest(nri.request); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + npi.cancelRequest(nri.request); } } else { // listens don't have a singular affectedNetwork. Check all networks to see @@ -3842,12 +3849,12 @@ public class ConnectivityService extends IConnectivityManager.Stub handleApplyDefaultProxy((ProxyInfo)msg.obj); break; } - case EVENT_REGISTER_NETWORK_FACTORY: { - handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); + case EVENT_REGISTER_NETWORK_PROVIDER: { + handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); break; } - case EVENT_UNREGISTER_NETWORK_FACTORY: { - handleUnregisterNetworkFactory((Messenger)msg.obj); + case EVENT_UNREGISTER_NETWORK_PROVIDER: { + handleUnregisterNetworkProvider((Messenger) msg.obj); break; } case EVENT_REGISTER_NETWORK_AGENT: { @@ -4892,7 +4899,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; - private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = new HashMap<>(); + private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; @@ -4900,35 +4907,73 @@ public class ConnectivityService extends IConnectivityManager.Stub @GuardedBy("mUidToNetworkRequestCount") private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); - private static class NetworkFactoryInfo { + private static class NetworkProviderInfo { public final String name; public final Messenger messenger; private final AsyncChannel mAsyncChannel; - public final int factorySerialNumber; + private final IBinder.DeathRecipient mDeathRecipient; + public final int providerId; - NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, - int factorySerialNumber) { + NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel, + int providerId, IBinder.DeathRecipient deathRecipient) { this.name = name; this.messenger = messenger; - this.mAsyncChannel = asyncChannel; - this.factorySerialNumber = factorySerialNumber; + this.providerId = providerId; + mAsyncChannel = asyncChannel; + mDeathRecipient = deathRecipient; + + if ((mAsyncChannel == null) == (mDeathRecipient == null)) { + throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient"); + } + } + + boolean isLegacyNetworkFactory() { + return mAsyncChannel != null; } - void requestNetwork(NetworkRequest request, int score, int servingSerialNumber) { - mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, - servingSerialNumber, request); + void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) { + try { + messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj)); + } catch (RemoteException e) { + // Remote process died. Ignore; the death recipient will remove this + // NetworkProviderInfo from mNetworkProviderInfos. + } + } + + void requestNetwork(NetworkRequest request, int score, int servingProviderId) { + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, + servingProviderId, request); + } else { + sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score, + servingProviderId, request); + } } void cancelRequest(NetworkRequest request) { - mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request); + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request); + } else { + sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request); + } } void connect(Context context, Handler handler) { - mAsyncChannel.connect(context, handler, messenger); + if (isLegacyNetworkFactory()) { + mAsyncChannel.connect(context, handler, messenger); + } else { + try { + messenger.getBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mDeathRecipient.binderDied(); + } + } } void completeConnection() { - mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + } } } @@ -5299,6 +5344,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); } + /** Returns the next Network provider ID. */ + public final int nextNetworkProviderId() { + return mNextNetworkProviderId.getAndIncrement(); + } + @Override public void releaseNetworkRequest(NetworkRequest networkRequest) { ensureNetworkRequestHasType(networkRequest); @@ -5309,31 +5359,65 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public int registerNetworkFactory(Messenger messenger, String name) { enforceNetworkFactoryPermission(); - NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(), - NetworkFactory.SerialNumber.nextSerialNumber()); - mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); - return nfi.factorySerialNumber; + NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, new AsyncChannel(), + nextNetworkProviderId(), null /* deathRecipient */); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); + return npi.providerId; + } + + private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { + if (mNetworkProviderInfos.containsKey(npi.messenger)) { + // Avoid creating duplicates. even if an app makes a direct AIDL call. + // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, + // as that will throw if a duplicate provider is registered. + Slog.e(TAG, "Attempt to register existing NetworkProviderInfo " + + mNetworkProviderInfos.get(npi.messenger).name); + return; + } + + if (DBG) log("Got NetworkProvider Messenger for " + npi.name); + mNetworkProviderInfos.put(npi.messenger, npi); + npi.connect(mContext, mTrackerHandler); + if (!npi.isLegacyNetworkFactory()) { + // Legacy NetworkFactories get their requests when their AsyncChannel connects. + sendAllRequestsToProvider(npi); + } + } + + @Override + public int registerNetworkProvider(Messenger messenger, String name) { + enforceNetworkFactoryPermission(); + NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, + null /* asyncChannel */, nextNetworkProviderId(), + () -> unregisterNetworkProvider(messenger)); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); + return npi.providerId; } - private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { - if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); - mNetworkFactoryInfos.put(nfi.messenger, nfi); - nfi.connect(mContext, mTrackerHandler); + @Override + public void unregisterNetworkProvider(Messenger messenger) { + enforceNetworkFactoryPermission(); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); } @Override public void unregisterNetworkFactory(Messenger messenger) { - enforceNetworkFactoryPermission(); - mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); + unregisterNetworkProvider(messenger); } - private void handleUnregisterNetworkFactory(Messenger messenger) { - NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); - if (nfi == null) { - loge("Failed to find Messenger in unregisterNetworkFactory"); + private void handleUnregisterNetworkProvider(Messenger messenger) { + NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); + if (npi == null) { + loge("Failed to find Messenger in unregisterNetworkProvider"); return; } - if (DBG) log("unregisterNetworkFactory for " + nfi.name); + if (DBG) log("unregisterNetworkProvider for " + npi.name); + } + + @Override + public void declareNetworkRequestUnfulfillable(NetworkRequest request) { + enforceNetworkFactoryPermission(); + mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true)); } // NOTE: Accessed on multiple threads, must be synchronized on itself. @@ -5401,7 +5485,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc) { return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities, - currentScore, networkMisc, NetworkFactory.SerialNumber.NONE); + currentScore, networkMisc, NetworkProvider.ID_NONE); } /** @@ -5417,11 +5501,11 @@ public class ConnectivityService extends IConnectivityManager.Stub * @param currentScore the initial score of the network. See * {@link NetworkAgentInfo#getCurrentScore}. * @param networkMisc metadata about the network. This is never updated. - * @param factorySerialNumber the serial number of the factory owning this NetworkAgent. + * @param providerId the ID of the provider owning this NetworkAgent. */ public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkMisc networkMisc, int factorySerialNumber) { + int currentScore, NetworkMisc networkMisc, int providerId) { enforceNetworkFactoryPermission(); LinkProperties lp = new LinkProperties(linkProperties); @@ -5434,7 +5518,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, ns, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, - mDnsResolver, mNMS, factorySerialNumber); + mDnsResolver, mNMS, providerId); // Make sure the network capabilities reflect what the agent info says. nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); @@ -5713,7 +5797,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. // Don't complain for VPNs since they're not driven by requests and there is no risk of // causing a connect/teardown loop. - // TODO: remove this altogether and make it the responsibility of the NetworkFactories to + // TODO: remove this altogether and make it the responsibility of the NetworkProviders to // avoid connect/teardown loops. if (nai.everConnected && !nai.isVPN() && @@ -5953,13 +6037,13 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || DDBG){ log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); } - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - nfi.requestNetwork(networkRequest, score, serial); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + npi.requestNetwork(networkRequest, score, serial); } } /** Sends all current NetworkRequests to the specified factory. */ - private void sendAllRequestsToFactory(NetworkFactoryInfo nfi) { + private void sendAllRequestsToProvider(NetworkProviderInfo npi) { ensureRunningOnConnectivityServiceThread(); for (NetworkRequestInfo nri : mNetworkRequests.values()) { if (nri.request.isListen()) continue; @@ -5971,9 +6055,9 @@ public class ConnectivityService extends IConnectivityManager.Stub serial = nai.factorySerialNumber; } else { score = 0; - serial = NetworkFactory.SerialNumber.NONE; + serial = NetworkProvider.ID_NONE; } - nfi.requestNetwork(nri.request, score, serial); + npi.requestNetwork(nri.request, score, serial); } } @@ -6254,11 +6338,11 @@ public class ConnectivityService extends IConnectivityManager.Stub Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request); } addedRequests.add(nri); - // Tell NetworkFactories about the new score, so they can stop + // Tell NetworkProviders about the new score, so they can stop // trying to connect if they know they cannot match it. // TODO - this could get expensive if we have a lot of requests for this // network. Think about if there is a way to reduce this. Push - // netid->request mapping to each factory? + // netid->request mapping to each provider? sendUpdatedScoreToFactories(nri.request, newSatisfier); if (isDefaultRequest(nri)) { isNewDefault = true; @@ -6287,7 +6371,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } else { Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + newNetwork.name() + - " without updating mSatisfier or factories!"); + " without updating mSatisfier or providers!"); } // TODO: Technically, sending CALLBACK_LOST here is // incorrect if there is a replacement network currently diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java index cfe56052118f..d20936c2d217 100644 --- a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java +++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java @@ -36,11 +36,11 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; +import android.os.TimestampedValue; import android.provider.Settings; import android.util.Log; import android.util.NtpTrustedTime; import android.util.TimeUtils; -import android.util.TimestampedValue; import com.android.internal.util.DumpUtils; diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index a788fc87b498..5e251df80224 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -46,6 +46,7 @@ import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.CallAttributes; import android.telephony.CallQuality; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.CellLocation; import android.telephony.DataFailCause; @@ -207,7 +208,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // Connection state of default APN type data (i.e. internet) of phones private int[] mDataConnectionState; - private Bundle[] mCellLocation; + private CellIdentity[] mCellIdentity; private int[] mDataConnectionNetworkType; @@ -295,7 +296,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int numPhones = getTelephonyManager().getPhoneCount(); for (int sub = 0; sub < numPhones; sub++) { TelephonyRegistry.this.notifyCellLocationForSubscriber(sub, - mCellLocation[sub]); + mCellIdentity[sub]); } break; } @@ -404,7 +405,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mSignalStrength = copyOf(mSignalStrength, mNumPhones); mMessageWaiting = copyOf(mMessageWaiting, mNumPhones); mCallForwarding = copyOf(mCallForwarding, mNumPhones); - mCellLocation = copyOf(mCellLocation, mNumPhones); + mCellIdentity = copyOf(mCellIdentity, mNumPhones); mSrvccState = copyOf(mSrvccState, mNumPhones); mPreciseCallState = copyOf(mPreciseCallState, mNumPhones); mForegroundCallState = copyOf(mForegroundCallState, mNumPhones); @@ -439,7 +440,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mUserMobileDataState[i] = false; mMessageWaiting[i] = false; mCallForwarding[i] = false; - mCellLocation[i] = new Bundle(); + mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; @@ -455,15 +456,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); } - - // Note that location can be null for non-phone builds like - // like the generic one. - CellLocation location = CellLocation.getEmpty(); - if (location != null) { - for (int i = oldNumPhones; i < mNumPhones; i++) { - location.fillInNotifierBundle(mCellLocation[i]); - } - } } private void cutListToSize(List list, int size) { @@ -503,7 +495,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mSignalStrength = new SignalStrength[numPhones]; mMessageWaiting = new boolean[numPhones]; mCallForwarding = new boolean[numPhones]; - mCellLocation = new Bundle[numPhones]; + mCellIdentity = new CellIdentity[numPhones]; mSrvccState = new int[numPhones]; mPreciseCallState = new PreciseCallState[numPhones]; mForegroundCallState = new int[numPhones]; @@ -532,7 +524,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mUserMobileDataState[i] = false; mMessageWaiting[i] = false; mCallForwarding[i] = false; - mCellLocation[i] = new Bundle(); + mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; @@ -549,14 +541,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); } - // Note that location can be null for non-phone builds like - // like the generic one. - if (location != null) { - for (int i = 0; i < numPhones; i++) { - location.fillInNotifierBundle(mCellLocation[i]); - } - } - mAppOps = mContext.getSystemService(AppOpsManager.class); } @@ -839,11 +823,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { - if (DBG_LOC) log("listen: mCellLocation = " - + mCellLocation[phoneId]); + if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]); if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onCellLocationChanged( - new Bundle(mCellLocation[phoneId])); + // null will be translated to empty CellLocation object in client. + r.callback.onCellLocationChanged(mCellIdentity[phoneId]); } } catch (RemoteException ex) { remove(r.binder); @@ -1629,11 +1612,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyCellLocation(Bundle cellLocation) { - notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); + @Override + public void notifyCellLocation(CellIdentity cellLocation) { + notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); } - public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { + @Override + public void notifyCellLocationForSubscriber(int subId, CellIdentity cellLocation) { log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); if (!checkNotifyPermission("notifyCellLocation()")) { @@ -1646,7 +1631,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { - mCellLocation[phoneId] = cellLocation; + mCellIdentity[phoneId] = cellLocation; for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && idMatch(r.subId, subId, phoneId) && @@ -1656,7 +1641,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyCellLocation: cellLocation=" + cellLocation + " r=" + r); } - r.callback.onCellLocationChanged(new Bundle(cellLocation)); + r.callback.onCellLocationChanged(cellLocation); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -2093,7 +2078,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mCallForwarding=" + mCallForwarding[i]); pw.println("mDataActivity=" + mDataActivity[i]); pw.println("mDataConnectionState=" + mDataConnectionState[i]); - pw.println("mCellLocation=" + mCellLocation[i]); + pw.println("mCellIdentity=" + mCellIdentity[i]); pw.println("mCellInfo=" + mCellInfo.get(i)); pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i)); pw.println("mSrvccState=" + mSrvccState[i]); @@ -2576,10 +2561,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { - if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " - + mCellLocation[phoneId]); + if (DBG_LOC) { + log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = " + + mCellIdentity[phoneId]); + } if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); + // null will be translated to empty CellLocation object in client. + r.callback.onCellLocationChanged(mCellIdentity[phoneId]); } } catch (RemoteException ex) { mRemoveList.add(r.binder); diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 9bae902eb7b1..af8a3666e9b7 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -39,11 +39,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.net.ISocketKeepaliveCallback; +import android.net.InvalidPacketException; import android.net.KeepalivePacketData; import android.net.NattKeepalivePacketData; import android.net.NetworkAgent; import android.net.NetworkUtils; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; import android.net.util.IpUtils; @@ -657,7 +657,10 @@ public class KeepaliveTracker { final TcpKeepalivePacketData packet; try { packet = TcpKeepaliveController.getTcpKeepalivePacket(fd); - } catch (InvalidPacketException | InvalidSocketException e) { + } catch (InvalidSocketException e) { + notifyErrorCallback(cb, e.error); + return; + } catch (InvalidPacketException e) { notifyErrorCallback(cb, e.error); return; } diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index e570ef1e9bf2..1129899ee3ff 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -30,8 +30,8 @@ import static android.system.OsConstants.IP_TTL; import static android.system.OsConstants.TIOCOUTQ; import android.annotation.NonNull; +import android.net.InvalidPacketException; import android.net.NetworkUtils; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; import android.net.TcpKeepalivePacketDataParcelable; diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 09790c46972e..a46ada873408 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -54,10 +54,10 @@ import android.net.LocalSocketAddress; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.RouteInfo; import android.net.UidRange; import android.net.VpnService; @@ -958,7 +958,7 @@ public class Vpn { mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE /* logtag */, mNetworkInfo, mNetworkCapabilities, lp, ConnectivityConstants.VPN_DEFAULT_SCORE, networkMisc, - NetworkFactory.SerialNumber.VPN) { + NetworkProvider.ID_VPN) { @Override public void unwanted() { // We are user controlled, not driven by NetworkRequest. diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 877c40f94696..18c6e3a5d4b7 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -222,13 +222,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.RoSystemProperties; -import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; -import com.android.internal.util.Preconditions; import com.android.internal.util.StatLogger; import com.android.server.EventLogTags; import com.android.server.LocalServices; @@ -389,6 +387,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_SUBSCRIPTION_OVERRIDE = 16; private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17; private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18; + private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19; private static final int UID_MSG_STATE_CHANGED = 100; private static final int UID_MSG_GONE = 101; @@ -3039,12 +3038,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // Verify they're not lying about package name mAppOps.checkPackage(callingUid, callingPackage); + final SubscriptionManager sm; final SubscriptionInfo si; final PersistableBundle config; final long token = Binder.clearCallingIdentity(); try { - si = mContext.getSystemService(SubscriptionManager.class) - .getActiveSubscriptionInfo(subId); + sm = mContext.getSystemService(SubscriptionManager.class); + si = sm.getActiveSubscriptionInfo(subId); config = mCarrierConfigManager.getConfigForSubId(subId); } finally { Binder.restoreCallingIdentity(token); @@ -3052,7 +3052,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // First check: is caller the CarrierService? if (si != null) { - if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) { + if (si.isEmbedded() && sm.canManageSubscription(si, callingPackage)) { return; } } @@ -3092,6 +3092,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG); } + private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { + // nothing to check if no plans + if (plans.length == 0) { + return; + } + + long applicableNetworkTypes = 0; + boolean allNetworks = false; + for (SubscriptionPlan plan : plans) { + if (plan.getNetworkTypes() == null) { + allNetworks = true; + } else { + if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) { + throw new IllegalArgumentException( + "Multiple subscription plans defined for a single network type."); + } else { + applicableNetworkTypes |= plan.getNetworkTypesBitMask(); + } + } + } + + // ensure at least one plan applies for every network type + if (!allNetworks) { + throw new IllegalArgumentException( + "No generic subscription plan that applies to all network types."); + } + } + @Override public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); @@ -3256,6 +3284,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); + enforceSubscriptionPlanValidity(plans); for (SubscriptionPlan plan : plans) { Objects.requireNonNull(plan); @@ -3284,6 +3313,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans)); } finally { Binder.restoreCallingIdentity(token); } @@ -3310,7 +3341,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, - long networkTypeMask, long timeoutMillis, String callingPackage) { + long timeoutMillis, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); // We can only override when carrier told us about plans @@ -3328,16 +3359,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(), NETPOLICY_OVERRIDE_ENABLED, 1) != 0; if (overrideEnabled || overrideValue == 0) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = subId; - args.arg2 = overrideMask; - args.arg3 = overrideValue; - args.arg4 = networkTypeMask; - mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args)); + mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, + overrideMask, overrideValue, subId)); if (timeoutMillis > 0) { - args.arg3 = 0; - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args), - timeoutMillis); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, + overrideMask, 0, subId), timeoutMillis); } } } @@ -4473,11 +4499,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId, - int overrideMask, int overrideValue, long networkTypeMask) { + int overrideMask, int overrideValue) { if (listener != null) { try { - listener.onSubscriptionOverride(subId, overrideMask, overrideValue, - networkTypeMask); + listener.onSubscriptionOverride(subId, overrideMask, overrideValue); + } catch (RemoteException ignored) { + } + } + } + + private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId, + SubscriptionPlan[] plans) { + if (listener != null) { + try { + listener.onSubscriptionPlansChanged(subId, plans); } catch (RemoteException ignored) { } } @@ -4578,16 +4613,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return true; } case MSG_SUBSCRIPTION_OVERRIDE: { - final SomeArgs args = (SomeArgs) msg.obj; - final int subId = (int) args.arg1; - final int overrideMask = (int) args.arg2; - final int overrideValue = (int) args.arg3; - final long networkTypeMask = (long) args.arg4; + final int overrideMask = msg.arg1; + final int overrideValue = msg.arg2; + final int subId = (int) msg.obj; final int length = mListeners.beginBroadcast(); for (int i = 0; i < length; i++) { final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); - dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue, - networkTypeMask); + dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue); } mListeners.finishBroadcast(); return true; @@ -4604,6 +4636,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { setNetworkTemplateEnabledInner(template, enabled); return true; } + case MSG_SUBSCRIPTION_PLANS_CHANGED: { + final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; + final int subId = msg.arg1; + final int length = mListeners.beginBroadcast(); + for (int i = 0; i < length; i++) { + final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); + dispatchSubscriptionPlansChanged(listener, subId, plans); + } + mListeners.finishBroadcast(); + return true; + } default: { return false; } diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java index b4f4eca5f188..f661b5e0d8a8 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java @@ -22,7 +22,7 @@ import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Intent; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.io.PrintWriter; diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index 02656eaf5c6c..da848d87ba71 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -24,10 +24,10 @@ import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Intent; +import android.os.TimestampedValue; import android.telephony.TelephonyManager; import android.util.LocalLog; import android.util.Slog; -import android.util.TimestampedValue; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java index 7f2f499ab21f..aad75ae16aa9 100644 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ b/services/net/java/android/net/TcpKeepalivePacketData.java @@ -19,7 +19,6 @@ import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java index 61cd88aac921..c93e5c5e4759 100644 --- a/services/net/java/android/net/ip/IpClientCallbacks.java +++ b/services/net/java/android/net/ip/IpClientCallbacks.java @@ -17,6 +17,7 @@ package android.net.ip; import android.net.DhcpResults; +import android.net.DhcpResultsParcelable; import android.net.Layer2PacketParcelable; import android.net.LinkProperties; @@ -69,6 +70,18 @@ public class IpClientCallbacks { public void onNewDhcpResults(DhcpResults dhcpResults) {} /** + * Callback called when new DHCP results are available. + * + * <p>This is purely advisory and not an indication of provisioning success or failure. This is + * only here for callers that want to expose DHCPv4 results to other APIs + * (e.g., WifiInfo#setInetAddress). + * + * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not + * the passed-in DhcpResults object is null. + */ + public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {} + + /** * Indicates that provisioning was successful. */ public void onProvisioningSuccess(LinkProperties newLp) {} diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index 4d60e6239376..7f723b1c232b 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -119,6 +119,7 @@ public class IpClientUtil { @Override public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) { mCb.onNewDhcpResults(fromStableParcelable(dhcpResults)); + mCb.onNewDhcpResults(dhcpResults); } @Override diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index 8fd8d0461e75..07b17ebdeb63 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -29,6 +29,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; @@ -57,7 +58,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; -import android.net.wifi.WifiSsid; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; @@ -180,8 +180,8 @@ public class NetworkScoreServiceTest { } private ScanResult createScanResult(String ssid, String bssid) { - ScanResult result = new ScanResult(); - result.wifiSsid = WifiSsid.createFromAsciiEncoded(ssid); + ScanResult result = mock(ScanResult.class); + result.SSID = ssid; result.BSSID = bssid; return result; } @@ -792,7 +792,7 @@ public class NetworkScoreServiceTest { @Test public void testScanResultsScoreCacheFilter_invalidScanResults() throws Exception { List<ScanResult> invalidScanResults = Lists.newArrayList( - new ScanResult(), + mock(ScanResult.class), createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid), createScanResult(WifiManager.UNKNOWN_SSID, SCORED_NETWORK.networkKey.wifiKey.bssid), createScanResult(SSID, null), diff --git a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java index bd3d9ab2220d..3852b9fec001 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java @@ -17,6 +17,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.ModuleInfo; +import android.content.pm.PackageManager; import android.test.InstrumentationTestCase; import com.android.frameworks.servicestests.R; @@ -28,7 +29,7 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testSuccessfulParse() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List<ModuleInfo> mi = provider.getInstalledModules(0); + List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); Collections.sort(mi, (ModuleInfo m1, ModuleInfo m2) -> @@ -49,18 +50,18 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testParseFailure_incorrectTopLevelElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata1); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParseFailure_incorrectModuleElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata2); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParse_unknownAttributesIgnored() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List<ModuleInfo> mi = provider.getInstalledModules(0); + List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); ModuleInfo mi1 = provider.getModuleInfo("com.android.module1", 0); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index 71b568cc06c5..ae5369204428 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -37,7 +37,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index ca6fd08092df..aaf9799de777 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -30,7 +30,7 @@ import android.content.Intent; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java index 239d413c12d2..f1e9191ddb4f 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java @@ -18,7 +18,7 @@ package com.android.server.timedetector; import static org.junit.Assert.assertEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 7482ecc85324..9e6dfef0608b 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -596,4 +596,17 @@ public class Annotation { @Retention(RetentionPolicy.SOURCE) public @interface ImsAudioCodec { } + + /** + * UICC SIM Application Types + */ + @IntDef(prefix = { "APPTYPE_" }, value = { + TelephonyManager.APPTYPE_SIM, + TelephonyManager.APPTYPE_USIM, + TelephonyManager.APPTYPE_RUIM, + TelephonyManager.APPTYPE_CSIM, + TelephonyManager.APPTYPE_ISIM + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UiccAppType{} } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 2f37c2a3af5a..de99b0da77df 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3018,7 +3018,7 @@ public class CarrierConfigManager { "ping_test_before_data_switch_bool"; /** - * Controls time in milli seconds until DcTracker reevaluates 5G connection state. + * Controls time in milliseconds until DcTracker reevaluates 5G connection state. * @hide */ public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index b7dab161c331..e523fbab2bb0 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -19,6 +19,7 @@ package android.telephony; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -181,7 +182,8 @@ public abstract class CellIdentity implements Parcelable { * @return a CellLocation object for this CellIdentity * @hide */ - public abstract CellLocation asCellLocation(); + @SystemApi + public abstract @NonNull CellLocation asCellLocation(); @Override public boolean equals(Object other) { diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index 880d3db681b5..54236b426d98 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -16,6 +16,7 @@ package android.telephony; +import android.annotation.NonNull; import android.os.Parcel; import android.telephony.cdma.CdmaCellLocation; @@ -198,6 +199,7 @@ public final class CellIdentityCdma extends CellIdentity { } /** @hide */ + @NonNull @Override public CdmaCellLocation asCellLocation() { CdmaCellLocation cl = new CdmaCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 25c6577bdcf5..4e4454d6a1c2 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -16,6 +16,7 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -200,6 +201,7 @@ public final class CellIdentityGsm extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index 997b19f3d4eb..c3fc73b775d7 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -16,6 +16,7 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Build; @@ -232,6 +233,7 @@ public final class CellIdentityLte extends CellIdentity { * * @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index edc838c163db..e3fec7b7f820 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.IntRange; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; @@ -77,6 +78,7 @@ public final class CellIdentityNr extends CellIdentity { * @return a CellLocation object for this CellIdentity. * @hide */ + @NonNull @Override public CellLocation asCellLocation() { return new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 558e346284ea..8f812b6b892e 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -171,6 +171,7 @@ public final class CellIdentityTdscdma extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 031fed13d9f1..556bc32e7c36 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -16,6 +16,7 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -196,6 +197,7 @@ public final class CellIdentityWcdma extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index f31fafe36508..d28d750c6011 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -155,7 +155,17 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa * @param ss signal strength from modem. */ public CellSignalStrengthNr(android.hardware.radio.V1_4.NrSignalStrength ss) { - this(ss.csiRsrp, ss.csiRsrq, ss.csiSinr, ss.ssRsrp, ss.ssRsrq, ss.ssSinr); + this(flip(ss.csiRsrp), flip(ss.csiRsrq), ss.csiSinr, flip(ss.ssRsrp), flip(ss.ssRsrq), + ss.ssSinr); + } + + /** + * Flip sign cell strength value when taking in the value from hal + * @param val cell strength value + * @return flipped value + */ + private static int flip(int val) { + return val != CellInfo.UNAVAILABLE ? -val : val; } /** diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 71ea3a3e7198..4de9e1e4c1c7 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -54,7 +54,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Telephony.SimInfo; -import android.telephony.Annotation.NetworkType; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; @@ -2503,6 +2502,8 @@ public class SubscriptionManager { * may not be displayed or used by decision making logic. * @throws SecurityException if the caller doesn't meet the requirements * outlined above. + * @throws IllegalArgumentException if plans don't meet the requirements + * defined in {@link SubscriptionPlan}. */ public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { try { @@ -2547,51 +2548,10 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long timeoutMillis) { - setSubscriptionOverrideUnmetered(subId, null, overrideUnmetered, timeoutMillis); - } - - /** - * Temporarily override the billing relationship between a carrier and - * a specific subscriber to be considered unmetered for the given network - * types. This will be reflected to apps via - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. - * This method is only accessible to the following narrow set of apps: - * <ul> - * <li>The carrier app for this subscriberId, as determined by - * {@link TelephonyManager#hasCarrierPrivileges()}. - * <li>The carrier app explicitly delegated access through - * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. - * </ul> - * - * @param subId the subscriber this override applies to. - * @param networkTypes all network types to set an override for. A null - * network type means to apply the override to all network types. - * Any unspecified network types will default to metered. - * @param overrideUnmetered set if the billing relationship should be - * considered unmetered. - * @param timeoutMillis the timeout after which the requested override will - * be automatically cleared, or {@code 0} to leave in the - * requested state until explicitly cleared, or the next reboot, - * whichever happens first. - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. - * {@hide} - */ - public void setSubscriptionOverrideUnmetered(int subId, - @Nullable @NetworkType int[] networkTypes, boolean overrideUnmetered, - @DurationMillisLong long timeoutMillis) { try { - long networkTypeMask = 0; - if (networkTypes != null) { - for (int networkType : networkTypes) { - networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); - } - } else { - networkTypeMask = ~0; - } final int overrideValue = overrideUnmetered ? OVERRIDE_UNMETERED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_UNMETERED, overrideValue, - networkTypeMask, timeoutMillis, mContext.getOpPackageName()); + timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2623,52 +2583,10 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long timeoutMillis) { - setSubscriptionOverrideCongested(subId, null, overrideCongested, timeoutMillis); - } - - /** - * Temporarily override the billing relationship plan between a carrier and - * a specific subscriber to be considered congested. This will cause the - * device to delay certain network requests when possible, such as developer - * jobs that are willing to run in a flexible time window. - * <p> - * This method is only accessible to the following narrow set of apps: - * <ul> - * <li>The carrier app for this subscriberId, as determined by - * {@link TelephonyManager#hasCarrierPrivileges()}. - * <li>The carrier app explicitly delegated access through - * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. - * </ul> - * - * @param subId the subscriber this override applies to. - * @param networkTypes all network types to set an override for. A null - * network type means to apply the override to all network types. - * Any unspecified network types will default to not congested. - * @param overrideCongested set if the subscription should be considered - * congested. - * @param timeoutMillis the timeout after which the requested override will - * be automatically cleared, or {@code 0} to leave in the - * requested state until explicitly cleared, or the next reboot, - * whichever happens first. - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. - * @hide - */ - public void setSubscriptionOverrideCongested(int subId, - @Nullable @NetworkType int[] networkTypes, boolean overrideCongested, - @DurationMillisLong long timeoutMillis) { try { - long networkTypeMask = 0; - if (networkTypes != null) { - for (int networkType : networkTypes) { - networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); - } - } else { - networkTypeMask = ~0; - } final int overrideValue = overrideCongested ? OVERRIDE_CONGESTED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_CONGESTED, overrideValue, - networkTypeMask, timeoutMillis, mContext.getOpPackageName()); + timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index cfb8fb4dd4c4..05fa67f9dbc1 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -77,6 +77,7 @@ import android.telephony.Annotation.DataState; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.UiccAppType; import android.telephony.VisualVoicemailService.VisualVoicemailTask; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; @@ -106,6 +107,7 @@ import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SmsApplication; +import com.android.telephony.Rlog; import dalvik.system.VMRuntime; @@ -1866,13 +1868,9 @@ public class TelephonyManager { return null; } - Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName(), null); - if (bundle == null || bundle.isEmpty()) { - Rlog.d(TAG, "getCellLocation returning null because CellLocation is unavailable"); - return null; - } - - CellLocation cl = CellLocation.newFromBundle(bundle); + CellIdentity cellIdentity = telephony.getCellLocation(mContext.getOpPackageName(), + null); + CellLocation cl = cellIdentity.asCellLocation(); if (cl == null || cl.isEmpty()) { Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty or" + " phone type doesn't match CellLocation type"); @@ -5737,7 +5735,10 @@ public class TelephonyManager { * @param AID Application id. See ETSI 102.221 and 101.220. * @param p2 P2 parameter (described in ISO 7816-4). * @return an IccOpenLogicalChannelResponse object. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID, int p2) { return iccOpenLogicalChannel(getSubId(), AID, p2); } @@ -5768,7 +5769,10 @@ public class TelephonyManager { * @param p2 P2 parameter (described in ISO 7816-4). * @return an IccOpenLogicalChannelResponse object. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2) { try { ITelephony telephony = getITelephony(); @@ -5796,7 +5800,10 @@ public class TelephonyManager { * iccOpenLogicalChannel. * @return true if the channel was closed successfully. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) { @@ -5823,7 +5830,10 @@ public class TelephonyManager { * @param channel is the channel id to be closed as returned by a successful * iccOpenLogicalChannel. * @return true if the channel was closed successfully. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public boolean iccCloseLogicalChannel(int channel) { return iccCloseLogicalChannel(getSubId(), channel); } @@ -5842,7 +5852,10 @@ public class TelephonyManager { * iccOpenLogicalChannel. * @return true if the channel was closed successfully. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public boolean iccCloseLogicalChannel(int subId, int channel) { try { ITelephony telephony = getITelephony(); @@ -5878,7 +5891,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at the end, or null if * there is an issue connecting to the Telephony service. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @Nullable @@ -5916,7 +5932,10 @@ public class TelephonyManager { * @param data Data to be sent with the APDU. * @return The APDU response from the ICC card with the status appended at * the end. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2, int p3, String data) { return iccTransmitApduLogicalChannel(getSubId(), channel, cla, @@ -5945,7 +5964,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduLogicalChannel(int subId, int channel, int cla, int instruction, int p1, int p2, int p3, String data) { try { @@ -5981,7 +6003,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @NonNull @@ -6017,7 +6042,10 @@ public class TelephonyManager { * @param data Data to be sent with the APDU. * @return The APDU response from the ICC card with the status appended at * the end. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3, String data) { return iccTransmitApduBasicChannel(getSubId(), cla, @@ -6044,7 +6072,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduBasicChannel(int subId, int cla, int instruction, int p1, int p2, int p3, String data) { try { @@ -6072,7 +6103,10 @@ public class TelephonyManager { * @param p3 P3 value of the APDU command. * @param filePath * @return The APDU response. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String filePath) { return iccExchangeSimIO(getSubId(), fileID, command, p1, p2, p3, filePath); @@ -6094,7 +6128,10 @@ public class TelephonyManager { * @param filePath * @return The APDU response. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath) { try { @@ -6120,7 +6157,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card in hexadecimal format * with the last 4 bytes being the status word. If the command fails, * returns an empty string. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String sendEnvelopeWithStatus(String content) { return sendEnvelopeWithStatus(getSubId(), content); } @@ -6140,7 +6180,10 @@ public class TelephonyManager { * with the last 4 bytes being the status word. If the command fails, * returns an empty string. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String sendEnvelopeWithStatus(int subId, String content) { try { ITelephony telephony = getITelephony(); @@ -6673,19 +6716,6 @@ public class TelephonyManager { } } - /** - * UICC SIM Application Types - * @hide - */ - @IntDef(prefix = { "APPTYPE_" }, value = { - APPTYPE_SIM, - APPTYPE_USIM, - APPTYPE_RUIM, - APPTYPE_CSIM, - APPTYPE_ISIM - }) - @Retention(RetentionPolicy.SOURCE) - public @interface UiccAppType{} /** UICC application type is SIM */ public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; /** UICC application type is USIM */ @@ -8105,9 +8135,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPin(pin); + return telephony.supplyPinForSubscriber(getSubId(), pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPin", e); + Log.e(TAG, "Error calling ITelephony#supplyPinForSubscriber", e); } return false; } @@ -8119,9 +8149,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPuk(puk, pin); + return telephony.supplyPukForSubscriber(getSubId(), puk, pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPuk", e); + Log.e(TAG, "Error calling ITelephony#supplyPukForSubscriber", e); } return false; } @@ -8133,9 +8163,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPinReportResult(pin); + return telephony.supplyPinReportResultForSubscriber(getSubId(), pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e); + Log.e(TAG, "Error calling ITelephony#supplyPinReportResultForSubscriber", e); } return new int[0]; } @@ -8147,7 +8177,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPukReportResult(puk, pin); + return telephony.supplyPukReportResultForSubscriber(getSubId(), puk, pin); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#]", e); } diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index 0c8dba664b0a..a01687c75e96 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -35,6 +35,8 @@ import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; +import com.android.internal.telephony.IIntegerConsumer; + import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -154,9 +156,20 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Register registration callback: IImsRcsController is null"); + throw new ImsException("Cannot find remote IMS service", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + c.setExecutor(executor); - throw new UnsupportedOperationException("registerImsRegistrationCallback is not" - + "supported."); + try { + imsRcsController.registerImsRegistrationCallback(mSubId, c.getBinder()); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } } /**{@inheritDoc}*/ @@ -167,8 +180,18 @@ public class ImsRcsManager implements RegistrationManager { if (c == null) { throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); } - throw new UnsupportedOperationException("unregisterImsRegistrationCallback is not" - + "supported."); + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Unregister registration callback: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.unregisterImsRegistrationCallback(mSubId, c.getBinder()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } } /**{@inheritDoc}*/ @@ -182,8 +205,23 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } - throw new UnsupportedOperationException("getRegistrationState is not" - + "supported."); + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Get registration state error: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.getImsRcsRegistrationState(mSubId, new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> stateCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } } /**{@inheritDoc}*/ @@ -198,10 +236,25 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } - throw new UnsupportedOperationException("getRegistrationTransportType is not" - + "supported."); - } + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Get registration transport type error: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.getImsRcsRegistrationTransportType(mSubId, + new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> transportTypeCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } /** * Registers an {@link AvailabilityCallback} with the system, which will provide RCS diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index e81bac0f6764..6f6aa44371fa 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -19,6 +19,9 @@ package android.telephony.ims.aidl; import android.net.Uri; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IRcsUceControllerCallback; +import android.telephony.ims.aidl.IImsRegistrationCallback; + +import com.android.internal.telephony.IIntegerConsumer; /** * Interface used to interact with the Telephony IMS. @@ -26,6 +29,13 @@ import android.telephony.ims.aidl.IRcsUceControllerCallback; * {@hide} */ interface IImsRcsController { + // IMS RCS registration commands + void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c); + void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c); + void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer); + void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer); + + // IMS RCS capability commands void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback c); void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback c); boolean isCapable(int subId, int capability, int radioTech); diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 668a6af08145..9e786ce32792 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -111,7 +111,7 @@ public class DctConstants { public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49; public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50; public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51; - public static final int EVENT_5G_NETWORK_CHANGED = BASE + 52; + public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52; public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53; public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54; diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 97b24aef4af5..c0d6369686c4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -30,6 +30,7 @@ import android.service.carrier.CarrierIdentifier; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.CarrierRestrictionRules; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.ClientRequestStats; import android.telephony.IccOpenLogicalChannelResponse; @@ -116,13 +117,6 @@ interface ITelephony { */ boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId); - /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. - * @param pin The pin to check. - * @return whether the operation was a success. - */ - @UnsupportedAppUsage - boolean supplyPin(String pin); /** * Supply a pin to unlock the SIM for particular subId. @@ -138,15 +132,6 @@ interface ITelephony { * Blocks until a result is determined. * @param puk The puk to check. * pin The new pin to be set in SIM - * @return whether the operation was a success. - */ - boolean supplyPuk(String puk, String pin); - - /** - * Supply puk to unlock the SIM and set SIM pin to new pin. - * Blocks until a result is determined. - * @param puk The puk to check. - * pin The new pin to be set in SIM * @param subId user preferred subId. * @return whether the operation was a success. */ @@ -159,15 +144,6 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPinReportResult(String pin); - - /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. - * Returns a specific success/error code. - * @param pin The pin to check. - * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code - * retValue[1] = number of attempts remaining if known otherwise -1 - */ int[] supplyPinReportResultForSubscriber(int subId, String pin); /** @@ -179,17 +155,6 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPukReportResult(String puk, String pin); - - /** - * Supply puk to unlock the SIM and set SIM pin to new pin. - * Blocks until a result is determined. - * Returns a specific success/error code - * @param puk The puk to check - * pin The pin to check. - * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code - * retValue[1] = number of attempts remaining if known otherwise -1 - */ int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin); /** @@ -305,7 +270,8 @@ interface ITelephony { */ boolean isDataConnectivityPossible(int subId); - Bundle getCellLocation(String callingPkg, String callingFeatureId); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + CellIdentity getCellLocation(String callingPkg, String callingFeatureId); /** * Returns the ISO country code equivalent of the current registered diff --git a/telephony/java/com/android/telephony/Rlog.java b/telephony/java/com/android/telephony/Rlog.java new file mode 100644 index 000000000000..9d6c930de8f5 --- /dev/null +++ b/telephony/java/com/android/telephony/Rlog.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.telephony; + +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import com.android.internal.telephony.util.TelephonyUtils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * A copy of {@link android.telephony.Rlog} to be used within the telephony mainline module. + * + * @hide + */ +public final class Rlog { + + private static final boolean USER_BUILD = TelephonyUtils.IS_USER; + + private Rlog() { + } + + private static int log(int priority, String tag, String msg) { + return Log.logToRadioBuffer(priority, tag, msg); + } + + public static int v(String tag, String msg) { + return log(Log.VERBOSE, tag, msg); + } + + public static int v(String tag, String msg, Throwable tr) { + return log(Log.VERBOSE, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int d(String tag, String msg) { + return log(Log.DEBUG, tag, msg); + } + + public static int d(String tag, String msg, Throwable tr) { + return log(Log.DEBUG, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int i(String tag, String msg) { + return log(Log.INFO, tag, msg); + } + + public static int i(String tag, String msg, Throwable tr) { + return log(Log.INFO, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int w(String tag, String msg) { + return log(Log.WARN, tag, msg); + } + + public static int w(String tag, String msg, Throwable tr) { + return log(Log.WARN, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int w(String tag, Throwable tr) { + return log(Log.WARN, tag, Log.getStackTraceString(tr)); + } + + public static int e(String tag, String msg) { + return log(Log.ERROR, tag, msg); + } + + public static int e(String tag, String msg, Throwable tr) { + return log(Log.ERROR, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int println(int priority, String tag, String msg) { + return log(priority, tag, msg); + } + + public static boolean isLoggable(String tag, int level) { + return Log.isLoggable(tag, level); + } + + /** + * Redact personally identifiable information for production users. + * @param tag used to identify the source of a log message + * @param pii the personally identifiable information we want to apply secure hash on. + * @return If tag is loggable in verbose mode or pii is null, return the original input. + * otherwise return a secure Hash of input pii + */ + public static String pii(String tag, Object pii) { + String val = String.valueOf(pii); + if (pii == null || TextUtils.isEmpty(val) || isLoggable(tag, Log.VERBOSE)) { + return val; + } + return "[" + secureHash(val.getBytes()) + "]"; + } + + /** + * Redact personally identifiable information for production users. + * @param enablePiiLogging set when caller explicitly want to enable sensitive logging. + * @param pii the personally identifiable information we want to apply secure hash on. + * @return If enablePiiLogging is set to true or pii is null, return the original input. + * otherwise return a secure Hash of input pii + */ + public static String pii(boolean enablePiiLogging, Object pii) { + String val = String.valueOf(pii); + if (pii == null || TextUtils.isEmpty(val) || enablePiiLogging) { + return val; + } + return "[" + secureHash(val.getBytes()) + "]"; + } + + /** + * Returns a secure hash (using the SHA1 algorithm) of the provided input. + * + * @return "****" if the build type is user, otherwise the hash + * @param input the bytes for which the secure hash should be computed. + */ + private static String secureHash(byte[] input) { + // Refrain from logging user personal information in user build. + if (USER_BUILD) { + return "****"; + } + + MessageDigest messageDigest; + + try { + messageDigest = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return "####"; + } + + byte[] result = messageDigest.digest(input); + return Base64.encodeToString( + result, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP); + } +} diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index 1e8d83c3c6cd..18474a83b368 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -36,9 +36,9 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.NetworkSpecifier; import android.net.SocketKeepalive; import android.net.UidRange; @@ -114,7 +114,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp) { super(wrapper.mHandlerThread.getLooper(), wrapper.mContext, wrapper.mLogTag, wrapper.mNetworkInfo, wrapper.mNetworkCapabilities, lp, wrapper.mScore, - new NetworkMisc(), NetworkFactory.SerialNumber.NONE); + new NetworkMisc(), NetworkProvider.ID_NONE); mWrapper = wrapper; } diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java index 5cb0d7e7a1a9..e632aafde70e 100644 --- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java +++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java @@ -22,8 +22,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import android.net.SocketKeepalive.InvalidPacketException; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 535298f9b09a..82cb1932d2c1 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -36,9 +36,9 @@ import android.net.IDnsResolver; import android.net.INetd; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.NetworkScore; import android.os.INetworkManagementService; import android.text.format.DateUtils; @@ -359,7 +359,7 @@ public class LingerMonitorTest { ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50); NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null, caps, ns, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS, - NetworkFactory.SerialNumber.NONE); + NetworkProvider.ID_NONE); nai.everValidated = true; return nai; } diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 46105f4d66b0..0b2077d9bba0 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -149,7 +149,12 @@ def extract_package(signature): The package name of the class containing the field/method. """ full_class_name = signature.split(";->")[0] - package_name = full_class_name[1:full_class_name.rindex("/")] + # Example: Landroid/hardware/radio/V1_2/IRadio$Proxy + if (full_class_name[0] != "L"): + raise ValueError("Expected to start with 'L': %s" % full_class_name) + full_class_name = full_class_name[1:] + # If full_class_name doesn't contain '/', then package_name will be ''. + package_name = full_class_name.rpartition("/")[0] return package_name.replace('/', '.') class FlagsDict: diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp index 79dce4a8ce09..7b2ca9a65242 100644 --- a/tools/lock_agent/Android.bp +++ b/tools/lock_agent/Android.bp @@ -25,6 +25,7 @@ cc_binary_host { srcs: ["agent.cpp"], static_libs: [ "libbase", + "liblog", "libz", "slicer", ], diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index c08f9b04f0df..d3958a65c704 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -21,9 +21,16 @@ cc_binary_host { name: "stats-log-api-gen", srcs: [ "Collation.cpp", + "atoms_info_writer.cpp", + "java_writer.cpp", + "java_writer_q.cpp", "main.cpp", + "native_writer.cpp", + "native_writer_q.cpp", + "utils.cpp", ], cflags: [ + "-DSTATS_SCHEMA_LEGACY", "-Wall", "-Werror", ], @@ -98,28 +105,23 @@ genrule { cc_library { name: "libstatslog", host_supported: true, - generated_sources: ["statslog.cpp"], - generated_headers: ["statslog.h"], + generated_sources: [ + "statslog.cpp", + ], + generated_headers: [ + "statslog.h" + ], cflags: [ "-Wall", "-Werror", ], - export_generated_headers: ["statslog.h"], + export_generated_headers: [ + "statslog.h" + ], shared_libs: [ "liblog", "libcutils", ], static_libs: ["libstatssocket"], - target: { - android: { - shared_libs: [ - "libutils", - ], - }, - host: { - static_libs: [ - "libutils", - ], - }, - }, } + diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index 373adca994a1..fa556010646c 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -379,6 +379,7 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { int errorCount = 0; const bool dbg = false; + int maxPushedAtomId = 2; for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor *atomField = descriptor->field(i); @@ -447,8 +448,14 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { } atoms->non_chained_decls.insert(nonChainedAtomDecl); } + + if (atomDecl.code < PULL_ATOM_START_ID && atomDecl.code > maxPushedAtomId) { + maxPushedAtomId = atomDecl.code; + } } + atoms->maxPushedAtomId = maxPushedAtomId; + if (dbg) { printf("signatures = [\n"); for (map<vector<java_type_t>, set<string>>::const_iterator it = diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 44746c96df1b..3efdd520d7f5 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -111,6 +111,7 @@ struct Atoms { set<AtomDecl> decls; set<AtomDecl> non_chained_decls; map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules; + int maxPushedAtomId; }; /** @@ -123,4 +124,4 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, vector<java_type_t> } // namespace android -#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
\ No newline at end of file +#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp new file mode 100644 index 000000000000..54a9982bb5c2 --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "atoms_info_writer.h" +#include "utils.h" + +#include <map> +#include <set> +#include <vector> + +namespace android { +namespace stats_log_api_gen { + +static void write_atoms_info_header_body(FILE* out, const Atoms& atoms) { + fprintf(out, "struct StateAtomFieldOptions {\n"); + fprintf(out, " std::vector<int> primaryFields;\n"); + fprintf(out, " int exclusiveField;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "struct AtomsInfo {\n"); + fprintf(out, + " const static std::set<int> " + "kTruncatingTimestampAtomBlackList;\n"); + fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); + fprintf(out, + " const static std::set<int> kAtomsWithAttributionChain;\n"); + fprintf(out, + " const static std::map<int, StateAtomFieldOptions> " + "kStateAtomsFieldOptions;\n"); + fprintf(out, + " const static std::map<int, std::vector<int>> " + "kBytesFieldAtoms;\n"); + fprintf(out, + " const static std::set<int> kWhitelistedAtoms;\n"); + fprintf(out, "};\n"); + fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", atoms.maxPushedAtomId); + +} + +static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { + std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", + "audio_state_changed", + "call_state_changed", + "phone_signal_strength_changed", + "mobile_bytes_transfer_by_fg_bg", + "mobile_bytes_transfer"}; + fprintf(out, + "const std::set<int> " + "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); + for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); + blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { + fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); + } + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + break; + } + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->whitelisted) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "static std::map<int, int> getAtomUidField() {\n"); + fprintf(out, " std::map<int, int> uidField;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->uidField == 0) { + continue; + } + fprintf(out, + "\n // Adding uid field for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " uidField[static_cast<int>(%s)] = %d;\n", + make_constant_name(atom->name).c_str(), atom->uidField); + } + + fprintf(out, " return uidField;\n"); + fprintf(out, "};\n"); + + fprintf(out, + "const std::map<int, int> AtomsInfo::kAtomsWithUidField = " + "getAtomUidField();\n"); + + fprintf(out, + "static std::map<int, StateAtomFieldOptions> " + "getStateAtomFieldOptions() {\n"); + fprintf(out, " std::map<int, StateAtomFieldOptions> options;\n"); + fprintf(out, " StateAtomFieldOptions opt;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { + continue; + } + fprintf(out, + "\n // Adding primary and exclusive fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " opt.primaryFields.clear();\n"); + for (const auto& field : atom->primaryFields) { + fprintf(out, " opt.primaryFields.push_back(%d);\n", field); + } + + fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); + fprintf(out, " options[static_cast<int>(%s)] = opt;\n", + make_constant_name(atom->name).c_str()); + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map<int, StateAtomFieldOptions> " + "AtomsInfo::kStateAtomsFieldOptions = " + "getStateAtomFieldOptions();\n"); + + fprintf(out, + "static std::map<int, std::vector<int>> " + "getBinaryFieldAtoms() {\n"); + fprintf(out, " std::map<int, std::vector<int>> options;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->binaryFields.size() == 0) { + continue; + } + fprintf(out, + "\n // Adding binary fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + + for (const auto& field : atom->binaryFields) { + fprintf(out, " options[static_cast<int>(%s)].push_back(%d);\n", + make_constant_name(atom->name).c_str(), field); + } + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map<int, std::vector<int>> " + "AtomsInfo::kBytesFieldAtoms = " + "getBinaryFieldAtoms();\n"); + +} + +int write_atoms_info_header(FILE* out, const Atoms &atoms, const string& namespaceStr) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#pragma once\n"); + fprintf(out, "\n"); + fprintf(out, "#include <vector>\n"); + fprintf(out, "#include <map>\n"); + fprintf(out, "#include <set>\n"); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_header_body(out, atoms); + + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +int write_atoms_info_cpp(FILE *out, const Atoms &atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#include <%s>\n", importHeader.c_str()); + fprintf(out, "#include <%s>\n", statslogHeader.c_str()); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_cpp_body(out, atoms); + + // Print footer + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/atoms_info_writer.h b/tools/stats_log_api_gen/atoms_info_writer.h new file mode 100644 index 000000000000..12ac862871ef --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader); + +int write_atoms_info_header(FILE* out, const Atoms& atoms, const string& namespaceStr); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp new file mode 100644 index 000000000000..fef490c7e5f9 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "java_writer.h" +#include "java_writer_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +static int write_java_q_logger_class( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName + ) { + fprintf(out, "\n"); + fprintf(out, " // Write logging helper methods for statsd in Q and earlier.\n"); + fprintf(out, " private static class QLogger {\n"); + + write_java_q_logging_constants(out, " "); + + // Print Q write methods. + fprintf(out, "\n"); + fprintf(out, " // Write methods.\n"); + write_java_methods_q_schema( + out, signatures_to_modules, attributionDecl, moduleName, " "); + + fprintf(out, " }\n"); + return 0; +} + + +static int write_java_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const bool supportQ + ) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static void write(int code"); + vector<java_type_t> signature = signature_to_modules_it->first; + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + fprintf(out, ", %s[] %s", + java_type_name(chainField.javaType), chainField.name.c_str()); + } + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", SparseArray<Object> valueMap"); + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ") {\n"); + + // Print method body. + string indent(""); + if (supportQ) { + // TODO(b/146235828): Use just SDK_INT check once it is incremented from Q. + fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q ||\n"); + fprintf(out, " Build.VERSION.CODENAME.equals(\"R\")) {\n"); + indent = " "; + } + + // Start StatsEvent.Builder. + fprintf(out, "%s final StatsEvent.Builder builder = StatsEvent.newBuilder();\n", + indent.c_str()); + + // Write atom code. + fprintf(out, "%s builder.setAtomId(code);\n", indent.c_str()); + + // Write the args. + argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_BOOLEAN: + fprintf(out, "%s builder.writeBoolean(arg%d);\n", indent.c_str(), argIndex); + break; + case JAVA_TYPE_INT: + case JAVA_TYPE_ENUM: + fprintf(out, "%s builder.writeInt(arg%d);\n", indent.c_str(), argIndex); + break; + case JAVA_TYPE_FLOAT: + fprintf(out, "%s builder.writeFloat(arg%d);\n", indent.c_str(), argIndex); + break; + case JAVA_TYPE_LONG: + fprintf(out, "%s builder.writeLong(arg%d);\n", indent.c_str(), argIndex); + break; + case JAVA_TYPE_STRING: + fprintf(out, "%s builder.writeString(arg%d);\n", indent.c_str(), argIndex); + break; + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, "%s builder.writeByteArray(null == arg%d ? new byte[0] : arg%d);\n", + indent.c_str(), argIndex, argIndex); + break; + case JAVA_TYPE_ATTRIBUTION_CHAIN: + { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + + fprintf(out, "%s builder.writeAttributionChain(\n", indent.c_str()); + fprintf(out, "%s null == %s ? new int[0] : %s,\n", + indent.c_str(), uidName, uidName); + fprintf(out, "%s null == %s ? new String[0] : %s);\n", + indent.c_str(), tagName, tagName); + break; + } + case JAVA_TYPE_KEY_VALUE_PAIR: + fprintf(out, "\n"); + fprintf(out, + "%s // Write KeyValuePairs.\n", indent.c_str()); + fprintf(out, + "%s final int count = valueMap.size();\n", indent.c_str()); + fprintf(out, + "%s final SparseIntArray intMap = new SparseIntArray();\n", + indent.c_str()); + fprintf(out, + "%s final SparseLongArray longMap = new SparseLongArray();\n", + indent.c_str()); + fprintf(out, + "%s final SparseArray<String> stringMap = new SparseArray<>();\n", + indent.c_str()); + fprintf(out, + "%s final SparseArray<Float> floatMap = new SparseArray<>();\n", + indent.c_str()); + fprintf(out, + "%s for (int i = 0; i < count; i++) {\n", indent.c_str()); + fprintf(out, + "%s final int key = valueMap.keyAt(i);\n", indent.c_str()); + fprintf(out, + "%s final Object value = valueMap.valueAt(i);\n", + indent.c_str()); + fprintf(out, + "%s if (value instanceof Integer) {\n", indent.c_str()); + fprintf(out, + "%s intMap.put(key, (Integer) value);\n", indent.c_str()); + fprintf(out, + "%s } else if (value instanceof Long) {\n", indent.c_str()); + fprintf(out, + "%s longMap.put(key, (Long) value);\n", indent.c_str()); + fprintf(out, + "%s } else if (value instanceof String) {\n", indent.c_str()); + fprintf(out, + "%s stringMap.put(key, (String) value);\n", indent.c_str()); + fprintf(out, + "%s } else if (value instanceof Float) {\n", indent.c_str()); + fprintf(out, + "%s floatMap.put(key, (Float) value);\n", indent.c_str()); + fprintf(out, + "%s }\n", indent.c_str()); + fprintf(out, + "%s }\n", indent.c_str()); + fprintf(out, + "%s builder.writeKeyValuePairs(" + "intMap, longMap, stringMap, floatMap);\n", indent.c_str()); + break; + default: + // Unsupported types: OBJECT, DOUBLE. + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + argIndex++; + } + + fprintf(out, "\n"); + fprintf(out, "%s builder.usePooledBuffer();\n", indent.c_str()); + fprintf(out, "%s StatsLog.write(builder.build());\n", indent.c_str()); + + // Add support for writing using Q schema if this is not the default module. + if (supportQ) { + fprintf(out, " } else {\n"); + fprintf(out, " QLogger.write(code"); + argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + fprintf(out, ", %s, %s", uidName, tagName); + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + // Module logging does not yet support key value pair. + fprintf(stderr, "Module logging does not yet support key value pair.\n"); + return 1; + } else { + fprintf(out, ", arg%d", argIndex); + } + argIndex++; + } + fprintf(out, ");\n"); + fprintf(out, " }\n"); // if + } + + fprintf(out, " }\n"); // method + fprintf(out, "\n"); + } + return 0; + +} + +int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& javaClass, + const string& javaPackage, const bool supportQ) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "package %s;\n", javaPackage.c_str()); + fprintf(out, "\n"); + fprintf(out, "\n"); + if (supportQ) { + fprintf(out, "import android.os.Build;\n"); + fprintf(out, "import android.os.SystemClock;\n"); + } + + if (DEFAULT_MODULE_NAME == moduleName) { + // Mainline modules don't use WorkSource logging. + fprintf(out, "import android.os.WorkSource;\n"); + + // SparseArray is used for writing KeyValuePairs; not supported for Mainline modules. + fprintf(out, "import android.util.SparseArray;\n"); + fprintf(out, "import android.util.SparseIntArray;\n"); + fprintf(out, "import android.util.SparseLongArray;\n"); + } + + fprintf(out, "import android.util.StatsEvent;\n"); + fprintf(out, "import android.util.StatsLog;\n"); + + if (DEFAULT_MODULE_NAME == moduleName) { + // List is used for WorkSource writing. Only needed for default module. + fprintf(out, "\n"); + fprintf(out, "import java.util.ArrayList;\n"); + } + + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "/**\n"); + fprintf(out, " * Utility class for logging statistics events.\n"); + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " * @hide\n"); + } + fprintf(out, " */\n"); + fprintf(out, "public class %s {\n", javaClass.c_str()); + + write_java_atom_codes(out, atoms, moduleName); + write_java_enum_values(out, atoms, moduleName); + + int errors = 0; + + // Print write methods. + fprintf(out, " // Write methods\n"); + errors += write_java_methods( + out, atoms.signatures_to_modules, attributionDecl, moduleName, supportQ); + errors += write_java_non_chained_methods( + out, atoms.non_chained_signatures_to_modules, moduleName); + if (DEFAULT_MODULE_NAME == moduleName) { + errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName); + } + + if (supportQ) { + errors += write_java_q_logger_class( + out, atoms.signatures_to_modules, attributionDecl, moduleName); + } + + fprintf(out, "}\n"); + + return errors; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h new file mode 100644 index 000000000000..9324b23e4025 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& javaClass, + const string& javaPackage, const bool supportQ); + +} // namespace stats_log_api_gen +} // namespace android + diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp new file mode 100644 index 000000000000..d6899f6131c6 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer_q.cpp @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "java_writer_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +void write_java_q_logging_constants(FILE* out, const string& indent) { + fprintf(out, "%s// Payload limits.\n", indent.c_str()); + fprintf(out, "%sprivate static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n", indent.c_str()); + fprintf(out, + "%sprivate static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n", + indent.c_str()); + + // Value types. Must match with EventLog.java and log.h. + fprintf(out, "\n"); + fprintf(out, "%s// Value types.\n", indent.c_str()); + fprintf(out, "%sprivate static final byte INT_TYPE = 0;\n", indent.c_str()); + fprintf(out, "%sprivate static final byte LONG_TYPE = 1;\n", indent.c_str()); + fprintf(out, "%sprivate static final byte STRING_TYPE = 2;\n", indent.c_str()); + fprintf(out, "%sprivate static final byte LIST_TYPE = 3;\n", indent.c_str()); + fprintf(out, "%sprivate static final byte FLOAT_TYPE = 4;\n", indent.c_str()); + + // Size of each value type. + // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value. + fprintf(out, "\n"); + fprintf(out, "%s// Size of each value type.\n", indent.c_str()); + fprintf(out, "%sprivate static final int INT_TYPE_SIZE = 5;\n", indent.c_str()); + fprintf(out, "%sprivate static final int FLOAT_TYPE_SIZE = 5;\n", indent.c_str()); + // Longs take 9 bytes, 1 for the type and 8 for the value. + fprintf(out, "%sprivate static final int LONG_TYPE_SIZE = 9;\n", indent.c_str()); + // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length. + fprintf(out, "%sprivate static final int STRING_TYPE_OVERHEAD = 5;\n", indent.c_str()); + fprintf(out, "%sprivate static final int LIST_TYPE_OVERHEAD = 2;\n", indent.c_str()); +} + +int write_java_methods_q_schema( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const string& indent) { + int requiredHelpers = 0; + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + vector<java_type_t> signature = signature_to_modules_it->first; + fprintf(out, "%spublic static void write(int code", indent.c_str()); + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + fprintf(out, ", %s[] %s", + java_type_name(chainField.javaType), chainField.name.c_str()); + } + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + // Module logging does not yet support key value pair. + fprintf(stderr, "Module logging does not yet support key value pair.\n"); + continue; + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ") {\n"); + + // Calculate the size of the buffer. + fprintf(out, "%s // Initial overhead of the list, timestamp, and atom tag.\n", + indent.c_str()); + fprintf(out, + "%s int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n", + indent.c_str()); + argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_BOOLEAN: + case JAVA_TYPE_INT: + case JAVA_TYPE_FLOAT: + case JAVA_TYPE_ENUM: + fprintf(out, "%s needed += INT_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_LONG: + // Longs take 9 bytes, 1 for the type and 8 for the value. + fprintf(out, "%s needed += LONG_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_STRING: + // Strings take 5 metadata bytes + length of byte encoded string. + fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex); + fprintf(out, "%s arg%d = \"\";\n", indent.c_str(), argIndex); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, + "%s byte[] arg%dBytes = " + "arg%d.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n", + indent.c_str(), argIndex, argIndex); + fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", + indent.c_str(), argIndex); + break; + case JAVA_TYPE_BYTE_ARRAY: + // Byte arrays take 5 metadata bytes + length of byte array. + fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex); + fprintf(out, "%s arg%d = new byte[0];\n", indent.c_str(), argIndex); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", + indent.c_str(), argIndex); + break; + case JAVA_TYPE_ATTRIBUTION_CHAIN: + { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + // Null checks on the params. + fprintf(out, "%s if (%s == null) {\n", indent.c_str(), uidName); + fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), uidName, + java_type_name(attributionDecl.fields.front().javaType)); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s if (%s == null) {\n", indent.c_str(), tagName); + fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), tagName, + java_type_name(attributionDecl.fields.back().javaType)); + fprintf(out, "%s }\n", indent.c_str()); + + // First check that the lengths of the uid and tag arrays are the same. + fprintf(out, "%s if (%s.length != %s.length) {\n", + indent.c_str(), uidName, tagName); + fprintf(out, "%s return;\n", indent.c_str()); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s int attrSize = LIST_TYPE_OVERHEAD;\n", indent.c_str()); + fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", + indent.c_str(), tagName); + fprintf(out, "%s String str%d = (%s[i] == null) ? \"\" : %s[i];\n", + indent.c_str(), argIndex, tagName, tagName); + fprintf(out, + "%s int str%dlen = " + "str%d.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;\n", + indent.c_str(), argIndex, argIndex); + fprintf(out, + "%s attrSize += " + "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n", + indent.c_str(), argIndex); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s needed += attrSize;\n", indent.c_str()); + break; + } + default: + // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. + fprintf(stderr, "Module logging does not yet support key value pair.\n"); + return 1; + } + argIndex++; + } + + // Now we have the size that is needed. Check for overflow and return if needed. + fprintf(out, "%s if (needed > MAX_EVENT_PAYLOAD) {\n", indent.c_str()); + fprintf(out, "%s return;\n", indent.c_str()); + fprintf(out, "%s }\n", indent.c_str()); + + // Create new buffer, and associated data types. + fprintf(out, "%s byte[] buff = new byte[needed];\n", indent.c_str()); + fprintf(out, "%s int pos = 0;\n", indent.c_str()); + + // Initialize the buffer with list data type. + fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); + fprintf(out, "%s buff[pos + 1] = %zu;\n", indent.c_str(), signature.size() + 2); + fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); + + // Write timestamp. + fprintf(out, "%s long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n", indent.c_str()); + fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyLong(buff, pos + 1, elapsedRealtime);\n", indent.c_str()); + fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str()); + + // Write atom code. + fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, code);\n", indent.c_str()); + fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); + + // Write the args. + argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_BOOLEAN: + fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, arg%d? 1 : 0);\n", + indent.c_str(), argIndex); + fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_INT: + case JAVA_TYPE_ENUM: + fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, arg%d);\n", indent.c_str(), argIndex); + fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_FLOAT: + requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT; + fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyFloat(buff, pos + 1, arg%d);\n", indent.c_str(), argIndex); + fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_LONG: + fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyLong(buff, pos + 1, arg%d);\n", indent.c_str(), argIndex); + fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str()); + break; + case JAVA_TYPE_STRING: + fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, arg%dBytes.length);\n", + indent.c_str(), argIndex); + fprintf(out, "%s System.arraycopy(" + "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n", + indent.c_str(), argIndex, argIndex); + fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", + indent.c_str(), argIndex); + break; + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, arg%d.length);\n", + indent.c_str(), argIndex); + fprintf(out, "%s System.arraycopy(" + "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n", + indent.c_str(), argIndex, argIndex); + fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", + indent.c_str(), argIndex); + break; + case JAVA_TYPE_ATTRIBUTION_CHAIN: + { + requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION; + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + + fprintf(out, "%s writeAttributionChain(buff, pos, %s, %s);\n", indent.c_str(), + uidName, tagName); + fprintf(out, "%s pos += attrSize;\n", indent.c_str()); + break; + } + default: + // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. + fprintf(stderr, + "Object, Double, and KeyValuePairs are not supported in module logging"); + return 1; + } + argIndex++; + } + + fprintf(out, "%s StatsLog.writeRaw(buff, pos);\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "\n"); + } + + write_java_helpers_for_q_schema_methods(out, attributionDecl, requiredHelpers, indent); + + return 0; +} + +void write_java_helpers_for_q_schema_methods( + FILE* out, + const AtomDecl &attributionDecl, + const int requiredHelpers, + const string& indent) { + fprintf(out, "\n"); + fprintf(out, "%s// Helper methods for copying primitives\n", indent.c_str()); + fprintf(out, "%sprivate static void copyInt(byte[] buff, int pos, int val) {\n", + indent.c_str()); + fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str()); + fprintf(out, "%s return;\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "\n"); + + fprintf(out, "%sprivate static void copyLong(byte[] buff, int pos, long val) {\n", + indent.c_str()); + fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 4] = (byte) (val >> 32);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 5] = (byte) (val >> 40);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 6] = (byte) (val >> 48);\n", indent.c_str()); + fprintf(out, "%s buff[pos + 7] = (byte) (val >> 56);\n", indent.c_str()); + fprintf(out, "%s return;\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "\n"); + + if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) { + fprintf(out, "%sprivate static void copyFloat(byte[] buff, int pos, float val) {\n", + indent.c_str()); + fprintf(out, "%s copyInt(buff, pos, Float.floatToIntBits(val));\n", indent.c_str()); + fprintf(out, "%s return;\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "\n"); + } + + if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) { + fprintf(out, "%sprivate static void writeAttributionChain(byte[] buff, int pos", + indent.c_str()); + for (auto chainField : attributionDecl.fields) { + fprintf(out, ", %s[] %s", + java_type_name(chainField.javaType), chainField.name.c_str()); + } + fprintf(out, ") {\n"); + + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + + // Write the first list begin. + fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); + fprintf(out, "%s buff[pos + 1] = (byte) (%s.length);\n", indent.c_str(), tagName); + fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); + + // Iterate through the attribution chain and write the nodes. + fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(), tagName); + // Write the list begin. + fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); + fprintf(out, "%s buff[pos + 1] = %lu;\n", + indent.c_str(), attributionDecl.fields.size()); + fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); + + // Write the uid. + fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, %s[i]);\n", indent.c_str(), uidName); + fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); + + // Write the tag. + fprintf(out, "%s String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", + indent.c_str(), tagName, tagName, tagName); + fprintf(out, "%s byte[] %sByte = " + "%sStr.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n", + indent.c_str(), tagName, tagName); + fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); + fprintf(out, "%s copyInt(buff, pos + 1, %sByte.length);\n", indent.c_str(), tagName); + fprintf(out, "%s System.arraycopy(" + "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n", + indent.c_str(), tagName, tagName); + fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", + indent.c_str(), tagName); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "\n"); + } +} + +#if defined(STATS_SCHEMA_LEGACY) +static void write_java_method( + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; + fprintf(out, " /** @hide */\n"); + fprintf(out, " public static native int %s(int code", method_name.c_str()); + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + fprintf(out, ", %s[] %s", + java_type_name(chainField.javaType), chainField.name.c_str()); + } + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", SparseArray<Object> value_map"); + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ");\n"); + fprintf(out, "\n"); + } +} + +int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "package android.util;\n"); + fprintf(out, "\n"); + fprintf(out, "import android.os.WorkSource;\n"); + fprintf(out, "import android.util.SparseArray;\n"); + fprintf(out, "import java.util.ArrayList;\n"); + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "/**\n"); + fprintf(out, " * API For logging statistics events.\n"); + fprintf(out, " * @hide\n"); + fprintf(out, " */\n"); + fprintf(out, "public class StatsLogInternal {\n"); + write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME); + + write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME); + + // Print write methods + fprintf(out, " // Write methods\n"); + write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); + write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); + write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME); + + fprintf(out, "}\n"); + + return 0; +} + +int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& javaClass, + const string& javaPackage) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "package %s;\n", javaPackage.c_str()); + fprintf(out, "\n"); + fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n"); + fprintf(out, "\n"); + fprintf(out, "import android.util.StatsLog;\n"); + fprintf(out, "import android.os.SystemClock;\n"); + fprintf(out, "\n"); + fprintf(out, "import java.util.ArrayList;\n"); + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "/**\n"); + fprintf(out, " * Utility class for logging statistics events.\n"); + fprintf(out, " */\n"); + fprintf(out, "public class %s {\n", javaClass.c_str()); + + write_java_q_logging_constants(out, " "); + + write_java_atom_codes(out, atoms, moduleName); + + write_java_enum_values(out, atoms, moduleName); + + int errors = 0; + // Print write methods + fprintf(out, " // Write methods\n"); + errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl, + moduleName, " "); + errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules, + moduleName); + + fprintf(out, "}\n"); + + return errors; +} +#endif + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h new file mode 100644 index 000000000000..96ac745beef8 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer_q.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +void write_java_q_logging_constants(FILE* out, const string& indent); + +int write_java_methods_q_schema( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const string& indent); + +void write_java_helpers_for_q_schema_methods( + FILE * out, + const AtomDecl &attributionDecl, + const int requiredHelpers, + const string& indent); + +#if defined(STATS_SCHEMA_LEGACY) +int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl); + +int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, + const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass, + const string& javaPackage); +#endif +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index f62fef076f48..00a370484823 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -1,9 +1,17 @@ #include "Collation.h" +#include "atoms_info_writer.h" +#if !defined(STATS_SCHEMA_LEGACY) +#include "java_writer.h" +#endif +#include "java_writer_q.h" +#include "native_writer.h" +#include "utils.h" #include "frameworks/base/cmds/statsd/src/atoms.pb.h" +#include <map> #include <set> #include <vector> @@ -12,1490 +20,19 @@ #include <stdlib.h> #include <string.h> -#include "android-base/strings.h" - using namespace google::protobuf; using namespace std; namespace android { namespace stats_log_api_gen { -int maxPushedAtomId = 2; - -const string DEFAULT_MODULE_NAME = "DEFAULT"; -const string DEFAULT_CPP_NAMESPACE = "android,util"; -const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; -const string DEFAULT_JAVA_PACKAGE = "android.util"; -const string DEFAULT_JAVA_CLASS = "StatsLogInternal"; - -const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; -const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; - using android::os::statsd::Atom; -/** - * Turn lower and camel case into upper case with underscores. - */ -static string -make_constant_name(const string& str) -{ - string result; - const int N = str.size(); - bool underscore_next = false; - for (int i=0; i<N; i++) { - char c = str[i]; - if (c >= 'A' && c <= 'Z') { - if (underscore_next) { - result += '_'; - underscore_next = false; - } - } else if (c >= 'a' && c <= 'z') { - c = 'A' + c - 'a'; - underscore_next = true; - } else if (c == '_') { - underscore_next = false; - } - result += c; - } - return result; -} - -static const char* -cpp_type_name(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "bool"; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - return "int32_t"; - case JAVA_TYPE_LONG: - return "int64_t"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "char const*"; - case JAVA_TYPE_BYTE_ARRAY: - return "const BytesField&"; - default: - return "UNKNOWN"; - } -} - -static const char* -java_type_name(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "boolean"; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - return "int"; - case JAVA_TYPE_LONG: - return "long"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "java.lang.String"; - case JAVA_TYPE_BYTE_ARRAY: - return "byte[]"; - default: - return "UNKNOWN"; - } -} - -static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { - if (moduleName == DEFAULT_MODULE_NAME) { - return true; - } - return atomDecl.hasModule && (moduleName == atomDecl.moduleName); -} - -static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { - if (moduleName == DEFAULT_MODULE_NAME) { - return true; - } - return modules.find(moduleName) != modules.end(); -} - -static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) { - std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; - fprintf(out, - "const std::set<int> " - "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); - for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); - blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { - fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); - } - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - break; - } - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->whitelisted) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "static std::map<int, int> getAtomUidField() {\n"); - fprintf(out, " std::map<int, int> uidField;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->uidField == 0) { - continue; - } - fprintf(out, - "\n // Adding uid field for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " uidField[static_cast<int>(%s)] = %d;\n", - make_constant_name(atom->name).c_str(), atom->uidField); - } - - fprintf(out, " return uidField;\n"); - fprintf(out, "};\n"); - - fprintf(out, - "const std::map<int, int> AtomsInfo::kAtomsWithUidField = " - "getAtomUidField();\n"); - - fprintf(out, - "static std::map<int, StateAtomFieldOptions> " - "getStateAtomFieldOptions() {\n"); - fprintf(out, " std::map<int, StateAtomFieldOptions> options;\n"); - fprintf(out, " StateAtomFieldOptions opt;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { - continue; - } - fprintf(out, - "\n // Adding primary and exclusive fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " opt.primaryFields.clear();\n"); - for (const auto& field : atom->primaryFields) { - fprintf(out, " opt.primaryFields.push_back(%d);\n", field); - } - - fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); - fprintf(out, " options[static_cast<int>(%s)] = opt;\n", - make_constant_name(atom->name).c_str()); - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map<int, StateAtomFieldOptions> " - "AtomsInfo::kStateAtomsFieldOptions = " - "getStateAtomFieldOptions();\n"); - - fprintf(out, - "static std::map<int, std::vector<int>> " - "getBinaryFieldAtoms() {\n"); - fprintf(out, " std::map<int, std::vector<int>> options;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->binaryFields.size() == 0) { - continue; - } - fprintf(out, - "\n // Adding binary fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - - for (const auto& field : atom->binaryFields) { - fprintf(out, " options[static_cast<int>(%s)].push_back(%d);\n", - make_constant_name(atom->name).c_str(), field); - } - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map<int, std::vector<int>> " - "AtomsInfo::kBytesFieldAtoms = " - "getBinaryFieldAtoms();\n"); -} - -// Writes namespaces for the cpp and header files, returning the number of namespaces written. -void write_namespace(FILE* out, const string& cppNamespaces) { - vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); - for (string cppNamespace : cppNamespaceVec) { - fprintf(out, "namespace %s {\n", cppNamespace.c_str()); - } -} - -// Writes namespace closing brackets for cpp and header files. -void write_closing_namespace(FILE* out, const string& cppNamespaces) { - vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); - for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { - fprintf(out, "} // namespace %s\n", it->c_str()); - } -} - -static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, - const string& moduleName, const string& cppNamespace, - const string& importHeader) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <mutex>\n"); - fprintf(out, "#include <chrono>\n"); - fprintf(out, "#include <thread>\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "#include <cutils/properties.h>\n"); - fprintf(out, "#endif\n"); - fprintf(out, "#include <stats_event_list.h>\n"); - fprintf(out, "#include <log/log.h>\n"); - fprintf(out, "#include <%s>\n", importHeader.c_str()); - fprintf(out, "#include <utils/SystemClock.h>\n"); - fprintf(out, "\n"); - - write_namespace(out, cppNamespace); - fprintf(out, "// the single event tag id for all stats logs\n"); - fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); - fprintf(out, "#else\n"); - fprintf(out, "const static bool kStatsdEnabled = false;\n"); - fprintf(out, "#endif\n"); - - // AtomsInfo is only used by statsd internally and is not needed for other modules. - if (moduleName == DEFAULT_MODULE_NAME) { - write_atoms_info_cpp(out, atoms); - } - - fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); - fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); - fprintf(out, "static std::mutex mLogdRetryMutex;\n"); - - // Print write methods - fprintf(out, "\n"); - for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); - signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "try_stats_write(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", - cpp_type_name(chainField.javaType), - chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), - chainField.name.c_str(), chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", const std::map<int, int32_t>& arg%d_1, " - "const std::map<int, int64_t>& arg%d_2, " - "const std::map<int, char const*>& arg%d_3, " - "const std::map<int, float>& arg%d_4", - argIndex, argIndex, argIndex, argIndex); - } else { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - argIndex = 1; - fprintf(out, " if (kStatsdEnabled) {\n"); - fprintf(out, " stats_event_list event(kStatsEventTag);\n"); - fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); - fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (const auto &chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, " if (%s_length != %s.size()) {\n", - attributionDecl.fields.front().name.c_str(), chainField.name.c_str()); - fprintf(out, " return -EINVAL;\n"); - fprintf(out, " }\n"); - } - } - fprintf(out, "\n event.begin();\n"); - fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n", - attributionDecl.fields.front().name.c_str()); - fprintf(out, " event.begin();\n"); - for (const auto &chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str()); - fprintf(out, " event << %s[i];\n", chainField.name.c_str()); - fprintf(out, " } else {\n"); - fprintf(out, " event << \"\";\n"); - fprintf(out, " }\n"); - } else { - fprintf(out, " event << %s[i];\n", chainField.name.c_str()); - } - } - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - fprintf(out, " event.end();\n\n"); - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, " event.begin();\n\n"); - fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " event.end();\n\n"); - } else if (*arg == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, - " event.AppendCharArray(arg%d.arg, " - "arg%d.arg_length);\n", - argIndex, argIndex); - } else { - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (arg%d == NULL) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - } - fprintf(out, " event << arg%d;\n", argIndex); - } - argIndex++; - } - - fprintf(out, " return event.write(LOG_ID_STATS);\n"); - fprintf(out, " } else {\n"); - fprintf(out, " return 1;\n"); - fprintf(out, " }\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); - signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "stats_write(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", - cpp_type_name(chainField.javaType), - chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), - chainField.name.c_str(), chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, - ", const std::map<int, int32_t>& arg%d_1, " - "const std::map<int, int64_t>& arg%d_2, " - "const std::map<int, char const*>& arg%d_3, " - "const std::map<int, float>& arg%d_4", - argIndex, argIndex, argIndex, argIndex); - } else { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - fprintf(out, " int ret = 0;\n"); - - fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n"); - fprintf(out, " ret = try_stats_write(code"); - - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", %s", - chainField.name.c_str()); - } else { - fprintf(out, ", %s, %s_length", - chainField.name.c_str(), chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex, - argIndex, argIndex, argIndex); - } else { - fprintf(out, ", arg%d", argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " if (ret >= 0) { break; }\n"); - - fprintf(out, " {\n"); - fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n"); - fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= " - "kMinRetryIntervalNs) break;\n"); - fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n"); - fprintf(out, " }\n"); - fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n"); - fprintf(out, " }\n"); - fprintf(out, " if (ret < 0) {\n"); - fprintf(out, " note_log_drop(ret, code);\n"); - fprintf(out, " }\n"); - fprintf(out, " return ret;\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); - signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { - if (!signature_needed_for_module(signature_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "try_stats_write_non_chained(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - argIndex = 1; - fprintf(out, " if (kStatsdEnabled) {\n"); - fprintf(out, " stats_event_list event(kStatsEventTag);\n"); - fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); - fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (argIndex == 1) { - fprintf(out, " event.begin();\n\n"); - fprintf(out, " event.begin();\n"); - } - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (arg%d == NULL) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - } - if (*arg == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, - " event.AppendCharArray(arg%d.arg, " - "arg%d.arg_length);", - argIndex, argIndex); - } else { - fprintf(out, " event << arg%d;\n", argIndex); - } - if (argIndex == 2) { - fprintf(out, " event.end();\n\n"); - fprintf(out, " event.end();\n\n"); - } - argIndex++; - } - - fprintf(out, " return event.write(LOG_ID_STATS);\n"); - fprintf(out, " } else {\n"); - fprintf(out, " return 1;\n"); - fprintf(out, " }\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); - signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { - if (!signature_needed_for_module(signature_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "stats_write_non_chained(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - - fprintf(out, " int ret = 0;\n"); - fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n"); - fprintf(out, " ret = try_stats_write_non_chained(code"); - - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", arg%d", argIndex); - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " if (ret >= 0) { break; }\n"); - - fprintf(out, " {\n"); - fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n"); - fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= " - "kMinRetryIntervalNs) break;\n"); - fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n"); - fprintf(out, " }\n"); - - fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n"); - fprintf(out, " }\n"); - fprintf(out, " if (ret < 0) {\n"); - fprintf(out, " note_log_drop(ret, code);\n"); - fprintf(out, " }\n"); - fprintf(out, " return ret;\n\n"); - fprintf(out, "}\n"); - - fprintf(out, "\n"); - } - - - // Print footer - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -void build_non_chained_decl_map(const Atoms& atoms, - std::map<int, set<AtomDecl>::const_iterator>* decl_map){ - for (set<AtomDecl>::const_iterator atom = atoms.non_chained_decls.begin(); - atom != atoms.non_chained_decls.end(); atom++) { - decl_map->insert(std::make_pair(atom->code, atom)); - } -} - -static void write_cpp_usage( - FILE* out, const string& method_name, const string& atom_code_name, - const AtomDecl& atom, const AtomDecl &attributionDecl) { - fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), - atom_code_name.c_str()); - - for (vector<AtomField>::const_iterator field = atom.fields.begin(); - field != atom.fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", - cpp_type_name(chainField.javaType), - chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), - chainField.name.c_str(), chainField.name.c_str()); - } - } - } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", const std::map<int, int32_t>& %s_int" - ", const std::map<int, int64_t>& %s_long" - ", const std::map<int, char const*>& %s_str" - ", const std::map<int, float>& %s_float", - field->name.c_str(), - field->name.c_str(), - field->name.c_str(), - field->name.c_str()); - } else { - fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str()); - } - } - fprintf(out, ");\n"); -} - -static void write_cpp_method_header( - FILE* out, - const string& method_name, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl, const string& moduleName) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, "int %s(int32_t code", method_name.c_str()); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", - cpp_type_name(chainField.javaType), chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), - chainField.name.c_str(), chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", const std::map<int, int32_t>& arg%d_1, " - "const std::map<int, int64_t>& arg%d_2, " - "const std::map<int, char const*>& arg%d_3, " - "const std::map<int, float>& arg%d_4", - argIndex, argIndex, argIndex, argIndex); - } else { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - - } -} - -static int -write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, - const string& moduleName, const string& cppNamespace) -{ - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "#pragma once\n"); - fprintf(out, "\n"); - fprintf(out, "#include <stdint.h>\n"); - fprintf(out, "#include <vector>\n"); - fprintf(out, "#include <map>\n"); - fprintf(out, "#include <set>\n"); - fprintf(out, "\n"); - - write_namespace(out, cppNamespace); - fprintf(out, "\n"); - fprintf(out, "/*\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Constants for atom codes.\n"); - fprintf(out, " */\n"); - fprintf(out, "enum {\n"); - - std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map; - build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); - - size_t i = 0; - // Print atom constants - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); - write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); - - auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code); - if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { - write_cpp_usage(out, "stats_write_non_chained", constant, *non_chained_decl->second, - attributionDecl); - } - fprintf(out, " */\n"); - char const* const comma = (i == atoms.decls.size() - 1) ? "" : ","; - fprintf(out, " %s = %d%s\n", constant.c_str(), atom->code, comma); - if (atom->code < PULL_ATOM_START_ID && atom->code > maxPushedAtomId) { - maxPushedAtomId = atom->code; - } - i++; - } - fprintf(out, "\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // Print constants for the enum values. - fprintf(out, "//\n"); - fprintf(out, "// Constants for enum values\n"); - fprintf(out, "//\n\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, "// Values for %s.%s\n", atom->message.c_str(), - field->name.c_str()); - for (map<int, string>::const_iterator value = field->enumValues.begin(); - value != field->enumValues.end(); value++) { - fprintf(out, "const int32_t %s__%s__%s = %d;\n", - make_constant_name(atom->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), - value->first); - } - fprintf(out, "\n"); - } - } - } - - fprintf(out, "struct BytesField {\n"); - fprintf(out, - " BytesField(char const* array, size_t len) : arg(array), " - "arg_length(len) {}\n"); - fprintf(out, " char const* arg;\n"); - fprintf(out, " size_t arg_length;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // This metadata is only used by statsd, which uses the default libstatslog. - if (moduleName == DEFAULT_MODULE_NAME) { - - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector<int> primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set<int> " - "kTruncatingTimestampAtomBlackList;\n"); - fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); - fprintf(out, - " const static std::set<int> kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map<int, StateAtomFieldOptions> " - "kStateAtomsFieldOptions;\n"); - fprintf(out, - " const static std::map<int, std::vector<int>> " - "kBytesFieldAtoms;"); - fprintf(out, - " const static std::set<int> kWhitelistedAtoms;\n"); - fprintf(out, "};\n"); - - fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", - maxPushedAtomId); - } - - // Print write methods - fprintf(out, "//\n"); - fprintf(out, "// Write methods\n"); - fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl, - moduleName); - - fprintf(out, "//\n"); - fprintf(out, "// Write flattened methods\n"); - fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules, - attributionDecl, moduleName); - - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -static void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name, - const AtomDecl& atom) { - fprintf(out, " * Usage: StatsLog.%s(StatsLog.%s", - method_name.c_str(), atom_code_name.c_str()); - for (vector<AtomField>::const_iterator field = atom.fields.begin(); - field != atom.fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - fprintf(out, ", android.os.WorkSource workSource"); - } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", SparseArray<Object> value_map"); - } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, ", byte[] %s", field->name.c_str()); - } else { - fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str()); - } - } - fprintf(out, ");<br>\n"); -} - -static void write_java_method( - FILE* out, - const string& method_name, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, " /** @hide */\n"); - fprintf(out, " public static native int %s(int code", method_name.c_str()); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", - java_type_name(chainField.javaType), chainField.name.c_str()); - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", SparseArray<Object> value_map"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - } -} - -static void write_java_helpers_for_module( - FILE * out, - const AtomDecl &attributionDecl, - const int requiredHelpers) { - fprintf(out, " private static void copyInt(byte[] buff, int pos, int val) {\n"); - fprintf(out, " buff[pos] = (byte) (val);\n"); - fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n"); - fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n"); - fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - - fprintf(out, " private static void copyLong(byte[] buff, int pos, long val) {\n"); - fprintf(out, " buff[pos] = (byte) (val);\n"); - fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n"); - fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n"); - fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n"); - fprintf(out, " buff[pos + 4] = (byte) (val >> 32);\n"); - fprintf(out, " buff[pos + 5] = (byte) (val >> 40);\n"); - fprintf(out, " buff[pos + 6] = (byte) (val >> 48);\n"); - fprintf(out, " buff[pos + 7] = (byte) (val >> 56);\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - - if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) { - fprintf(out, " private static void copyFloat(byte[] buff, int pos, float val) {\n"); - fprintf(out, " copyInt(buff, pos, Float.floatToIntBits(val));\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - - if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) { - fprintf(out, " private static void writeAttributionChain(byte[] buff, int pos"); - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", - java_type_name(chainField.javaType), chainField.name.c_str()); - } - fprintf(out, ") {\n"); - - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - - // Write the first list begin. - fprintf(out, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = (byte) (%s.length);\n", tagName); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Iterate through the attribution chain and write the nodes. - fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName); - // Write the list begin. - fprintf(out, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = %lu;\n", attributionDecl.fields.size()); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Write the uid. - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, %s[i]);\n", uidName); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - - // Write the tag. - fprintf(out, " String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", - tagName, tagName, tagName); - fprintf(out, " byte[] %sByte = %sStr.getBytes(UTF_8);\n", tagName, tagName); - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, %sByte.length);\n", tagName); - fprintf(out, " System.arraycopy(" - "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n", - tagName, tagName); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", tagName); - fprintf(out, " }\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } -} - - -static int write_java_non_chained_method_for_module( - FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const string& moduleName - ) { - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - // Print method signature. - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, " public static void write_non_chained(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - // Non chained signatures should not have attribution chains. - return 1; - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - // Module logging does not yet support key value pair. - return 1; - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - fprintf(out, " write(code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - // First two args are uid and tag of attribution chain. - if (argIndex == 1) { - fprintf(out, ", new int[] {arg%d}", argIndex); - } else if (argIndex == 2) { - fprintf(out, ", new java.lang.String[] {arg%d}", argIndex); - } else { - fprintf(out, ", arg%d", argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - return 0; -} - -static int write_java_method_for_module( - FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl, - const string& moduleName, - int* requiredHelpers - ) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - // Print method signature. - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, " public static void write(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", - java_type_name(chainField.javaType), chainField.name.c_str()); - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - // Module logging does not yet support key value pair. - return 1; - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // Calculate the size of the buffer. - fprintf(out, " // Initial overhead of the list, timestamp, and atom tag.\n"); - fprintf(out, " int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - case JAVA_TYPE_INT: - case JAVA_TYPE_FLOAT: - case JAVA_TYPE_ENUM: - fprintf(out, " needed += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_LONG: - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, " needed += LONG_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_STRING: - // Strings take 5 metadata bytes + length of byte encoded string. - fprintf(out, " if (arg%d == null) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - fprintf(out, " byte[] arg%dBytes= arg%d.getBytes(UTF_8);\n", - argIndex, argIndex); - fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - // Byte arrays take 5 metadata bytes + length of byte array. - fprintf(out, " if (arg%d == null) {\n", argIndex); - fprintf(out, " arg%d = new byte[0];\n", argIndex); - fprintf(out, " }\n"); - fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex); - break; - case JAVA_TYPE_ATTRIBUTION_CHAIN: - { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - // Null checks on the params. - fprintf(out, " if (%s == null) {\n", uidName); - fprintf(out, " %s = new %s[0];\n", uidName, - java_type_name(attributionDecl.fields.front().javaType)); - fprintf(out, " }\n"); - fprintf(out, " if (%s == null) {\n", tagName); - fprintf(out, " %s = new %s[0];\n", tagName, - java_type_name(attributionDecl.fields.back().javaType)); - fprintf(out, " }\n"); - - // First check that the lengths of the uid and tag arrays are the same. - fprintf(out, " if (%s.length != %s.length) {\n", uidName, tagName); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, " int attrSize = LIST_TYPE_OVERHEAD;\n"); - fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName); - fprintf(out, " String str%d = (%s[i] == null) ? \"\" : %s[i];\n", - argIndex, tagName, tagName); - fprintf(out, " int str%dlen = str%d.getBytes(UTF_8).length;\n", - argIndex, argIndex); - fprintf(out, - " attrSize += " - "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n", - argIndex); - fprintf(out, " }\n"); - fprintf(out, " needed += attrSize;\n"); - break; - } - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. - return 1; - } - argIndex++; - } - - // Now we have the size that is needed. Check for overflow and return if needed. - fprintf(out, " if (needed > MAX_EVENT_PAYLOAD) {\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - - // Create new buffer, and associated data types. - fprintf(out, " byte[] buff = new byte[needed];\n"); - fprintf(out, " int pos = 0;\n"); - - // Initialize the buffer with list data type. - fprintf(out, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = %zu;\n", signature.size() + 2); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Write timestamp. - fprintf(out, " long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n"); - fprintf(out, " buff[pos] = LONG_TYPE;\n"); - fprintf(out, " copyLong(buff, pos + 1, elapsedRealtime);\n"); - fprintf(out, " pos += LONG_TYPE_SIZE;\n"); - - // Write atom code. - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, code);\n"); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - - // Write the args. - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d? 1 : 0);\n", argIndex); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_FLOAT: - *requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT; - fprintf(out, " buff[pos] = FLOAT_TYPE;\n"); - fprintf(out, " copyFloat(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += FLOAT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_LONG: - fprintf(out, " buff[pos] = LONG_TYPE;\n"); - fprintf(out, " copyLong(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += LONG_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_STRING: - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%dBytes.length);\n", argIndex); - fprintf(out, " System.arraycopy(" - "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n", - argIndex, argIndex); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d.length);\n", argIndex); - fprintf(out, " System.arraycopy(" - "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n", - argIndex, argIndex); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex); - break; - case JAVA_TYPE_ATTRIBUTION_CHAIN: - { - *requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION; - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - - fprintf(out, " writeAttributionChain(buff, pos, %s, %s);\n", - uidName, tagName); - fprintf(out, " pos += attrSize;\n"); - break; - } - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. - return 1; - } - argIndex++; - } - - fprintf(out, " StatsLog.writeRaw(buff, pos);\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - return 0; -} - -static void write_java_work_source_method(FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const string& moduleName) { - fprintf(out, "\n // WorkSource methods.\n"); - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->first; - // Determine if there is Attribution in this signature. - int attributionArg = -1; - int argIndexMax = 0; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - argIndexMax++; - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - if (attributionArg > -1) { - fprintf(stderr, "An atom contains multiple AttributionNode fields.\n"); - fprintf(stderr, "This is not supported. Aborting WorkSource method writing.\n"); - fprintf(out, "\n// Invalid for WorkSource: more than one attribution chain.\n"); - return; - } - attributionArg = argIndexMax; - } - } - if (attributionArg < 0) { - continue; - } - - // Method header (signature) - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " /** @hide */\n"); - } - fprintf(out, " public static void write(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - fprintf(out, ", WorkSource ws"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // write_non_chained() component. TODO: Remove when flat uids are no longer needed. - fprintf(out, " for (int i = 0; i < ws.size(); ++i) {\n"); - fprintf(out, " write_non_chained(code"); - for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { - if (argIndex == attributionArg) { - fprintf(out, ", ws.get(i), ws.getName(i)"); - } else { - fprintf(out, ", arg%d", argIndex); - } - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // close for-loop - - // write() component. - fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n"); - fprintf(out, " if (workChains != null) {\n"); - fprintf(out, " for (WorkSource.WorkChain wc : workChains) {\n"); - fprintf(out, " write(code"); - for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { - if (argIndex == attributionArg) { - fprintf(out, ", wc.getUids(), wc.getTags()"); - } else { - fprintf(out, ", arg%d", argIndex); - } - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // close for-loop - fprintf(out, " }\n"); // close if - fprintf(out, " }\n"); // close method - } -} - -static void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) { - fprintf(out, " // Constants for atom codes.\n"); - - std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map; - build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); - - // Print constants for the atom codes. - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s<br>\n", atom->message.c_str(), atom->name.c_str()); - write_java_usage(out, "write", constant, *atom); - auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code); - if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { - write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second); - } - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " * @hide\n"); - } - fprintf(out, " */\n"); - fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code); - } - fprintf(out, "\n"); -} - -static void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) { - fprintf(out, " // Constants for enum values.\n\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), - field->name.c_str()); - for (map<int, string>::const_iterator value = field->enumValues.begin(); - value != field->enumValues.end(); value++) { - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " /** @hide */\n"); - } - fprintf(out, " public static final int %s__%s__%s = %d;\n", - make_constant_name(atom->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), - value->first); - } - fprintf(out, "\n"); - } - } - } -} - -static int -write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) -{ - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package android.util;\n"); - fprintf(out, "\n"); - fprintf(out, "import android.os.WorkSource;\n"); - fprintf(out, "import android.util.SparseArray;\n"); - fprintf(out, "import java.util.ArrayList;\n"); - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " * @hide\n"); - fprintf(out, " */\n"); - fprintf(out, "public class StatsLogInternal {\n"); - write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME); - - write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME); - - // Print write methods - fprintf(out, " // Write methods\n"); - write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); - write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, - attributionDecl); - write_java_work_source_method(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME); - - fprintf(out, "}\n"); - - return 0; -} - -// TODO: Merge this with write_stats_log_java so that we can get rid of StatsLogInternal JNI. -static int -write_stats_log_java_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, - const string& moduleName, const string& javaClass, const string& javaPackage) -{ - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package %s;\n", javaPackage.c_str()); - fprintf(out, "\n"); - fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n"); - fprintf(out, "\n"); - fprintf(out, "import android.util.StatsLog;\n"); - fprintf(out, "import android.os.SystemClock;\n"); - fprintf(out, "\n"); - fprintf(out, "import java.util.ArrayList;\n"); - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Utility class for logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "public class %s {\n", javaClass.c_str()); - - // TODO: ideally these match with the native values (and automatically change if they change). - fprintf(out, " private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n"); - fprintf(out, - " private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n"); - // Value types. Must match with EventLog.java and log.h. - fprintf(out, " private static final byte INT_TYPE = 0;\n"); - fprintf(out, " private static final byte LONG_TYPE = 1;\n"); - fprintf(out, " private static final byte STRING_TYPE = 2;\n"); - fprintf(out, " private static final byte LIST_TYPE = 3;\n"); - fprintf(out, " private static final byte FLOAT_TYPE = 4;\n"); - - // Size of each value type. - // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value. - fprintf(out, " private static final int INT_TYPE_SIZE = 5;\n"); - fprintf(out, " private static final int FLOAT_TYPE_SIZE = 5;\n"); - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, " private static final int LONG_TYPE_SIZE = 9;\n"); - // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length. - fprintf(out, " private static final int STRING_TYPE_OVERHEAD = 5;\n"); - fprintf(out, " private static final int LIST_TYPE_OVERHEAD = 2;\n"); - - write_java_atom_codes(out, atoms, moduleName); - - write_java_enum_values(out, atoms, moduleName); - - int errors = 0; - int requiredHelpers = 0; - // Print write methods - fprintf(out, " // Write methods\n"); - errors += write_java_method_for_module(out, atoms.signatures_to_modules, attributionDecl, - moduleName, &requiredHelpers); - errors += write_java_non_chained_method_for_module(out, atoms.non_chained_signatures_to_modules, - moduleName); - - fprintf(out, " // Helper methods for copying primitives\n"); - write_java_helpers_for_module(out, attributionDecl, requiredHelpers); - - fprintf(out, "}\n"); - - return errors; -} - +// Hide the JNI write helpers that are not used in the new schema. +// TODO(b/145100015): Remove this and other JNI related functionality once StatsEvent migration is +// complete. +#if defined(STATS_SCHEMA_LEGACY) +// JNI helpers. static const char* jni_type_name(java_type_t type) { @@ -1666,7 +203,7 @@ static void write_key_value_map_jni(FILE* out) { } static int -write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name, +write_stats_log_jni_method(FILE* out, const string& java_method_name, const string& cpp_method_name, const map<vector<java_type_t>, set<string>>& signatures_to_modules, const AtomDecl &attributionDecl) { // Print write methods @@ -1882,40 +419,56 @@ void write_jni_registration(FILE* out, const string& java_method_name, jni_function_name(java_method_name, signature).c_str()); } } +#endif // JNI helpers. static int +#if defined(STATS_SCHEMA_LEGACY) write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) +#else +// Write empty JNI file that doesn't contain any JNI methods. +// TODO(b/145100015): remove this function and all JNI autogen code once StatsEvent migration is +// complete. +write_stats_log_jni(FILE* out) +#endif { // Print prelude fprintf(out, "// This file is autogenerated\n"); fprintf(out, "\n"); +#if defined(STATS_SCHEMA_LEGACY) fprintf(out, "#include <statslog.h>\n"); fprintf(out, "\n"); fprintf(out, "#include <nativehelper/JNIHelp.h>\n"); fprintf(out, "#include <nativehelper/ScopedUtfChars.h>\n"); fprintf(out, "#include <utils/Vector.h>\n"); +#endif fprintf(out, "#include \"core_jni_helpers.h\"\n"); fprintf(out, "#include \"jni.h\"\n"); fprintf(out, "\n"); +#if defined(STATS_SCHEMA_LEGACY) fprintf(out, "#define UNUSED __attribute__((__unused__))\n"); fprintf(out, "\n"); +#endif fprintf(out, "namespace android {\n"); fprintf(out, "\n"); - write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); - write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained", +#if defined(STATS_SCHEMA_LEGACY) + write_stats_log_jni_method(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); + write_stats_log_jni_method(out, "write_non_chained", "stats_write_non_chained", atoms.non_chained_signatures_to_modules, attributionDecl); +#endif // Print registration function table fprintf(out, "/*\n"); fprintf(out, " * JNI registration.\n"); fprintf(out, " */\n"); fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n"); +#if defined(STATS_SCHEMA_LEGACY) write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl); write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules, attributionDecl); +#endif fprintf(out, "};\n"); fprintf(out, "\n"); @@ -1938,20 +491,28 @@ print_usage() fprintf(stderr, "usage: stats-log-api-gen OPTIONS\n"); fprintf(stderr, "\n"); fprintf(stderr, "OPTIONS\n"); - fprintf(stderr, " --cpp FILENAME the header file to output\n"); - fprintf(stderr, " --header FILENAME the cpp file to output\n"); + fprintf(stderr, " --cpp FILENAME the header file to output for write helpers\n"); + fprintf(stderr, " --header FILENAME the cpp file to output for write helpers\n"); + fprintf(stderr, + " --atomsInfoCpp FILENAME the header file to output for statsd metadata\n"); + fprintf(stderr, " --atomsInfoHeader FILENAME the cpp file to output for statsd metadata\n"); fprintf(stderr, " --help this message\n"); fprintf(stderr, " --java FILENAME the java file to output\n"); fprintf(stderr, " --jni FILENAME the jni file to output\n"); fprintf(stderr, " --module NAME optional, module name to generate outputs for\n"); fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n"); fprintf(stderr, " comma separated namespace of the files\n"); - fprintf(stderr, " --importHeader NAME required for cpp/jni to say which header to import\n"); + fprintf(stderr," --importHeader NAME required for cpp/jni to say which header to import " + "for write helpers\n"); + fprintf(stderr," --atomsInfoImportHeader NAME required for cpp to say which header to import " + "for statsd metadata\n"); fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n"); fprintf(stderr, " required for java with module\n"); fprintf(stderr, " --javaClass CLASS the class name of the java class.\n"); fprintf(stderr, " Optional for Java with module.\n"); - fprintf(stderr, " Default is \"StatsLogInternal\"\n");} + fprintf(stderr, " Default is \"StatsLogInternal\"\n"); + fprintf(stderr, " --supportQ Include support for Android Q.\n"); +} /** * Do the argument parsing and execute the tasks. @@ -1963,12 +524,16 @@ run(int argc, char const*const* argv) string headerFilename; string javaFilename; string jniFilename; + string atomsInfoCppFilename; + string atomsInfoHeaderFilename; string moduleName = DEFAULT_MODULE_NAME; string cppNamespace = DEFAULT_CPP_NAMESPACE; string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; + string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT; string javaPackage = DEFAULT_JAVA_PACKAGE; string javaClass = DEFAULT_JAVA_CLASS; + bool supportQ = false; int index = 1; while (index < argc) { @@ -2038,18 +603,50 @@ run(int argc, char const*const* argv) return 1; } javaClass = argv[index]; + } else if (0 == strcmp("--atomsInfoHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoHeaderFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoCpp", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoImportHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppHeaderImport = argv[index]; + } else if (0 == strcmp("--supportQ", argv[index])) { + supportQ = true; } + index++; } if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0 - && jniFilename.size() == 0) { + && jniFilename.size() == 0 + && atomsInfoHeaderFilename.size() == 0 + && atomsInfoCppFilename.size() == 0) { print_usage(); return 1; } + if (DEFAULT_MODULE_NAME == moduleName && supportQ) { + // Support for Q schema is not needed for default module. + fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str()); + return 1; + } + // Collate the parameters Atoms atoms; int errorCount = collate_atoms(Atom::descriptor(), &atoms); @@ -2062,6 +659,30 @@ run(int argc, char const*const* argv) collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl, &attributionSignature); + // Write the atoms info .cpp file + if (atomsInfoCppFilename.size() != 0) { + FILE* out = fopen(atomsInfoCppFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoCppFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_cpp( + out, atoms, cppNamespace, atomsInfoCppHeaderImport, cppHeaderImport); + fclose(out); + } + + // Write the atoms info .h file + if (atomsInfoHeaderFilename.size() != 0) { + FILE* out = fopen(atomsInfoHeaderFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoHeaderFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_header(out, atoms, cppNamespace); + fclose(out); + } + + // Write the .cpp file if (cppFilename.size() != 0) { FILE* out = fopen(cppFilename.c_str(), "w"); @@ -2080,7 +701,7 @@ run(int argc, char const*const* argv) return 1; } errorCount = android::stats_log_api_gen::write_stats_log_cpp( - out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport); + out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport, supportQ); fclose(out); } @@ -2112,13 +733,25 @@ run(int argc, char const*const* argv) fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n"); return 1; } + +#if defined(STATS_SCHEMA_LEGACY) if (moduleName == DEFAULT_MODULE_NAME) { - errorCount = android::stats_log_api_gen::write_stats_log_java( + errorCount = android::stats_log_api_gen::write_stats_log_java_q( out, atoms, attributionDecl); } else { - errorCount = android::stats_log_api_gen::write_stats_log_java_for_module( + errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module( out, atoms, attributionDecl, moduleName, javaClass, javaPackage); + + } +#else + if (moduleName == DEFAULT_MODULE_NAME) { + javaClass = "StatsLogInternal"; + javaPackage = "android.util"; } + errorCount = android::stats_log_api_gen::write_stats_log_java( + out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ); +#endif + fclose(out); } @@ -2129,16 +762,22 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", jniFilename.c_str()); return 1; } + +#if defined(STATS_SCHEMA_LEGACY) errorCount = android::stats_log_api_gen::write_stats_log_jni( out, atoms, attributionDecl); +#else + errorCount = android::stats_log_api_gen::write_stats_log_jni(out); +#endif + fclose(out); } return errorCount; } -} -} +} // namespace stats_log_api_gen +} // namespace android /** * Main. diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp new file mode 100644 index 000000000000..c7a34feff94b --- /dev/null +++ b/tools/stats_log_api_gen/native_writer.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_writer.h" +#include "native_writer_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +#if !defined(STATS_SCHEMA_LEGACY) +static void write_native_key_value_pairs_for_type(FILE* out, const int argIndex, + const int typeIndex, const string& type, const string& valueFieldName) { + fprintf(out, " for (const auto& it : arg%d_%d) {\n", argIndex, typeIndex); + fprintf(out, " pairs.push_back(" + "{ .key = it.first, .valueType = %s, .%s = it.second });\n", + type.c_str(), valueFieldName.c_str()); + fprintf(out, " }\n"); + +} + +static int write_native_stats_write_methods(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const bool supportQ) { + fprintf(out, "\n"); + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + write_native_method_signature(out, "int stats_write", signature, + attributionDecl, " {"); + + int argIndex = 1; + if (supportQ) { + fprintf(out, " StatsEventCompat event;\n"); + fprintf(out, " event.setAtomId(code);\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_ATTRIBUTION_CHAIN: { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + fprintf(out, " event.writeAttributionChain(%s, %s_length, %s);\n", + uidName, uidName, tagName); + break; + } + case JAVA_TYPE_KEY_VALUE_PAIR: + fprintf(out, " event.writeKeyValuePairs(" + "arg%d_1, arg%d_2, arg%d_3, arg%d_4);\n", + argIndex, argIndex, argIndex, argIndex); + break; + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n", + argIndex, argIndex); + break; + case JAVA_TYPE_BOOLEAN: + fprintf(out, " event.writeBool(arg%d);\n", argIndex); + break; + case JAVA_TYPE_INT: // Fall through. + case JAVA_TYPE_ENUM: + fprintf(out, " event.writeInt32(arg%d);\n", argIndex); + break; + case JAVA_TYPE_FLOAT: + fprintf(out, " event.writeFloat(arg%d);\n", argIndex); + break; + case JAVA_TYPE_LONG: + fprintf(out, " event.writeInt64(arg%d);\n", argIndex); + break; + case JAVA_TYPE_STRING: + fprintf(out, " event.writeString(arg%d);\n", argIndex); + break; + default: + // Unsupported types: OBJECT, DOUBLE. + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + argIndex++; + } + fprintf(out, " return event.writeToSocket();\n"); + } else { + fprintf(out, " struct stats_event* event = stats_event_obtain();\n"); + fprintf(out, " stats_event_set_atom_id(event, code);\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + switch (*arg) { + case JAVA_TYPE_ATTRIBUTION_CHAIN: { + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + fprintf(out, + " stats_event_write_attribution_chain(event, " + "reinterpret_cast<const uint32_t*>(%s), %s.data(), " + "static_cast<uint8_t>(%s_length));\n", + uidName, tagName, uidName); + break; + } + case JAVA_TYPE_KEY_VALUE_PAIR: + fprintf(out, " std::vector<key_value_pair> pairs;\n"); + write_native_key_value_pairs_for_type( + out, argIndex, 1, "INT32_TYPE", "int32Value"); + write_native_key_value_pairs_for_type( + out, argIndex, 2, "INT64_TYPE", "int64Value"); + write_native_key_value_pairs_for_type( + out, argIndex, 3, "STRING_TYPE", "stringValue"); + write_native_key_value_pairs_for_type( + out, argIndex, 4, "FLOAT_TYPE", "floatValue"); + fprintf(out, + " stats_event_write_key_value_pairs(event, pairs.data(), " + "static_cast<uint8_t>(pairs.size()));\n"); + break; + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, + " stats_event_write_byte_array(event, " + "reinterpret_cast<const uint8_t*>(arg%d.arg), arg%d.arg_length);\n", + argIndex, argIndex); + break; + case JAVA_TYPE_BOOLEAN: + fprintf(out, " stats_event_write_bool(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_INT: // Fall through. + case JAVA_TYPE_ENUM: + fprintf(out, " stats_event_write_int32(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_FLOAT: + fprintf(out, " stats_event_write_float(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_LONG: + fprintf(out, " stats_event_write_int64(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_STRING: + fprintf(out, " stats_event_write_string8(event, arg%d);\n", argIndex); + break; + default: + // Unsupported types: OBJECT, DOUBLE. + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + argIndex++; + } + fprintf(out, " const int ret = stats_event_write(event);\n"); + fprintf(out, " stats_event_release(event);\n"); + fprintf(out, " return ret;\n"); + } + fprintf(out, "}\n\n"); + } + return 0; +} + +static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName) { + fprintf(out, "\n"); + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + write_native_method_signature(out, "int stats_write_non_chained", signature, + attributionDecl, " {"); + + vector<java_type_t> newSignature; + + // First two args form the attribution node so size goes down by 1. + newSignature.reserve(signature.size() - 1); + + // First arg is Attribution Chain. + newSignature.push_back(JAVA_TYPE_ATTRIBUTION_CHAIN); + + // Followed by the originial signature except the first 2 args. + newSignature.insert(newSignature.end(), signature.begin() + 2, signature.end()); + + const char* uidName = attributionDecl.fields.front().name.c_str(); + const char* tagName = attributionDecl.fields.back().name.c_str(); + fprintf(out, " const int32_t* %s = &arg1;\n", uidName); + fprintf(out, " const size_t %s_length = 1;\n", uidName); + fprintf(out, " const std::vector<char const*> %s(1, arg2);\n", tagName); + fprintf(out, " return "); + write_native_method_call(out, "stats_write", newSignature, attributionDecl, 2); + + fprintf(out, "}\n\n"); + } + +} +#endif + +static void write_native_method_header( + FILE* out, + const string& methodName, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, const string& moduleName) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + vector<java_type_t> signature = signature_to_modules_it->first; + write_native_method_signature(out, methodName, signature, attributionDecl, ";"); + } +} + +int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace, + const string& importHeader, const bool supportQ) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + + fprintf(out, "#include <%s>\n", importHeader.c_str()); +#if defined(STATS_SCHEMA_LEGACY) + (void)supportQ; // Workaround for unused parameter error. + write_native_cpp_includes_q(out); +#else + if (supportQ) { + fprintf(out, "#include <StatsEventCompat.h>\n"); + } else { + fprintf(out, "#include <stats_event.h>\n"); + } +#endif + + fprintf(out, "\n"); + write_namespace(out, cppNamespace); + +#if defined(STATS_SCHEMA_LEGACY) + write_native_stats_log_cpp_globals_q(out); + write_native_get_timestamp_ns_q(out); + write_native_try_stats_write_methods_q(out, atoms, attributionDecl, moduleName); + write_native_stats_write_methods_q(out, "int stats_write", atoms, attributionDecl, moduleName, + "try_stats_write"); + write_native_try_stats_write_non_chained_methods_q(out, atoms, attributionDecl, moduleName); + write_native_stats_write_non_chained_methods_q(out, "int stats_write_non_chained", atoms, + attributionDecl, moduleName, "try_stats_write_non_chained"); +#else + write_native_stats_write_methods(out, atoms, attributionDecl, moduleName, supportQ); + write_native_stats_write_non_chained_methods(out, atoms, attributionDecl, moduleName); +#endif + + // Print footer + fprintf(out, "\n"); + write_closing_namespace(out, cppNamespace); + + return 0; +} + +int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#pragma once\n"); + fprintf(out, "\n"); + fprintf(out, "#include <stdint.h>\n"); + fprintf(out, "#include <vector>\n"); + fprintf(out, "#include <map>\n"); + fprintf(out, "#include <set>\n"); + fprintf(out, "\n"); + + write_namespace(out, cppNamespace); + fprintf(out, "\n"); + fprintf(out, "/*\n"); + fprintf(out, " * API For logging statistics events.\n"); + fprintf(out, " */\n"); + fprintf(out, "\n"); + + write_native_atom_constants(out, atoms, attributionDecl, moduleName); + + // Print constants for the enum values. + fprintf(out, "//\n"); + fprintf(out, "// Constants for enum values\n"); + fprintf(out, "//\n\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ENUM) { + fprintf(out, "// Values for %s.%s\n", atom->message.c_str(), + field->name.c_str()); + for (map<int, string>::const_iterator value = field->enumValues.begin(); + value != field->enumValues.end(); value++) { + fprintf(out, "const int32_t %s__%s__%s = %d;\n", + make_constant_name(atom->message).c_str(), + make_constant_name(field->name).c_str(), + make_constant_name(value->second).c_str(), + value->first); + } + fprintf(out, "\n"); + } + } + } + + fprintf(out, "struct BytesField {\n"); + fprintf(out, + " BytesField(char const* array, size_t len) : arg(array), " + "arg_length(len) {}\n"); + fprintf(out, " char const* arg;\n"); + fprintf(out, " size_t arg_length;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); + + // Print write methods + fprintf(out, "//\n"); + fprintf(out, "// Write methods\n"); + fprintf(out, "//\n"); + write_native_method_header(out, "int stats_write", atoms.signatures_to_modules, attributionDecl, + moduleName); + + fprintf(out, "//\n"); + fprintf(out, "// Write flattened methods\n"); + fprintf(out, "//\n"); + write_native_method_header(out, "int stats_write_non_chained", + atoms.non_chained_signatures_to_modules, attributionDecl, moduleName); + + fprintf(out, "\n"); + write_closing_namespace(out, cppNamespace); + + return 0; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h new file mode 100644 index 000000000000..aafa96ece2d0 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace, const string& importHeader, + const bool supportQ); + +int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/native_writer_q.cpp b/tools/stats_log_api_gen/native_writer_q.cpp new file mode 100644 index 000000000000..299873dad975 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer_q.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_writer_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +static void write_native_stats_write_body_q(FILE* out, const vector<java_type_t>& signature, + const AtomDecl& attributionDecl, const string& indent, const string& tryMethodName) { + fprintf(out, "%sint ret = 0;\n", indent.c_str()); + + fprintf(out, "%sfor(int retry = 0; retry < 2; ++retry) {\n", indent.c_str()); + fprintf(out, "%s ret = ", indent.c_str()); + write_native_method_call(out, tryMethodName, signature, attributionDecl); + fprintf(out, "%s if (ret >= 0) { break; }\n", indent.c_str()); + + fprintf(out, "%s {\n", indent.c_str()); + fprintf(out, "%s std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n", indent.c_str()); + fprintf(out, "%s if ((get_elapsed_realtime_ns() - lastRetryTimestampNs) <= " + "kMinRetryIntervalNs) break;\n", indent.c_str()); + fprintf(out, "%s lastRetryTimestampNs = get_elapsed_realtime_ns();\n", + indent.c_str()); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s std::this_thread::sleep_for(std::chrono::milliseconds(10));\n", + indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "%sif (ret < 0) {\n", indent.c_str()); + fprintf(out, "%s note_log_drop(ret, code);\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "%sreturn ret;\n", indent.c_str()); +} + +void write_native_cpp_includes_q(FILE* out) { + fprintf(out, "#include <mutex>\n"); + fprintf(out, "#include <chrono>\n"); + fprintf(out, "#include <thread>\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "#include <cutils/properties.h>\n"); + fprintf(out, "#endif\n"); + fprintf(out, "#include <stats_event_list.h>\n"); + fprintf(out, "#include <log/log.h>\n"); + fprintf(out, "#include <time.h>\n"); +} + +void write_native_get_timestamp_ns_q(FILE* out) { + fprintf(out, "\n"); + fprintf(out, "static int64_t get_elapsed_realtime_ns() {\n"); + fprintf(out, " struct timespec t;\n"); + fprintf(out, " t.tv_sec = t.tv_nsec = 0;\n"); + fprintf(out, " clock_gettime(CLOCK_BOOTTIME, &t);\n"); + fprintf(out, " return (int64_t)t.tv_sec * 1000000000LL + t.tv_nsec;\n"); + fprintf(out, "}\n"); +} + +void write_native_stats_log_cpp_globals_q(FILE* out) { + fprintf(out, "// the single event tag id for all stats logs\n"); + fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, + "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); + fprintf(out, "#else\n"); + fprintf(out, "const static bool kStatsdEnabled = false;\n"); + fprintf(out, "#endif\n"); + + fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); + fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); + fprintf(out, "static std::mutex mLogdRetryMutex;\n"); +} + +void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName) { + fprintf(out, "\n"); + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + write_native_method_signature(out, "static int try_stats_write", signature, + attributionDecl, " {"); + + int argIndex = 1; + fprintf(out, " if (kStatsdEnabled) {\n"); + fprintf(out, " stats_event_list event(kStatsEventTag);\n"); + fprintf(out, " event << get_elapsed_realtime_ns();\n\n"); + fprintf(out, " event << code;\n\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (const auto &chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, " if (%s_length != %s.size()) {\n", + attributionDecl.fields.front().name.c_str(), chainField.name.c_str()); + fprintf(out, " return -EINVAL;\n"); + fprintf(out, " }\n"); + } + } + fprintf(out, "\n event.begin();\n"); + fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n", + attributionDecl.fields.front().name.c_str()); + fprintf(out, " event.begin();\n"); + for (const auto &chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str()); + fprintf(out, " event << %s[i];\n", chainField.name.c_str()); + fprintf(out, " } else {\n"); + fprintf(out, " event << \"\";\n"); + fprintf(out, " }\n"); + } else { + fprintf(out, " event << %s[i];\n", chainField.name.c_str()); + } + } + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + fprintf(out, " event.end();\n\n"); + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, " event.begin();\n\n"); + fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " event.end();\n\n"); + } else if (*arg == JAVA_TYPE_BYTE_ARRAY) { + fprintf(out, + " event.AppendCharArray(arg%d.arg, " + "arg%d.arg_length);\n", + argIndex, argIndex); + } else { + if (*arg == JAVA_TYPE_STRING) { + fprintf(out, " if (arg%d == NULL) {\n", argIndex); + fprintf(out, " arg%d = \"\";\n", argIndex); + fprintf(out, " }\n"); + } + fprintf(out, " event << arg%d;\n", argIndex); + } + argIndex++; + } + + fprintf(out, " return event.write(LOG_ID_STATS);\n"); + fprintf(out, " } else {\n"); + fprintf(out, " return 1;\n"); + fprintf(out, " }\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + } + +} + +void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); + signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + write_native_method_signature(out, methodName, signature, attributionDecl, " {"); + + write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName); + fprintf(out, "}\n\n"); + } +} + +void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName, + const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName, + const string& tryMethodName) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + write_native_method_signature(out, methodName, signature, attributionDecl, " {"); + + write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName); + fprintf(out, "}\n\n"); + } +} + +void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + write_native_method_signature(out, "static int try_stats_write_non_chained", signature, + attributionDecl, " {"); + + int argIndex = 1; + fprintf(out, " if (kStatsdEnabled) {\n"); + fprintf(out, " stats_event_list event(kStatsEventTag);\n"); + fprintf(out, " event << get_elapsed_realtime_ns();\n\n"); + fprintf(out, " event << code;\n\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (argIndex == 1) { + fprintf(out, " event.begin();\n\n"); + fprintf(out, " event.begin();\n"); + } + if (*arg == JAVA_TYPE_STRING) { + fprintf(out, " if (arg%d == NULL) {\n", argIndex); + fprintf(out, " arg%d = \"\";\n", argIndex); + fprintf(out, " }\n"); + } + if (*arg == JAVA_TYPE_BYTE_ARRAY) { + fprintf(out, + " event.AppendCharArray(arg%d.arg, " + "arg%d.arg_length);\n", + argIndex, argIndex); + } else { + fprintf(out, " event << arg%d;\n", argIndex); + } + if (argIndex == 2) { + fprintf(out, " event.end();\n\n"); + fprintf(out, " event.end();\n\n"); + } + argIndex++; + } + + fprintf(out, " return event.write(LOG_ID_STATS);\n"); + fprintf(out, " } else {\n"); + fprintf(out, " return 1;\n"); + fprintf(out, " }\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + } +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/native_writer_q.h b/tools/stats_log_api_gen/native_writer_q.h new file mode 100644 index 000000000000..a2ab1ae5d5e2 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer_q.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +void write_native_cpp_includes_q(FILE* out); + +void write_native_stats_log_cpp_globals_q(FILE* out); + +void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName); + +void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName); + +void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName); + +void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName, + const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName, + const string& tryMethodName); + +void write_native_get_timestamp_ns_q(FILE* out); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp new file mode 100644 index 000000000000..5b830eef0603 --- /dev/null +++ b/tools/stats_log_api_gen/utils.cpp @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" + +#include "android-base/strings.h" + +namespace android { +namespace stats_log_api_gen { + +static void build_non_chained_decl_map(const Atoms& atoms, + std::map<int, set<AtomDecl>::const_iterator>* decl_map) { + for (set<AtomDecl>::const_iterator atom = atoms.non_chained_decls.begin(); + atom != atoms.non_chained_decls.end(); atom++) { + decl_map->insert(std::make_pair(atom->code, atom)); + } +} + +/** + * Turn lower and camel case into upper case with underscores. + */ +string make_constant_name(const string& str) { + string result; + const int N = str.size(); + bool underscore_next = false; + for (int i=0; i<N; i++) { + char c = str[i]; + if (c >= 'A' && c <= 'Z') { + if (underscore_next) { + result += '_'; + underscore_next = false; + } + } else if (c >= 'a' && c <= 'z') { + c = 'A' + c - 'a'; + underscore_next = true; + } else if (c == '_') { + underscore_next = false; + } + result += c; + } + return result; +} + +const char* cpp_type_name(java_type_t type) { + switch (type) { + case JAVA_TYPE_BOOLEAN: + return "bool"; + case JAVA_TYPE_INT: + case JAVA_TYPE_ENUM: + return "int32_t"; + case JAVA_TYPE_LONG: + return "int64_t"; + case JAVA_TYPE_FLOAT: + return "float"; + case JAVA_TYPE_DOUBLE: + return "double"; + case JAVA_TYPE_STRING: + return "char const*"; + case JAVA_TYPE_BYTE_ARRAY: + return "const BytesField&"; + default: + return "UNKNOWN"; + } +} + +const char* java_type_name(java_type_t type) { + switch (type) { + case JAVA_TYPE_BOOLEAN: + return "boolean"; + case JAVA_TYPE_INT: + case JAVA_TYPE_ENUM: + return "int"; + case JAVA_TYPE_LONG: + return "long"; + case JAVA_TYPE_FLOAT: + return "float"; + case JAVA_TYPE_DOUBLE: + return "double"; + case JAVA_TYPE_STRING: + return "java.lang.String"; + case JAVA_TYPE_BYTE_ARRAY: + return "byte[]"; + default: + return "UNKNOWN"; + } +} + +bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return atomDecl.hasModule && (moduleName == atomDecl.moduleName); +} + +bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return modules.find(moduleName) != modules.end(); +} + +// Native +// Writes namespaces for the cpp and header files, returning the number of namespaces written. +void write_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (string cppNamespace : cppNamespaceVec) { + fprintf(out, "namespace %s {\n", cppNamespace.c_str()); + } +} + +// Writes namespace closing brackets for cpp and header files. +void write_closing_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { + fprintf(out, "} // namespace %s\n", it->c_str()); + } +} + +static void write_cpp_usage( + FILE* out, const string& method_name, const string& atom_code_name, + const AtomDecl& atom, const AtomDecl &attributionDecl) { + fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), + atom_code_name.c_str()); + + for (vector<AtomField>::const_iterator field = atom.fields.begin(); + field != atom.fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, ", const std::vector<%s>& %s", + cpp_type_name(chainField.javaType), + chainField.name.c_str()); + } else { + fprintf(out, ", const %s* %s, size_t %s_length", + cpp_type_name(chainField.javaType), + chainField.name.c_str(), chainField.name.c_str()); + } + } + } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", const std::map<int, int32_t>& %s_int" + ", const std::map<int, int64_t>& %s_long" + ", const std::map<int, char const*>& %s_str" + ", const std::map<int, float>& %s_float", + field->name.c_str(), + field->name.c_str(), + field->name.c_str(), + field->name.c_str()); + } else { + fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str()); + } + } + fprintf(out, ");\n"); +} + +void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, + const string& moduleName) { + fprintf(out, "/**\n"); + fprintf(out, " * Constants for atom codes.\n"); + fprintf(out, " */\n"); + fprintf(out, "enum {\n"); + + std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map; + build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); + + size_t i = 0; + // Print atom constants + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + string constant = make_constant_name(atom->name); + fprintf(out, "\n"); + fprintf(out, " /**\n"); + fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); + write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); + + auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code); + if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { + write_cpp_usage(out, "stats_write_non_chained", constant, *non_chained_decl->second, + attributionDecl); + } + fprintf(out, " */\n"); + char const* const comma = (i == atoms.decls.size() - 1) ? "" : ","; + fprintf(out, " %s = %d%s\n", constant.c_str(), atom->code, comma); + i++; + } + fprintf(out, "\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); +} + +void write_native_method_signature(FILE* out, const string& methodName, + const vector<java_type_t>& signature, const AtomDecl& attributionDecl, + const string& closer) { + fprintf(out, "%s(int32_t code", methodName.c_str()); + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, ", const std::vector<%s>& %s", + cpp_type_name(chainField.javaType), + chainField.name.c_str()); + } else { + fprintf(out, ", const %s* %s, size_t %s_length", + cpp_type_name(chainField.javaType), + chainField.name.c_str(), chainField.name.c_str()); + } + } + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", const std::map<int, int32_t>& arg%d_1, " + "const std::map<int, int64_t>& arg%d_2, " + "const std::map<int, char const*>& arg%d_3, " + "const std::map<int, float>& arg%d_4", + argIndex, argIndex, argIndex, argIndex); + } else { + fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ")%s\n", closer.c_str()); +} + +void write_native_method_call(FILE* out, const string& methodName, + const vector<java_type_t>& signature, const AtomDecl& attributionDecl, int argIndex) { + fprintf(out, "%s(code", methodName.c_str()); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (auto chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, ", %s", + chainField.name.c_str()); + } else { + fprintf(out, ", %s, %s_length", + chainField.name.c_str(), chainField.name.c_str()); + } + } + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex, + argIndex, argIndex, argIndex); + } else { + fprintf(out, ", arg%d", argIndex); + } + argIndex++; + } + fprintf(out, ");\n"); +} + +// Java +void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) { + fprintf(out, " // Constants for atom codes.\n"); + + std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map; + build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); + + // Print constants for the atom codes. + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + string constant = make_constant_name(atom->name); + fprintf(out, "\n"); + fprintf(out, " /**\n"); + fprintf(out, " * %s %s<br>\n", atom->message.c_str(), atom->name.c_str()); + write_java_usage(out, "write", constant, *atom); + auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code); + if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { + write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second); + } + if (moduleName == DEFAULT_MODULE_NAME) { + fprintf(out, " * @hide\n"); + } + fprintf(out, " */\n"); + fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code); + } + fprintf(out, "\n"); +} + +void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) { + fprintf(out, " // Constants for enum values.\n\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ENUM) { + fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), + field->name.c_str()); + for (map<int, string>::const_iterator value = field->enumValues.begin(); + value != field->enumValues.end(); value++) { + if (moduleName == DEFAULT_MODULE_NAME) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static final int %s__%s__%s = %d;\n", + make_constant_name(atom->message).c_str(), + make_constant_name(field->name).c_str(), + make_constant_name(value->second).c_str(), + value->first); + } + fprintf(out, "\n"); + } + } + } +} + +void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name, + const AtomDecl& atom) { + fprintf(out, " * Usage: StatsLog.%s(StatsLog.%s", + method_name.c_str(), atom_code_name.c_str()); + for (vector<AtomField>::const_iterator field = atom.fields.begin(); + field != atom.fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { + fprintf(out, ", android.os.WorkSource workSource"); + } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, ", SparseArray<Object> value_map"); + } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) { + fprintf(out, ", byte[] %s", field->name.c_str()); + } else { + fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str()); + } + } + fprintf(out, ");<br>\n"); +} + +int write_java_non_chained_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName + ) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static void write_non_chained(int code"); + vector<java_type_t> signature = signature_to_modules_it->first; + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + // Non chained signatures should not have attribution chains. + return 1; + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + // Module logging does not yet support key value pair. + return 1; + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ") {\n"); + + fprintf(out, " write(code"); + argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + // First two args are uid and tag of attribution chain. + if (argIndex == 1) { + fprintf(out, ", new int[] {arg%d}", argIndex); + } else if (argIndex == 2) { + fprintf(out, ", new java.lang.String[] {arg%d}", argIndex); + } else { + fprintf(out, ", arg%d", argIndex); + } + argIndex++; + } + fprintf(out, ");\n"); + fprintf(out, " }\n"); + fprintf(out, "\n"); + } + return 0; +} + +int write_java_work_source_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName + ) { + fprintf(out, " // WorkSource methods.\n"); + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + // Determine if there is Attribution in this signature. + int attributionArg = -1; + int argIndexMax = 0; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + argIndexMax++; + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + if (attributionArg > -1) { + fprintf(stderr, "An atom contains multiple AttributionNode fields.\n"); + fprintf(stderr, "This is not supported. Aborting WorkSource method writing.\n"); + fprintf(out, "\n// Invalid for WorkSource: more than one attribution chain.\n"); + return 1; + } + attributionArg = argIndexMax; + } + } + if (attributionArg < 0) { + continue; + } + + fprintf(out, "\n"); + // Method header (signature) + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static void write(int code"); + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + fprintf(out, ", WorkSource ws"); + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ") {\n"); + + // write_non_chained() component. TODO: Remove when flat uids are no longer needed. + fprintf(out, " for (int i = 0; i < ws.size(); ++i) {\n"); + fprintf(out, " write_non_chained(code"); + for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { + if (argIndex == attributionArg) { + fprintf(out, ", ws.get(i), ws.getName(i)"); + } else { + fprintf(out, ", arg%d", argIndex); + } + } + fprintf(out, ");\n"); + fprintf(out, " }\n"); // close for-loop + + // write() component. + fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n"); + fprintf(out, " if (workChains != null) {\n"); + fprintf(out, " for (WorkSource.WorkChain wc : workChains) {\n"); + fprintf(out, " write(code"); + for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { + if (argIndex == attributionArg) { + fprintf(out, ", wc.getUids(), wc.getTags()"); + } else { + fprintf(out, ", arg%d", argIndex); + } + } + fprintf(out, ");\n"); + fprintf(out, " }\n"); // close for-loop + fprintf(out, " }\n"); // close if + fprintf(out, " }\n"); // close method + } + return 0; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h new file mode 100644 index 000000000000..50737a68bf89 --- /dev/null +++ b/tools/stats_log_api_gen/utils.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +const string DEFAULT_MODULE_NAME = "DEFAULT"; +const string DEFAULT_CPP_NAMESPACE = "android,util"; +const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; +const string DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT = "atoms_info.h"; +const string DEFAULT_JAVA_PACKAGE = "android.util"; +const string DEFAULT_JAVA_CLASS = "StatsLogInternal"; + +const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; +const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; + +string make_constant_name(const string& str); + +const char* cpp_type_name(java_type_t type); + +const char* java_type_name(java_type_t type); + +bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName); + +bool signature_needed_for_module(const set<string>& modules, const string& moduleName); + +// Common Native helpers +void write_namespace(FILE* out, const string& cppNamespaces); + +void write_closing_namespace(FILE* out, const string& cppNamespaces); + +void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, + const string& moduleName); + +void write_native_method_signature(FILE* out, const string& methodName, + const vector<java_type_t>& signature, const AtomDecl& attributionDecl, + const string& closer); + +void write_native_method_call(FILE* out, const string& methodName, + const vector<java_type_t>& signature, const AtomDecl& attributionDecl, int argIndex = 1); + +// Common Java helpers. +void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName); + +void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName); + +void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name, + const AtomDecl& atom); + +int write_java_non_chained_methods(FILE* out, const map<vector<java_type_t>, + set<string>>& signatures_to_modules, + const string& moduleName); + +int write_java_work_source_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName); + +} // namespace stats_log_api_gen +} // namespace android |