summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp233
-rw-r--r--api/current.txt7
-rw-r--r--api/system-current.txt6
-rw-r--r--api/test-current.txt12
-rw-r--r--cmds/statsd/Android.bp8
-rw-r--r--cmds/statsd/src/condition/CombinationConditionTracker.cpp29
-rw-r--r--cmds/statsd/src/condition/CombinationConditionTracker.h11
-rw-r--r--cmds/statsd/src/condition/ConditionTracker.h17
-rw-r--r--cmds/statsd/src/condition/ConditionWizard.cpp20
-rw-r--r--cmds/statsd/src/condition/ConditionWizard.h10
-rw-r--r--cmds/statsd/src/condition/SimpleConditionTracker.cpp77
-rw-r--r--cmds/statsd/src/condition/SimpleConditionTracker.h11
-rw-r--r--cmds/statsd/src/condition/StateTracker.cpp27
-rw-r--r--cmds/statsd/src/condition/StateTracker.h18
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.cpp17
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp235
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp16
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.cpp22
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h6
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h11
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp16
-rw-r--r--cmds/statsd/src/metrics/duration_helper/DurationTracker.h6
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp22
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp30
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h2
-rw-r--r--cmds/statsd/src/stats_log.proto22
-rw-r--r--cmds/statsd/src/statsd_config.proto8
-rw-r--r--cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp55
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp961
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp816
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp814
-rw-r--r--cmds/statsd/tests/metrics/CountMetricProducer_test.cpp4
-rw-r--r--cmds/statsd/tests/metrics/EventMetricProducer_test.cpp4
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp15
-rw-r--r--cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp26
-rw-r--r--cmds/statsd/tests/metrics/OringDurationTracker_test.cpp45
-rw-r--r--cmds/statsd/tests/metrics/metrics_test_helper.h8
-rw-r--r--core/java/android/app/AppOpsManager.java97
-rw-r--r--core/java/android/app/LoadedApk.java6
-rw-r--r--core/java/android/content/pm/UserInfo.java8
-rw-r--r--core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java22
-rw-r--r--core/java/android/service/textclassifier/TextClassifierService.java18
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java1
-rw-r--r--core/jni/AndroidRuntime.cpp28
-rw-r--r--core/jni/fd_utils.cpp6
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--location/lib/Android.bp1
-rw-r--r--media/lib/signer/Android.bp1
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hy/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SoundPicker/res/layout-watch/radio_with_work_badge.xml4
-rw-r--r--packages/SoundPicker/res/layout/radio_with_work_badge.xml4
-rw-r--r--packages/SoundPicker/src/com/android/soundpicker/CheckedListItem.java67
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java36
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java30
-rw-r--r--packages/services/PacProcessor/Android.bp6
-rw-r--r--packages/services/PacProcessor/src/com/android/net/IProxyService.aidl (renamed from packages/services/PacProcessor/com/android/net/IProxyService.aidl)0
-rw-r--r--packages/services/Proxy/Android.bp6
-rw-r--r--packages/services/Proxy/src/com/android/net/IProxyCallback.aidl (renamed from packages/services/Proxy/com/android/net/IProxyCallback.aidl)0
-rw-r--r--packages/services/Proxy/src/com/android/net/IProxyPortListener.aidl (renamed from packages/services/Proxy/com/android/net/IProxyPortListener.aidl)0
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java8
-rw-r--r--services/core/java/com/android/server/SystemService.java53
-rw-r--r--services/core/java/com/android/server/SystemServiceManager.java88
-rw-r--r--services/core/java/com/android/server/am/UserController.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java4
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java16
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java4
-rw-r--r--services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java86
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java12
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java10
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java49
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/ByteStream.java7
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java10
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java39
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java5
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java103
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java70
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java7
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java3
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java3
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbVCEndpoint.java61
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbVCInterface.java112
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java7
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/tree/UsbDescriptorsTree.java8
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java89
-rw-r--r--telephony/java/android/provider/Telephony.java47
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java8
-rw-r--r--telephony/java/com/android/internal/telephony/CbGeoUtils.java359
-rw-r--r--test-mock/Android.bp1
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java416
102 files changed, 2035 insertions, 3694 deletions
diff --git a/Android.bp b/Android.bp
index b2ed0de2f2e9..af2f112bb6ae 100644
--- a/Android.bp
+++ b/Android.bp
@@ -26,47 +26,164 @@
// READ ME: ########################################################
filegroup {
- name: "framework-defaults-java-srcs",
+ name: "framework-core-sources",
srcs: [
- // java sources under this directory
"core/java/**/*.java",
+ "core/java/**/*.aidl",
+ ],
+ path: "core/java",
+}
+
+filegroup {
+ name: "framework-drm-sources",
+ srcs: [
"drm/java/**/*.java",
+ ],
+ path: "drm/java",
+}
+
+filegroup {
+ name: "framework-graphics-sources",
+ srcs: [
"graphics/java/**/*.java",
+ "graphics/java/**/*.aidl",
+ ],
+ path: "graphics/java",
+}
+
+filegroup {
+ name: "framework-keystore-sources",
+ srcs: [
"keystore/java/**/*.java",
+ "keystore/java/**/*.aidl",
+ ],
+ path: "keystore/java",
+}
+
+filegroup {
+ name: "framework-location-sources",
+ srcs: [
"location/java/**/*.java",
+ "location/java/**/*.aidl",
+ ],
+ path: "location/java",
+}
+
+filegroup {
+ name: "framework-lowpan-sources",
+ srcs: [
"lowpan/java/**/*.java",
+ "lowpan/java/**/*.aidl",
+ ],
+ path: "lowpan/java",
+}
+
+filegroup {
+ name: "framework-media-sources",
+ srcs: [
"media/java/**/*.java",
+ "media/java/**/*.aidl",
+ ],
+ path: "media/java",
+}
+
+filegroup {
+ name: "framework-mca-effect-sources",
+ srcs: [
"media/mca/effect/java/**/*.java",
+ ],
+ path: "media/mca/effect/java",
+}
+
+filegroup {
+ name: "framework-mca-filterfw-sources",
+ srcs: [
"media/mca/filterfw/java/**/*.java",
+ ],
+ path: "media/mca/filterfw/java",
+}
+
+filegroup {
+ name: "framework-mca-filterpacks-sources",
+ srcs: [
"media/mca/filterpacks/java/**/*.java",
+ ],
+ path: "media/mca/filterpacks/java",
+}
+
+filegroup {
+ name: "framework-opengl-sources",
+ srcs: [
"opengl/java/**/*.java",
+ ],
+ path: "opengl/java",
+}
+
+filegroup {
+ name: "framework-rs-sources",
+ srcs: [
"rs/java/**/*.java",
+ ],
+ path: "rs/java",
+}
+
+filegroup {
+ name: "framework-sax-sources",
+ srcs: [
"sax/java/**/*.java",
+ ],
+ path: "sax/java",
+}
+
+filegroup {
+ name: "framework-telecomm-sources",
+ srcs: [
"telecomm/java/**/*.java",
+ "telecomm/java/**/*.aidl",
+ ],
+ path: "telecomm/java",
+}
+
+filegroup {
+ name: "framework-telephony-sources",
+ srcs: [
"telephony/java/**/*.java",
+ "telephony/java/**/*.aidl",
+ ],
+ path: "telephony/java",
+}
+
+filegroup {
+ name: "framework-wifi-sources",
+ srcs: [
"wifi/java/**/*.java",
+ "wifi/java/**/*.aidl",
],
+ path: "wifi/java",
}
-// TODO(b/70046217): make these as filegroups where the base directory for aidl files
-// is given as 'path'. Eliminate the need for aidl_local_include_dirs.
framework_srcs = [
- // aidl under this directory
- // b/70046217#comment15 These MUST come after all java srcs.
- // TODO(b/70046217) remove the above requirement
- "core/java/**/*.aidl",
- "graphics/java/**/*.aidl",
- "keystore/java/**/*.aidl",
- "location/java/**/*.aidl",
- "lowpan/java/**/*.aidl",
- "media/java/**/*.aidl",
- "packages/services/PacProcessor/**/*.aidl",
- "packages/services/Proxy/**/*.aidl",
- "telecomm/java/**/*.aidl",
- "telephony/java/**/*.aidl",
- "wifi/java/**/*.aidl",
-
- // aidl from external directories
+ // Java/AIDL sources under frameworks/base
+ ":framework-core-sources",
+ ":framework-drm-sources",
+ ":framework-graphics-sources",
+ ":framework-keystore-sources",
+ ":framework-location-sources",
+ ":framework-lowpan-sources",
+ ":framework-media-sources",
+ ":framework-mca-effect-sources",
+ ":framework-mca-filterfw-sources",
+ ":framework-mca-filterpacks-sources",
+ ":framework-opengl-sources",
+ ":framework-rs-sources",
+ ":framework-sax-sources",
+ ":framework-telecomm-sources",
+ ":framework-telephony-sources",
+ ":framework-wifi-sources",
+ ":PacProcessor-aidl-sources",
+ ":ProxyHandler-aidl-sources",
+
+ // AIDL sources from external directories
":dumpstate_aidl",
":gatekeeper_aidl",
":gsiservice_aidl",
@@ -88,47 +205,28 @@ framework_srcs = [
":framework-statslog-gen",
]
-framework_aidl_local_include_dirs = [
- "core/java",
- "drm/java",
- "graphics/java",
- "keystore/java",
- "location/java",
- "lowpan/java",
- "media/java",
- "media/apex/java",
- "media/mca/effect/java",
- "media/mca/filterfw/java",
- "media/mca/filterpacks/java",
- "opengl/java",
- "rs/java",
- "sax/java",
- "telecomm/java",
- "telephony/java",
- "wifi/java",
-]
-
-framework_aidl_external_include_dirs = [
- "frameworks/av/camera/aidl",
- "frameworks/av/media/libaudioclient/aidl",
- "frameworks/native/aidl/binder",
- "frameworks/native/aidl/gui",
- "frameworks/native/cmds/dumpstate/binder",
- "frameworks/native/libs/incidentcompanion/binder",
- "system/bt/binder",
- "system/core/gatekeeperd/binder",
- "system/core/storaged/binder",
- "system/gsid/aidl",
- "system/security/keystore/binder",
- "system/update_engine/binder_bindings",
- "system/vold/binder",
-]
-
java_defaults {
name: "framework-aidl-export-defaults",
-
aidl: {
- export_include_dirs: framework_aidl_local_include_dirs,
+ export_include_dirs: [
+ "core/java",
+ "drm/java",
+ "graphics/java",
+ "keystore/java",
+ "location/java",
+ "lowpan/java",
+ "media/java",
+ "media/apex/java",
+ "media/mca/effect/java",
+ "media/mca/filterfw/java",
+ "media/mca/filterpacks/java",
+ "opengl/java",
+ "rs/java",
+ "sax/java",
+ "telecomm/java",
+ "telephony/java",
+ "wifi/java",
+ ],
},
}
@@ -137,13 +235,15 @@ java_defaults {
defaults: ["framework-aidl-export-defaults"],
installable: true,
- srcs: [
- ":framework-defaults-java-srcs",
- ] + framework_srcs,
+ srcs: framework_srcs,
aidl: {
- local_include_dirs: framework_aidl_local_include_dirs,
- include_dirs: framework_aidl_external_include_dirs,
+ // TODO(b/70046217) remove this by moving the AIDL files into frameworks/base
+ // so that they are referenced via framework-core-sources
+ include_dirs: [
+ "frameworks/native/aidl/binder",
+ "frameworks/native/aidl/gui",
+ ],
generate_get_transaction_name: true,
},
@@ -793,7 +893,6 @@ stubs_defaults {
":jobscheduler-framework-source",
],
srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_dirs: frameworks_base_subdirs,
srcs_lib_whitelist_pkgs: packages_to_document,
libs: framework_docs_only_libs,
local_sourcepaths: frameworks_base_subdirs,
@@ -851,7 +950,6 @@ stubs_defaults {
":jobscheduler-framework-source",
],
srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_dirs: frameworks_base_subdirs,
srcs_lib_whitelist_pkgs: packages_to_document,
local_sourcepaths: frameworks_base_subdirs,
installable: false,
@@ -1172,8 +1270,7 @@ droidstubs {
droidstubs {
name: "hiddenapi-mappings",
defaults: ["metalava-api-stubs-default"],
- srcs: [
- ":framework-defaults-java-srcs",
+ srcs: framework_srcs + [
":non_openjdk_java_files",
":openjdk_java_files",
":opt-telephony-common-srcs",
@@ -1313,8 +1410,6 @@ filegroup {
aidl_mapping {
name: "framework-aidl-mappings",
srcs: framework_srcs,
- local_include_dirs: framework_aidl_local_include_dirs,
- include_dirs: framework_aidl_external_include_dirs,
output: "framework-aidl-mappings.txt",
}
diff --git a/api/current.txt b/api/current.txt
index 652f23f4e75d..c68120d68557 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4278,6 +4278,7 @@ package android.app {
method @Deprecated public int checkOpNoThrow(@NonNull String, int, @NonNull String);
method public void checkPackage(int, @NonNull String);
method public void finishOp(@NonNull String, int, @NonNull String);
+ method public boolean isOpActive(@NonNull String, int, @NonNull String);
method public int noteOp(@NonNull String, int, @NonNull String);
method public int noteOpNoThrow(@NonNull String, int, @NonNull String);
method public int noteProxyOp(@NonNull String, @NonNull String);
@@ -4286,8 +4287,10 @@ package android.app {
method public static String permissionToOp(String);
method public int startOp(@NonNull String, int, @NonNull String);
method public int startOpNoThrow(@NonNull String, int, @NonNull String);
+ method public void startWatchingActive(@NonNull String[], @NonNull java.util.concurrent.Executor, @NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
method public void startWatchingMode(@NonNull String, @Nullable String, @NonNull android.app.AppOpsManager.OnOpChangedListener);
method public void startWatchingMode(@NonNull String, @Nullable String, int, @NonNull android.app.AppOpsManager.OnOpChangedListener);
+ method public void stopWatchingActive(@NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
method public void stopWatchingMode(@NonNull android.app.AppOpsManager.OnOpChangedListener);
method public int unsafeCheckOp(@NonNull String, int, @NonNull String);
method public int unsafeCheckOpNoThrow(@NonNull String, int, @NonNull String);
@@ -4335,6 +4338,10 @@ package android.app {
field public static final int WATCH_FOREGROUND_CHANGES = 1; // 0x1
}
+ public static interface AppOpsManager.OnOpActiveChangedListener {
+ method public void onOpActiveChanged(@NonNull String, int, @NonNull String, boolean);
+ }
+
public static interface AppOpsManager.OnOpChangedListener {
method public void onOpChanged(String, String);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index ed2616a5e744..86e5f2e31a43 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -353,6 +353,9 @@ package android.app {
field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
+ field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
+ field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
+ field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
@@ -368,6 +371,9 @@ package android.app {
field public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
field public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
+ field public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
+ field public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
+ field public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
field public static final String OPSTR_WRITE_SMS = "android:write_sms";
field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
field public static final int OP_FLAGS_ALL = 31; // 0x1f
diff --git a/api/test-current.txt b/api/test-current.txt
index 1b2c59d87069..ec3cb0681e84 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -160,8 +160,6 @@ package android.app {
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(int, int, String, int);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(String, int, int);
- method public void startWatchingActive(@NonNull int[], @NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
- method public void stopWatchingActive(@NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
method public static int strOpToOp(@NonNull String);
field public static final int HISTORICAL_MODE_DISABLED = 0; // 0x0
field public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; // 0x1
@@ -193,6 +191,9 @@ package android.app {
field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
+ field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
+ field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
+ field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
@@ -208,6 +209,9 @@ package android.app {
field public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
field public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
+ field public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
+ field public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
+ field public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
field public static final String OPSTR_WRITE_SMS = "android:write_sms";
field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
field public static final int OP_COARSE_LOCATION = 0; // 0x0
@@ -293,10 +297,6 @@ package android.app {
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
}
- public static interface AppOpsManager.OnOpActiveChangedListener {
- method public void onOpActiveChanged(int, int, String, boolean);
- }
-
public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
method public int describeContents();
method public long getDuration();
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 6df0a8e14f6a..19fa64073183 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -129,17 +129,12 @@ cc_defaults {
"libservices",
"libprotoutil",
"libstatslog",
- "libhardware",
- "libhardware_legacy",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"android.frameworks.stats@1.0",
"android.hardware.health@2.0",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
"android.hardware.power.stats@1.0",
- "libpackagelistparser",
"libsysutils",
"libcutils",
],
@@ -253,9 +248,6 @@ cc_test {
"tests/e2e/GaugeMetric_e2e_push_test.cpp",
"tests/e2e/GaugeMetric_e2e_pull_test.cpp",
"tests/e2e/ValueMetric_pull_e2e_test.cpp",
- "tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp",
- "tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp",
- "tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp",
"tests/e2e/Anomaly_count_e2e_test.cpp",
"tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
"tests/e2e/ConfigTtl_e2e_test.cpp",
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index 60a4b236df11..52a1269798ca 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -110,20 +110,14 @@ bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConf
void CombinationConditionTracker::isConditionMet(
const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const std::vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
+ vector<ConditionState>& conditionCache) const {
// So far, this is fine as there is at most one child having sliced output.
for (const int childIndex : mChildren) {
if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
allConditions[childIndex]->isConditionMet(conditionParameters, allConditions,
- dimensionFields,
- isSubOutputDimensionFields,
isPartialLink,
- conditionCache,
- dimensionsKeySet);
+ conditionCache);
}
}
conditionCache[mIndex] =
@@ -178,25 +172,6 @@ void CombinationConditionTracker::evaluateCondition(
}
}
-ConditionState CombinationConditionTracker::getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const std::vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
- vector<ConditionState> conditionCache(allConditions.size(), ConditionState::kNotEvaluated);
- // So far, this is fine as there is at most one child having sliced output.
- for (const int childIndex : mChildren) {
- conditionCache[childIndex] = conditionCache[childIndex] |
- allConditions[childIndex]->getMetConditionDimension(
- allConditions, dimensionFields, isSubOutputDimensionFields, dimensionsKeySet);
- }
- evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
- if (conditionCache[mIndex] == ConditionState::kTrue && dimensionsKeySet.empty()) {
- dimensionsKeySet.insert(DEFAULT_DIMENSION_KEY);
- }
- return conditionCache[mIndex];
-}
-
bool CombinationConditionTracker::equalOutputDimensions(
const std::vector<sp<ConditionTracker>>& allConditions,
const vector<Matcher>& dimensions) const {
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
index 481cb200d8e6..e3d860127780 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -43,17 +43,8 @@ public:
void isConditionMet(const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
-
- ConditionState getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
+ std::vector<ConditionState>& conditionCache) const override;
// Only one child predicate can have dimension.
const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
index 1f4266b61cdf..e94ea6586f05 100644
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -84,29 +84,14 @@ public:
// condition.
// [allConditions]: all condition trackers. This is needed because the condition evaluation is
// done recursively
- // [dimensionFields]: the needed dimension fields which should be all or subset of the condition
- // tracker output dimension.
- // [isSubOutputDimensionFields]: true if the needed dimension fields which is strictly subset of
- // the condition tracker output dimension.
// [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
// in the condition tracker output dimension.
// [conditionCache]: the cache holding the condition evaluation values.
- // [dimensionsKeySet]: the dimensions where the sliced condition is true. For combination
- // condition, it assumes that only one child predicate is sliced.
virtual void isConditionMet(
const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0;
-
- virtual ConditionState getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0;
+ std::vector<ConditionState>& conditionCache) const = 0;
// return the list of LogMatchingTracker index that this ConditionTracker uses.
virtual const std::set<int>& getLogTrackerIndex() const {
diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp
index 23a9d371145e..4f44a69ba980 100644
--- a/cmds/statsd/src/condition/ConditionWizard.cpp
+++ b/cmds/statsd/src/condition/ConditionWizard.cpp
@@ -25,27 +25,15 @@ using std::string;
using std::vector;
ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- const bool isPartialLink,
- std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
+ const bool isPartialLink) {
vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated);
mAllConditions[index]->isConditionMet(
- parameters, mAllConditions, dimensionFields, isSubOutputDimensionFields, isPartialLink,
- cache, *dimensionKeySet);
+ parameters, mAllConditions, isPartialLink,
+ cache);
return cache[index];
}
-ConditionState ConditionWizard::getMetConditionDimension(
- const int index, const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const {
- return mAllConditions[index]->getMetConditionDimension(mAllConditions, dimensionFields,
- isSubOutputDimensionFields,
- *dimensionsKeySet);
-}
-
const set<HashableDimensionKey>* ConditionWizard::getChangedToTrueDimensions(
const int index) const {
return mAllConditions[index]->getChangedToTrueDimensions(mAllConditions);
@@ -82,4 +70,4 @@ bool ConditionWizard::equalOutputDimensions(const int index, const vector<Matche
} // namespace statsd
} // namespace os
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
index 2c8814772839..892647910d9f 100644
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ b/cmds/statsd/src/condition/ConditionWizard.h
@@ -40,15 +40,7 @@ public:
// The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case,
// the conditionParameters contains the parameters for it's children SimpleConditionTrackers.
virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- const bool isPartialLink,
- std::unordered_set<HashableDimensionKey>* dimensionKeySet);
-
- virtual ConditionState getMetConditionDimension(
- const int index, const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const;
+ const bool isPartialLink);
virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(const int index) const;
virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 87104a34c009..0c92149f4c96 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -344,11 +344,8 @@ void SimpleConditionTracker::evaluateCondition(
void SimpleConditionTracker::isConditionMet(
const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
+ vector<ConditionState>& conditionCache) const {
if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
// it has been evaluated.
@@ -360,18 +357,13 @@ void SimpleConditionTracker::isConditionMet(
if (pair == conditionParameters.end()) {
ConditionState conditionState = ConditionState::kNotEvaluated;
- if (dimensionFields.size() > 0 && dimensionFields[0].mMatcher.getTag() == mDimensionTag) {
- conditionState = conditionState | getMetConditionDimension(
- allConditions, dimensionFields, isSubOutputDimensionFields, dimensionsKeySet);
- } else {
- conditionState = conditionState | mInitialValue;
- if (!mSliced) {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr != mSlicedConditionState.end()) {
- ConditionState sliceState =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
+ conditionState = conditionState | mInitialValue;
+ if (!mSliced) {
+ const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
+ if (itr != mSlicedConditionState.end()) {
+ ConditionState sliceState =
+ itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
+ conditionState = conditionState | sliceState;
}
}
conditionCache[mIndex] = conditionState;
@@ -389,15 +381,6 @@ void SimpleConditionTracker::isConditionMet(
slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
if (slice.first.contains(key)) {
conditionState = conditionState | sliceState;
- if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
- if (isSubOutputDimensionFields) {
- HashableDimensionKey dimensionKey;
- filterValues(dimensionFields, slice.first.getValues(), &dimensionKey);
- dimensionsKeySet.insert(dimensionKey);
- } else {
- dimensionsKeySet.insert(slice.first);
- }
- }
}
}
} else {
@@ -407,15 +390,6 @@ void SimpleConditionTracker::isConditionMet(
ConditionState sliceState =
startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
conditionState = conditionState | sliceState;
- if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
- if (isSubOutputDimensionFields) {
- HashableDimensionKey dimensionKey;
- filterValues(dimensionFields, startedCountIt->first.getValues(), &dimensionKey);
- dimensionsKeySet.insert(dimensionKey);
- } else {
- dimensionsKeySet.insert(startedCountIt->first);
- }
- }
}
}
@@ -423,41 +397,6 @@ void SimpleConditionTracker::isConditionMet(
VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
}
-ConditionState SimpleConditionTracker::getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
- ConditionState conditionState = mInitialValue;
- if (dimensionFields.size() == 0 || mOutputDimensions.size() == 0 ||
- dimensionFields[0].mMatcher.getTag() != mOutputDimensions[0].mMatcher.getTag()) {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr != mSlicedConditionState.end()) {
- ConditionState sliceState =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
- return conditionState;
- }
-
- for (const auto& slice : mSlicedConditionState) {
- ConditionState sliceState =
- slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
-
- if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
- if (isSubOutputDimensionFields) {
- HashableDimensionKey dimensionKey;
- filterValues(dimensionFields, slice.first.getValues(), &dimensionKey);
- dimensionsKeySet.insert(dimensionKey);
- } else {
- dimensionsKeySet.insert(slice.first);
- }
- }
- }
- return conditionState;
-}
-
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
index 47d1eceb9022..5c5cc565f783 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -48,17 +48,8 @@ public:
void isConditionMet(const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
-
- ConditionState getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
+ std::vector<ConditionState>& conditionCache) const override;
virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
const std::vector<sp<ConditionTracker>>& allConditions) const {
diff --git a/cmds/statsd/src/condition/StateTracker.cpp b/cmds/statsd/src/condition/StateTracker.cpp
index 1965ce6015ff..18c7178dd7d7 100644
--- a/cmds/statsd/src/condition/StateTracker.cpp
+++ b/cmds/statsd/src/condition/StateTracker.cpp
@@ -178,11 +178,8 @@ void StateTracker::evaluateCondition(const LogEvent& event,
void StateTracker::isConditionMet(
const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
+ vector<ConditionState>& conditionCache) const {
if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
// it has been evaluated.
VLOG("Yes, already evaluated, %lld %d", (long long)mConditionId, conditionCache[mIndex]);
@@ -193,10 +190,6 @@ void StateTracker::isConditionMet(
if (pair == conditionParameters.end()) {
if (mSlicedState.size() > 0) {
conditionCache[mIndex] = ConditionState::kTrue;
-
- for (const auto& state : mSlicedState) {
- dimensionsKeySet.insert(state.second);
- }
} else {
conditionCache[mIndex] = ConditionState::kUnknown;
}
@@ -208,25 +201,9 @@ void StateTracker::isConditionMet(
auto it = mSlicedState.find(primaryKey);
if (it != mSlicedState.end()) {
conditionCache[mIndex] = ConditionState::kTrue;
- dimensionsKeySet.insert(it->second);
- }
-}
-
-ConditionState StateTracker::getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
- if (mSlicedState.size() > 0) {
- for (const auto& state : mSlicedState) {
- dimensionsKeySet.insert(state.second);
- }
- return ConditionState::kTrue;
}
-
- return mInitialValue;
}
} // namespace statsd
} // namespace os
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/condition/StateTracker.h b/cmds/statsd/src/condition/StateTracker.h
index 2bdf98c34c32..5ae4441713cd 100644
--- a/cmds/statsd/src/condition/StateTracker.h
+++ b/cmds/statsd/src/condition/StateTracker.h
@@ -55,22 +55,8 @@ public:
*/
void isConditionMet(const ConditionKey& conditionParameters,
const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
const bool isPartialLink,
- std::vector<ConditionState>& conditionCache,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
-
- /**
- * Note: dimensionFields will be ignored in StateTracker, because we demand metrics
- * must take the entire dimension fields from StateTracker. This is to make implementation
- * simple and efficient.
- */
- ConditionState getMetConditionDimension(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensionFields,
- const bool isSubOutputDimensionFields,
- std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
+ std::vector<ConditionState>& conditionCache) const override;
virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
const std::vector<sp<ConditionTracker>>& allConditions) const {
@@ -128,4 +114,4 @@ private:
} // namespace statsd
} // namespace os
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index c023e6f77e7c..23d025f82c26 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -48,7 +48,6 @@ const int FIELD_ID_COUNT_METRICS = 5;
const int FIELD_ID_TIME_BASE = 9;
const int FIELD_ID_BUCKET_SIZE = 10;
const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12;
const int FIELD_ID_IS_ACTIVE = 14;
// for CountMetricDataWrapper
@@ -82,12 +81,7 @@ CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric
mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
}
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
- HasPositionALL(metric.dimensions_in_condition());
-
- if (metric.has_dimensions_in_condition()) {
- translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
- }
+ mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
if (metric.links().size() > 0) {
for (const auto& link : metric.links()) {
@@ -100,8 +94,6 @@ CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric
mConditionSliced = true;
}
- mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
-
flushIfNeededLocked(startTimeNs);
// Adjust start for partial bucket
mCurrentBucketStartTimeNs = startTimeNs;
@@ -171,13 +163,6 @@ void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
protoOutput->end(dimenPathToken);
}
- if (!mDimensionsInCondition.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
- writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
- protoOutput->end(dimenPathToken);
- }
-
}
uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 96fbf7fb5ebe..cca793b2146a 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -47,7 +47,6 @@ const int FIELD_ID_DURATION_METRICS = 6;
const int FIELD_ID_TIME_BASE = 9;
const int FIELD_ID_BUCKET_SIZE = 10;
const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12;
const int FIELD_ID_IS_ACTIVE = 14;
// for DurationMetricDataWrapper
const int FIELD_ID_DATA = 1;
@@ -100,12 +99,7 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat
ALOGE("Position ANY in dimension_in_what not supported.");
}
- if (metric.has_dimensions_in_condition()) {
- translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
- }
-
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
- HasPositionALL(metric.dimensions_in_condition());
+ mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
if (metric.links().size() > 0) {
for (const auto& link : metric.links()) {
@@ -115,19 +109,16 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat
translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
mMetric2ConditionLinks.push_back(mc);
}
+ mConditionSliced = true;
}
- mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
mUnSlicedPartCondition = ConditionState::kUnknown;
mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions);
- if (mWizard != nullptr && mConditionTrackerIndex >= 0) {
- mSameConditionDimensionsInTracker =
- mWizard->equalOutputDimensions(mConditionTrackerIndex, mDimensionsInCondition);
- if (mMetric2ConditionLinks.size() == 1) {
- mHasLinksToAllConditionDimensionsInTracker =
- mWizard->equalOutputDimensions(mConditionTrackerIndex,
- mMetric2ConditionLinks.begin()->conditionFields);
- }
+ if (mWizard != nullptr && mConditionTrackerIndex >= 0 &&
+ mMetric2ConditionLinks.size() == 1) {
+ mHasLinksToAllConditionDimensionsInTracker =
+ mWizard->equalOutputDimensions(mConditionTrackerIndex,
+ mMetric2ConditionLinks.begin()->conditionFields);
}
flushIfNeededLocked(startTimeNs);
// Adjust start for partial bucket
@@ -164,13 +155,13 @@ unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
case DurationMetric_AggregationType_SUM:
return make_unique<OringDurationTracker>(
mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex,
- mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
+ mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
mTimeBaseNs, mBucketSizeNs, mConditionSliced,
mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
case DurationMetric_AggregationType_MAX_SPARSE:
return make_unique<MaxDurationTracker>(
mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex,
- mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
+ mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
mTimeBaseNs, mBucketSizeNs, mConditionSliced,
mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
}
@@ -178,13 +169,11 @@ unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
// SlicedConditionChange optimization case 1:
// 1. If combination condition, logical operation is AND, only one sliced child predicate.
-// 2. No condition in dimension
-// 3. The links covers all dimension fields in the sliced child condition predicate.
+// 2. The links covers all dimension fields in the sliced child condition predicate.
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
const int64_t eventTime) {
if (mMetric2ConditionLinks.size() != 1 ||
- !mHasLinksToAllConditionDimensionsInTracker ||
- !mDimensionsInCondition.empty()) {
+ !mHasLinksToAllConditionDimensionsInTracker) {
return;
}
@@ -249,178 +238,20 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool conditio
}
}
-
-// SlicedConditionChange optimization case 2:
-// 1. If combination condition, logical operation is AND, only one sliced child predicate.
-// 2. Has dimensions_in_condition and it equals to the output dimensions of the sliced predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool condition,
- const int64_t eventTime) {
- if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) {
- return;
- }
-
- auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
- auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
-
- bool currentUnSlicedPartCondition = true;
- if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
- ConditionState unslicedPartState =
- mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
- // When the unsliced part is still false, return directly.
- if (mUnSlicedPartCondition == ConditionState::kFalse &&
- unslicedPartState == ConditionState::kFalse) {
- return;
- }
- mUnSlicedPartCondition = unslicedPartState;
- currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
- }
-
- const std::set<HashableDimensionKey>* trueDimensionsToProcess = nullptr;
- const std::set<HashableDimensionKey>* falseDimensionsToProcess = nullptr;
-
- std::set<HashableDimensionKey> currentTrueConditionDimensions;
- if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
- (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
- mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &currentTrueConditionDimensions);
- trueDimensionsToProcess = &currentTrueConditionDimensions;
- } else if (currentUnSlicedPartCondition) {
- // Handles the condition change from the sliced predicate. If the unsliced condition state
- // is not true, not need to do anything.
- trueDimensionsToProcess = dimensionsChangedToTrue;
- falseDimensionsToProcess = dimensionsChangedToFalse;
- }
-
- if (trueDimensionsToProcess == nullptr && falseDimensionsToProcess == nullptr) {
- return;
- }
-
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- if (falseDimensionsToProcess != nullptr) {
- for (const auto& changedDim : *falseDimensionsToProcess) {
- auto condIt = whatIt.second.find(changedDim);
- if (condIt != whatIt.second.end()) {
- condIt->second->onConditionChanged(false, eventTime);
- }
- }
- }
- if (trueDimensionsToProcess != nullptr) {
- HashableDimensionKey linkedConditionDimensionKey;
- if (!trueDimensionsToProcess->empty() && mMetric2ConditionLinks.size() == 1) {
- getDimensionForCondition(whatIt.first.getValues(),
- mMetric2ConditionLinks[0],
- &linkedConditionDimensionKey);
- }
- for (auto& trueDim : *trueDimensionsToProcess) {
- auto condIt = whatIt.second.find(trueDim);
- if (condIt != whatIt.second.end()) {
- condIt->second->onConditionChanged(
- currentUnSlicedPartCondition, eventTime);
- } else {
- if (mMetric2ConditionLinks.size() == 0 ||
- trueDim.contains(linkedConditionDimensionKey)) {
- if (!whatIt.second.empty()) {
- auto newEventKey = MetricDimensionKey(whatIt.first, trueDim);
- if (hitGuardRailLocked(newEventKey)) {
- continue;
- }
- unique_ptr<DurationTracker> newTracker =
- whatIt.second.begin()->second->clone(eventTime);
- if (newTracker != nullptr) {
- newTracker->setEventKey(newEventKey);
- newTracker->onConditionChanged(true, eventTime);
- whatIt.second[trueDim] = std::move(newTracker);
- }
- }
- }
- }
- }
- }
- }
-}
-
void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
const int64_t eventTimeNs) {
bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
- if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
- mDimensionsInCondition.empty()) {
+ if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker) {
onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
return;
}
- if (changeDimTrackable && mSameConditionDimensionsInTracker &&
- mMetric2ConditionLinks.size() <= 1) {
- onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTimeNs);
- return;
- }
-
// Now for each of the on-going event, check if the condition has changed for them.
for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
for (auto& pair : whatIt.second) {
pair.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
}
}
-
- if (mDimensionsInCondition.empty()) {
- return;
- }
-
- if (mMetric2ConditionLinks.empty()) {
- std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet;
- mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition,
- !mSameConditionDimensionsInTracker,
- &conditionDimensionsKeySet);
- for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- for (const auto& pair : whatIt.second) {
- conditionDimensionsKeySet.erase(pair.first);
- }
- }
- for (const auto& conditionDimension : conditionDimensionsKeySet) {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- if (!whatIt.second.empty()) {
- auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
- if (hitGuardRailLocked(newEventKey)) {
- continue;
- }
- unique_ptr<DurationTracker> newTracker =
- whatIt.second.begin()->second->clone(eventTimeNs);
- if (newTracker != nullptr) {
- newTracker->setEventKey(MetricDimensionKey(newEventKey));
- newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
- whatIt.second[conditionDimension] = std::move(newTracker);
- }
- }
- }
- }
- } else {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- ConditionKey conditionKey;
- for (const auto& link : mMetric2ConditionLinks) {
- getDimensionForCondition(whatIt.first.getValues(), link,
- &conditionKey[link.conditionId]);
- }
- std::unordered_set<HashableDimensionKey> conditionDimensionsKeys;
- mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &conditionDimensionsKeys);
-
- for (const auto& conditionDimension : conditionDimensionsKeys) {
- if (!whatIt.second.empty() &&
- whatIt.second.find(conditionDimension) == whatIt.second.end()) {
- auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
- if (hitGuardRailLocked(newEventKey)) {
- continue;
- }
- auto newTracker = whatIt.second.begin()->second->clone(eventTimeNs);
- if (newTracker != nullptr) {
- newTracker->setEventKey(newEventKey);
- newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
- whatIt.second[conditionDimension] = std::move(newTracker);
- }
- }
- }
- }
- }
}
void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
@@ -526,12 +357,6 @@ void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
protoOutput->end(dimenPathToken);
}
- if (!mDimensionsInCondition.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
- writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
- protoOutput->end(dimenPathToken);
- }
}
uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
@@ -790,52 +615,24 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
bool condition;
ConditionKey conditionKey;
- std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
if (mConditionSliced) {
for (const auto& link : mMetric2ConditionLinks) {
getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
}
auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &dimensionKeysInCondition);
+ mWizard->query(mConditionTrackerIndex, conditionKey,
+ !mHasLinksToAllConditionDimensionsInTracker);
condition = conditionState == ConditionState::kTrue;
- if (mDimensionsInCondition.empty() && condition) {
- dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
- }
} else {
// TODO: The unknown condition state is not handled here, we should fix it.
condition = mCondition == ConditionState::kTrue;
- if (condition) {
- dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
- }
}
condition = condition && mIsActive;
- if (dimensionKeysInCondition.empty()) {
- handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY),
- conditionKey, condition, event);
- } else {
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
- // If the what dimension is already there, we should update all the trackers even
- // the condition is false.
- if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
- for (const auto& condIt : whatIt->second) {
- const bool cond = dimensionKeysInCondition.find(condIt.first) !=
- dimensionKeysInCondition.end() && condition;
- handleStartEvent(MetricDimensionKey(dimensionInWhat, condIt.first),
- conditionKey, cond, event);
- dimensionKeysInCondition.erase(condIt.first);
- }
- }
- for (const auto& conditionDimension : dimensionKeysInCondition) {
- handleStartEvent(MetricDimensionKey(dimensionInWhat, conditionDimension), conditionKey,
- condition, event);
- }
- }
+ handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY),
+ conditionKey, condition, event);
}
size_t DurationMetricProducer::byteSizeLocked() const {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index a64bbc1056e0..1f423cd384ef 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -48,7 +48,6 @@ const int FIELD_ID_GAUGE_METRICS = 8;
const int FIELD_ID_TIME_BASE = 9;
const int FIELD_ID_BUCKET_SIZE = 10;
const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12;
const int FIELD_ID_IS_ACTIVE = 14;
// for GaugeMetricDataWrapper
const int FIELD_ID_DATA = 1;
@@ -115,10 +114,6 @@ GaugeMetricProducer::GaugeMetricProducer(
mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
}
- if (metric.has_dimensions_in_condition()) {
- translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
- }
-
if (metric.links().size() > 0) {
for (const auto& link : metric.links()) {
Metric2Condition mc;
@@ -127,10 +122,9 @@ GaugeMetricProducer::GaugeMetricProducer(
translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
mMetric2ConditionLinks.push_back(mc);
}
+ mConditionSliced = true;
}
- mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
- HasPositionALL(metric.dimensions_in_condition());
+ mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
flushIfNeededLocked(startTimeNs);
// Kicks off the puller immediately.
@@ -209,12 +203,6 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
protoOutput->end(dimenPathToken);
}
- if (!mDimensionsInCondition.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
- writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
- protoOutput->end(dimenPathToken);
- }
}
uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS);
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 92752b29ecda..1ab4fdf6e90c 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -52,38 +52,24 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo
bool condition;
ConditionKey conditionKey;
- std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
if (mConditionSliced) {
for (const auto& link : mMetric2ConditionLinks) {
getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
}
auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &dimensionKeysInCondition);
+ mWizard->query(mConditionTrackerIndex, conditionKey,
+ !mHasLinksToAllConditionDimensionsInTracker);
condition = (conditionState == ConditionState::kTrue);
} else {
// TODO: The unknown condition state is not handled here, we should fix it.
condition = mCondition == ConditionState::kTrue;
}
- if (mDimensionsInCondition.empty() && condition) {
- dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
- }
-
HashableDimensionKey dimensionInWhat;
filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
MetricDimensionKey metricKey(dimensionInWhat, DEFAULT_DIMENSION_KEY);
- for (const auto& conditionDimensionKey : dimensionKeysInCondition) {
- metricKey.setDimensionKeyInCondition(conditionDimensionKey);
- onMatchedLogEventInternalLocked(
- matcherIndex, metricKey, conditionKey, condition, event);
- }
- if (dimensionKeysInCondition.empty()) {
- onMatchedLogEventInternalLocked(
- matcherIndex, metricKey, conditionKey, condition, event);
- }
+ onMatchedLogEventInternalLocked(
+ matcherIndex, metricKey, conditionKey, condition, event);
}
bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 09ad2903fa4c..94f833b20814 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -88,7 +88,6 @@ public:
mConditionTrackerIndex(conditionIndex),
mContainANYPositionInDimensionsInWhat(false),
mSliceByPositionALL(false),
- mSameConditionDimensionsInTracker(false),
mHasLinksToAllConditionDimensionsInTracker(false),
mIsActive(true) {
}
@@ -349,15 +348,10 @@ protected:
int mConditionTrackerIndex;
vector<Matcher> mDimensionsInWhat; // The dimensions_in_what defined in statsd_config
- vector<Matcher> mDimensionsInCondition; // The dimensions_in_condition defined in statsd_config
bool mContainANYPositionInDimensionsInWhat;
bool mSliceByPositionALL;
- // True iff the condition dimensions equal to the sliced dimensions in the simple condition
- // tracker. This field is always false for combinational condition trackers.
- bool mSameConditionDimensionsInTracker;
-
// True iff the metric to condition links cover all dimension fields in the condition tracker.
// This field is always false for combinational condition trackers.
bool mHasLinksToAllConditionDimensionsInTracker;
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 8efca1e10de5..3dad61465416 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -260,17 +260,6 @@ private:
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
-
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 0e33a0f9f29b..bc1602497c39 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -51,7 +51,6 @@ const int FIELD_ID_VALUE_METRICS = 7;
const int FIELD_ID_TIME_BASE = 9;
const int FIELD_ID_BUCKET_SIZE = 10;
const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12;
const int FIELD_ID_IS_ACTIVE = 14;
// for ValueMetricDataWrapper
const int FIELD_ID_DATA = 1;
@@ -127,10 +126,6 @@ ValueMetricProducer::ValueMetricProducer(
mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
}
- if (metric.has_dimensions_in_condition()) {
- translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
- }
-
if (metric.links().size() > 0) {
for (const auto& link : metric.links()) {
Metric2Condition mc;
@@ -139,11 +134,10 @@ ValueMetricProducer::ValueMetricProducer(
translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
mMetric2ConditionLinks.push_back(mc);
}
+ mConditionSliced = true;
}
- mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
- HasPositionALL(metric.dimensions_in_condition());
+ mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs);
mCurrentBucketNum += numBucketsForward;
@@ -243,12 +237,6 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
protoOutput->end(dimenPathToken);
}
- if (!mDimensionsInCondition.empty()) {
- uint64_t dimenPathToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
- writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
- protoOutput->end(dimenPathToken);
- }
}
uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS);
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 081e61ed21fa..6b5c2994a0c8 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -60,7 +60,7 @@ class DurationTracker {
public:
DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const std::vector<Matcher>& dimensionInCondition, bool nesting,
+ bool nesting,
int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
@@ -70,7 +70,6 @@ public:
mWizard(wizard),
mConditionTrackerIndex(conditionIndex),
mBucketSizeNs(bucketSizeNs),
- mDimensionInCondition(dimensionInCondition),
mNested(nesting),
mCurrentBucketStartTimeNs(currentBucketStartNs),
mDuration(0),
@@ -180,8 +179,6 @@ protected:
const int64_t mBucketSizeNs;
- const std::vector<Matcher>& mDimensionInCondition;
-
const bool mNested;
int64_t mCurrentBucketStartTimeNs;
@@ -196,7 +193,6 @@ protected:
const bool mConditionSliced;
- bool mSameConditionDimensionsInTracker;
bool mHasLinksToAllConditionDimensionsInTracker;
std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 6868b8c24c71..df66cb0c53e5 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -27,18 +27,14 @@ namespace statsd {
MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id,
const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const vector<Matcher>& dimensionInCondition, bool nesting,
+ bool nesting,
int64_t currentBucketStartNs, int64_t currentBucketNum,
int64_t startTimeNs, int64_t bucketSizeNs,
bool conditionSliced, bool fullLink,
const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting,
+ : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting,
currentBucketStartNs, currentBucketNum, startTimeNs, bucketSizeNs,
conditionSliced, fullLink, anomalyTrackers) {
- if (mWizard != nullptr) {
- mSameConditionDimensionsInTracker =
- mWizard->equalOutputDimensions(conditionIndex, mDimensionInCondition);
- }
}
unique_ptr<DurationTracker> MaxDurationTracker::clone(const int64_t eventTime) {
@@ -252,17 +248,11 @@ void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
if (pair.second.state == kStopped) {
continue;
}
- std::unordered_set<HashableDimensionKey> conditionDimensionKeySet;
ConditionState conditionState = mWizard->query(
- mConditionTrackerIndex, pair.second.conditionKeys, mDimensionInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &conditionDimensionKeySet);
- bool conditionMet =
- (conditionState == ConditionState::kTrue) &&
- (mDimensionInCondition.size() == 0 ||
- conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) !=
- conditionDimensionKeySet.end());
+ mConditionTrackerIndex, pair.second.conditionKeys,
+ !mHasLinksToAllConditionDimensionsInTracker);
+ bool conditionMet = (conditionState == ConditionState::kTrue);
+
VLOG("key: %s, condition: %d", pair.first.toString().c_str(), conditionMet);
noteConditionChanged(pair.first, conditionMet, timestamp);
}
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 8e8f2cd6c582..d0371da096ea 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -30,7 +30,7 @@ class MaxDurationTracker : public DurationTracker {
public:
MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
- const std::vector<Matcher>& dimensionInCondition, bool nesting,
+ bool nesting,
int64_t currentBucketStartNs, int64_t currentBucketNum,
int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
bool fullLink,
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 956383a99eea..b0fd975b2328 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -26,20 +26,16 @@ using std::pair;
OringDurationTracker::OringDurationTracker(
const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, const vector<Matcher>& dimensionInCondition,
+ sp<ConditionWizard> wizard, int conditionIndex,
bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum,
int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting,
+ : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting,
currentBucketStartNs, currentBucketNum, startTimeNs, bucketSizeNs,
conditionSliced, fullLink, anomalyTrackers),
mStarted(),
mPaused() {
mLastStartTime = 0;
- if (mWizard != nullptr) {
- mSameConditionDimensionsInTracker =
- mWizard->equalOutputDimensions(conditionIndex, mDimensionInCondition);
- }
}
unique_ptr<DurationTracker> OringDurationTracker::clone(const int64_t eventTime) {
@@ -227,17 +223,10 @@ void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
++it;
continue;
}
- std::unordered_set<HashableDimensionKey> conditionDimensionKeySet;
ConditionState conditionState =
mWizard->query(mConditionTrackerIndex, condIt->second,
- mDimensionInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &conditionDimensionKeySet);
- if (conditionState != ConditionState::kTrue ||
- (mDimensionInCondition.size() != 0 &&
- conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) ==
- conditionDimensionKeySet.end())) {
+ !mHasLinksToAllConditionDimensionsInTracker);
+ if (conditionState != ConditionState::kTrue) {
startedToPaused.push_back(*it);
it = mStarted.erase(it);
VLOG("Key %s started -> paused", key.toString().c_str());
@@ -262,17 +251,10 @@ void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
++it;
continue;
}
- std::unordered_set<HashableDimensionKey> conditionDimensionKeySet;
ConditionState conditionState =
mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
- mDimensionInCondition,
- !mSameConditionDimensionsInTracker,
- !mHasLinksToAllConditionDimensionsInTracker,
- &conditionDimensionKeySet);
- if (conditionState == ConditionState::kTrue &&
- (mDimensionInCondition.size() == 0 ||
- conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) !=
- conditionDimensionKeySet.end())) {
+ !mHasLinksToAllConditionDimensionsInTracker);
+ if (conditionState == ConditionState::kTrue) {
pausedToStarted.push_back(*it);
it = mPaused.erase(it);
VLOG("Key %s paused -> started", key.toString().c_str());
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 8e73256d4a01..43c48d5f536b 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -29,7 +29,7 @@ class OringDurationTracker : public DurationTracker {
public:
OringDurationTracker(const ConfigKey& key, const int64_t& id,
const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
- int conditionIndex, const std::vector<Matcher>& dimensionInCondition,
+ int conditionIndex,
bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum,
int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
bool fullLink,
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index b87547056ad3..d9c04f248af0 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -66,13 +66,13 @@ message CountBucketInfo {
message CountMetricData {
optional DimensionsValue dimensions_in_what = 1;
- optional DimensionsValue dimensions_in_condition = 2;
+ optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
repeated CountBucketInfo bucket_info = 3;
repeated DimensionsValue dimension_leaf_values_in_what = 4;
- repeated DimensionsValue dimension_leaf_values_in_condition = 5;
+ repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
}
message DurationBucketInfo {
@@ -92,13 +92,13 @@ message DurationBucketInfo {
message DurationMetricData {
optional DimensionsValue dimensions_in_what = 1;
- optional DimensionsValue dimensions_in_condition = 2;
+ optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
repeated DurationBucketInfo bucket_info = 3;
repeated DimensionsValue dimension_leaf_values_in_what = 4;
- repeated DimensionsValue dimension_leaf_values_in_condition = 5;
+ repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
}
message ValueBucketInfo {
@@ -136,13 +136,13 @@ message ValueBucketInfo {
message ValueMetricData {
optional DimensionsValue dimensions_in_what = 1;
- optional DimensionsValue dimensions_in_condition = 2;
+ optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
repeated ValueBucketInfo bucket_info = 3;
repeated DimensionsValue dimension_leaf_values_in_what = 4;
- repeated DimensionsValue dimension_leaf_values_in_condition = 5;
+ repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
}
message GaugeBucketInfo {
@@ -166,13 +166,13 @@ message GaugeBucketInfo {
message GaugeMetricData {
optional DimensionsValue dimensions_in_what = 1;
- optional DimensionsValue dimensions_in_condition = 2;
+ optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
repeated GaugeBucketInfo bucket_info = 3;
repeated DimensionsValue dimension_leaf_values_in_what = 4;
- repeated DimensionsValue dimension_leaf_values_in_condition = 5;
+ repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
}
message StatsLogReport {
@@ -220,7 +220,7 @@ message StatsLogReport {
optional DimensionsValue dimensions_path_in_what = 11;
- optional DimensionsValue dimensions_path_in_condition = 12;
+ optional DimensionsValue dimensions_path_in_condition = 12 [deprecated = true];
// DO NOT USE field 13.
@@ -363,7 +363,7 @@ message StatsdStatsReport {
repeated ConditionStats condition_stats = 14;
repeated MetricStats metric_stats = 15;
repeated AlertStats alert_stats = 16;
- repeated MetricStats metric_dimension_in_condition_stats = 17;
+ repeated MetricStats metric_dimension_in_condition_stats = 17 [deprecated = true];
message Annotation {
optional int64 field_int64 = 1;
optional int32 field_int32 = 2;
@@ -483,7 +483,7 @@ message AlertTriggerDetails {
message MetricValue {
optional int64 metric_id = 1;
optional DimensionsValue dimension_in_what = 2;
- optional DimensionsValue dimension_in_condition = 3;
+ optional DimensionsValue dimension_in_condition = 3 [deprecated = true];
optional int64 value = 4;
}
oneof value {
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 79c06b98a82d..1b7f39806608 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -182,7 +182,7 @@ message CountMetric {
optional FieldMatcher dimensions_in_what = 4;
- optional FieldMatcher dimensions_in_condition = 7;
+ optional FieldMatcher dimensions_in_condition = 7 [deprecated = true];
optional TimeUnit bucket = 5;
@@ -207,7 +207,7 @@ message DurationMetric {
optional FieldMatcher dimensions_in_what = 6;
- optional FieldMatcher dimensions_in_condition = 8;
+ optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
optional TimeUnit bucket = 7;
}
@@ -225,7 +225,7 @@ message GaugeMetric {
optional FieldMatcher dimensions_in_what = 5;
- optional FieldMatcher dimensions_in_condition = 8;
+ optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
optional TimeUnit bucket = 6;
@@ -259,7 +259,7 @@ message ValueMetric {
optional FieldMatcher dimensions_in_what = 5;
- optional FieldMatcher dimensions_in_condition = 9;
+ optional FieldMatcher dimensions_in_condition = 9 [deprecated = true];
optional TimeUnit bucket = 6;
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
index e826a52c2f33..6eaa2311e5ed 100644
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
@@ -268,8 +268,6 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
std::vector<sp<ConditionTracker>> allConditions;
for (Position position :
{ Position::FIRST, Position::LAST}) {
- vector<Matcher> dimensionInCondition;
- std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
@@ -321,9 +319,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by this uid
@@ -389,9 +387,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
// query again
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
@@ -399,8 +397,6 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
std::vector<sp<ConditionTracker>> allConditions;
- vector<Matcher> dimensionInCondition;
- std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, false /*slice output by uid*/,
@@ -445,9 +441,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
ConditionKey queryKey;
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- true, true,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ true,
+ conditionCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by this uid
@@ -489,10 +485,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
// query again
conditionCache[0] = ConditionState::kNotEvaluated;
- dimensionKeys.clear();
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- true, true,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ true,
+ conditionCache);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
@@ -500,8 +495,6 @@ TEST(SimpleConditionTrackerTest, TestStopAll) {
std::vector<sp<ConditionTracker>> allConditions;
for (Position position :
{ Position::FIRST, Position::LAST }) {
- vector<Matcher> dimensionInCondition;
- std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
position);
@@ -555,9 +548,9 @@ TEST(SimpleConditionTrackerTest, TestStopAll) {
const auto queryKey = getWakeLockQueryKey(position, uid_list1, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by uid2
@@ -594,9 +587,9 @@ TEST(SimpleConditionTrackerTest, TestStopAll) {
// TEST QUERY
const auto queryKey2 = getWakeLockQueryKey(position, uid_list2, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
@@ -628,17 +621,17 @@ TEST(SimpleConditionTrackerTest, TestStopAll) {
// TEST QUERY
const auto queryKey3 = getWakeLockQueryKey(position, uid_list1, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
// TEST QUERY
const auto queryKey4 = getWakeLockQueryKey(position, uid_list2, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
- false, false,
- conditionCache, dimensionKeys);
+ conditionTracker.isConditionMet(queryKey, allPredicates,
+ false,
+ conditionCache);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
}
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
deleted file mode 100644
index e4186b7200a0..000000000000
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
+++ /dev/null
@@ -1,961 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition,
- bool hashStringInReport) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensions->add_child()->set_field(2); // job name field.
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- config.set_hash_strings_in_metric_report(hashStringInReport);
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- auto dimensionWhat = metric->mutable_dimensions_in_what();
- dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(2); // job name field.
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-/*
- The following test has the following input.
-
-{ 10000000002 10000000002 (8)9999[I], [S], job0[S], 1[I], }
-{ 10000000010 10000000010 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I], }
-{ 10000000011 10000000011 (29)1[I], }
-{ 10000000040 10000000040 (29)2[I], }
-{ 10000000050 10000000050 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I], }
-{ 10000000101 10000000101 (8)9999[I], [S], job0[S], 0[I], }
-{ 10000000102 10000000102 (29)1[I], }
-{ 10000000200 10000000200 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I], }
-{ 10000000201 10000000201 (8)9999[I], [S], job2[S], 1[I], }
-{ 10000000400 10000000400 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 1[I], }
-{ 10000000401 10000000401 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 1[I], }
-{ 10000000450 10000000450 (29)2[I], }
-{ 10000000500 10000000500 (8)9999[I], [S], job2[S], 0[I], }
-{ 10000000600 10000000600 (8)8888[I], [S], job2[S], 1[I], }
-{ 10000000650 10000000650 (29)1[I], }
-{ 309999999999 309999999999 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 0[I], }
-{ 310000000100 310000000100 (29)2[I], }
-{ 310000000300 310000000300 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I], }
-{ 310000000600 310000000600 (8)8888[I], [S], job1[S], 1[I], }
-{ 310000000640 310000000640 (29)1[I], }
-{ 310000000650 310000000650 (29)2[I], }
-{ 310000000700 310000000700 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 0[I], }
-{ 310000000850 310000000850 (8)8888[I], [S], job2[S], 0[I], }
-{ 310000000900 310000000900 (8)8888[I], [S], job1[S], 0[I], }
-*/
-TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition) {
- for (const bool hashStringInReport : { true, false }) {
- for (bool isDimensionInConditionSubSetOfConditionTrackerDimension : { true, false }) {
- for (auto aggregationType : {DurationMetric::MAX_SPARSE, DurationMetric::SUM}) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- aggregationType, isDimensionInConditionSubSetOfConditionTrackerDimension,
- hashStringInReport);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(
- config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 11));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 40));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 102));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 450));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 650));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + bucketSizeNs + 100));
-
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + bucketSizeNs + 640));
- events.push_back(CreateScreenStateChangedEvent(
- android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + bucketSizeNs + 650));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job0", bucketStartTimeNs + 2));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job0",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job2",bucketStartTimeNs + 500));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job2", bucketStartTimeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job2",
- bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job1",
- bucketStartTimeNs + bucketSizeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job1",
- bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 10));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 200));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 401));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- true, ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job0"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40 - 11);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
-
- data = metrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job1"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 10);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201 + bucketSizeNs - 650);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401 + bucketSizeNs - 650);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100 + 650 - 640);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job0"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40 - 11);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job1"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 10);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().
- dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(
- data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 110);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
- }
- }
-}
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition) {
- for (bool isFullLink : {true, false}) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition(
- aggregationType, !isFullLink);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions3 = {
- CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 55));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 120));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 121));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 450));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 501));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + bucketSizeNs + 100));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500));
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",
- bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(
- CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(
- CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 110));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 300));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
- events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 550));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 800));
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- true, ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
-
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
- }
-}
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_PartialLink_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool hashStringInReport) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field*/);
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- config.set_hash_strings_in_metric_report(hashStringInReport);
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *metric->mutable_dimensions_in_condition() = *syncDimension;
-
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition) {
- for (const bool hashStringInReport : {true, false}) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config =
- CreateDurationMetricConfig_PartialLink_AND_CombinationCondition(
- aggregationType, hashStringInReport);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions3 = {
- CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 55));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 120));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 121));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 450));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 501));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + bucketSizeNs + 100));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500));
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",
- bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(
- CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(
- CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 110));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 300));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
- events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 550));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 800));
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- true, ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 1 - 600 + 50);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 50);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 1 - 600);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().
- dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
- }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
deleted file mode 100644
index f3ecd56dd946..000000000000
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
+++ /dev/null
@@ -1,816 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateCountMetric_NoLink_CombinationCondition_Config() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto screenBrightnessChangeAtomMatcher = CreateScreenBrightnessChangedAtomMatcher();
- *config.add_atom_matcher() = screenBrightnessChangeAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by any attribution node and both by uid and tag.
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateAttributionUidAndTagDimensions(android::util::WAKELOCK_STATE_CHANGED,
- {Position::FIRST});
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(987654);
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(holdingWakelockPredicate, combinationPredicate);
-
- auto metric = config.add_count_metric();
- metric->set_id(StringToId("ScreenBrightnessChangeMetric"));
- metric->set_what(screenBrightnessChangeAtomMatcher.id());
- metric->set_condition(combinationPredicate->id());
- *metric->mutable_dimensions_in_what() =
- CreateDimensions(android::util::SCREEN_BRIGHTNESS_CHANGED, {1 /* level */});
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidDimensions(
- android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- metric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition) {
- ConfigKey cfgKey;
- auto config = CreateCountMetric_NoLink_CombinationCondition_Config();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
- CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"),
- CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + bucketSizeNs + 1));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 2 * bucketSizeNs - 10));
-
- events.push_back(CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 200));
- events.push_back(
- CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1));
-
- events.push_back(CreateAcquireWakelockEvent(attributions2, "wl2",
- bucketStartTimeNs + bucketSizeNs - 100));
- events.push_back(CreateReleaseWakelockEvent(attributions2, "wl2",
- bucketStartTimeNs + 2 * bucketSizeNs - 50));
-
- events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 11));
- events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 101));
- events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 201));
- events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + 203));
- events.push_back(
- CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 99));
- events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs + 2));
- events.push_back(
- CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 11));
- events.push_back(
- CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 9));
- events.push_back(
- CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 1));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-
- EXPECT_EQ(countMetrics.data_size(), 7);
- auto data = countMetrics.data(0);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 123);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
-
- data = countMetrics.data(1);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 123);
- ValidateAttributionUidDimension(data.dimensions_in_condition(),
- android::util::WAKELOCK_STATE_CHANGED, 111);
-
- data = countMetrics.data(2);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 3);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456);
- ValidateAttributionUidDimension(data.dimensions_in_condition(),
- android::util::WAKELOCK_STATE_CHANGED, 111);
-
- data = countMetrics.data(3);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456);
- ValidateAttributionUidDimension(data.dimensions_in_condition(),
- android::util::WAKELOCK_STATE_CHANGED, 333);
-
- data = countMetrics.data(4);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
-
- data = countMetrics.data(5);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789);
- ValidateAttributionUidDimension(data.dimensions_in_condition(),
- android::util::WAKELOCK_STATE_CHANGED, 111);
-
- data = countMetrics.data(6);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789);
- ValidateAttributionUidDimension(data.dimensions_in_condition(),
- android::util::WAKELOCK_STATE_CHANGED, 333);
-}
-
-namespace {
-
-StatsdConfig CreateCountMetric_Link_CombinationCondition() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field*/);
-
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(987654);
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_count_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("AppCrashMetric"));
- metric->set_what(appCrashMatcher.id());
- metric->set_condition(combinationPredicate->id());
- *metric->mutable_dimensions_in_what() =
- CreateDimensions(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1 /* uid */});
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
-
- // Links between crash atom and condition of app is in syncing.
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition) {
- ConfigKey cfgKey;
- auto config = CreateCountMetric_Link_CombinationCondition();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
- CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"),
- CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 11));
- events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 101));
- events.push_back(CreateAppCrashEvent(222, bucketStartTimeNs + 101));
-
- events.push_back(CreateAppCrashEvent(222, bucketStartTimeNs + 201));
- events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 211));
- events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + 211));
-
- events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 401));
- events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + 401));
- events.push_back(CreateAppCrashEvent(555, bucketStartTimeNs + 401));
-
- events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + bucketSizeNs + 301));
- events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + bucketSizeNs + 301));
-
- events.push_back(CreateAppCrashEvent(777, bucketStartTimeNs + bucketSizeNs + 701));
-
- events.push_back(
- CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + bucketSizeNs + 700));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
- events.push_back(
- CreateSyncEndEvent(attributions1, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(
- CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 400));
- events.push_back(
- CreateSyncEndEvent(attributions2, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 600));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-
- EXPECT_EQ(countMetrics.data_size(), 5);
- auto data = countMetrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = countMetrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = countMetrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 222);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = countMetrics.data(3);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = countMetrics.data(4);
- EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 777);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
-}
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_NoLink_CombinationCondition(
- DurationMetric::AggregationType aggregationType) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto inBatterySaverModePredicate = CreateBatterySaverModePredicate();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field */);
-
- *config.add_predicate() = inBatterySaverModePredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(987654);
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("BatterySaverModeDurationMetric"));
- metric->set_what(inBatterySaverModePredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition) {
- for (auto aggregationType : { DurationMetric::MAX_SPARSE, DurationMetric::SUM}) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_NoLink_CombinationCondition(aggregationType);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 1));
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 101));
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 110));
-
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 201));
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 500));
-
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 600));
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + bucketSizeNs + 870));
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + bucketSizeNs + 800));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(
- CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metrics);
-
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- EXPECT_FALSE(data.dimensions_in_what().has_field());
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 30);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 30);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
-
- data = metrics.data(1);
- EXPECT_FALSE(data.dimensions_in_what().has_field());
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 2);
-
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 300);
- } else {
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 300);
- }
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- EXPECT_FALSE(data.dimensions_in_what().has_field());
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- } else {
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs + 700 - 600);
- }
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
-}
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_Link_CombinationCondition(
- DurationMetric::AggregationType aggregationType) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field */);
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */});
-
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- *config.add_predicate() = isInBackgroundPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(987654);
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("AppInBackgroundMetric"));
- metric->set_what(isInBackgroundPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() =
- CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */});
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
-
- // Links between crash atom and condition of app is in syncing.
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_Link_CombinationCondition(aggregationType);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateMoveToBackgroundEvent(111, bucketStartTimeNs + 101));
- events.push_back(CreateMoveToForegroundEvent(111, bucketStartTimeNs + 110));
-
- events.push_back(CreateMoveToBackgroundEvent(111, bucketStartTimeNs + 201));
- events.push_back(CreateMoveToForegroundEvent(111, bucketStartTimeNs + bucketSizeNs + 100));
-
- events.push_back(CreateMoveToBackgroundEvent(333, bucketStartTimeNs + 399));
- events.push_back(CreateMoveToForegroundEvent(333, bucketStartTimeNs + bucketSizeNs + 800));
-
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 10));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + 100));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
- bucketStartTimeNs + 202));
- events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
- bucketStartTimeNs + bucketSizeNs + 801));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400));
- events.push_back(
- CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metrics);
-
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- EXPECT_FALSE(data.dimensions_in_condition().has_field());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 201);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs + 100 - 201);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
-
- data = metrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 401);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs + 299);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
deleted file mode 100644
index 489bb0b21a2e..000000000000
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateDurationMetricConfig_NoLink_SimpleCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = isSyncingPredicate;
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(isSyncingPredicate.id());
- metric->set_aggregation_type(aggregationType);
- auto dimensionWhat = metric->mutable_dimensions_in_what();
- dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(2); // job name field.
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition) {
- for (bool isDimensionInConditionSubSetOfConditionTrackerDimension : {true, false}) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_NoLink_SimpleCondition(
- aggregationType, isDimensionInConditionSubSetOfConditionTrackerDimension);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job0", bucketStartTimeNs + 1));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job0",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(9999, "")}, "job2",bucketStartTimeNs + 500));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job2", bucketStartTimeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job2",bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 10));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 200));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 300));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 401));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- true, ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job0"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job1"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 300);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job0"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job1"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 111, "App1");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 300);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- EXPECT_EQ(data.dimensions_in_what().field(),
- android::util::SCHEDULED_JOB_STATE_CHANGED);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(),
- 2); // job name field
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(),
- "job2"); // job name
- ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(),
- android::util::SYNC_STATE_CHANGED, 333, "App2");
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 );
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
- }
-}
-
-namespace {
-
-StatsdConfig createDurationMetric_Link_SimpleConditionConfig(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = isSyncingPredicate;
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(isSyncingPredicate.id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition) {
- for (bool isFullLink : {true, false}) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config = createDurationMetric_Link_SimpleConditionConfig(
- aggregationType, !isFullLink);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions3 = {
- CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500));
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600));
- events.push_back(
- CreateFinishScheduledJobEvent({CreateAttribution(333, "App2")}, "job2",
- bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(
- CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(
- CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 110));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 300));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
- events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 550));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 800));
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- true, ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
-
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 3);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 701);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
- }
-}
-
-namespace {
-
-StatsdConfig createDurationMetric_PartialLink_SimpleConditionConfig(
- DurationMetric::AggregationType aggregationType) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field*/);
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = isSyncingPredicate;
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(isSyncingPredicate.id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *metric->mutable_dimensions_in_condition() = *syncDimension;
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-} // namespace
-
-TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition) {
- for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) {
- ConfigKey cfgKey;
- auto config = createDurationMetric_PartialLink_SimpleConditionConfig(
- aggregationType);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<AttributionNodeInternal> attributions1 = {
- CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(222, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions2 = {
- CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<AttributionNodeInternal> attributions3 = {
- CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"),
- CreateAttribution(555, "GMSCoreModule2")};
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101));
-
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500));
- events.push_back(CreateStartScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600));
- events.push_back(CreateFinishScheduledJobEvent(
- {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + bucketSizeNs + 850));
-
- events.push_back(
- CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs - 2));
- events.push_back(
- CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
- bucketStartTimeNs + bucketSizeNs + 900));
-
- events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 50));
- events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
- bucketStartTimeNs + 110));
-
- events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + 300));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
- bucketStartTimeNs + bucketSizeNs + 700));
- events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + 400));
- events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
-
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 550));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + 800));
- events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs - 1));
- events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
- bucketStartTimeNs + bucketSizeNs + 700));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- EXPECT_EQ(reports.reports_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics_size(), 1);
- StatsLogReport::DurationMetricDataWrapper metrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).duration_metrics(), &metrics);
-
- if (aggregationType == DurationMetric::SUM) {
- EXPECT_EQ(4, metrics.data_size());
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 1 - 400 - 100);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300 + bucketSizeNs - 600);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- } else {
- EXPECT_EQ(metrics.data_size(), 4);
- auto data = metrics.data(0);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
-
- data = metrics.data(1);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 1 - 600);
-
- data = metrics.data(2);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333);
- EXPECT_EQ("ReadEmail",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300);
- EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = metrics.data(3);
- ValidateAttributionUidDimension(
- data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444);
- ValidateAttributionUidDimension(
- data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444);
- EXPECT_EQ("ReadDoc",
- data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str());
- EXPECT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).duration_nanos(), 701);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- }
- }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 67c704eb87fd..839daa4b7f8a 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -187,9 +187,9 @@ TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
{getMockedDimensionKey(conditionTagId, 2, "222")};
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse));
+ EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
- EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue));
+ EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard,
bucketStartTimeNs, bucketStartTimeNs);
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index d2fd95c818cf..f30873b92afc 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -113,9 +113,9 @@ TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {getMockedDimensionKey(conditionTagId, 2, "222")};
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse));
+ EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
- EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue));
+ EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index b9553a8fded8..47c21aa8f1df 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -485,10 +485,6 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
dim->set_field(tagId);
dim->add_child()->set_field(1);
- dim = metric.mutable_dimensions_in_condition();
- dim->set_field(conditionTag);
- dim->add_child()->set_field(1);
-
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
@@ -496,18 +492,14 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, _, _, _, _, _))
+ EXPECT_CALL(*wizard, query(_, _, _))
.WillRepeatedly(
Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
- const vector<Matcher>& dimensionFields, const bool isSubsetDim,
- const bool isPartialLink,
- std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
- dimensionKeySet->clear();
+ const bool isPartialLink) {
int pos[] = {1, 0, 0};
Field f(conditionTag, pos, 0);
HashableDimensionKey key;
key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
- dimensionKeySet->insert(key);
return ConditionState::kTrue;
}));
@@ -538,9 +530,6 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(1UL, key.getDimensionKeyInCondition().getValues().size());
- EXPECT_EQ(1000000, key.getDimensionKeyInCondition().getValues()[0].mValue.int_value);
-
EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
vector<shared_ptr<LogEvent>> allData;
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index bf047520cc77..100220b730d7 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -52,7 +52,6 @@ TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
@@ -63,7 +62,7 @@ TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
int64_t bucketNum = 0;
int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
false, false, {});
@@ -88,7 +87,6 @@ TEST(MaxDurationTrackerTest, TestStopAll) {
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -99,7 +97,7 @@ TEST(MaxDurationTrackerTest, TestStopAll) {
int64_t bucketNum = 0;
int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
false, false, {});
@@ -124,7 +122,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -135,7 +132,7 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
int64_t bucketNum = 0;
int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
false, false, {});
@@ -165,7 +162,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -176,7 +172,7 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
int64_t bucketNum = 0;
int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
false, false, {});
@@ -202,7 +198,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
const HashableDimensionKey conditionDimKey = key1;
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey conditionKey1;
@@ -223,7 +218,7 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
int64_t eventStopTimeNs = conditionStops2 + 8 * NS_PER_SEC;
int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, true,
false, {});
EXPECT_TRUE(tracker.mAnomalyTrackers.empty());
@@ -246,7 +241,6 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
}
TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey conditionKey1;
@@ -273,7 +267,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
true, false, {anomalyTracker});
@@ -295,7 +289,6 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
// This tests that we correctly compute the predicted time of an anomaly assuming that the current
// state continues forward as-is.
TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey conditionKey1;
@@ -333,7 +326,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
true, false, {anomalyTracker});
@@ -381,7 +374,6 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
// Suppose A starts, then B starts, and then A stops. We still need to set an anomaly based on the
// elapsed duration of B.
TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey conditionKey1;
@@ -416,7 +408,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
true, false, {anomalyTracker});
@@ -434,4 +426,4 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
} // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif \ No newline at end of file
+#endif
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index 7c2b4236add8..1cd7bdbf7bb0 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -51,7 +51,6 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -62,7 +61,7 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) {
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
int64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, false, false, {});
@@ -84,7 +83,6 @@ TEST(OringDurationTrackerTest, TestDurationNested) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -94,7 +92,7 @@ TEST(OringDurationTrackerTest, TestDurationNested) {
int64_t bucketNum = 0;
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, false, false, {});
@@ -117,7 +115,6 @@ TEST(OringDurationTrackerTest, TestStopAll) {
{getMockedDimensionKey(TagId, 1, "maps")};
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -127,7 +124,7 @@ TEST(OringDurationTrackerTest, TestStopAll) {
int64_t bucketNum = 0;
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, false, false, {});
@@ -147,7 +144,6 @@ TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -158,7 +154,7 @@ TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
int64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, false, false, {});
@@ -186,13 +182,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)) // #4
+ EXPECT_CALL(*wizard, query(_, key1, _)) // #4
.WillOnce(Return(ConditionState::kFalse));
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -203,7 +198,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) {
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
int64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {});
@@ -224,13 +219,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _))
+ EXPECT_CALL(*wizard, query(_, key1, _))
.Times(2)
.WillOnce(Return(ConditionState::kFalse))
.WillOnce(Return(ConditionState::kTrue));
@@ -243,7 +237,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
int64_t durationTimeNs = 2 * 1000;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
false, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {});
@@ -266,13 +260,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
ConditionKey key1;
key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)) // #4
+ EXPECT_CALL(*wizard, query(_, key1, _)) // #4
.WillOnce(Return(ConditionState::kFalse));
unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
@@ -282,7 +275,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
int64_t bucketNum = 0;
int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {});
@@ -306,7 +299,6 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -324,7 +316,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {anomalyTracker});
@@ -371,7 +363,6 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
}
TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) {
- vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -387,7 +378,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) {
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard, 1,
- dimensionInCondition,
+
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {anomalyTracker});
@@ -415,7 +406,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) {
for (int j = 0; j < 3; j++) {
int64_t thresholdNs = j * bucketSizeNs + 5 * NS_PER_SEC;
for (int i = 0; i <= 7; ++i) {
- vector<Matcher> dimensionInCondition;
+
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -432,7 +423,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) {
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY,
- wizard, 1, dimensionInCondition,
+ wizard, 1,
true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, true, false, {anomalyTracker});
@@ -472,7 +463,6 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -491,7 +481,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true /*nesting*/, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
bucketSizeNs, false, false, {anomalyTracker});
@@ -522,7 +512,6 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- vector<Matcher> dimensionInCondition;
Alert alert;
alert.set_id(101);
alert.set_metric_id(1);
@@ -541,7 +530,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
sp<AlarmMonitor> alarmMonitor;
sp<DurationAnomalyTracker> anomalyTracker =
new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
+ OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1,
true /*nesting*/, bucketStartTimeNs, 0, bucketStartTimeNs,
bucketSizeNs, false, false, {anomalyTracker});
@@ -589,4 +578,4 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
} // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif \ No newline at end of file
+#endif
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index 97c107228f9c..329e39fc4eff 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -26,11 +26,9 @@ namespace statsd {
class MockConditionWizard : public ConditionWizard {
public:
- MOCK_METHOD6(query,
+ MOCK_METHOD3(query,
ConditionState(const int conditionIndex, const ConditionKey& conditionParameters,
- const vector<Matcher>& dimensionFields,
- const bool isSubsetDim, const bool isPartialLink,
- std::unordered_set<HashableDimensionKey>* dimensionKeySet));
+ const bool isPartialLink));
};
class MockStatsPullerManager : public StatsPullerManager {
@@ -55,4 +53,4 @@ void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
} // namespace statsd
} // namespace os
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d20cc4131261..34045c995aed 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -17,6 +17,7 @@
package android.app;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -29,6 +30,7 @@ import android.annotation.UnsupportedAppUsage;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes.AttributeUsage;
import android.os.Binder;
@@ -1095,21 +1097,27 @@ public class AppOpsManager {
"android:sms_financial_transactions";
/** @hide Read media of audio type. */
+ @SystemApi @TestApi
public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
/** @hide Write media of audio type. */
+ @SystemApi @TestApi
public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
/** @hide Read media of video type. */
+ @SystemApi @TestApi
public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
/** @hide Write media of video type. */
+ @SystemApi @TestApi
public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
/** @hide Read media of image type. */
+ @SystemApi @TestApi
public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
/** @hide Write media of image type. */
+ @SystemApi @TestApi
public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
/** @hide Has a legacy (non-isolated) view of storage. */
- @TestApi
- @SystemApi
+ @SystemApi @TestApi
public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
+
/** @hide Interact with accessibility. */
@SystemApi
public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
@@ -4281,20 +4289,17 @@ public class AppOpsManager {
/**
* Callback for notification of changes to operation active state.
- *
- * @hide
*/
- @TestApi
public interface OnOpActiveChangedListener {
/**
* Called when the active state of an app op changes.
*
- * @param code The op code.
- * @param uid The UID performing the operation.
+ * @param op The operation that changed.
* @param packageName The package performing the operation.
* @param active Whether the operation became active or inactive.
*/
- void onOpActiveChanged(int code, int uid, String packageName, boolean active);
+ void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
+ boolean active);
}
/**
@@ -4324,6 +4329,16 @@ public class AppOpsManager {
public void onOpChanged(int op, String packageName) { }
}
+ /**
+ * Callback for notification of changes to operation state.
+ * This allows you to see the raw op codes instead of strings.
+ * @hide
+ */
+ public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
+ default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
+ default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
+ }
+
AppOpsManager(Context context, IAppOpsService service) {
mContext = context;
mService = service;
@@ -4779,6 +4794,17 @@ public class AppOpsManager {
}
}
+ /** {@hide} */
+ @Deprecated
+ public void startWatchingActive(@NonNull int[] ops,
+ @NonNull OnOpActiveChangedListener callback) {
+ final String[] strOps = new String[ops.length];
+ for (int i = 0; i < ops.length; i++) {
+ strOps[i] = opToPublicName(ops[i]);
+ }
+ startWatchingActive(strOps, mContext.getMainExecutor(), callback);
+ }
+
/**
* Start watching for changes to the active state of app ops. An app op may be
* long running and it has a clear start and stop delimiters. If an op is being
@@ -4786,26 +4812,25 @@ public class AppOpsManager {
* watched ops for a registered callback you need to unregister and register it
* again.
*
- * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
+ * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
* you can watch changes only for your UID.
*
- * @param ops The ops to watch.
+ * @param ops The operations to watch.
* @param callback Where to report changes.
*
- * @see #isOperationActive(int, int, String)
- * @see #stopWatchingActive(OnOpActiveChangedListener)
+ * @see #isOperationActive
+ * @see #stopWatchingActive
* @see #startOp(int, int, String)
* @see #finishOp(int, int, String)
- *
- * @hide
*/
- @TestApi
// TODO: Uncomment below annotation once b/73559440 is fixed
// @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
- public void startWatchingActive(@NonNull int[] ops,
+ public void startWatchingActive(@NonNull String[] ops,
+ @CallbackExecutor @NonNull Executor executor,
@NonNull OnOpActiveChangedListener callback) {
- Preconditions.checkNotNull(ops, "ops cannot be null");
- Preconditions.checkNotNull(callback, "callback cannot be null");
+ Objects.requireNonNull(ops);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
IAppOpsActiveCallback cb;
synchronized (mActiveWatchers) {
cb = mActiveWatchers.get(callback);
@@ -4815,13 +4840,25 @@ public class AppOpsManager {
cb = new IAppOpsActiveCallback.Stub() {
@Override
public void opActiveChanged(int op, int uid, String packageName, boolean active) {
- callback.onOpActiveChanged(op, uid, packageName, active);
+ executor.execute(() -> {
+ if (callback instanceof OnOpActiveChangedInternalListener) {
+ ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
+ uid, packageName, active);
+ }
+ if (sOpToString[op] != null) {
+ callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
+ }
+ });
}
};
mActiveWatchers.put(callback, cb);
}
+ final int[] rawOps = new int[ops.length];
+ for (int i = 0; i < ops.length; i++) {
+ rawOps[i] = strOpToOp(ops[i]);
+ }
try {
- mService.startWatchingActive(ops, cb);
+ mService.startWatchingActive(rawOps, cb);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4832,14 +4869,11 @@ public class AppOpsManager {
* long running and it has a clear start and stop delimiters. Unregistering a
* non-registered callback has no effect.
*
- * @see #isOperationActive#(int, int, String)
- * @see #startWatchingActive(int[], OnOpActiveChangedListener)
+ * @see #isOperationActive
+ * @see #startWatchingActive
* @see #startOp(int, int, String)
* @see #finishOp(int, int, String)
- *
- * @hide
*/
- @TestApi
public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
synchronized (mActiveWatchers) {
final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
@@ -5449,6 +5483,19 @@ public class AppOpsManager {
}
/**
+ * Checks whether the given op for a package is active.
+ * <p>
+ * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
+ * permission you can query only for your UID.
+ *
+ * @see #finishOp(int)
+ * @see #startOp(int)
+ */
+ public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
+ return isOperationActive(strOpToOp(op), uid, packageName);
+ }
+
+ /**
* Checks whether the given op for a UID and package is active.
*
* <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c49ea09c3a25..8987b239013c 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -883,7 +883,7 @@ public final class LoadedApk {
}
}
- // /aepx/com.android.runtime/lib, /vendor/lib, /odm/lib and /product/lib
+ // /apex/com.android.art/lib, /vendor/lib, /odm/lib and /product/lib
// are added to the native lib search paths of the classloader.
// Note that this is done AFTER the classloader is
// created by ApplicationLoaders.getDefault().getClassLoader(...). The
@@ -904,8 +904,8 @@ public final class LoadedApk {
// (linker namespace).
List<String> extraLibPaths = new ArrayList<>(4);
String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
- if (!defaultSearchPaths.contains("/apex/com.android.runtime/lib")) {
- extraLibPaths.add("/apex/com.android.runtime/lib" + abiSuffix);
+ if (!defaultSearchPaths.contains("/apex/com.android.art/lib")) {
+ extraLibPaths.add("/apex/com.android.art/lib" + abiSuffix);
}
if (!defaultSearchPaths.contains("/vendor/lib")) {
extraLibPaths.add("/vendor/lib" + abiSuffix);
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index fcdc81cf7533..d03bea2fb19e 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -328,6 +328,14 @@ public class UserInfo implements Parcelable {
}
/** @hide */
+ public String toFullString() {
+ return "UserInfo[id=" + id
+ + ", name=" + name
+ + ", flags=" + flagsToString(flags)
+ + "]";
+ }
+
+ /** @hide */
public static String flagsToString(int flags) {
return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags);
}
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index 1b28d614a7f2..a4c65aeb1050 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -28,7 +28,6 @@ import android.opengl.EGLSurface;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.Matrix;
-import android.text.format.Time;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
@@ -39,9 +38,14 @@ import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Locale;
/**
* A renderer class that manages the GL state, and can draw a frame into a set of output
@@ -63,6 +67,9 @@ public class SurfaceTextureRenderer {
private static final int FLIP_TYPE_VERTICAL = 2;
private static final int FLIP_TYPE_BOTH = FLIP_TYPE_HORIZONTAL | FLIP_TYPE_VERTICAL;
+ private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER =
+ DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss", Locale.ROOT);
+
private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
private EGLConfig mConfigs;
@@ -624,9 +631,7 @@ public class SurfaceTextureRenderer {
path.append(File.separator);
path.append("durations_");
- Time now = new Time();
- now.setToNow();
- path.append(now.format2445());
+ path.append(formatTimestamp(System.currentTimeMillis()));
path.append("_S");
for (EGLSurfaceHolder surface : mSurfaces) {
path.append(String.format("_%d_%d", surface.width, surface.height));
@@ -639,6 +644,15 @@ public class SurfaceTextureRenderer {
mPerfMeasurer.dumpPerformanceData(path.toString());
}
+ private static String formatTimestamp(long timeMillis) {
+ // This is a replacement for {@link Time#format2445()} that doesn't suffer from Y2038
+ // issues.
+ Instant instant = Instant.ofEpochMilli(timeMillis);
+ ZoneId zoneId = ZoneId.systemDefault();
+ LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
+ return LOG_NAME_TIME_FORMATTER.format(localDateTime);
+ }
+
private void setupGlTiming() {
if (PerfMeasurement.isGlTimingSupported()) {
Log.d(TAG, "Enabling GL performance measurement");
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 9108c3365f77..5143f1820c2d 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -51,7 +51,6 @@ import android.view.textclassifier.TextSelection;
import com.android.internal.util.Preconditions;
-import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -431,23 +430,18 @@ public abstract class TextClassifierService extends Service {
* Forwards the callback result to a wrapped binder callback.
*/
private static final class ProxyCallback<T extends Parcelable> implements Callback<T> {
- private WeakReference<ITextClassifierCallback> mTextClassifierCallback;
+ private ITextClassifierCallback mTextClassifierCallback;
private ProxyCallback(ITextClassifierCallback textClassifierCallback) {
- mTextClassifierCallback =
- new WeakReference<>(Preconditions.checkNotNull(textClassifierCallback));
+ mTextClassifierCallback = Preconditions.checkNotNull(textClassifierCallback);
}
@Override
public void onSuccess(T result) {
- ITextClassifierCallback callback = mTextClassifierCallback.get();
- if (callback == null) {
- return;
- }
try {
Bundle bundle = new Bundle(1);
bundle.putParcelable(KEY_RESULT, result);
- callback.onSuccess(bundle);
+ mTextClassifierCallback.onSuccess(bundle);
} catch (RemoteException e) {
Slog.d(LOG_TAG, "Error calling callback");
}
@@ -455,13 +449,9 @@ public abstract class TextClassifierService extends Service {
@Override
public void onFailure(CharSequence error) {
- ITextClassifierCallback callback = mTextClassifierCallback.get();
- if (callback == null) {
- return;
- }
try {
Slog.w(LOG_TAG, "Request fail: " + error);
- callback.onFailure();
+ mTextClassifierCallback.onFailure();
} catch (RemoteException e) {
Slog.d(LOG_TAG, "Error calling callback");
}
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 51ca80524090..d0f80936f477 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -999,6 +999,7 @@ public final class SelectionActionModeHelper {
}
private void onTimeOut() {
+ Log.d(LOG_TAG, "Timeout in TextClassificationAsyncTask");
if (getStatus() == Status.RUNNING) {
onPostExecute(mTimeOutResultSupplier.get());
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index a3fd915c29b2..c12940a4d582 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -245,6 +245,9 @@ static const char* kGenerationalCCRuntimeOption = "-Xgc:generational_cc";
// Copying (CC) garbage collector.
static const char* kNoGenerationalCCRuntimeOption = "-Xgc:nogenerational_cc";
+// Phenotype property name for enabling profiling the boot class path.
+static const char* PROFILE_BOOT_CLASS_PATH = "profilebootclasspath";
+
// Feature flag name for running the JIT in Zygote experiment, b/119800099.
static const char* ENABLE_APEX_IMAGE = "enable_apex_image";
// Flag to pass to the runtime when using the apex image.
@@ -690,6 +693,24 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX];
char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX];
+ // Read if we are using the profile configuration, do this at the start since the last ART args
+ // take precedence.
+ property_get("dalvik.vm.profilebootclasspath", propBuf, "");
+ std::string profile_boot_class_path = propBuf;
+ // Empty means the property is unset and we should default to the phenotype property.
+ // The possible values are {"true", "false", ""}
+ if (profile_boot_class_path.empty()) {
+ profile_boot_class_path = server_configurable_flags::GetServerConfigurableFlag(
+ RUNTIME_NATIVE_BOOT_NAMESPACE,
+ PROFILE_BOOT_CLASS_PATH,
+ /*default_value=*/ "");
+ }
+ if (profile_boot_class_path == "true") {
+ addOption("-Xps-profile-boot-class-path");
+ addOption("-Xps-profile-aot-code");
+ addOption("-Xjitsaveprofilinginfo");
+ }
+
std::string use_apex_image =
server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
ENABLE_APEX_IMAGE,
@@ -807,13 +828,6 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
parseRuntimeOption("dalvik.vm.jittransitionweight",
jittransitionweightOptBuf,
"-Xjittransitionweight:");
-
- property_get("dalvik.vm.profilebootimage", propBuf, "");
- if (strcmp(propBuf, "true") == 0) {
- addOption("-Xps-profile-boot-class-path");
- addOption("-Xps-profile-aot-code");
- }
-
/*
* Madvise related options.
*/
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index ea4b25267512..bb5780558bdf 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -80,9 +80,9 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
return true;
}
- // Jars from the runtime apex are allowed.
- static const char* kRuntimeApexPrefix = "/apex/com.android.runtime/javalib/";
- if (android::base::StartsWith(path, kRuntimeApexPrefix)
+ // Jars from the ART APEX are allowed.
+ static const char* kArtApexPrefix = "/apex/com.android.art/javalib/";
+ if (android::base::StartsWith(path, kArtApexPrefix)
&& android::base::EndsWith(path, kJarSuffix)) {
return true;
}
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2067735f2620..96c0cf3fd86a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2927,7 +2927,6 @@
<public type="attr" name="enforceStatusBarContrast" id="0x01010604" />
<public type="attr" name="enforceNavigationBarContrast" id="0x01010605" />
<public type="attr" name="identifier" id="0x01010606" />
- <public type="attr" name="forceQueryable" id="0x01010608" />
<!-- @hide @SystemApi -->
<public type="drawable" name="ic_info" id="0x010800b4" />
@@ -3000,6 +2999,7 @@
<public-group type="attr" first-id="0x01010607">
<public name="importantForContentCapture" />
+ <public name="forceQueryable" />
</public-group>
<public-group type="drawable" first-id="0x010800b5">
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index db63889d7743..b15cc5ccd656 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -24,6 +24,5 @@ java_sdk_library {
srcs_lib: "framework-minus-apex",
// TODO(b/70046217): remove core/java and android below. It was added to provide definitions for
// types like android.os.Bundle
- srcs_lib_whitelist_dirs: ["core/java", "location/java"],
srcs_lib_whitelist_pkgs: ["android", "com.android.internal.location"],
}
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index f320397bc84b..338ec12a9e28 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -19,6 +19,5 @@ java_sdk_library {
srcs: ["java/**/*.java"],
api_packages: ["com.android.mediadrm.signer"],
srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_dirs: ["media/java"],
srcs_lib_whitelist_pkgs: ["android.media"],
}
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
index 7846be161c0f..363d88544a03 100644
--- a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1604061903696928905">"Definições de pesquisa"</string>
+ <string name="search_menu" msgid="1604061903696928905">"Pesquisar definições"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 13890e029274..f1fc9f9e3d4e 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -452,7 +452,7 @@
<string name="cancel" msgid="6859253417269739139">"বাতিল"</string>
<string name="okay" msgid="1997666393121016642">"ঠিক আছে"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"চালু করুন"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"\'বিরক্ত করবেন না\' মোড চালু করুন"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"\'বিরক্ত করবে না\' মোড চালু করুন"</string>
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"কখনও নয়"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"শুধুমাত্র অগ্রাধিকার"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 2734f4e28632..7874aeb02996 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -286,7 +286,7 @@
<string name="wait_for_debugger_summary" msgid="1766918303462746804">"Esperar que se conecte el depurador para iniciar la aplicación"</string>
<string name="debug_input_category" msgid="1811069939601180246">"Entrada"</string>
<string name="debug_drawing_category" msgid="6755716469267367852">"Dibujo"</string>
- <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Representación acelerada mediante hardware"</string>
+ <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Procesamiento acelerado mediante hardware"</string>
<string name="media_category" msgid="4388305075496848353">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="7640508148375798343">"Supervisión"</string>
<string name="strict_mode" msgid="1938795874357830695">"Modo estricto"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 5cffafed6689..7368f1d105f2 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -43,7 +43,7 @@
<item msgid="8937994881315223448">"Միացված է <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-ին"</item>
<item msgid="1330262655415760617">"Անջատված"</item>
<item msgid="7698638434317271902">"Անջատվում է <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-ից…"</item>
- <item msgid="197508606402264311">"Անջատած է"</item>
+ <item msgid="197508606402264311">"Անջատված է"</item>
<item msgid="8578370891960825148">"Անհաջող"</item>
<item msgid="5660739516542454527">"Արգելափակված"</item>
<item msgid="1805837518286731242">"Վատ ցանցից ժամանակավոր խուսափում"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index bf587405c668..a74b4ae3ae9e 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -263,7 +263,7 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Միացնել ցուցադրման հատկանիշների ստուգումը"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Միշտ ակտիվացրած պահել բջջային տվյալները, նույնիսկ Wi‑Fi-ը միացրած ժամանակ (ցանցերի միջև արագ փոխարկման համար):"</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Օգտագործել սարքակազմի արագացման միացումը, եթե հասանելի է"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB-ի վրիպազերծումը:"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB վրիպազերծումը:"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"USB վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"Փակե՞լ USB-ի վրիպազերծման մուտքը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Ընդունե՞լ ծրագրավորման կարգավորումներ:"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index cf442b73e721..57e690d46b23 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -159,7 +159,7 @@
<string name="tts_default_pitch_title" msgid="6135942113172488671">"ஒலித்திறன்"</string>
<string name="tts_default_pitch_summary" msgid="1944885882882650009">"உருவாக்கப்படும் பேச்சின் டோன் பாதிக்கப்படும்"</string>
<string name="tts_default_lang_title" msgid="8018087612299820556">"மொழி"</string>
- <string name="tts_lang_use_system" msgid="2679252467416513208">"அமைப்பின் மொழியில்"</string>
+ <string name="tts_lang_use_system" msgid="2679252467416513208">"அமைப்பின் மொழியைப் பயன்படுத்தவும்"</string>
<string name="tts_lang_not_selected" msgid="7395787019276734765">"மொழி தேர்ந்தெடுக்கப்படவில்லை"</string>
<string name="tts_default_lang_summary" msgid="5219362163902707785">"பேசப்படும் உரைக்கு மொழி சார்ந்த குரலை அமைக்கிறது"</string>
<string name="tts_play_example_title" msgid="7094780383253097230">"எடுத்துக்காட்டைக் கவனிக்கவும்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 83636dc19beb..eb6160a47fce 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -143,7 +143,7 @@
<string name="data_usage_ota" msgid="5377889154805560860">"సిస్టమ్ అప్‌డేట్‌లు"</string>
<string name="tether_settings_title_usb" msgid="6688416425801386511">"USB టీథరింగ్"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"పోర్టబుల్ హాట్‌స్పాట్"</string>
- <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టీథరింగ్"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టెథెరింగ్"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"టీథరింగ్"</string>
<string name="tether_settings_title_all" msgid="8356136101061143841">"టీథరింగ్ &amp; పోర్టబుల్ హాట్‌స్పాట్"</string>
<string name="managed_user_title" msgid="8109605045406748842">"అన్ని కార్యాలయ అనువర్తనాలు"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 4e2d6fa76ad0..5c06c80a049c 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -201,7 +201,7 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"Cài đặt VPN không khả dụng cho người dùng này"</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"Cài đặt chia sẻ kết nối không khả dụng cho người dùng này"</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"Cài đặt tên điểm truy cập không khả dụng cho người dùng này"</string>
- <string name="enable_adb" msgid="7982306934419797485">"Gỡ lỗi USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Gỡ lỗi qua USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Bật chế độ gỡ lỗi khi kết nối USB"</string>
<string name="clear_adb_keys" msgid="4038889221503122743">"Thu hồi ủy quyền gỡ lỗi USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Phím tắt báo cáo lỗi"</string>
@@ -263,7 +263,7 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Cho phép kiểm tra thuộc tính của chế độ xem"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Luôn bật dữ liệu di động ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ kết nối nếu có"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi USB?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi qua USB?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Gỡ lỗi USB chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị của bạn mà không thông báo và đọc dữ liệu nhật ký."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Cho phép cài đặt phát triển?"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index e85199f9ca0d..c64130210d37 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -329,7 +329,7 @@
<string name="show_all_anrs" msgid="4924885492787069007">"顯示背景 ANR"</string>
<string name="show_all_anrs_summary" msgid="6636514318275139826">"為背景應用程式顯示「應用程式無回應」對話方塊"</string>
<string name="show_notification_channel_warnings" msgid="1399948193466922683">"顯示通知管道警告"</string>
- <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發佈通知時,在畫面上顯示警告"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發布通知時,在畫面上顯示警告"</string>
<string name="force_allow_on_external" msgid="3215759785081916381">"強制允許將應用程式寫入外部儲存空間"</string>
<string name="force_allow_on_external_summary" msgid="3640752408258034689">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string>
<string name="force_resizable_activities" msgid="8615764378147824985">"將活動強制設為可調整大小"</string>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c05609e33ab5..b2ff4b3268b2 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -238,6 +238,7 @@
<activity
android:name=".BugreportWarningActivity"
+ android:theme="@android:style/Theme.DeviceDefault.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
android:exported="false" />
diff --git a/packages/SoundPicker/res/layout-watch/radio_with_work_badge.xml b/packages/SoundPicker/res/layout-watch/radio_with_work_badge.xml
index 0e11621e5f4d..ee29a3710143 100644
--- a/packages/SoundPicker/res/layout-watch/radio_with_work_badge.xml
+++ b/packages/SoundPicker/res/layout-watch/radio_with_work_badge.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.providers.media.CheckedListItem xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.soundpicker.CheckedListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@@ -44,4 +44,4 @@
android:layout_centerVertical="true"
android:scaleType="centerCrop"
android:layout_marginRight="20dp" />
-</com.android.providers.media.CheckedListItem>
+</com.android.soundpicker.CheckedListItem>
diff --git a/packages/SoundPicker/res/layout/radio_with_work_badge.xml b/packages/SoundPicker/res/layout/radio_with_work_badge.xml
index e7d37eab205c..c8ca231f27a4 100644
--- a/packages/SoundPicker/res/layout/radio_with_work_badge.xml
+++ b/packages/SoundPicker/res/layout/radio_with_work_badge.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.providers.media.CheckedListItem xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.soundpicker.CheckedListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@@ -45,4 +45,4 @@
android:layout_centerVertical="true"
android:scaleType="centerCrop"
android:layout_marginRight="20dp" />
-</com.android.providers.media.CheckedListItem>
+</com.android.soundpicker.CheckedListItem>
diff --git a/packages/SoundPicker/src/com/android/soundpicker/CheckedListItem.java b/packages/SoundPicker/src/com/android/soundpicker/CheckedListItem.java
new file mode 100644
index 000000000000..bde87cfc39ef
--- /dev/null
+++ b/packages/SoundPicker/src/com/android/soundpicker/CheckedListItem.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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.soundpicker;
+
+import android.content.Context;
+import android.widget.Checkable;
+import android.widget.CheckedTextView;
+import android.widget.RelativeLayout;
+import android.util.AttributeSet;
+
+/**
+ * The {@link CheckedListItem} is a layout item that represents a ringtone, and is used in
+ * {@link RingtonePickerActivity}. It contains the ringtone's name, and a work badge to right of the
+ * name if the ringtone belongs to a work profile.
+ */
+public class CheckedListItem extends RelativeLayout implements Checkable {
+
+ public CheckedListItem(Context context) {
+ super(context);
+ }
+
+ public CheckedListItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CheckedListItem(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public CheckedListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ getCheckedTextView().setChecked(checked);
+ }
+
+ @Override
+ public boolean isChecked() {
+ return getCheckedTextView().isChecked();
+ }
+
+ @Override
+ public void toggle() {
+ getCheckedTextView().toggle();
+ }
+
+ private CheckedTextView getCheckedTextView() {
+ return (CheckedTextView) findViewById(R.id.checked_text_view);
+ }
+
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java
new file mode 100644
index 000000000000..cac673fdbf0b
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.plugins;
+
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Test plugin for home controls
+ */
+@ProvidesInterface(action = HomeControlsPlugin.ACTION, version = HomeControlsPlugin.VERSION)
+public interface HomeControlsPlugin extends Plugin {
+
+ String ACTION = "com.android.systemui.action.PLUGIN_HOME_CONTROLS";
+ int VERSION = 1;
+
+ /**
+ * Pass the container for the plugin to use however it wants. Ideally the plugin impl
+ * will add home controls to this space.
+ */
+ void sendParentGroup(ViewGroup group);
+}
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 7d403b24354c..7a9400887c75 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -55,6 +55,19 @@
android:clipChildren="false"
systemui:viewType="com.android.systemui.plugins.qs.QS" />
+ <!-- Temporary area to test out home controls -->
+ <LinearLayout
+ android:id="@+id/home_controls_layout"
+ android:layout_width="match_parent"
+ android:layout_height="125dp"
+ android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:visibility="gone"
+ android:padding="8dp"
+ android:layout_margin="5dp"
+ android:background="?android:attr/colorBackgroundFloating"
+ android:orientation="vertical">
+ </LinearLayout>
+
<com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
android:id="@+id/notification_stack_scroller"
android:layout_marginTop="@dimen/notification_panel_margin_top"
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 858ed6dcf93d..ef171d305d28 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -50,7 +50,7 @@ import javax.inject.Singleton;
*/
@Singleton
public class AppOpsControllerImpl implements AppOpsController,
- AppOpsManager.OnOpActiveChangedListener,
+ AppOpsManager.OnOpActiveChangedInternalListener,
AppOpsManager.OnOpNotedListener, Dumpable {
private static final long NOTED_OP_TIME_DELAY_MS = 5000;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c17173063fc9..c76cdcb85c34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -53,6 +53,7 @@ import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -68,10 +69,13 @@ import com.android.systemui.R;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.HomeControlsPlugin;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.qs.QSFragment;
+import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
@@ -192,6 +196,7 @@ public class NotificationPanelView extends PanelView implements
private View mQsNavbarScrim;
protected NotificationsQuickSettingsContainer mNotificationContainerParent;
protected NotificationStackScrollLayout mNotificationStackScroller;
+ protected LinearLayout mHomeControlsLayout;
private boolean mAnimateNextPositionUpdate;
private int mTrackingPointer;
@@ -450,6 +455,7 @@ public class NotificationPanelView extends PanelView implements
mBigClockContainer = findViewById(R.id.big_clock_container);
keyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mHomeControlsLayout = findViewById(R.id.home_controls_layout);
mNotificationContainerParent = findViewById(R.id.notification_container_parent);
mNotificationStackScroller = findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(this);
@@ -480,6 +486,21 @@ public class NotificationPanelView extends PanelView implements
}
}
});
+
+ Dependency.get(PluginManager.class).addPluginListener(
+ new PluginListener<HomeControlsPlugin>() {
+
+ @Override
+ public void onPluginConnected(HomeControlsPlugin plugin,
+ Context pluginContext) {
+ plugin.sendParentGroup(mHomeControlsLayout);
+ }
+
+ @Override
+ public void onPluginDisconnected(HomeControlsPlugin plugin) {
+
+ }
+ }, HomeControlsPlugin.class, false);
}
@Override
@@ -1270,9 +1291,11 @@ public class NotificationPanelView extends PanelView implements
if (mQsExpandImmediate) {
mNotificationStackScroller.setVisibility(View.GONE);
mQsFrame.setVisibility(View.VISIBLE);
+ mHomeControlsLayout.setVisibility(View.VISIBLE);
} else {
mNotificationStackScroller.setVisibility(View.VISIBLE);
mQsFrame.setVisibility(View.GONE);
+ mHomeControlsLayout.setVisibility(View.GONE);
}
}
return false;
@@ -1551,6 +1574,7 @@ public class NotificationPanelView extends PanelView implements
if (mKeyguardShowing && isQsSplitEnabled()) {
mNotificationStackScroller.setVisibility(View.VISIBLE);
mQsFrame.setVisibility(View.VISIBLE);
+ mHomeControlsLayout.setVisibility(View.GONE);
}
if (oldState == StatusBarState.KEYGUARD
@@ -2099,8 +2123,10 @@ public class NotificationPanelView extends PanelView implements
t = (expandedHeight - panelHeightQsCollapsed)
/ (panelHeightQsExpanded - panelHeightQsCollapsed);
}
- setQsExpansion(mQsMinExpansionHeight
- + t * (mQsMaxExpansionHeight - mQsMinExpansionHeight));
+ float targetHeight = mQsMinExpansionHeight
+ + t * (mQsMaxExpansionHeight - mQsMinExpansionHeight);
+ setQsExpansion(targetHeight);
+ mHomeControlsLayout.setTranslationY(targetHeight);
}
updateExpandedHeight(expandedHeight);
updateHeader();
diff --git a/packages/services/PacProcessor/Android.bp b/packages/services/PacProcessor/Android.bp
index 93b2d956cf6f..494a8187886d 100644
--- a/packages/services/PacProcessor/Android.bp
+++ b/packages/services/PacProcessor/Android.bp
@@ -21,3 +21,9 @@ android_app {
certificate: "platform",
jni_libs: ["libjni_pacprocessor"],
}
+
+filegroup {
+ name: "PacProcessor-aidl-sources",
+ srcs: ["src/**/*.aidl"],
+ path: "src",
+}
diff --git a/packages/services/PacProcessor/com/android/net/IProxyService.aidl b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl
index 4e54aba5c3bf..4e54aba5c3bf 100644
--- a/packages/services/PacProcessor/com/android/net/IProxyService.aidl
+++ b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl
diff --git a/packages/services/Proxy/Android.bp b/packages/services/Proxy/Android.bp
index 87aa7637df8e..d93c9f8d9941 100644
--- a/packages/services/Proxy/Android.bp
+++ b/packages/services/Proxy/Android.bp
@@ -5,3 +5,9 @@ android_app {
certificate: "platform",
privileged: true,
}
+
+filegroup {
+ name: "ProxyHandler-aidl-sources",
+ srcs: ["src/**/*.aidl"],
+ path: "src",
+}
diff --git a/packages/services/Proxy/com/android/net/IProxyCallback.aidl b/packages/services/Proxy/src/com/android/net/IProxyCallback.aidl
index 26b2a3f9da2d..26b2a3f9da2d 100644
--- a/packages/services/Proxy/com/android/net/IProxyCallback.aidl
+++ b/packages/services/Proxy/src/com/android/net/IProxyCallback.aidl
diff --git a/packages/services/Proxy/com/android/net/IProxyPortListener.aidl b/packages/services/Proxy/src/com/android/net/IProxyPortListener.aidl
index fa4caf3dba91..fa4caf3dba91 100644
--- a/packages/services/Proxy/com/android/net/IProxyPortListener.aidl
+++ b/packages/services/Proxy/src/com/android/net/IProxyPortListener.aidl
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
index b88b24e21c2a..203210998c48 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
@@ -468,7 +468,13 @@ public class AccessibilitySecurityPolicy {
}
}
- boolean hasPermission(String permission) {
+ /**
+ * Permission check to caller.
+ *
+ * @param permission The permission to check
+ * @return true if caller has permission
+ */
+ public boolean hasPermission(@NonNull String permission) {
return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 4facf4ea62a2..4151c7269934 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -54,6 +54,10 @@ import com.android.server.pm.UserManagerService;
* {@hide}
*/
public abstract class SystemService {
+
+ // TODO(b/133242016) STOPSHIP: change to false before R ships
+ protected static final boolean DEBUG_USER = true;
+
/*
* Boot Phases
*/
@@ -150,7 +154,17 @@ public abstract class SystemService {
public void onBootPhase(int phase) {}
/**
- * @deprecated subclasses should extend {@link #onStartUser(int, int)} instead (which by default
+ * Checks if the service should be available for the given user.
+ *
+ * <p>By default returns {@code true}, but subclasses should extend for optimization, if they
+ * don't support some types (like headless system user).
+ */
+ public boolean isSupported(@NonNull UserInfo userInfo) {
+ return true;
+ }
+
+ /**
+ * @deprecated subclasses should extend {@link #onStartUser(UserInfo)} instead (which by default
* calls this method).
*/
@Deprecated
@@ -160,6 +174,9 @@ public abstract class SystemService {
* Called when a new user is starting, for system services to initialize any per-user
* state they maintain for running users.
*
+ * <p>This method is only called when the service {@link #isSupported(UserInfo) supports} this
+ * user.
+ *
* @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
* referenced by {@link UserManagerService} and hence should not be modified.
*/
@@ -168,7 +185,7 @@ public abstract class SystemService {
}
/**
- * @deprecated subclasses should extend {@link #onUnlockUser(int, int)} instead (which by
+ * @deprecated subclasses should extend {@link #onUnlockUser(UserInfo)} instead (which by
* default calls this method).
*/
@Deprecated
@@ -185,6 +202,9 @@ public abstract class SystemService {
* Code written inside system services should use
* {@link UserManager#isUserUnlockingOrUnlocked(int)} to handle both of
* these states.
+ * <p>
+ * This method is only called when the service {@link #isSupported(UserInfo) supports} this
+ * user.
*
* @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
* referenced by {@link UserManagerService} and hence should not be modified.
@@ -194,8 +214,8 @@ public abstract class SystemService {
}
/**
- * @deprecated subclasses should extend {@link #onSwitchUser(int, int)} instead (which by
- * default calls this method).
+ * @deprecated subclasses should extend {@link #onSwitchUser(UserInfo, UserInfo)} instead
+ * (which by default calls this method).
*/
@Deprecated
public void onSwitchUser(@UserIdInt int userHandle) {}
@@ -205,15 +225,21 @@ public abstract class SystemService {
* special behavior for whichever user is currently in the foreground. This is called
* before any application processes are aware of the new user.
*
- * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
+ * <p>This method is only called when the service {@link #isSupported(UserInfo) supports} either
+ * of the users ({@code from} or {@code to}).
+ *
+ * <b>NOTE: </b> both {@code from} and {@code to} are "live" objects
* referenced by {@link UserManagerService} and hence should not be modified.
+ *
+ * @param from The information about the user being switched from.
+ * @param to The information about the user being switched from to.
*/
- public void onSwitchUser(@NonNull UserInfo userInfo) {
- onSwitchUser(userInfo.id);
+ public void onSwitchUser(@NonNull UserInfo from, @NonNull UserInfo to) {
+ onSwitchUser(to.id);
}
/**
- * @deprecated subclasses should extend {@link #onStopUser(int, int)} instead (which by default
+ * @deprecated subclasses should extend {@link #onStopUser(UserInfo)} instead (which by default
* calls this method).
*/
@Deprecated
@@ -225,6 +251,9 @@ public abstract class SystemService {
* broadcast to the user; it is a good place to stop making use of any resources of that
* user (such as binding to a service running in the user).
*
+ * <p>This method is only called when the service {@link #isSupported(UserInfo) supports} this
+ * user.
+ *
* <p>NOTE: This is the last callback where the callee may access the target user's CE storage.
*
* @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
@@ -235,7 +264,7 @@ public abstract class SystemService {
}
/**
- * @deprecated subclasses should extend {@link #onCleanupUser(int, int)} instead (which by
+ * @deprecated subclasses should extend {@link #onCleanupUser(UserInfo)} instead (which by
* default calls this method).
*/
@Deprecated
@@ -246,8 +275,12 @@ public abstract class SystemService {
* state they maintain for running users. This is called after all application process
* teardown of the user is complete.
*
+ * <p>This method is only called when the service {@link #isSupported(UserInfo) supports} this
+ * user.
+ *
* <p>NOTE: When this callback is called, the CE storage for the target user may not be
- * accessible already. Use {@link #onCleanupUser} instead if you need to access the CE storage.
+ * accessible already. Use {@link #onStopUser(UserInfo)} instead if you need to access the CE
+ * storage.
*
* @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
* referenced by {@link UserManagerService} and hence should not be modified.
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index b085946899bd..c7157981ada2 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -23,6 +23,7 @@ import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.SystemClock;
import android.os.Trace;
+import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.util.Slog;
@@ -41,8 +42,16 @@ import java.util.ArrayList;
*/
public class SystemServiceManager {
private static final String TAG = "SystemServiceManager";
+ private static final boolean DEBUG = false;
private static final int SERVICE_CALL_WARN_TIME_MS = 50;
+ // Constants used on onUser(...)
+ private static final String START = "Start";
+ private static final String UNLOCK = "Unlock";
+ private static final String SWITCH = "Switch";
+ private static final String STOP = "Stop";
+ private static final String CLEANUP = "Cleanup";
+
private static File sSystemDir;
private final Context mContext;
private boolean mSafeMode;
@@ -90,7 +99,6 @@ public class SystemServiceManager {
* @return The service instance, never null.
* @throws RuntimeException if the service fails to start.
*/
- @SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
@@ -212,64 +220,104 @@ public class SystemServiceManager {
* Starts the given user.
*/
public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
- onUser(t, "Start", userHandle, (s, u) -> s.onStartUser(u));
+ onUser(t, START, userHandle);
}
/**
* Unlocks the given user.
*/
public void unlockUser(final @UserIdInt int userHandle) {
- onUser("Unlock", userHandle, (s, u) -> s.onUnlockUser(u));
+ onUser(UNLOCK, userHandle);
}
/**
* Switches to the given user.
*/
- public void switchUser(final @UserIdInt int userHandle) {
- onUser("Switch", userHandle, (s, u) -> s.onSwitchUser(u));
+ public void switchUser(final @UserIdInt int from, final @UserIdInt int to) {
+ onUser(TimingsTraceAndSlog.newAsyncLog(), SWITCH, to, from);
}
/**
* Stops the given user.
*/
public void stopUser(final @UserIdInt int userHandle) {
- onUser("Stop", userHandle, (s, u) -> s.onStopUser(u));
+ onUser(STOP, userHandle);
}
/**
* Cleans up the given user.
*/
public void cleanupUser(final @UserIdInt int userHandle) {
- onUser("Cleanup", userHandle, (s, u) -> s.onCleanupUser(u));
+ onUser(CLEANUP, userHandle);
}
- private interface ServiceVisitor {
- void visit(@NonNull SystemService service, @NonNull UserInfo userInfo);
+ private void onUser(@NonNull String onWhat, @UserIdInt int userHandle) {
+ onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, userHandle);
}
- private void onUser(@NonNull String onWhat, @UserIdInt int userHandle,
- @NonNull ServiceVisitor visitor) {
- onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, userHandle, visitor);
+ private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
+ @UserIdInt int userHandle) {
+ onUser(t, onWhat, userHandle, UserHandle.USER_NULL);
}
private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
- @UserIdInt int userHandle, @NonNull ServiceVisitor visitor) {
- t.traceBegin("ssm." + onWhat + "User-" + userHandle);
- Slog.i(TAG, "Calling on" + onWhat + "User u" + userHandle);
- final UserInfo userInfo = getUserInfo(userHandle);
+ @UserIdInt int curUserId, @UserIdInt int prevUserId) {
+ t.traceBegin("ssm." + onWhat + "User-" + curUserId);
+ Slog.i(TAG, "Calling on" + onWhat + "User " + curUserId);
+ final UserInfo curUserInfo = getUserInfo(curUserId);
+ final UserInfo prevUserInfo = prevUserId == UserHandle.USER_NULL ? null
+ : getUserInfo(prevUserId);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
final String serviceName = service.getClass().getName();
- t.traceBegin("ssm.on" + onWhat + "User-" + userHandle + " " + serviceName);
+ boolean supported = service.isSupported(curUserInfo);
+
+ // Must check if either curUser or prevUser is supported (for example, if switching from
+ // unsupported to supported, we still need to notify the services)
+ if (!supported && prevUserInfo != null) {
+ supported = service.isSupported(prevUserInfo);
+ }
+
+ if (!supported) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping " + onWhat + "User-" + curUserId + " on service "
+ + serviceName + " because it's not supported (curUser: "
+ + curUserInfo + ", prevUser:" + prevUserInfo + ")");
+ } else {
+ Slog.i(TAG, "Skipping " + onWhat + "User-" + curUserId + " on "
+ + serviceName);
+ }
+ continue;
+ }
+ t.traceBegin("ssm.on" + onWhat + "User-" + curUserId + " " + serviceName);
long time = SystemClock.elapsedRealtime();
try {
- visitor.visit(service, userInfo);
+ switch (onWhat) {
+ case SWITCH:
+ service.onSwitchUser(prevUserInfo, curUserInfo);
+ break;
+ case START:
+ service.onStartUser(curUserInfo);
+ break;
+ case UNLOCK:
+ service.onUnlockUser(curUserInfo);
+ break;
+ case STOP:
+ service.onStopUser(curUserInfo);
+ break;
+ case CLEANUP:
+ service.onCleanupUser(curUserInfo);
+ break;
+ default:
+ throw new IllegalArgumentException(onWhat + " what?");
+ }
} catch (Exception ex) {
- Slog.wtf(TAG, "Failure reporting " + onWhat + " of user " + userHandle
+ Slog.wtf(TAG, "Failure reporting " + onWhat + " of user " + curUserInfo
+ " to service " + serviceName, ex);
}
- warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "on" + onWhat + "User ");
+ warnIfTooLong(SystemClock.elapsedRealtime() - time, service,
+ "on" + onWhat + "User-" + curUserId);
t.traceEnd(); // what on service
}
t.traceEnd(); // main entry
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index d4ceb5a86946..b2c40ef897aa 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2180,7 +2180,7 @@ class UserController implements Handler.Callback {
BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
Integer.toString(msg.arg1), msg.arg1);
- mInjector.getSystemServiceManager().switchUser(msg.arg1);
+ mInjector.getSystemServiceManager().switchUser(msg.arg2, msg.arg1);
break;
case FOREGROUND_PROFILE_CHANGED_MSG:
dispatchForegroundProfileChanged(msg.arg1);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 4f33ebb035da..c466640e658b 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2020,6 +2020,10 @@ public final class DisplayManagerService extends SystemService {
@Override // Binder call
public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
int width, int height, int densityDpi) {
+ if (width <= 0 || height <= 0 || densityDpi <= 0) {
+ throw new IllegalArgumentException("width, height, and densityDpi must be "
+ + "greater than 0");
+ }
final long token = Binder.clearCallingIdentity();
try {
resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 92ac1d48d784..d580bd6f0a11 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -74,6 +74,9 @@ public class PreferencesHelper implements RankingConfig {
private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
@VisibleForTesting
+ static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000;
+
+ @VisibleForTesting
static final String TAG_RANKING = "ranking";
private static final String TAG_PACKAGE = "package";
private static final String TAG_CHANNEL = "channel";
@@ -180,6 +183,7 @@ public class PreferencesHelper implements RankingConfig {
// noop
}
}
+ boolean skipWarningLogged = false;
PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid,
XmlUtils.readIntAttribute(
@@ -226,6 +230,14 @@ public class PreferencesHelper implements RankingConfig {
}
// Channels
if (TAG_CHANNEL.equals(tagName)) {
+ if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
+ if (!skipWarningLogged) {
+ Slog.w(TAG, "Skipping further channels for " + r.pkg
+ + "; app has too many");
+ skipWarningLogged = true;
+ }
+ continue;
+ }
String id = parser.getAttributeValue(null, ATT_ID);
String channelName = parser.getAttributeValue(null, ATT_NAME);
int channelImportance = XmlUtils.readIntAttribute(
@@ -696,6 +708,10 @@ public class PreferencesHelper implements RankingConfig {
return needsPolicyFileChange;
}
+ if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
+ throw new IllegalStateException("Limit exceed; cannot create more channels");
+ }
+
needsPolicyFileChange = true;
if (channel.getImportance() < IMPORTANCE_NONE
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index a1b6d492a4a3..1da5bc6c26ee 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -38,6 +38,7 @@ import android.sysprop.ApexProperties;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
import java.io.File;
@@ -263,7 +264,8 @@ abstract class ApexManager {
populateAllPackagesCacheIfNeeded();
mContext.unregisterReceiver(this);
}
- }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+ }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED), /* broadcastPermission */ null,
+ BackgroundThread.getHandler());
}
private void populateAllPackagesCacheIfNeeded() {
diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
index 77bf930fb4d7..712012d9e621 100644
--- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
+++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
@@ -24,20 +24,17 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
-import android.os.Debug;
import android.provider.Settings;
-import android.telecom.TelecomManager;
import android.text.TextUtils;
-import android.util.Log;
import android.util.Slog;
+import com.android.internal.R;
import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.CollectionUtils;
import com.android.server.LocalServices;
import com.android.server.role.RoleManagerService;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -67,14 +64,25 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder
public List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId) {
switch (roleName) {
case RoleManager.ROLE_ASSISTANT: {
- String legacyAssistant = Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId);
- if (legacyAssistant == null || legacyAssistant.isEmpty()) {
- return Collections.emptyList();
+ String packageName;
+ String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSISTANT, userId);
+ // AssistUtils was using the default assistant app if Settings.Secure.ASSISTANT is
+ // null, while only an empty string means user selected "None".
+ if (setting != null) {
+ if (!setting.isEmpty()) {
+ ComponentName componentName = ComponentName.unflattenFromString(setting);
+ packageName = componentName != null ? componentName.getPackageName() : null;
+ } else {
+ packageName = null;
+ }
+ } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+ String defaultAssistant = mContext.getString(R.string.config_defaultAssistant);
+ packageName = !TextUtils.isEmpty(defaultAssistant) ? defaultAssistant : null;
} else {
- return Collections.singletonList(
- ComponentName.unflattenFromString(legacyAssistant).getPackageName());
+ packageName = null;
}
+ return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_BROWSER: {
PackageManagerInternal packageManagerInternal = LocalServices.getService(
@@ -84,44 +92,36 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_DIALER: {
- String setting = Settings.Secure.getStringForUser(
- mContext.getContentResolver(),
+ String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION, userId);
- return CollectionUtils.singletonOrEmpty(!TextUtils.isEmpty(setting)
- ? setting
- : mContext.getSystemService(TelecomManager.class).getSystemDialerPackage());
+ String packageName;
+ if (!TextUtils.isEmpty(setting)) {
+ packageName = setting;
+ } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+ // DefaultDialerManager was using the default dialer app if
+ // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
+ // TelecomManager.getSystemDialerPackage() won't work because it might not
+ // be ready.
+ packageName = mContext.getString(R.string.config_defaultDialer);
+ } else {
+ packageName = null;
+ }
+ return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_SMS: {
- // Moved over from SmsApplication#getApplication
- String result = Settings.Secure.getStringForUser(
- mContext.getContentResolver(),
+ String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.SMS_DEFAULT_APPLICATION, userId);
- // TODO: STOPSHIP: Remove the following code once we read the value of
- // config_defaultSms in RoleControllerService.
- if (result == null) {
- Collection<SmsApplication.SmsApplicationData> applications =
- SmsApplication.getApplicationCollectionAsUser(mContext, userId);
- SmsApplication.SmsApplicationData applicationData;
- String defaultPackage = mContext.getResources()
- .getString(com.android.internal.R.string.default_sms_application);
- applicationData =
- SmsApplication.getApplicationForPackage(applications, defaultPackage);
-
- if (applicationData == null) {
- // Are there any applications?
- if (applications.size() != 0) {
- applicationData =
- (SmsApplication.SmsApplicationData) applications.toArray()[0];
- }
- }
- if (DEBUG) {
- Log.i(LOG_TAG, "Found default sms app: " + applicationData
- + " among: " + applications + " from " + Debug.getCallers(4));
- }
- SmsApplication.SmsApplicationData app = applicationData;
- result = app == null ? null : app.mPackageName;
+ String packageName;
+ if (!TextUtils.isEmpty(setting)) {
+ packageName = setting;
+ } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+ // SmsApplication was using the default SMS app if
+ // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
+ packageName = mContext.getString(R.string.config_defaultSms);
+ } else {
+ packageName = null;
}
- return CollectionUtils.singletonOrEmpty(result);
+ return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_HOME: {
PackageManager packageManager = mContext.getPackageManager();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4135ef3f2e0b..e851a06cbb85 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -796,10 +796,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mTmpApplySurfaceChangesTransactionState.obscured = true;
}
- mTmpApplySurfaceChangesTransactionState.displayHasContent |=
- root.handleNotObscuredLocked(w,
- mTmpApplySurfaceChangesTransactionState.obscured,
- mTmpApplySurfaceChangesTransactionState.syswin);
+ final boolean displayHasContent = root.handleNotObscuredLocked(w,
+ mTmpApplySurfaceChangesTransactionState.obscured,
+ mTmpApplySurfaceChangesTransactionState.syswin);
+
+ if (!mTmpApplySurfaceChangesTransactionState.displayHasContent
+ && !getDisplayPolicy().isWindowExcludedFromContent(w)) {
+ mTmpApplySurfaceChangesTransactionState.displayHasContent |= displayHasContent;
+ }
if (w.mHasSurface && isDisplayed) {
final int type = w.mAttrs.type;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e35ef258e96d..e5962ae19413 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -3790,6 +3790,20 @@ public class DisplayPolicy {
mPointerLocationView = null;
}
+ /**
+ * Check if the window could be excluded from checking if the display has content.
+ *
+ * @param w WindowState to check if should be excluded.
+ * @return True if the window type is PointerLocation which is excluded.
+ */
+ boolean isWindowExcludedFromContent(WindowState w) {
+ if (w != null && mPointerLocationView != null) {
+ return w.mClient == mPointerLocationView.getWindowToken();
+ }
+
+ return false;
+ }
+
@VisibleForTesting
static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
if (navBarWindow == null || !navBarWindow.isVisibleLw()
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java
index 65c5781a9114..41142f6b8505 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java
@@ -57,15 +57,15 @@ public class AppOpsActiveWatcherTest {
// Start watching active ops
final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
- appOpsManager.startWatchingActive(new int[] {AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_RECORD_AUDIO}, listener);
+ appOpsManager.startWatchingActive(new String[] {AppOpsManager.OPSTR_CAMERA,
+ AppOpsManager.OPSTR_RECORD_AUDIO}, getContext().getMainExecutor(), listener);
// Start the op
appOpsManager.startOp(AppOpsManager.OP_CAMERA);
// Verify that we got called for the op being active
verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
- .times(1)).onOpActiveChanged(eq(AppOpsManager.OP_CAMERA),
+ .times(1)).onOpActiveChanged(eq(AppOpsManager.OPSTR_CAMERA),
eq(Process.myUid()), eq(getContext().getPackageName()), eq(true));
// This should be the only callback we got
@@ -83,7 +83,7 @@ public class AppOpsActiveWatcherTest {
// Verify that we got called for the op being active
verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
- .times(1)).onOpActiveChanged(eq(AppOpsManager.OP_CAMERA),
+ .times(1)).onOpActiveChanged(eq(AppOpsManager.OPSTR_CAMERA),
eq(Process.myUid()), eq(getContext().getPackageName()), eq(false));
// Verify that the op is not active
@@ -155,4 +155,4 @@ public class AppOpsActiveWatcherTest {
private static Context getContext() {
return InstrumentationRegistry.getContext();
}
-} \ No newline at end of file
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 8f8b746b59d4..365cd80c88c7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -22,6 +22,8 @@ import static android.app.NotificationManager.IMPORTANCE_MAX;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
+
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.fail;
@@ -2690,4 +2692,51 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
verify(mHandler, times(1)).requestSort();
}
+
+ @Test
+ public void testTooManyChannels() {
+ for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+ NotificationChannel channel = new NotificationChannel(String.valueOf(i),
+ String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ }
+ try {
+ NotificationChannel channel = new NotificationChannel(
+ String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
+ String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
+ NotificationManager.IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ fail("Allowed to create too many notification channels");
+ } catch (IllegalStateException e) {
+ // great
+ }
+ }
+
+ @Test
+ public void testTooManyChannels_xml() throws Exception {
+ String extraChannel = "EXTRA";
+ String extraChannel1 = "EXTRA1";
+
+ // create first... many... directly so we don't need a big xml blob in this test
+ for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+ NotificationChannel channel = new NotificationChannel(String.valueOf(i),
+ String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+ }
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
+ + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
+ assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
+ }
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
index 1e823b63d5b2..56dc3e05a240 100644
--- a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
+++ b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
@@ -185,12 +185,14 @@ public final class ByteStream {
// Positive offsets only
throw new IllegalArgumentException();
}
- // do arithmetic and comparison in long to ovoid potention integer overflow
+ // do arithmetic and comparison in long to avoid potential integer overflow
long longNewIndex = (long) mIndex + (long) numBytes;
- if (longNewIndex < (long) mBytes.length) {
+ if (longNewIndex <= (long) mBytes.length) {
mReadCount += numBytes;
mIndex += numBytes;
} else {
+ // Position the stream to the end so available() will return 0
+ mIndex = mBytes.length;
throw new IndexOutOfBoundsException();
}
}
@@ -210,6 +212,7 @@ public final class ByteStream {
mReadCount -= numBytes;
mIndex -= numBytes;
} else {
+ mIndex = 0;
throw new IndexOutOfBoundsException();
}
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
index 7ebccf39868c..0535d717222e 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
@@ -45,7 +45,6 @@ abstract class UsbACEndpoint extends UsbDescriptor {
@Override
public int parseRawDescriptors(ByteStream stream) {
mSubtype = stream.getByte();
-
return mLength;
}
@@ -55,12 +54,21 @@ abstract class UsbACEndpoint extends UsbDescriptor {
int subClass = interfaceDesc.getUsbSubclass();
switch (subClass) {
case AUDIO_AUDIOCONTROL:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, "---> AUDIO_AUDIOCONTROL");
+ }
return new UsbACAudioControlEndpoint(length, type, subClass);
case AUDIO_AUDIOSTREAMING:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, "---> AUDIO_AUDIOSTREAMING");
+ }
return new UsbACAudioStreamEndpoint(length, type, subClass);
case AUDIO_MIDISTREAMING:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, "---> AUDIO_MIDISTREAMING");
+ }
return new UsbACMidiEndpoint(length, type, subClass);
default:
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
index 38c12a1f6c16..82fbfb89c498 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
@@ -100,8 +100,14 @@ public abstract class UsbACInterface extends UsbDescriptor {
switch (subtype) {
case ACI_HEADER:
{
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_HEADER");
+ }
int acInterfaceSpec = stream.unpackUsbShort();
parser.setACInterfaceSpec(acInterfaceSpec);
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " acInterfaceSpec:0x" + Integer.toHexString(acInterfaceSpec));
+ }
if (acInterfaceSpec == UsbDeviceDescriptor.USBSPEC_2_0) {
return new Usb20ACHeader(length, type, subtype, subClass, acInterfaceSpec);
} else {
@@ -111,7 +117,13 @@ public abstract class UsbACInterface extends UsbDescriptor {
case ACI_INPUT_TERMINAL:
{
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_INPUT_TERMINAL");
+ }
int acInterfaceSpec = parser.getACInterfaceSpec();
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " acInterfaceSpec:0x" + Integer.toHexString(acInterfaceSpec));
+ }
if (acInterfaceSpec == UsbDeviceDescriptor.USBSPEC_2_0) {
return new Usb20ACInputTerminal(length, type, subtype, subClass);
} else {
@@ -121,7 +133,13 @@ public abstract class UsbACInterface extends UsbDescriptor {
case ACI_OUTPUT_TERMINAL:
{
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_OUTPUT_TERMINAL");
+ }
int acInterfaceSpec = parser.getACInterfaceSpec();
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " acInterfaceSpec:0x" + Integer.toHexString(acInterfaceSpec));
+ }
if (acInterfaceSpec == UsbDeviceDescriptor.USBSPEC_2_0) {
return new Usb20ACOutputTerminal(length, type, subtype, subClass);
} else {
@@ -130,14 +148,26 @@ public abstract class UsbACInterface extends UsbDescriptor {
}
case ACI_SELECTOR_UNIT:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_SELECTOR_UNIT");
+ }
return new UsbACSelectorUnit(length, type, subtype, subClass);
case ACI_FEATURE_UNIT:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_FEATURE_UNIT");
+ }
return new UsbACFeatureUnit(length, type, subtype, subClass);
case ACI_MIXER_UNIT:
{
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> ACI_MIXER_UNIT");
+ }
int acInterfaceSpec = parser.getACInterfaceSpec();
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " acInterfaceSpec:0x" + Integer.toHexString(acInterfaceSpec));
+ }
if (acInterfaceSpec == UsbDeviceDescriptor.USBSPEC_2_0) {
return new Usb20ACMixerUnit(length, type, subtype, subClass);
} else {
@@ -215,14 +245,23 @@ public abstract class UsbACInterface extends UsbDescriptor {
int subClass = interfaceDesc.getUsbSubclass();
switch (subClass) {
case AUDIO_AUDIOCONTROL:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " AUDIO_AUDIOCONTROL");
+ }
return allocAudioControlDescriptor(
parser, stream, length, type, subtype, subClass);
case AUDIO_AUDIOSTREAMING:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " AUDIO_AUDIOSTREAMING");
+ }
return allocAudioStreamingDescriptor(
parser, stream, length, type, subtype, subClass);
case AUDIO_MIDISTREAMING:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " AUDIO_MIDISTREAMING");
+ }
return allocMidiStreamingDescriptor(length, type, subtype, subClass);
default:
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
index 639aa4e03849..de2dd101acfd 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
@@ -30,7 +30,6 @@ import java.util.ArrayList;
*/
public final class UsbConfigDescriptor extends UsbDescriptor {
private static final String TAG = "UsbConfigDescriptor";
- private static final boolean DEBUG = false;
private int mTotalLength; // 2:2 Total length in bytes of data returned
private byte mNumInterfaces; // 4:1 Number of Interfaces
@@ -79,14 +78,14 @@ public final class UsbConfigDescriptor extends UsbDescriptor {
}
UsbConfiguration toAndroid(UsbDescriptorParser parser) {
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, " toAndroid()");
}
String name = parser.getDescriptorString(mConfigIndex);
UsbConfiguration config = new
UsbConfiguration(mConfigValue, name, mAttribs, mMaxPower);
UsbInterface[] interfaces = new UsbInterface[mInterfaceDescriptors.size()];
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, " " + mInterfaceDescriptors.size() + " interfaces.");
}
for (int index = 0; index < mInterfaceDescriptors.size(); index++) {
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
index ff67667e848d..44422a2d4603 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
@@ -43,7 +43,7 @@ public abstract class UsbDescriptor implements Reporting {
protected int mHierarchyLevel;
protected final int mLength; // 0:1 bLength Number Size of the Descriptor in Bytes (18 bytes)
- // we store this as an int because Java bytes are SIGNED.
+ // we store this as an int because Java bytes are SIGNED.
protected final byte mType; // 1:1 bDescriptorType Constant Device Descriptor (0x01)
private byte[] mRawData;
@@ -52,11 +52,11 @@ public abstract class UsbDescriptor implements Reporting {
private static byte[] sStringBuffer = new byte[SIZE_STRINGBUFFER];
// Status
- public static final int STATUS_UNPARSED = 0;
- public static final int STATUS_PARSED_OK = 1;
- public static final int STATUS_PARSED_UNDERRUN = 2;
- public static final int STATUS_PARSED_OVERRUN = 3;
- public static final int STATUS_PARSE_EXCEPTION = 4;
+ public static final int STATUS_UNPARSED = 0;
+ public static final int STATUS_PARSED_OK = 1;
+ public static final int STATUS_PARSED_UNDERRUN = 2;
+ public static final int STATUS_PARSED_OVERRUN = 3;
+ public static final int STATUS_PARSE_EXCEPTION = 4;
private int mStatus = STATUS_UNPARSED;
@@ -78,53 +78,53 @@ public abstract class UsbDescriptor implements Reporting {
public static final byte DESCRIPTORTYPE_HID = 0x21; // 33
public static final byte DESCRIPTORTYPE_REPORT = 0x22; // 34
public static final byte DESCRIPTORTYPE_PHYSICAL = 0x23; // 35
- public static final byte DESCRIPTORTYPE_AUDIO_INTERFACE = 0x24; // 36
- public static final byte DESCRIPTORTYPE_AUDIO_ENDPOINT = 0x25; // 37
+ public static final byte DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE = 0x24; // 36
+ public static final byte DESCRIPTORTYPE_CLASSSPECIFIC_ENDPOINT = 0x25; // 37
public static final byte DESCRIPTORTYPE_HUB = 0x29; // 41
public static final byte DESCRIPTORTYPE_SUPERSPEED_HUB = 0x2A; // 42
public static final byte DESCRIPTORTYPE_ENDPOINT_COMPANION = 0x30; // 48
// Class IDs
- public static final int CLASSID_DEVICE = 0x00;
- public static final int CLASSID_AUDIO = 0x01;
- public static final int CLASSID_COM = 0x02;
- public static final int CLASSID_HID = 0x03;
+ public static final int CLASSID_DEVICE = 0x00;
+ public static final int CLASSID_AUDIO = 0x01;
+ public static final int CLASSID_COM = 0x02;
+ public static final int CLASSID_HID = 0x03;
// public static final int CLASSID_??? = 0x04;
- public static final int CLASSID_PHYSICAL = 0x05;
- public static final int CLASSID_IMAGE = 0x06;
- public static final int CLASSID_PRINTER = 0x07;
- public static final int CLASSID_STORAGE = 0x08;
- public static final int CLASSID_HUB = 0x09;
- public static final int CLASSID_CDC_CONTROL = 0x0A;
- public static final int CLASSID_SMART_CARD = 0x0B;
+ public static final int CLASSID_PHYSICAL = 0x05;
+ public static final int CLASSID_IMAGE = 0x06;
+ public static final int CLASSID_PRINTER = 0x07;
+ public static final int CLASSID_STORAGE = 0x08;
+ public static final int CLASSID_HUB = 0x09;
+ public static final int CLASSID_CDC_CONTROL = 0x0A;
+ public static final int CLASSID_SMART_CARD = 0x0B;
//public static final int CLASSID_??? = 0x0C;
- public static final int CLASSID_SECURITY = 0x0D;
- public static final int CLASSID_VIDEO = 0x0E;
- public static final int CLASSID_HEALTHCARE = 0x0F;
- public static final int CLASSID_AUDIOVIDEO = 0x10;
- public static final int CLASSID_BILLBOARD = 0x11;
- public static final int CLASSID_TYPECBRIDGE = 0x12;
- public static final int CLASSID_DIAGNOSTIC = 0xDC;
- public static final int CLASSID_WIRELESS = 0xE0;
- public static final int CLASSID_MISC = 0xEF;
- public static final int CLASSID_APPSPECIFIC = 0xFE;
+ public static final int CLASSID_SECURITY = 0x0D;
+ public static final int CLASSID_VIDEO = 0x0E;
+ public static final int CLASSID_HEALTHCARE = 0x0F;
+ public static final int CLASSID_AUDIOVIDEO = 0x10;
+ public static final int CLASSID_BILLBOARD = 0x11;
+ public static final int CLASSID_TYPECBRIDGE = 0x12;
+ public static final int CLASSID_DIAGNOSTIC = 0xDC;
+ public static final int CLASSID_WIRELESS = 0xE0;
+ public static final int CLASSID_MISC = 0xEF;
+ public static final int CLASSID_APPSPECIFIC = 0xFE;
public static final int CLASSID_VENDSPECIFIC = 0xFF;
// Audio Subclass codes
- public static final int AUDIO_SUBCLASS_UNDEFINED = 0x00;
- public static final int AUDIO_AUDIOCONTROL = 0x01;
- public static final int AUDIO_AUDIOSTREAMING = 0x02;
- public static final int AUDIO_MIDISTREAMING = 0x03;
+ public static final int AUDIO_SUBCLASS_UNDEFINED = 0x00;
+ public static final int AUDIO_AUDIOCONTROL = 0x01;
+ public static final int AUDIO_AUDIOSTREAMING = 0x02;
+ public static final int AUDIO_MIDISTREAMING = 0x03;
// Request IDs
- public static final int REQUEST_GET_STATUS = 0x00;
- public static final int REQUEST_CLEAR_FEATURE = 0x01;
- public static final int REQUEST_SET_FEATURE = 0x03;
- public static final int REQUEST_GET_ADDRESS = 0x05;
- public static final int REQUEST_GET_DESCRIPTOR = 0x06;
- public static final int REQUEST_SET_DESCRIPTOR = 0x07;
- public static final int REQUEST_GET_CONFIGURATION = 0x08;
- public static final int REQUEST_SET_CONFIGURATION = 0x09;
+ public static final int REQUEST_GET_STATUS = 0x00;
+ public static final int REQUEST_CLEAR_FEATURE = 0x01;
+ public static final int REQUEST_SET_FEATURE = 0x03;
+ public static final int REQUEST_GET_ADDRESS = 0x05;
+ public static final int REQUEST_GET_DESCRIPTOR = 0x06;
+ public static final int REQUEST_SET_DESCRIPTOR = 0x07;
+ public static final int REQUEST_GET_CONFIGURATION = 0x08;
+ public static final int REQUEST_SET_CONFIGURATION = 0x09;
// USB control transfer timeout
public static final int USB_CONTROL_TRANSFER_TIMEOUT_MS = 200;
@@ -163,7 +163,6 @@ public abstract class UsbDescriptor implements Reporting {
public int getOverUnderRunCount() {
return mOverUnderRunCount;
}
-
public String getStatusString() {
return sStatusStrings[mStatus];
}
@@ -278,4 +277,24 @@ public abstract class UsbDescriptor implements Reporting {
+ " Len: " + getLength();
canvas.writeParagraph(text, false);
}
+
+ /*
+ * Logging Helpers
+ */
+ static String getDescriptorName(byte descriptorType, int descriptorLength) {
+ String name = UsbStrings.getDescriptorName(descriptorType);
+ if (name != null) {
+ return name;
+ } else {
+ return "Unknown Descriptor Type " + descriptorType
+ + " 0x" + Integer.toHexString(descriptorType)
+ + " length:" + descriptorLength;
+ }
+ }
+
+ static void logDescriptorName(byte descriptorType, int descriptorLength) {
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, "----> " + getDescriptorName(descriptorType, descriptorLength));
+ }
+ }
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index c02110186d8d..4f62d5a5c967 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
*/
public final class UsbDescriptorParser {
private static final String TAG = "UsbDescriptorParser";
- private static final boolean DEBUG = false;
+ public static final boolean DEBUG = false;
private final String mDeviceAddr;
@@ -115,6 +115,8 @@ public final class UsbDescriptorParser {
int length = stream.getUnsignedByte();
byte type = stream.getByte();
+ UsbDescriptor.logDescriptorName(type, length);
+
UsbDescriptor descriptor = null;
switch (type) {
/*
@@ -174,14 +176,56 @@ public final class UsbDescriptorParser {
break;
/*
- * Audio Class Specific
+ * Various Class Specific
*/
- case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
- descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+ case UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE:
+ if (mCurInterfaceDescriptor != null) {
+ switch (mCurInterfaceDescriptor.getUsbClass()) {
+ case UsbDescriptor.CLASSID_AUDIO:
+ descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+ break;
+
+ case UsbDescriptor.CLASSID_VIDEO:
+ Log.d(TAG, " UsbDescriptor.CLASSID_VIDEO subType:0x"
+ + Integer.toHexString(stream.getByte()));
+ descriptor = UsbVCInterface.allocDescriptor(this, stream, length, type);
+ break;
+
+ case UsbDescriptor.CLASSID_AUDIOVIDEO:
+ Log.d(TAG, " UsbDescriptor.CLASSID_AUDIOVIDEO subType:0x"
+ + Integer.toHexString(stream.getByte()));
+ break;
+
+ default:
+ Log.d(TAG, " Unparsed Class-specific Interface:0x"
+ + Integer.toHexString(mCurInterfaceDescriptor.getUsbClass()));
+ break;
+ }
+ }
break;
- case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
- descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+ case UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_ENDPOINT:
+ if (mCurInterfaceDescriptor != null) {
+ switch (mCurInterfaceDescriptor.getUsbClass()) {
+ case UsbDescriptor.CLASSID_AUDIO:
+ descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+ break;
+ case UsbDescriptor.CLASSID_VIDEO:
+ Log.d(TAG, "UsbDescriptor.CLASSID_VIDEO subType:0x"
+ + Integer.toHexString(stream.getByte()));
+ descriptor = UsbVCEndpoint.allocDescriptor(this, length, type);
+ break;
+
+ case UsbDescriptor.CLASSID_AUDIOVIDEO:
+ Log.d(TAG, "UsbDescriptor.CLASSID_AUDIOVIDEO subType:0x"
+ + Integer.toHexString(stream.getByte()));
+ break;
+ default:
+ Log.d(TAG, " Unparsed Class-specific Endpoint:0x"
+ + Integer.toHexString(mCurInterfaceDescriptor.getUsbClass()));
+ break;
+ }
+ }
break;
default:
@@ -190,8 +234,6 @@ public final class UsbDescriptorParser {
if (descriptor == null) {
// Unknown Descriptor
- Log.i(TAG, "Unknown Descriptor len: " + length + " type:0x"
- + Integer.toHexString(type));
descriptor = new UsbUnknown(length, type);
}
@@ -210,10 +252,6 @@ public final class UsbDescriptorParser {
* @hide
*/
public void parseDescriptors(byte[] descriptors) {
- if (DEBUG) {
- Log.d(TAG, "parseDescriptors() - start");
- }
-
ByteStream stream = new ByteStream(descriptors);
while (stream.available() > 0) {
UsbDescriptor descriptor = null;
@@ -325,8 +363,8 @@ public final class UsbDescriptorParser {
public ArrayList<UsbDescriptor> getACInterfaceDescriptors(byte subtype, int subclass) {
ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
for (UsbDescriptor descriptor : mDescriptors) {
- if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE) {
- // ensure that this isn't an unrecognized DESCRIPTORTYPE_AUDIO_INTERFACE
+ if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE) {
+ // ensure that this isn't an unrecognized DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE
if (descriptor instanceof UsbACInterface) {
UsbACInterface acDescriptor = (UsbACInterface) descriptor;
if (acDescriptor.getSubtype() == subtype
@@ -334,8 +372,8 @@ public final class UsbDescriptorParser {
list.add(descriptor);
}
} else {
- Log.w(TAG, "Unrecognized Audio Interface l: " + descriptor.getLength()
- + " t:0x" + Integer.toHexString(descriptor.getType()));
+ Log.w(TAG, "Unrecognized Audio Interface len: " + descriptor.getLength()
+ + " type:0x" + Integer.toHexString(descriptor.getType()));
}
}
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
index f50b9cbc5e3d..e6e10fef9f9a 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -31,7 +31,6 @@ import java.util.ArrayList;
*/
public final class UsbDeviceDescriptor extends UsbDescriptor {
private static final String TAG = "UsbDeviceDescriptor";
- private static final boolean DEBUG = false;
public static final int USBSPEC_1_0 = 0x0100;
public static final int USBSPEC_1_1 = 0x0110;
@@ -136,19 +135,19 @@ public final class UsbDeviceDescriptor extends UsbDescriptor {
* @hide
*/
public UsbDevice.Builder toAndroid(UsbDescriptorParser parser) {
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, "toAndroid()");
}
String mfgName = getMfgString(parser);
String prodName = getProductString(parser);
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, " mfgName:" + mfgName + " prodName:" + prodName);
}
String versionString = getDeviceReleaseString();
String serialStr = getSerialString(parser);
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, " versionString:" + versionString + " serialStr:" + serialStr);
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
index 4da31ea469c3..5eb0a2f75ded 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
@@ -27,7 +27,6 @@ import com.android.server.usb.descriptors.report.ReportCanvas;
*/
public class UsbEndpointDescriptor extends UsbDescriptor {
private static final String TAG = "UsbEndpointDescriptor";
- private static final boolean DEBUG = false;
public static final int MASK_ENDPOINT_ADDRESS = 0b000000000001111;
public static final int MASK_ENDPOINT_DIRECTION = (byte) 0b0000000010000000;
@@ -110,7 +109,7 @@ public class UsbEndpointDescriptor extends UsbDescriptor {
}
/* package */ UsbEndpoint toAndroid(UsbDescriptorParser parser) {
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, "toAndroid() type:"
+ Integer.toHexString(mAttributes & MASK_ATTRIBS_TRANSTYPE)
+ " sync:" + Integer.toHexString(mAttributes & MASK_ATTRIBS_SYNCTYPE)
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
index 632e3dc500fa..1dc6069bbb0a 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
@@ -31,7 +31,6 @@ import java.util.ArrayList;
*/
public class UsbInterfaceDescriptor extends UsbDescriptor {
private static final String TAG = "UsbInterfaceDescriptor";
- private static final boolean DEBUG = false;
protected int mInterfaceNumber; // 2:1 Number of Interface
protected byte mAlternateSetting; // 3:1 Value used to select alternative setting
@@ -95,7 +94,7 @@ public class UsbInterfaceDescriptor extends UsbDescriptor {
}
UsbInterface toAndroid(UsbDescriptorParser parser) {
- if (DEBUG) {
+ if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, "toAndroid() class:" + Integer.toHexString(mUsbClass)
+ " subclass:" + Integer.toHexString(mUsbSubclass)
+ " " + mEndpointDescriptors.size() + " endpoints.");
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbVCEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbVCEndpoint.java
new file mode 100644
index 000000000000..39fbc0d50b87
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbVCEndpoint.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 com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * A video class-specific Endpoint
+ * see
+ */
+abstract class UsbVCEndpoint extends UsbDescriptor {
+ private static final String TAG = "UsbVCEndpoint";
+
+ UsbVCEndpoint(int length, byte type, int subclass) {
+ super(length, type);
+ // mSubclass = subclass;
+ }
+
+ public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser,
+ int length, byte type) {
+ UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+ int subClass = interfaceDesc.getUsbSubclass();
+ switch (subClass) {
+// case AUDIO_AUDIOCONTROL:
+// if (UsbDescriptorParser.DEBUG) {
+// Log.i(TAG, "---> AUDIO_AUDIOCONTROL");
+// }
+// return new UsbACAudioControlEndpoint(length, type, subClass);
+//
+// case AUDIO_AUDIOSTREAMING:
+// if (UsbDescriptorParser.DEBUG) {
+// Log.i(TAG, "---> AUDIO_AUDIOSTREAMING");
+// }
+// return new UsbACAudioStreamEndpoint(length, type, subClass);
+//
+// case AUDIO_MIDISTREAMING:
+// if (UsbDescriptorParser.DEBUG) {
+// Log.i(TAG, "---> AUDIO_MIDISTREAMING");
+// }
+// return new UsbACMidiEndpoint(length, type, subClass);
+
+ default:
+ Log.w(TAG, "Unknown Video Class Endpoint id:0x" + Integer.toHexString(subClass));
+ return null;
+ }
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbVCInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbVCInterface.java
new file mode 100644
index 000000000000..c9eb1ec36eb1
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbVCInterface.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * A video class-specific Interface.
+ * see USB_Video_Class_1.1.pdf, section 3.7.2
+ */
+public abstract class UsbVCInterface extends UsbDescriptor {
+ private static final String TAG = "UsbVCInterface";
+
+ // Class-specific Video Subtypes
+ public static final byte VCI_UNDEFINED = 0x00;
+ public static final byte VCI_VEADER = 0x01;
+ public static final byte VCI_INPUT_TERMINAL = 0x02;
+ public static final byte VCI_VOUTPUT_TERMINAL = 0x03;
+ public static final byte VCI_SELECTOR_UNIT = 0x04;
+ public static final byte VCI_VROCESSING_UNIT = 0x05;
+ public static final byte VCI_VEXTENSION_UNIT = 0x06;
+
+ // See “Universal Serial Bus Device Class Definition for Video
+ protected final byte mSubtype; // 2:1 HEADER descriptor subtype
+ protected final int mSubclass; // from the mSubclass member of the
+ // "enclosing" Interface Descriptor
+
+ public UsbVCInterface(int length, byte type, byte subtype, int subclass) {
+ super(length, type);
+ mSubtype = subtype;
+ mSubclass = subclass;
+ }
+
+ /**
+ * Allocates an audio class interface subtype based on subtype and subclass.
+ */
+ public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, ByteStream stream,
+ int length, byte type) {
+ byte subtype = stream.getByte();
+ UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+ int subClass = interfaceDesc.getUsbSubclass();
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " Video Class-specific Interface subClass:0x"
+ + Integer.toHexString(subClass));
+ }
+ switch (subClass) {
+ // TODO - Create descriptor classes and parse these...
+ case VCI_UNDEFINED:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_UNDEFINED");
+ }
+ break;
+
+ case VCI_VEADER:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_VEADER");
+ }
+ break;
+
+ case VCI_INPUT_TERMINAL:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_INPUT_TERMINAL");
+ }
+ break;
+
+ case VCI_VOUTPUT_TERMINAL:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_VOUTPUT_TERMINAL");
+ }
+ break;
+
+ case VCI_SELECTOR_UNIT:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_SELECTOR_UNIT");
+ }
+ break;
+
+ case VCI_VROCESSING_UNIT:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_VROCESSING_UNIT");
+ }
+ break;
+
+ case VCI_VEXTENSION_UNIT:
+ if (UsbDescriptorParser.DEBUG) {
+ Log.d(TAG, " ---> VCI_VEXTENSION_UNIT");
+ }
+ break;
+
+ default:
+ Log.w(TAG, "Unknown Video Class Interface Subclass: 0x"
+ + Integer.toHexString(subClass));
+ return null;
+ }
+
+ return null;
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
index fb4576a6ee78..918ba2cc9249 100644
--- a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
+++ b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
@@ -56,9 +56,10 @@ public final class UsbStrings {
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HID, "HID");
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_REPORT, "Report");
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_PHYSICAL, "Physical");
- sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE,
- "Audio Class Interface");
- sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT, "Audio Class Endpoint");
+ sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE,
+ "Class-specific Interface");
+ sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_ENDPOINT,
+ "Class-specific Endpoint");
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HUB, "Hub");
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_SUPERSPEED_HUB, "Superspeed Hub");
sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT_COMPANION,
diff --git a/services/usb/java/com/android/server/usb/descriptors/tree/UsbDescriptorsTree.java b/services/usb/java/com/android/server/usb/descriptors/tree/UsbDescriptorsTree.java
index 1aa30fa94f42..72fa8977b675 100644
--- a/services/usb/java/com/android/server/usb/descriptors/tree/UsbDescriptorsTree.java
+++ b/services/usb/java/com/android/server/usb/descriptors/tree/UsbDescriptorsTree.java
@@ -126,11 +126,13 @@ public final class UsbDescriptorsTree {
//
// Audio Class Descriptors
//
- case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
- addACInterface((UsbACInterface) descriptor);
+ case UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_INTERFACE:
+ //TODO: This needs to be parsed out to Audio/Video...
+ // addACInterface((UsbACInterface) descriptor);
break;
- case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
+ case UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_ENDPOINT:
+ //TODO: This needs to be parsed out to Audio/Video...
break;
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index b2ac5490440d..6132cc2250b9 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -52,8 +52,9 @@ import android.os.Parcel;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.Trace;
import android.os.UserHandle;
-import android.os.UserManager;
+import android.os.UserManagerInternal;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
@@ -95,14 +96,14 @@ import java.util.concurrent.Executor;
*/
public class VoiceInteractionManagerService extends SystemService {
static final String TAG = "VoiceInteractionManagerService";
- static final boolean DEBUG = true; // TODO(b/133242016) STOPSHIP: change to false before R ships
+ static final boolean DEBUG = false;
final Context mContext;
final ContentResolver mResolver;
final DatabaseHelper mDbHelper;
final ActivityManagerInternal mAmInternal;
final ActivityTaskManagerInternal mAtmInternal;
- final UserManager mUserManager;
+ final UserManagerInternal mUserManagerInternal;
final ArraySet<Integer> mLoadedKeyphraseIds = new ArraySet<>();
ShortcutServiceInternal mShortcutServiceInternal;
SoundTriggerInternal mSoundTriggerInternal;
@@ -120,8 +121,8 @@ public class VoiceInteractionManagerService extends SystemService {
LocalServices.getService(ActivityManagerInternal.class));
mAtmInternal = Preconditions.checkNotNull(
LocalServices.getService(ActivityTaskManagerInternal.class));
- mUserManager = Preconditions.checkNotNull(
- context.getSystemService(UserManager.class));
+ mUserManagerInternal = Preconditions.checkNotNull(
+ LocalServices.getService(UserManagerInternal.class));
PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
PermissionManagerServiceInternal.class);
@@ -157,37 +158,30 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
+ public boolean isSupported(UserInfo userInfo) {
+ return userInfo.isFull();
+ }
+
+ @Override
public void onStartUser(@NonNull UserInfo userInfo) {
- if (DEBUG) Slog.d(TAG, "onStartUser(" + userInfo + ")");
+ if (DEBUG_USER) Slog.d(TAG, "onStartUser(" + userInfo + ")");
- if (!userInfo.isFull()) {
- if (DEBUG) Slog.d(TAG, "***** skipping on non-full user " + userInfo);
- return;
- }
mServiceStub.initForUser(userInfo.id);
}
@Override
public void onUnlockUser(@NonNull UserInfo userInfo) {
- if (DEBUG) Slog.d(TAG, "onUnlockUser(" + userInfo + ")");
+ if (DEBUG_USER) Slog.d(TAG, "onUnlockUser(" + userInfo + ")");
- if (!userInfo.isFull()) {
- if (DEBUG) Slog.d(TAG, "***** skipping on non-full user " + userInfo);
- return;
- }
mServiceStub.initForUser(userInfo.id);
mServiceStub.switchImplementationIfNeeded(false);
}
@Override
- public void onSwitchUser(@NonNull UserInfo userInfo) {
- if (DEBUG) Slog.d(TAG, "onSwitchUser(" + userInfo + ")");
+ public void onSwitchUser(@NonNull UserInfo from, @NonNull UserInfo to) {
+ if (DEBUG_USER) Slog.d(TAG, "onSwitchUser(" + from + " > " + to + ")");
- if (!userInfo.isFull()) {
- if (DEBUG) Slog.d(TAG, "***** skipping on non-full user " + userInfo);
- return;
- }
- mServiceStub.switchUser(userInfo.id);
+ mServiceStub.switchUser(to.id);
}
class LocalService extends VoiceInteractionManagerInternal {
@@ -225,6 +219,7 @@ public class VoiceInteractionManagerService extends SystemService {
private boolean mSafeMode;
private int mCurUser;
private boolean mCurUserUnlocked;
+ private boolean mCurUserSupported;
private final boolean mEnableService;
VoiceInteractionManagerServiceStub() {
@@ -292,9 +287,9 @@ public class VoiceInteractionManagerService extends SystemService {
public void initForUser(int userHandle) {
final TimingsTraceAndSlog t;
- if (DEBUG) {
- t = TimingsTraceAndSlog.newAsyncLog();
- t.traceBegin("VoiceInteractionSvc.initForUser(" + userHandle + ")");
+ if (DEBUG_USER) {
+ t = new TimingsTraceAndSlog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("initForUser(" + userHandle + ")");
} else {
t = null;
}
@@ -439,15 +434,21 @@ public class VoiceInteractionManagerService extends SystemService {
new SettingsObserver(UiThread.getHandler());
synchronized (this) {
- mCurUser = ActivityManager.getCurrentUser();
+ setCurrentUserLocked(ActivityManager.getCurrentUser());
switchImplementationIfNeededLocked(false);
}
}
- public void switchUser(int userHandle) {
+ private void setCurrentUserLocked(@UserIdInt int userHandle) {
+ mCurUser = userHandle;
+ final UserInfo userInfo = mUserManagerInternal.getUserInfo(mCurUser);
+ mCurUserSupported = isSupported(userInfo);
+ }
+
+ public void switchUser(@UserIdInt int userHandle) {
FgThread.getHandler().post(() -> {
synchronized (this) {
- mCurUser = userHandle;
+ setCurrentUserLocked(userHandle);
mCurUserUnlocked = false;
switchImplementationIfNeededLocked(false);
}
@@ -461,10 +462,22 @@ public class VoiceInteractionManagerService extends SystemService {
}
void switchImplementationIfNeededLocked(boolean force) {
+ if (!mCurUserSupported) {
+ if (DEBUG_USER) {
+ Slog.d(TAG, "switchImplementationIfNeeded(): skipping on unsuported user "
+ + mCurUser);
+ }
+ if (mImpl != null) {
+ mImpl.shutdownLocked();
+ setImplLocked(null);
+ }
+ return;
+ }
+
final TimingsTraceAndSlog t;
- if (DEBUG) {
- t = TimingsTraceAndSlog.newAsyncLog();
- t.traceBegin("VoiceInteractionSvc.switchImplementation(" + mCurUser + ")");
+ if (DEBUG_USER) {
+ t = new TimingsTraceAndSlog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("switchImplementation(" + mCurUser + ")");
} else {
t = null;
}
@@ -494,7 +507,7 @@ public class VoiceInteractionManagerService extends SystemService {
final boolean hasComponent = serviceComponent != null && serviceInfo != null;
- if (mUserManager.isUserUnlockingOrUnlocked(mCurUser)) {
+ if (mUserManagerInternal.isUserUnlockingOrUnlocked(mCurUser)) {
if (hasComponent) {
mShortcutServiceInternal.setShortcutHostPackage(TAG,
serviceComponent.getPackageName(), mCurUser);
@@ -1275,6 +1288,9 @@ public class VoiceInteractionManagerService extends SystemService {
synchronized (this) {
pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
+ pw.println(" mCurUser: " + mCurUser);
+ pw.println(" mCurUserUnlocked: " + mCurUserUnlocked);
+ pw.println(" mCurUserSupported: " + mCurUserSupported);
if (mImpl == null) {
pw.println(" (No active implementation)");
return;
@@ -1330,9 +1346,12 @@ public class VoiceInteractionManagerService extends SystemService {
RoleObserver(@NonNull @CallbackExecutor Executor executor) {
mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
- UserHandle currentUser = UserHandle.of(LocalServices.getService(
- ActivityManagerInternal.class).getCurrentUserId());
- onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
+ // Sync only if assistant role has been initialized.
+ if (mRm.isRoleAvailable(RoleManager.ROLE_ASSISTANT)) {
+ UserHandle currentUser = UserHandle.of(LocalServices.getService(
+ ActivityManagerInternal.class).getCurrentUserId());
+ onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
+ }
}
private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 42a5501cc229..bf6c0197a468 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -4058,6 +4058,53 @@ public final class Telephony {
public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
/**
+ * The Epoch Unix timestamp when the device received the message.
+ * <P>Type: INTEGER</P>
+ */
+ public static final String RECEIVED_TIME = "received_time";
+
+ /**
+ * Indicates that whether the message has been broadcasted to the application.
+ * <P>Type: BOOLEAN</P>
+ */
+ public static final String MESSAGE_BROADCASTED = "message_broadcasted";
+
+ /**
+ * The Warning Area Coordinates Elements. This element is used for geo-fencing purpose.
+ *
+ * The geometry and its coordinates are separated vertical bar, the first item is the
+ * geometry type and the remaining items are the parameter of this geometry.
+ *
+ * Only circle and polygon are supported. The coordinates are represented in Horizontal
+ * coordinates format.
+ *
+ * Coordinate encoding:
+ * "latitude, longitude"
+ * where -90.00000 <= latitude <= 90.00000 and -180.00000 <= longitude <= 180.00000
+ *
+ * Polygon encoding:
+ * "polygon|lat1,lng1|lat2,lng2|...|latn,lngn"
+ * lat1,lng1 ... latn,lngn are the vertices coordinate of the polygon.
+ *
+ * Circle encoding:
+ * "circle|lat,lng|radius".
+ * lat,lng is the center of the circle. The unit of circle's radius is meter.
+ *
+ * Example:
+ * "circle|0,0|100" mean a circle which center located at (0,0) and its radius is 100 meter.
+ * "polygon|0,1.5|0,1|1,1|1,0" mean a polygon has vertices (0,1.5),(0,1),(1,1),(1,0).
+ *
+ * There could be more than one geometry store in this field, they are separated by a
+ * semicolon.
+ *
+ * Example:
+ * "circle|0,0|100;polygon|0,0|0,1.5|1,1|1,0;circle|100.123,100|200.123"
+ *
+ * <P>Type: TEXT</P>
+ */
+ public static final String GEOMETRIES = "geometries";
+
+ /**
* Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
*/
public static final String[] QUERY_COLUMNS = {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7d9462adbc79..654b54d988cf 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1403,6 +1403,13 @@ public class CarrierConfigManager {
"read_only_apn_fields_string_array";
/**
+ * Default value of APN types field if not specified by user when adding/modifying an APN.
+ * @hide
+ */
+ public static final String KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY =
+ "apn_settings_default_apn_types_string_array";
+
+ /**
* Boolean indicating if intent for emergency call state changes should be broadcast
* @hide
*/
@@ -3275,6 +3282,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true);
sDefaults.putStringArray(KEY_READ_ONLY_APN_TYPES_STRING_ARRAY, new String[] {"dun"});
sDefaults.putStringArray(KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
new file mode 100644
index 000000000000..c973b672ae40
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.annotation.NonNull;
+import android.telephony.Rlog;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * This utils class is specifically used for geo-targeting of CellBroadcast messages.
+ * The coordinates used by this utils class are latitude and longitude, but some algorithms in this
+ * class only use them as coordinates on plane, so the calculation will be inaccurate. So don't use
+ * this class for anything other then geo-targeting of cellbroadcast messages.
+ */
+public class CbGeoUtils {
+ /** Geometric interface. */
+ public interface Geometry {
+ /**
+ * Determines if the given point {@code p} is inside the geometry.
+ * @param p point in latitude, longitude format.
+ * @return {@code True} if the given point is inside the geometry.
+ */
+ boolean contains(LatLng p);
+ }
+
+ /**
+ * Tolerance for determining if the value is 0. If the absolute value of a value is less than
+ * this tolerance, it will be treated as 0.
+ */
+ public static final double EPS = 1e-7;
+
+ /** The radius of earth. */
+ public static final int EARTH_RADIUS_METER = 6371 * 1000;
+
+ private static final String TAG = "CbGeoUtils";
+
+ /** The identifier of geometry in the encoded string. */
+ private static final String CIRCLE_SYMBOL = "circle";
+ private static final String POLYGON_SYMBOL = "polygon";
+
+ /** Point represent by (latitude, longitude). */
+ public static class LatLng {
+ public final double lat;
+ public final double lng;
+
+ /**
+ * Constructor.
+ * @param lat latitude, range [-90, 90]
+ * @param lng longitude, range [-180, 180]
+ */
+ public LatLng(double lat, double lng) {
+ this.lat = lat;
+ this.lng = lng;
+ }
+
+ /**
+ * @param p the point use to calculate the subtraction result.
+ * @return the result of this point subtract the given point {@code p}.
+ */
+ public LatLng subtract(LatLng p) {
+ return new LatLng(lat - p.lat, lng - p.lng);
+ }
+
+ /**
+ * Calculate the distance in meter between this point and the given point {@code p}.
+ * @param p the point use to calculate the distance.
+ * @return the distance in meter.
+ */
+ public double distance(LatLng p) {
+ double dlat = Math.sin(0.5 * Math.toRadians(lat - p.lat));
+ double dlng = Math.sin(0.5 * Math.toRadians(lng - p.lng));
+ double x = dlat * dlat
+ + dlng * dlng * Math.cos(Math.toRadians(lat)) * Math.cos(Math.toRadians(p.lat));
+ return 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x)) * EARTH_RADIUS_METER;
+ }
+ }
+
+ /**
+ * The class represents a simple polygon with at least 3 points.
+ */
+ public static class Polygon implements Geometry {
+ /**
+ * In order to reduce the loss of precision in floating point calculations, all vertices
+ * of the polygon are scaled. Set the value of scale to 1000 can take into account the
+ * actual distance accuracy of 1 meter if the EPS is 1e-7 during the calculation.
+ */
+ private static final double SCALE = 1000.0;
+
+ private final List<LatLng> mVertices;
+ private final List<Point> mScaledVertices;
+ private final LatLng mOrigin;
+
+ /**
+ * Constructs a simple polygon from the given vertices. The adjacent two vertices are
+ * connected to form an edge of the polygon. The polygon has at least 3 vertices, and the
+ * last vertices and the first vertices must be adjacent.
+ *
+ * The longitude difference in the vertices should be less than 180 degree.
+ */
+ public Polygon(@NonNull List<LatLng> vertices) {
+ mVertices = vertices;
+
+ // Find the point with smallest longitude as the mOrigin point.
+ int idx = 0;
+ for (int i = 1; i < vertices.size(); i++) {
+ if (vertices.get(i).lng < vertices.get(idx).lng) {
+ idx = i;
+ }
+ }
+ mOrigin = vertices.get(idx);
+
+ mScaledVertices = vertices.stream()
+ .map(latLng -> convertAndScaleLatLng(latLng))
+ .collect(Collectors.toList());
+ }
+
+ public List<LatLng> getVertices() {
+ return mVertices;
+ }
+
+ /**
+ * Check if the given point {@code p} is inside the polygon. This method counts the number
+ * of times the polygon winds around the point P, A.K.A "winding number". The point is
+ * outside only when this "winding number" is 0.
+ *
+ * If a point is on the edge of the polygon, it is also considered to be inside the polygon.
+ */
+ @Override
+ public boolean contains(LatLng latLng) {
+ Point p = convertAndScaleLatLng(latLng);
+
+ int n = mScaledVertices.size();
+ int windingNumber = 0;
+ for (int i = 0; i < n; i++) {
+ Point a = mScaledVertices.get(i);
+ Point b = mScaledVertices.get((i + 1) % n);
+
+ // CCW is counterclockwise
+ // CCW = ab x ap
+ // CCW > 0 -> ap is on the left side of ab
+ // CCW == 0 -> ap is on the same line of ab
+ // CCW < 0 -> ap is on the right side of ab
+ int ccw = sign(crossProduct(b.subtract(a), p.subtract(a)));
+
+ if (ccw == 0) {
+ if (Math.min(a.x, b.x) <= p.x && p.x <= Math.max(a.x, b.x)
+ && Math.min(a.y, b.y) <= p.y && p.y <= Math.max(a.y, b.y)) {
+ return true;
+ }
+ } else {
+ if (sign(a.y - p.y) <= 0) {
+ // upward crossing
+ if (ccw > 0 && sign(b.y - p.y) > 0) {
+ ++windingNumber;
+ }
+ } else {
+ // downward crossing
+ if (ccw < 0 && sign(b.y - p.y) <= 0) {
+ --windingNumber;
+ }
+ }
+ }
+ }
+ return windingNumber != 0;
+ }
+
+ /**
+ * Move the given point {@code latLng} to the coordinate system with {@code mOrigin} as the
+ * origin and scale it. {@code mOrigin} is selected from the vertices of a polygon, it has
+ * the smallest longitude value among all of the polygon vertices.
+ *
+ * @param latLng the point need to be converted and scaled.
+ * @Return a {@link Point} object.
+ */
+ private Point convertAndScaleLatLng(LatLng latLng) {
+ double x = latLng.lat - mOrigin.lat;
+ double y = latLng.lng - mOrigin.lng;
+
+ // If the point is in different hemispheres(western/eastern) than the mOrigin, and the
+ // edge between them cross the 180th meridian, then its relative coordinates will be
+ // extended.
+ // For example, suppose the longitude of the mOrigin is -178, and the longitude of the
+ // point to be converted is 175, then the longitude after the conversion is -8.
+ // calculation: (-178 - 8) - (-178).
+ if (sign(mOrigin.lng) != 0 && sign(mOrigin.lng) != sign(latLng.lng)) {
+ double distCross0thMeridian = Math.abs(mOrigin.lng) + Math.abs(latLng.lng);
+ if (sign(distCross0thMeridian * 2 - 360) > 0) {
+ y = sign(mOrigin.lng) * (360 - distCross0thMeridian);
+ }
+ }
+ return new Point(x * SCALE, y * SCALE);
+ }
+
+ private static double crossProduct(Point a, Point b) {
+ return a.x * b.y - a.y * b.x;
+ }
+
+ static final class Point {
+ public final double x;
+ public final double y;
+
+ Point(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Point subtract(Point p) {
+ return new Point(x - p.x, y - p.y);
+ }
+ }
+ }
+
+ /** The class represents a circle. */
+ public static class Circle implements Geometry {
+ private final LatLng mCenter;
+ private final double mRadiusMeter;
+
+ public Circle(LatLng center, double radiusMeter) {
+ this.mCenter = center;
+ this.mRadiusMeter = radiusMeter;
+ }
+
+ public LatLng getCenter() {
+ return mCenter;
+ }
+
+ public double getRadius() {
+ return mRadiusMeter;
+ }
+
+ @Override
+ public boolean contains(LatLng p) {
+ return mCenter.distance(p) <= mRadiusMeter;
+ }
+ }
+
+ /**
+ * Parse the geometries from the encoded string {@code str}. The string must follow the
+ * geometry encoding specified by {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+ */
+ @NonNull
+ public static List<Geometry> parseGeometriesFromString(@NonNull String str) {
+ List<Geometry> geometries = new ArrayList<>();
+ for (String geometryStr : str.split("\\s*;\\s*")) {
+ String[] geoParameters = geometryStr.split("\\s*\\|\\s*");
+ switch (geoParameters[0]) {
+ case CIRCLE_SYMBOL:
+ geometries.add(new Circle(parseLatLngFromString(geoParameters[1]),
+ Double.parseDouble(geoParameters[2])));
+ break;
+ case POLYGON_SYMBOL:
+ List<LatLng> vertices = new ArrayList<>(geoParameters.length - 1);
+ for (int i = 1; i < geoParameters.length; i++) {
+ vertices.add(parseLatLngFromString(geoParameters[i]));
+ }
+ geometries.add(new Polygon(vertices));
+ break;
+ default:
+ Rlog.e(TAG, "Invalid geometry format " + geometryStr);
+ }
+ }
+ return geometries;
+ }
+
+ /**
+ * Encode a list of geometry objects to string. The encoding format is specified by
+ * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+ *
+ * @param geometries the list of geometry objects need to be encoded.
+ * @return the encoded string.
+ */
+ @NonNull
+ public static String encodeGeometriesToString(@NonNull List<Geometry> geometries) {
+ return geometries.stream()
+ .map(geometry -> encodeGeometryToString(geometry))
+ .filter(encodedStr -> !TextUtils.isEmpty(encodedStr))
+ .collect(Collectors.joining(";"));
+ }
+
+
+ /**
+ * Encode the geometry object to string. The encoding format is specified by
+ * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+ * @param geometry the geometry object need to be encoded.
+ * @return the encoded string.
+ */
+ @NonNull
+ private static String encodeGeometryToString(@NonNull Geometry geometry) {
+ StringBuilder sb = new StringBuilder();
+ if (geometry instanceof Polygon) {
+ sb.append(POLYGON_SYMBOL);
+ for (LatLng latLng : ((Polygon) geometry).getVertices()) {
+ sb.append("|");
+ sb.append(latLng.lat);
+ sb.append(",");
+ sb.append(latLng.lng);
+ }
+ } else if (geometry instanceof Circle) {
+ sb.append(CIRCLE_SYMBOL);
+ Circle circle = (Circle) geometry;
+
+ // Center
+ sb.append("|");
+ sb.append(circle.getCenter().lat);
+ sb.append(",");
+ sb.append(circle.getCenter().lng);
+
+ // Radius
+ sb.append("|");
+ sb.append(circle.getRadius());
+ } else {
+ Rlog.e(TAG, "Unsupported geometry object " + geometry);
+ return null;
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Parse {@link LatLng} from {@link String}. Latitude and longitude are separated by ",".
+ * Example: "13.56,-55.447".
+ *
+ * @param str encoded lat/lng string.
+ * @Return {@link LatLng} object.
+ */
+ @NonNull
+ public static LatLng parseLatLngFromString(@NonNull String str) {
+ String[] latLng = str.split("\\s*,\\s*");
+ return new LatLng(Double.parseDouble(latLng[0]), Double.parseDouble(latLng[1]));
+ }
+
+ /**
+ * @Return the sign of the given value {@code value} with the specified tolerance. Return 1
+ * means the sign is positive, -1 means negative, 0 means the value will be treated as 0.
+ */
+ public static int sign(double value) {
+ if (value > EPS) return 1;
+ if (value < -EPS) return -1;
+ return 0;
+ }
+}
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 0129c4ca5bc1..9a653cf7204c 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -26,7 +26,6 @@ java_sdk_library {
],
srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_dirs: ["core/java"],
srcs_lib_whitelist_pkgs: ["android"],
compile_dex: true,
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ca65736d8ec2..e9c24cd6e3e0 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -70,7 +70,6 @@ import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -1170,15 +1169,16 @@ public class WifiManager {
updateVerboseLoggingEnabledFromService();
}
- private IWifiManager getIWifiManager() throws RemoteException {
+ private IWifiManager getIWifiManager() {
if (mService == null) {
synchronized (this) {
mService = IWifiManager.Stub.asInterface(
ServiceManager.getService(Context.WIFI_SERVICE));
- if (mService == null) {
- throw new RemoteException("Wifi Service not running");
+ if (mService != null) {
+ updateVerboseLoggingEnabledFromService();
+ } else {
+ Log.e(TAG, "Wifi Service not running yet, ignoring WifiManager API call");
}
- updateVerboseLoggingEnabledFromService();
}
}
return mService;
@@ -1223,8 +1223,10 @@ public class WifiManager {
@RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
public List<WifiConfiguration> getConfiguredNetworks() {
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyList();
ParceledListSlice<WifiConfiguration> parceledList =
- getIWifiManager().getConfiguredNetworks(mContext.getOpPackageName());
+ iWifiManager.getConfiguredNetworks(mContext.getOpPackageName());
if (parceledList == null) {
return Collections.emptyList();
}
@@ -1239,8 +1241,10 @@ public class WifiManager {
@RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL})
public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyList();
ParceledListSlice<WifiConfiguration> parceledList =
- getIWifiManager().getPrivilegedConfiguredNetworks(mContext.getOpPackageName());
+ iWifiManager.getPrivilegedConfiguredNetworks(mContext.getOpPackageName());
if (parceledList == null) {
return Collections.emptyList();
}
@@ -1271,14 +1275,16 @@ public class WifiManager {
@NonNull List<ScanResult> scanResults) {
List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>();
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyList();
Map<String, Map<Integer, List<ScanResult>>> results =
- getIWifiManager().getAllMatchingFqdnsForScanResults(
+ iWifiManager.getAllMatchingFqdnsForScanResults(
scanResults);
if (results.isEmpty()) {
return configs;
}
List<WifiConfiguration> wifiConfigurations =
- getIWifiManager().getWifiConfigsForPasspointProfiles(
+ iWifiManager.getWifiConfigsForPasspointProfiles(
new ArrayList<>(results.keySet()));
for (WifiConfiguration configuration : wifiConfigurations) {
Map<Integer, List<ScanResult>> scanResultsPerNetworkType = results.get(
@@ -1313,10 +1319,12 @@ public class WifiManager {
public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
@Nullable List<ScanResult> scanResults) {
if (scanResults == null) {
- return new HashMap<>();
+ return Collections.emptyMap();
}
try {
- return getIWifiManager().getMatchingOsuProviders(scanResults);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyMap();
+ return iWifiManager.getMatchingOsuProviders(scanResults);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1343,7 +1351,9 @@ public class WifiManager {
public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
@NonNull Set<OsuProvider> osuProviders) {
try {
- return getIWifiManager().getMatchingPasspointConfigsForOsuProviders(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyMap();
+ return iWifiManager.getMatchingPasspointConfigsForOsuProviders(
new ArrayList<>(osuProviders));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1428,7 +1438,9 @@ public class WifiManager {
*/
private int addOrUpdateNetwork(WifiConfiguration config) {
try {
- return getIWifiManager().addOrUpdateNetwork(config, mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return -1;
+ return iWifiManager.addOrUpdateNetwork(config, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1654,7 +1666,11 @@ public class WifiManager {
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
Binder binder = new Binder();
try {
- getIWifiManager().registerNetworkRequestMatchCallback(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.registerNetworkRequestMatchCallback(
binder, new NetworkRequestMatchCallbackProxy(looper, callback),
callback.hashCode());
} catch (RemoteException e) {
@@ -1680,7 +1696,11 @@ public class WifiManager {
Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback);
try {
- getIWifiManager().unregisterNetworkRequestMatchCallback(callback.hashCode());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.unregisterNetworkRequestMatchCallback(callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1714,7 +1734,9 @@ public class WifiManager {
public @NetworkSuggestionsStatusCode int addNetworkSuggestions(
@NonNull List<WifiNetworkSuggestion> networkSuggestions) {
try {
- return getIWifiManager().addNetworkSuggestions(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
+ return iWifiManager.addNetworkSuggestions(
networkSuggestions, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1738,7 +1760,9 @@ public class WifiManager {
public @NetworkSuggestionsStatusCode int removeNetworkSuggestions(
@NonNull List<WifiNetworkSuggestion> networkSuggestions) {
try {
- return getIWifiManager().removeNetworkSuggestions(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
+ return iWifiManager.removeNetworkSuggestions(
networkSuggestions, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1754,7 +1778,9 @@ public class WifiManager {
@RequiresPermission(ACCESS_WIFI_STATE)
public @NonNull List<WifiNetworkSuggestion> getNetworkSuggestions() {
try {
- return mService.getNetworkSuggestions(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyList();
+ return iWifiManager.getNetworkSuggestions(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -1784,7 +1810,11 @@ public class WifiManager {
*/
public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
try {
- if (!getIWifiManager().addOrUpdatePasspointConfiguration(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ if (!iWifiManager.addOrUpdatePasspointConfiguration(
config, mContext.getOpPackageName())) {
throw new IllegalArgumentException();
}
@@ -1808,7 +1838,11 @@ public class WifiManager {
})
public void removePasspointConfiguration(String fqdn) {
try {
- if (!getIWifiManager().removePasspointConfiguration(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ if (!iWifiManager.removePasspointConfiguration(
fqdn, mContext.getOpPackageName())) {
throw new IllegalArgumentException();
}
@@ -1832,7 +1866,9 @@ public class WifiManager {
})
public List<PasspointConfiguration> getPasspointConfigurations() {
try {
- return getIWifiManager().getPasspointConfigurations(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) Collections.emptyList();
+ return iWifiManager.getPasspointConfigurations(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1852,7 +1888,11 @@ public class WifiManager {
*/
public void queryPasspointIcon(long bssid, String fileName) {
try {
- getIWifiManager().queryPasspointIcon(bssid, fileName);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.queryPasspointIcon(bssid, fileName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1866,7 +1906,9 @@ public class WifiManager {
*/
public int matchProviderWithCurrentNetwork(String fqdn) {
try {
- return getIWifiManager().matchProviderWithCurrentNetwork(fqdn);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return -1;
+ return iWifiManager.matchProviderWithCurrentNetwork(fqdn);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1880,7 +1922,11 @@ public class WifiManager {
*/
public void deauthenticateNetwork(long holdoff, boolean ess) {
try {
- getIWifiManager().deauthenticateNetwork(holdoff, ess);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.deauthenticateNetwork(holdoff, ess);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1910,7 +1956,9 @@ public class WifiManager {
@Deprecated
public boolean removeNetwork(int netId) {
try {
- return getIWifiManager().removeNetwork(netId, mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.removeNetwork(netId, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1965,7 +2013,9 @@ public class WifiManager {
boolean success;
try {
- success = getIWifiManager().enableNetwork(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ success = iWifiManager.enableNetwork(
netId, attemptConnect, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -2002,7 +2052,9 @@ public class WifiManager {
@Deprecated
public boolean disableNetwork(int netId) {
try {
- return getIWifiManager().disableNetwork(netId, mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.disableNetwork(netId, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2025,7 +2077,9 @@ public class WifiManager {
@Deprecated
public boolean disconnect() {
try {
- return getIWifiManager().disconnect(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.disconnect(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2049,7 +2103,9 @@ public class WifiManager {
@Deprecated
public boolean reconnect() {
try {
- return getIWifiManager().reconnect(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.reconnect(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2073,7 +2129,9 @@ public class WifiManager {
@Deprecated
public boolean reassociate() {
try {
- return getIWifiManager().reassociate(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.reassociate(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2159,7 +2217,9 @@ public class WifiManager {
private long getSupportedFeatures() {
try {
- return getIWifiManager().getSupportedFeatures();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return 0L;
+ return iWifiManager.getSupportedFeatures();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2289,8 +2349,10 @@ public class WifiManager {
*/
public WifiActivityEnergyInfo getControllerActivityEnergyInfo() {
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
synchronized(this) {
- return getIWifiManager().reportActivityInfo();
+ return iWifiManager.reportActivityInfo();
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -2329,8 +2391,10 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
public boolean startScan(WorkSource workSource) {
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
String packageName = mContext.getOpPackageName();
- return getIWifiManager().startScan(packageName);
+ return iWifiManager.startScan(packageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2359,7 +2423,9 @@ public class WifiManager {
*/
public WifiInfo getConnectionInfo() {
try {
- return getIWifiManager().getConnectionInfo(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getConnectionInfo(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2373,7 +2439,9 @@ public class WifiManager {
*/
public List<ScanResult> getScanResults() {
try {
- return getIWifiManager().getScanResults(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return Collections.emptyList();
+ return iWifiManager.getScanResults(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2392,7 +2460,9 @@ public class WifiManager {
@Deprecated
public boolean isScanAlwaysAvailable() {
try {
- return getIWifiManager().isScanAlwaysAvailable();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.isScanAlwaysAvailable();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2423,7 +2493,11 @@ public class WifiManager {
*/
public void setCountryCode(@NonNull String country) {
try {
- getIWifiManager().setCountryCode(country);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.setCountryCode(country);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2438,7 +2512,9 @@ public class WifiManager {
@UnsupportedAppUsage
public String getCountryCode() {
try {
- String country = getIWifiManager().getCountryCode();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ String country = iWifiManager.getCountryCode();
return country;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -2453,7 +2529,9 @@ public class WifiManager {
@UnsupportedAppUsage
public boolean isDualBandSupported() {
try {
- return getIWifiManager().isDualBandSupported();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.isDualBandSupported();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2466,7 +2544,9 @@ public class WifiManager {
*/
public boolean isDualModeSupported() {
try {
- return getIWifiManager().needs5GHzToAnyApBandConversion();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.needs5GHzToAnyApBandConversion();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2479,7 +2559,9 @@ public class WifiManager {
*/
public DhcpInfo getDhcpInfo() {
try {
- return getIWifiManager().getDhcpInfo();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getDhcpInfo();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2506,7 +2588,9 @@ public class WifiManager {
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
- return getIWifiManager().setWifiEnabled(mContext.getOpPackageName(), enabled);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2521,7 +2605,9 @@ public class WifiManager {
*/
public int getWifiState() {
try {
- return getIWifiManager().getWifiEnabledState();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return WIFI_STATE_UNKNOWN;
+ return iWifiManager.getWifiEnabledState();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2595,7 +2681,11 @@ public class WifiManager {
*/
public void updateInterfaceIpState(String ifaceName, int mode) {
try {
- getIWifiManager().updateInterfaceIpState(ifaceName, mode);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.updateInterfaceIpState(ifaceName, mode);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2613,7 +2703,9 @@ public class WifiManager {
*/
public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
try {
- return getIWifiManager().startSoftAp(wifiConfig);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.startSoftAp(wifiConfig);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2628,7 +2720,9 @@ public class WifiManager {
*/
public boolean stopSoftAp() {
try {
- return getIWifiManager().stopSoftAp();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.stopSoftAp();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2696,8 +2790,12 @@ public class WifiManager {
LocalOnlyHotspotCallbackProxy proxy =
new LocalOnlyHotspotCallbackProxy(this, looper, callback);
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
String packageName = mContext.getOpPackageName();
- int returnCode = getIWifiManager().startLocalOnlyHotspot(
+ int returnCode = iWifiManager.startLocalOnlyHotspot(
proxy.getMessenger(), new Binder(), packageName);
if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
// Send message to the proxy to make sure we call back on the correct thread
@@ -2749,7 +2847,11 @@ public class WifiManager {
}
mLOHSCallbackProxy = null;
try {
- getIWifiManager().stopLocalOnlyHotspot();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.stopLocalOnlyHotspot();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2779,7 +2881,11 @@ public class WifiManager {
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer);
try {
- getIWifiManager().startWatchLocalOnlyHotspot(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.startWatchLocalOnlyHotspot(
mLOHSObserverProxy.getMessenger(), new Binder());
mLOHSObserverProxy.registered();
} catch (RemoteException e) {
@@ -2803,7 +2909,11 @@ public class WifiManager {
}
mLOHSObserverProxy = null;
try {
- getIWifiManager().stopWatchLocalOnlyHotspot();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.stopWatchLocalOnlyHotspot();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2823,7 +2933,9 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
public int getWifiApState() {
try {
- return getIWifiManager().getWifiApEnabledState();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return WIFI_AP_STATE_FAILED;
+ return iWifiManager.getWifiApEnabledState();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2852,7 +2964,9 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
public WifiConfiguration getWifiApConfiguration() {
try {
- return getIWifiManager().getWifiApConfiguration();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getWifiApConfiguration();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2869,7 +2983,9 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
try {
- return getIWifiManager().setWifiApConfiguration(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.setWifiApConfiguration(
wifiConfig, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -2885,7 +3001,11 @@ public class WifiManager {
public void notifyUserOfApBandConversion() {
Log.d(TAG, "apBand was converted, notify the user");
try {
- getIWifiManager().notifyUserOfApBandConversion(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.notifyUserOfApBandConversion(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2913,7 +3033,11 @@ public class WifiManager {
*/
public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
try {
- getIWifiManager().enableTdls(remoteIPAddress.getHostAddress(), enable);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.enableTdls(remoteIPAddress.getHostAddress(), enable);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2927,7 +3051,11 @@ public class WifiManager {
*/
public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
try {
- getIWifiManager().enableTdlsWithMacAddress(remoteMacAddress, enable);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.enableTdlsWithMacAddress(remoteMacAddress, enable);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3216,7 +3344,11 @@ public class WifiManager {
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
Binder binder = new Binder();
try {
- getIWifiManager().registerSoftApCallback(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.registerSoftApCallback(
binder, new SoftApCallbackProxy(looper, callback), callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -3237,7 +3369,11 @@ public class WifiManager {
Log.v(TAG, "unregisterSoftApCallback: callback=" + callback);
try {
- getIWifiManager().unregisterSoftApCallback(callback.hashCode());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.unregisterSoftApCallback(callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3807,7 +3943,11 @@ public class WifiManager {
public void disableEphemeralNetwork(String SSID) {
if (SSID == null) throw new IllegalArgumentException("SSID cannot be null");
try {
- getIWifiManager().disableEphemeralNetwork(SSID, mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.disableEphemeralNetwork(SSID, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3851,7 +3991,9 @@ public class WifiManager {
@UnsupportedAppUsage
private Messenger getWifiServiceMessenger() {
try {
- return getIWifiManager().getWifiServiceMessenger(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getWifiServiceMessenger(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3911,10 +4053,14 @@ public class WifiManager {
synchronized (mBinder) {
if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
try {
- getIWifiManager().acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
synchronized (WifiManager.this) {
if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
- getIWifiManager().releaseWifiLock(mBinder);
+ iWifiManager.releaseWifiLock(mBinder);
throw new UnsupportedOperationException(
"Exceeded maximum number of wifi locks");
}
@@ -3944,7 +4090,11 @@ public class WifiManager {
synchronized (mBinder) {
if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
try {
- getIWifiManager().releaseWifiLock(mBinder);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.releaseWifiLock(mBinder);
synchronized (WifiManager.this) {
mActiveLockCount--;
}
@@ -4007,7 +4157,11 @@ public class WifiManager {
}
if (changed && mHeld) {
try {
- getIWifiManager().updateWifiLockWorkSource(mBinder, mWorkSource);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.updateWifiLockWorkSource(mBinder, mWorkSource);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4035,7 +4189,11 @@ public class WifiManager {
synchronized (mBinder) {
if (mHeld) {
try {
- getIWifiManager().releaseWifiLock(mBinder);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.releaseWifiLock(mBinder);
synchronized (WifiManager.this) {
mActiveLockCount--;
}
@@ -4148,10 +4306,14 @@ public class WifiManager {
synchronized (mBinder) {
if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
try {
- getIWifiManager().acquireMulticastLock(mBinder, mTag);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.acquireMulticastLock(mBinder, mTag);
synchronized (WifiManager.this) {
if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
- getIWifiManager().releaseMulticastLock(mTag);
+ iWifiManager.releaseMulticastLock(mTag);
throw new UnsupportedOperationException(
"Exceeded maximum number of wifi locks");
}
@@ -4193,7 +4355,11 @@ public class WifiManager {
synchronized (mBinder) {
if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
try {
- getIWifiManager().releaseMulticastLock(mTag);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.releaseMulticastLock(mTag);
synchronized (WifiManager.this) {
mActiveLockCount--;
}
@@ -4270,7 +4436,9 @@ public class WifiManager {
*/
public boolean isMulticastEnabled() {
try {
- return getIWifiManager().isMulticastEnabled();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ return iWifiManager.isMulticastEnabled();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4283,7 +4451,9 @@ public class WifiManager {
@UnsupportedAppUsage
public boolean initializeMulticastFiltering() {
try {
- getIWifiManager().initializeMulticastFiltering();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return false;
+ iWifiManager.initializeMulticastFiltering();
return true;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -4308,7 +4478,11 @@ public class WifiManager {
@UnsupportedAppUsage
public void enableVerboseLogging (int verbose) {
try {
- getIWifiManager().enableVerboseLogging(verbose);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.enableVerboseLogging(verbose);
} catch (Exception e) {
//ignore any failure here
Log.e(TAG, "enableVerboseLogging " + e.toString());
@@ -4323,7 +4497,9 @@ public class WifiManager {
@UnsupportedAppUsage
public int getVerboseLoggingLevel() {
try {
- return getIWifiManager().getVerboseLoggingLevel();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return -1;
+ return iWifiManager.getVerboseLoggingLevel();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4336,7 +4512,11 @@ public class WifiManager {
*/
public void factoryReset() {
try {
- getIWifiManager().factoryReset(mContext.getOpPackageName());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.factoryReset(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4350,7 +4530,9 @@ public class WifiManager {
@UnsupportedAppUsage
public Network getCurrentNetwork() {
try {
- return getIWifiManager().getCurrentNetwork();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getCurrentNetwork();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4382,7 +4564,11 @@ public class WifiManager {
*/
public void enableWifiConnectivityManager(boolean enabled) {
try {
- getIWifiManager().enableWifiConnectivityManager(enabled);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.enableWifiConnectivityManager(enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4394,7 +4580,9 @@ public class WifiManager {
*/
public byte[] retrieveBackupData() {
try {
- return getIWifiManager().retrieveBackupData();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.retrieveBackupData();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4406,7 +4594,11 @@ public class WifiManager {
*/
public void restoreBackupData(byte[] data) {
try {
- getIWifiManager().restoreBackupData(data);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.restoreBackupData(data);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4422,7 +4614,11 @@ public class WifiManager {
@Deprecated
public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
try {
- getIWifiManager().restoreSupplicantBackupData(supplicantData, ipConfigData);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.restoreSupplicantBackupData(supplicantData, ipConfigData);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4451,7 +4647,11 @@ public class WifiManager {
throw new IllegalArgumentException("callback must not be null");
}
try {
- getIWifiManager().startSubscriptionProvisioning(provider,
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.startSubscriptionProvisioning(provider,
new ProvisioningCallbackProxy(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -4565,7 +4765,11 @@ public class WifiManager {
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
Binder binder = new Binder();
try {
- getIWifiManager().registerTrafficStateCallback(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.registerTrafficStateCallback(
binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -4585,7 +4789,11 @@ public class WifiManager {
Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback);
try {
- getIWifiManager().unregisterTrafficStateCallback(callback.hashCode());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.unregisterTrafficStateCallback(callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4641,7 +4849,9 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public String[] getFactoryMacAddresses() {
try {
- return getIWifiManager().getFactoryMacAddresses();
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) return null;
+ return iWifiManager.getFactoryMacAddresses();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4710,7 +4920,11 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE)
public void setDeviceMobilityState(@DeviceMobilityState int state) {
try {
- getIWifiManager().setDeviceMobilityState(state);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.setDeviceMobilityState(state);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4765,7 +4979,11 @@ public class WifiManager {
@NonNull EasyConnectStatusCallback callback) {
Binder binder = new Binder();
try {
- getIWifiManager().startDppAsConfiguratorInitiator(
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.startDppAsConfiguratorInitiator(
binder, enrolleeUri, selectedNetworkId, enrolleeNetworkRole,
new EasyConnectCallbackProxy(executor, callback));
} catch (RemoteException e) {
@@ -4792,7 +5010,11 @@ public class WifiManager {
@NonNull EasyConnectStatusCallback callback) {
Binder binder = new Binder();
try {
- getIWifiManager().startDppAsEnrolleeInitiator(binder, configuratorUri,
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.startDppAsEnrolleeInitiator(binder, configuratorUri,
new EasyConnectCallbackProxy(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -4813,8 +5035,12 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETUP_WIZARD})
public void stopEasyConnectSession() {
try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
/* Request lower layers to stop/abort and clear resources */
- getIWifiManager().stopDppSession();
+ iWifiManager.stopDppSession();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4913,7 +5139,11 @@ public class WifiManager {
Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener);
}
try {
- getIWifiManager().addOnWifiUsabilityStatsListener(new Binder(),
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.addOnWifiUsabilityStatsListener(new Binder(),
new IOnWifiUsabilityStatsListener.Stub() {
@Override
public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
@@ -4950,7 +5180,11 @@ public class WifiManager {
Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener);
}
try {
- getIWifiManager().removeOnWifiUsabilityStatsListener(listener.hashCode());
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.removeOnWifiUsabilityStatsListener(listener.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4973,7 +5207,11 @@ public class WifiManager {
@RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) {
try {
- getIWifiManager().updateWifiUsabilityScore(seqNum, score, predictionHorizonSec);
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}