summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java5
-rw-r--r--cmds/bootanimation/Android.bp2
-rw-r--r--cmds/bootanimation/BootAnimation.cpp111
-rw-r--r--cmds/bootanimation/BootAnimation.h6
-rw-r--r--cmds/idmap2/Android.bp1
-rw-r--r--cmds/idmap2/idmap2/Commands.h1
-rw-r--r--cmds/idmap2/idmap2/Create.cpp1
-rw-r--r--cmds/idmap2/idmap2/CreateMultiple.cpp1
-rw-r--r--cmds/idmap2/idmap2/Main.cpp6
-rw-r--r--cmds/idmap2/idmap2/Scan.cpp257
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.h2
-rw-r--r--cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl1
-rw-r--r--cmds/idmap2/include/idmap2/FileUtils.h14
-rw-r--r--cmds/idmap2/libidmap2/FileUtils.cpp60
-rw-r--r--cmds/idmap2/libidmap2/PolicyUtils.cpp2
-rw-r--r--cmds/idmap2/libidmap2/ResourceMapping.cpp7
-rw-r--r--cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h11
-rw-r--r--cmds/idmap2/tests/FileUtilsTests.cpp57
-rw-r--r--cmds/idmap2/tests/Idmap2BinaryTests.cpp125
-rw-r--r--cmds/idmap2/tests/R.h68
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp18
-rw-r--r--cmds/idmap2/tests/TestConstants.h14
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-no-name-static.apkbin3477 -> 3485 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-no-name.apkbin3389 -> 3393 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-shared.apkbin3757 -> 3757 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-static-1.apkbin3469 -> 3477 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-static-2.apkbin3469 -> 3477 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay.apkbin3489 -> 3489 bytes
-rw-r--r--cmds/idmap2/tests/data/signature-overlay/signature-overlay.apkbin1315 -> 1299 bytes
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apkbin1827 -> 1907 bytes
-rw-r--r--cmds/idmap2/tests/data/system-overlay/system-overlay.apkbin1319 -> 1387 bytes
-rw-r--r--cmds/idmap2/tests/data/target/res/values/overlayable.xml4
-rw-r--r--cmds/idmap2/tests/data/target/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/target/target-no-overlayable.apkbin2311 -> 2391 bytes
-rw-r--r--cmds/idmap2/tests/data/target/target.apkbin5097 -> 5201 bytes
-rwxr-xr-xcmds/idmap2/valgrind.sh2
-rw-r--r--cmds/input/Android.bp5
-rwxr-xr-xcmds/input/input3
-rw-r--r--cmds/input/src/com/android/commands/input/Input.java435
-rw-r--r--cmds/locksettings/TEST_MAPPING2
-rw-r--r--cmds/screencap/Android.bp2
-rw-r--r--cmds/screencap/screencap.cpp95
-rw-r--r--cmds/statsd/Android.bp18
-rw-r--r--cmds/statsd/TEST_MAPPING12
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp79
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h34
-rw-r--r--cmds/statsd/src/StatsService.cpp56
-rw-r--r--cmds/statsd/src/StatsService.h5
-rw-r--r--cmds/statsd/src/atoms.proto36
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp81
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.h13
-rw-r--r--cmds/statsd/src/hash.h1
-rw-r--r--cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp5
-rw-r--r--cmds/statsd/src/matchers/CombinationLogMatchingTracker.h2
-rw-r--r--cmds/statsd/src/matchers/LogMatchingTracker.h18
-rw-r--r--cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp6
-rw-r--r--cmds/statsd/src/matchers/SimpleLogMatchingTracker.h7
-rw-r--r--cmds/statsd/src/matchers/matcher_util.cpp9
-rw-r--r--cmds/statsd/src/matchers/matcher_util.h4
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp34
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h10
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp14
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp203
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/config_update_utils.h89
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp (renamed from cmds/statsd/src/metrics/metrics_manager_util.cpp)145
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h (renamed from cmds/statsd/src/metrics/metrics_manager_util.h)33
-rw-r--r--cmds/statsd/src/packages/PackageInfoListener.h2
-rw-r--r--cmds/statsd/src/packages/UidMap.h1
-rw-r--r--cmds/statsd/src/shell/ShellSubscriber.cpp4
-rw-r--r--cmds/statsd/tests/LogEntryMatcher_test.cpp28
-rw-r--r--cmds/statsd/tests/MetricsManager_test.cpp556
-rw-r--r--cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp264
-rw-r--r--cmds/statsd/tests/external/StatsPullerManager_test.cpp16
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp107
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp500
-rw-r--r--cmds/statsd/tests/metrics/metrics_test_helper.h9
-rw-r--r--cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp382
-rw-r--r--cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp708
-rw-r--r--cmds/statsd/tests/shell/ShellSubscriber_test.cpp4
-rw-r--r--cmds/statsd/tests/statsd_test_util.cpp16
-rw-r--r--cmds/statsd/tests/statsd_test_util.h4
83 files changed, 2409 insertions, 2428 deletions
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index ed717c491467..4b7eda096e54 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -19,6 +19,7 @@ package com.android.commands.bmgr;
import android.annotation.IntDef;
import android.annotation.UserIdInt;
import android.app.backup.BackupManager;
+import android.app.backup.BackupManager.OperationType;
import android.app.backup.BackupManagerMonitor;
import android.app.backup.BackupProgress;
import android.app.backup.BackupTransport;
@@ -666,7 +667,7 @@ public class Bmgr {
// The rest of the 'list' options work with a restore session on the current transport
try {
- mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
+ mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null, OperationType.BACKUP);
if (mRestore == null) {
System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
return;
@@ -821,7 +822,7 @@ public class Bmgr {
try {
boolean didRestore = false;
- mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
+ mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null, OperationType.BACKUP);
if (mRestore == null) {
System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
return;
diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp
index 757c2b2a4cfa..0f569971ff62 100644
--- a/cmds/bootanimation/Android.bp
+++ b/cmds/bootanimation/Android.bp
@@ -60,7 +60,7 @@ cc_library_shared {
shared_libs: [
"libui",
- "libhwui",
+ "libjnigraphics",
"libEGL",
"libGLESv1_CM",
"libgui",
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index bb2de17b42f3..9c796128df84 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -34,6 +34,7 @@
#include <cutils/atomic.h>
#include <cutils/properties.h>
+#include <android/imagedecoder.h>
#include <androidfw/AssetManager.h>
#include <binder/IPCThreadState.h>
#include <utils/Errors.h>
@@ -52,14 +53,6 @@
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
-// TODO: Fix Skia.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#include <SkBitmap.h>
-#include <SkImage.h>
-#include <SkStream.h>
-#pragma GCC diagnostic pop
-
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/eglext.h>
@@ -114,8 +107,8 @@ static constexpr size_t TEXT_POS_LEN_MAX = 16;
// ---------------------------------------------------------------------------
BootAnimation::BootAnimation(sp<Callbacks> callbacks)
- : Thread(false), mClockEnabled(true), mTimeIsAccurate(false), mTimeFormat12Hour(false),
- mTimeCheckThread(nullptr), mCallbacks(callbacks), mLooper(new Looper(false)) {
+ : Thread(false), mLooper(new Looper(false)), mClockEnabled(true), mTimeIsAccurate(false),
+ mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) {
mSession = new SurfaceComposerClient();
std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
@@ -165,22 +158,51 @@ void BootAnimation::binderDied(const wp<IBinder>&) {
requestExit();
}
+static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo) {
+ AImageDecoder* decoder = nullptr;
+ AImageDecoder_createFromBuffer(encodedData, dataLength, &decoder);
+ if (!decoder) {
+ return nullptr;
+ }
+
+ const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
+ outInfo->width = AImageDecoderHeaderInfo_getWidth(info);
+ outInfo->height = AImageDecoderHeaderInfo_getHeight(info);
+ outInfo->format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
+ outInfo->stride = AImageDecoder_getMinimumStride(decoder);
+ outInfo->flags = 0;
+
+ const size_t size = outInfo->stride * outInfo->height;
+ void* pixels = malloc(size);
+ int result = AImageDecoder_decodeImage(decoder, pixels, outInfo->stride, size);
+ AImageDecoder_delete(decoder);
+
+ if (result != ANDROID_IMAGE_DECODER_SUCCESS) {
+ free(pixels);
+ return nullptr;
+ }
+ return pixels;
+}
+
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
if (asset == nullptr)
return NO_INIT;
- SkBitmap bitmap;
- sk_sp<SkData> data = SkData::MakeWithoutCopy(asset->getBuffer(false),
- asset->getLength());
- sk_sp<SkImage> image = SkImage::MakeFromEncoded(data);
- image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode);
+
+ AndroidBitmapInfo bitmapInfo;
+ void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo);
+ auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
+
asset->close();
delete asset;
- const int w = bitmap.width();
- const int h = bitmap.height();
- const void* p = bitmap.getPixels();
+ if (!pixels) {
+ return NO_INIT;
+ }
+
+ const int w = bitmapInfo.width;
+ const int h = bitmapInfo.height;
GLint crop[4] = { 0, h, w, -h };
texture->w = w;
@@ -189,22 +211,22 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
glGenTextures(1, &texture->name);
glBindTexture(GL_TEXTURE_2D, texture->name);
- switch (bitmap.colorType()) {
- case kAlpha_8_SkColorType:
+ switch (bitmapInfo.format) {
+ case ANDROID_BITMAP_FORMAT_A_8:
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
- GL_UNSIGNED_BYTE, p);
+ GL_UNSIGNED_BYTE, pixels);
break;
- case kARGB_4444_SkColorType:
+ case ANDROID_BITMAP_FORMAT_RGBA_4444:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
- GL_UNSIGNED_SHORT_4_4_4_4, p);
+ GL_UNSIGNED_SHORT_4_4_4_4, pixels);
break;
- case kN32_SkColorType:
+ case ANDROID_BITMAP_FORMAT_RGBA_8888:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, p);
+ GL_UNSIGNED_BYTE, pixels);
break;
- case kRGB_565_SkColorType:
+ case ANDROID_BITMAP_FORMAT_RGB_565:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, p);
+ GL_UNSIGNED_SHORT_5_6_5, pixels);
break;
default:
break;
@@ -220,20 +242,21 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
}
status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) {
- SkBitmap bitmap;
- sk_sp<SkData> data = SkData::MakeWithoutCopy(map->getDataPtr(),
- map->getDataLength());
- sk_sp<SkImage> image = SkImage::MakeFromEncoded(data);
- image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode);
+ AndroidBitmapInfo bitmapInfo;
+ void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo);
+ auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
// FileMap memory is never released until application exit.
// Release it now as the texture is already loaded and the memory used for
// the packed resource can be released.
delete map;
- const int w = bitmap.width();
- const int h = bitmap.height();
- const void* p = bitmap.getPixels();
+ if (!pixels) {
+ return NO_INIT;
+ }
+
+ const int w = bitmapInfo.width;
+ const int h = bitmapInfo.height;
GLint crop[4] = { 0, h, w, -h };
int tw = 1 << (31 - __builtin_clz(w));
@@ -241,28 +264,28 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) {
if (tw < w) tw <<= 1;
if (th < h) th <<= 1;
- switch (bitmap.colorType()) {
- case kN32_SkColorType:
+ switch (bitmapInfo.format) {
+ case ANDROID_BITMAP_FORMAT_RGBA_8888:
if (!mUseNpotTextures && (tw != w || th != h)) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
+ 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, p);
+ GL_UNSIGNED_BYTE, pixels);
}
break;
- case kRGB_565_SkColorType:
+ case ANDROID_BITMAP_FORMAT_RGB_565:
if (!mUseNpotTextures && (tw != w || th != h)) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, nullptr);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
+ 0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, p);
+ GL_UNSIGNED_SHORT_5_6_5, pixels);
}
break;
default:
@@ -394,7 +417,7 @@ status_t BootAnimation::readyToRun() {
// this guest property specifies multi-display IDs to show the boot animation
// multiple ids can be set with comma (,) as separator, for example:
// setprop persist.boot.animation.displays 19260422155234049,19261083906282754
- Vector<uint64_t> physicalDisplayIds;
+ Vector<PhysicalDisplayId> physicalDisplayIds;
char displayValue[PROPERTY_VALUE_MAX] = "";
property_get(DISPLAYS_PROP_NAME, displayValue, "");
bool isValid = displayValue[0] != '\0';
@@ -412,7 +435,7 @@ status_t BootAnimation::readyToRun() {
}
if (isValid) {
std::istringstream stream(displayValue);
- for (PhysicalDisplayId id; stream >> id; ) {
+ for (PhysicalDisplayId id; stream >> id.value; ) {
physicalDisplayIds.add(id);
if (stream.peek() == ',')
stream.ignore();
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 6ba7fd450fbb..9e6e4aa42f1c 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -32,8 +32,6 @@
#include <EGL/egl.h>
#include <GLES/gl.h>
-class SkBitmap;
-
namespace android {
class Surface;
@@ -150,6 +148,8 @@ private:
// Display event handling
class DisplayEventCallback;
+ std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver;
+ sp<Looper> mLooper;
int displayEventCallback(int fd, int events, void* data);
void processDisplayEvents();
@@ -202,8 +202,6 @@ private:
sp<TimeCheckThread> mTimeCheckThread = nullptr;
sp<Callbacks> mCallbacks;
Animation* mAnimation = nullptr;
- std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver;
- sp<Looper> mLooper;
};
// ---------------------------------------------------------------------------
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 878cef94b674..e21a6b288fb3 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -181,7 +181,6 @@ cc_binary {
"idmap2/Dump.cpp",
"idmap2/Lookup.cpp",
"idmap2/Main.cpp",
- "idmap2/Scan.cpp",
],
target: {
android: {
diff --git a/cmds/idmap2/idmap2/Commands.h b/cmds/idmap2/idmap2/Commands.h
index 69eea8d262d2..4099671066a2 100644
--- a/cmds/idmap2/idmap2/Commands.h
+++ b/cmds/idmap2/idmap2/Commands.h
@@ -26,6 +26,5 @@ android::idmap2::Result<android::idmap2::Unit> Create(const std::vector<std::str
android::idmap2::Result<android::idmap2::Unit> CreateMultiple(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args);
-android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args);
#endif // IDMAP2_IDMAP2_COMMANDS_H_
diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp
index 9682b6ead293..648b78e24c23 100644
--- a/cmds/idmap2/idmap2/Create.cpp
+++ b/cmds/idmap2/idmap2/Create.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <memory>
#include <ostream>
+#include <string>
#include <vector>
#include "androidfw/ResourceTypes.h"
diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp
index abdfaf4dccab..19622c4ef65a 100644
--- a/cmds/idmap2/idmap2/CreateMultiple.cpp
+++ b/cmds/idmap2/idmap2/CreateMultiple.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <memory>
#include <ostream>
+#include <string>
#include <vector>
#include "Commands.h"
diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp
index fb093f0f22a4..aa6d0e76698f 100644
--- a/cmds/idmap2/idmap2/Main.cpp
+++ b/cmds/idmap2/idmap2/Main.cpp
@@ -53,8 +53,10 @@ void PrintUsage(const NameToFunctionMap& commands, std::ostream& out) {
int main(int argc, char** argv) {
SYSTRACE << "main";
const NameToFunctionMap commands = {
- {"create", Create}, {"create-multiple", CreateMultiple}, {"dump", Dump}, {"lookup", Lookup},
- {"scan", Scan},
+ {"create", Create},
+ {"create-multiple", CreateMultiple},
+ {"dump", Dump},
+ {"lookup", Lookup},
};
if (argc <= 1) {
PrintUsage(commands, std::cerr);
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
deleted file mode 100644
index 36250450cc74..000000000000
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-
-#include <fstream>
-#include <memory>
-#include <ostream>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "Commands.h"
-#include "android-base/properties.h"
-#include "idmap2/CommandLineOptions.h"
-#include "idmap2/CommandUtils.h"
-#include "idmap2/FileUtils.h"
-#include "idmap2/Idmap.h"
-#include "idmap2/Policies.h"
-#include "idmap2/PolicyUtils.h"
-#include "idmap2/ResourceUtils.h"
-#include "idmap2/Result.h"
-#include "idmap2/SysTrace.h"
-#include "idmap2/XmlParser.h"
-
-using android::idmap2::CommandLineOptions;
-using android::idmap2::Error;
-using android::idmap2::Idmap;
-using android::idmap2::Result;
-using android::idmap2::Unit;
-using android::idmap2::policy::kPolicyOdm;
-using android::idmap2::policy::kPolicyOem;
-using android::idmap2::policy::kPolicyProduct;
-using android::idmap2::policy::kPolicyPublic;
-using android::idmap2::policy::kPolicySystem;
-using android::idmap2::policy::kPolicyVendor;
-using android::idmap2::utils::ExtractOverlayManifestInfo;
-using android::idmap2::utils::FindFiles;
-using android::idmap2::utils::OverlayManifestInfo;
-using android::idmap2::utils::PoliciesToBitmaskResult;
-
-using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
-
-namespace {
-
-struct InputOverlay {
- bool operator<(InputOverlay const& rhs) const {
- return priority < rhs.priority || (priority == rhs.priority && apk_path < rhs.apk_path);
- }
-
- std::string apk_path; // NOLINT(misc-non-private-member-variables-in-classes)
- std::string idmap_path; // NOLINT(misc-non-private-member-variables-in-classes)
- int priority; // NOLINT(misc-non-private-member-variables-in-classes)
- std::vector<std::string> policies; // NOLINT(misc-non-private-member-variables-in-classes)
- bool ignore_overlayable; // NOLINT(misc-non-private-member-variables-in-classes)
-};
-
-bool VendorIsQOrLater() {
- constexpr int kQSdkVersion = 29;
- constexpr int kBase = 10;
- std::string version_prop = android::base::GetProperty("ro.vndk.version", "29");
- int version = strtol(version_prop.data(), nullptr, kBase);
-
- // If the string cannot be parsed, it is a development sdk codename.
- return version >= kQSdkVersion || version == 0;
-}
-
-Result<std::unique_ptr<std::vector<std::string>>> FindApkFiles(const std::vector<std::string>& dirs,
- bool recursive) {
- SYSTRACE << "FindApkFiles " << dirs << " " << recursive;
- const auto predicate = [](unsigned char type, const std::string& path) -> bool {
- static constexpr size_t kExtLen = 4; // strlen(".apk")
- return type == DT_REG && path.size() > kExtLen &&
- path.compare(path.size() - kExtLen, kExtLen, ".apk") == 0;
- };
- // pass apk paths through a set to filter out duplicates
- std::set<std::string> paths;
- for (const auto& dir : dirs) {
- const auto apk_paths = FindFiles(dir, recursive, predicate);
- if (!apk_paths) {
- return Error("failed to open directory %s", dir.c_str());
- }
- paths.insert(apk_paths->cbegin(), apk_paths->cend());
- }
- return std::make_unique<std::vector<std::string>>(paths.cbegin(), paths.cend());
-}
-
-std::vector<std::string> PoliciesForPath(const std::string& apk_path) {
- // clang-format off
- static const std::vector<std::pair<std::string, std::string>> values = {
- {"/odm/", kPolicyOdm},
- {"/oem/", kPolicyOem},
- {"/product/", kPolicyProduct},
- {"/system/", kPolicySystem},
- {"/system_ext/", kPolicySystem},
- {"/vendor/", kPolicyVendor},
- };
- // clang-format on
-
- std::vector<std::string> fulfilled_policies = {kPolicyPublic};
- for (auto const& pair : values) {
- if (apk_path.compare(0, pair.first.size(), pair.first) == 0) {
- fulfilled_policies.emplace_back(pair.second);
- break;
- }
- }
-
- return fulfilled_policies;
-}
-
-} // namespace
-
-Result<Unit> Scan(const std::vector<std::string>& args) {
- SYSTRACE << "Scan " << args;
- std::vector<std::string> input_directories;
- std::string target_package_name;
- std::string target_apk_path;
- std::string output_directory;
- std::vector<std::string> override_policies;
- bool recursive = false;
-
- const CommandLineOptions opts =
- CommandLineOptions("idmap2 scan")
- .MandatoryOption("--input-directory", "directory containing overlay apks to scan",
- &input_directories)
- .OptionalFlag("--recursive", "also scan subfolders of overlay-directory", &recursive)
- .MandatoryOption("--target-package-name", "package name of target package",
- &target_package_name)
- .MandatoryOption("--target-apk-path", "path to target apk", &target_apk_path)
- .MandatoryOption("--output-directory",
- "directory in which to write artifacts (idmap files and overlays.list)",
- &output_directory)
- .OptionalOption(
- "--override-policy",
- "input: an overlayable policy this overlay fulfills "
- "(if none or supplied, the overlays will not have their policies overriden",
- &override_policies);
- const auto opts_ok = opts.Parse(args);
- if (!opts_ok) {
- return opts_ok.GetError();
- }
-
- const auto apk_paths = FindApkFiles(input_directories, recursive);
- if (!apk_paths) {
- return Error(apk_paths.GetError(), "failed to find apk files");
- }
-
- std::vector<InputOverlay> interesting_apks;
- for (const std::string& path : **apk_paths) {
- Result<OverlayManifestInfo> overlay_info =
- ExtractOverlayManifestInfo(path, /* assert_overlay */ false);
- if (!overlay_info) {
- return overlay_info.GetError();
- }
-
- if (!overlay_info->is_static) {
- continue;
- }
-
- if (overlay_info->target_package.empty() ||
- overlay_info->target_package != target_package_name) {
- continue;
- }
-
- if (overlay_info->priority < 0) {
- continue;
- }
-
- // Note that conditional property enablement/exclusion only applies if
- // the attribute is present. In its absence, all overlays are presumed enabled.
- if (!overlay_info->requiredSystemPropertyName.empty() &&
- !overlay_info->requiredSystemPropertyValue.empty()) {
- // if property set & equal to value, then include overlay - otherwise skip
- if (android::base::GetProperty(overlay_info->requiredSystemPropertyName, "") !=
- overlay_info->requiredSystemPropertyValue) {
- continue;
- }
- }
-
- std::vector<std::string> fulfilled_policies;
- if (!override_policies.empty()) {
- fulfilled_policies = override_policies;
- } else {
- fulfilled_policies = PoliciesForPath(path);
- }
-
- bool ignore_overlayable = false;
- if (std::find(fulfilled_policies.begin(), fulfilled_policies.end(), kPolicyVendor) !=
- fulfilled_policies.end() &&
- !VendorIsQOrLater()) {
- // If the overlay is on a pre-Q vendor partition, do not enforce overlayable
- // restrictions on this overlay because the pre-Q platform has no understanding of
- // overlayable.
- ignore_overlayable = true;
- }
-
- std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, path);
-
- // Sort the static overlays in ascending priority order
- InputOverlay input{path, idmap_path, overlay_info->priority, fulfilled_policies,
- ignore_overlayable};
- interesting_apks.insert(
- std::lower_bound(interesting_apks.begin(), interesting_apks.end(), input), input);
- }
-
- std::stringstream stream;
- for (const auto& overlay : interesting_apks) {
- const auto policy_bitmask = PoliciesToBitmaskResult(overlay.policies);
- if (!policy_bitmask) {
- LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path
- << "\": " << policy_bitmask.GetErrorMessage();
- continue;
- }
-
- if (!Verify(overlay.idmap_path, target_apk_path, overlay.apk_path, *policy_bitmask,
- !overlay.ignore_overlayable)) {
- std::vector<std::string> create_args = {"--target-apk-path", target_apk_path,
- "--overlay-apk-path", overlay.apk_path,
- "--idmap-path", overlay.idmap_path};
- if (overlay.ignore_overlayable) {
- create_args.emplace_back("--ignore-overlayable");
- }
-
- for (const std::string& policy : overlay.policies) {
- create_args.emplace_back("--policy");
- create_args.emplace_back(policy);
- }
-
- const auto create_ok = Create(create_args);
- if (!create_ok) {
- LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path
- << "\": " << create_ok.GetError().GetMessage();
- continue;
- }
- }
-
- stream << overlay.idmap_path << std::endl;
- }
-
- std::cout << stream.str();
-
- return Unit{};
-}
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h
index abee999dd2b2..1a445192aff8 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -17,6 +17,8 @@
#ifndef IDMAP2_IDMAP2D_IDMAP2SERVICE_H_
#define IDMAP2_IDMAP2D_IDMAP2SERVICE_H_
+#include <string>
+
#include <android-base/unique_fd.h>
#include <binder/BinderService.h>
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
index 02b27a8800b6..403d8c55de16 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
@@ -29,4 +29,5 @@ interface OverlayablePolicy {
const int ODM_PARTITION = 0x00000020;
const int OEM_PARTITION = 0x00000040;
const int ACTOR_SIGNATURE = 0x00000080;
+ const int CONFIG_SIGNATURE = 0x0000100;
}
diff --git a/cmds/idmap2/include/idmap2/FileUtils.h b/cmds/idmap2/include/idmap2/FileUtils.h
index 3f03236d5e1a..c4e0e1fd8ef0 100644
--- a/cmds/idmap2/include/idmap2/FileUtils.h
+++ b/cmds/idmap2/include/idmap2/FileUtils.h
@@ -17,27 +17,13 @@
#ifndef IDMAP2_INCLUDE_IDMAP2_FILEUTILS_H_
#define IDMAP2_INCLUDE_IDMAP2_FILEUTILS_H_
-#include <sys/types.h>
-
-#include <functional>
-#include <memory>
#include <string>
-#include <vector>
namespace android::idmap2::utils {
constexpr const char* kIdmapCacheDir = "/data/resource-cache";
constexpr const mode_t kIdmapFilePermissionMask = 0133; // u=rw,g=r,o=r
-typedef std::function<bool(unsigned char type /* DT_* from dirent.h */, const std::string& path)>
- FindFilesPredicate;
-std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse,
- const FindFilesPredicate& predicate);
-
-std::unique_ptr<std::string> ReadFile(int fd);
-
-std::unique_ptr<std::string> ReadFile(const std::string& path);
-
bool UidHasWriteAccessToPath(uid_t uid, const std::string& path);
} // namespace android::idmap2::utils
diff --git a/cmds/idmap2/libidmap2/FileUtils.cpp b/cmds/idmap2/libidmap2/FileUtils.cpp
index 3e8e32989a09..3af1f70ebe39 100644
--- a/cmds/idmap2/libidmap2/FileUtils.cpp
+++ b/cmds/idmap2/libidmap2/FileUtils.cpp
@@ -16,19 +16,7 @@
#include "idmap2/FileUtils.h"
-#include <dirent.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <cerrno>
-#include <climits>
-#include <cstdlib>
-#include <cstring>
-#include <fstream>
-#include <memory>
#include <string>
-#include <utility>
-#include <vector>
#include "android-base/file.h"
#include "android-base/macros.h"
@@ -37,54 +25,6 @@
namespace android::idmap2::utils {
-std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse,
- const FindFilesPredicate& predicate) {
- DIR* dir = opendir(root.c_str());
- if (dir == nullptr) {
- return nullptr;
- }
- std::unique_ptr<std::vector<std::string>> vector(new std::vector<std::string>());
- struct dirent* dirent;
- while ((dirent = readdir(dir)) != nullptr) {
- const std::string path = root + "/" + dirent->d_name;
- if (predicate(dirent->d_type, path)) {
- vector->push_back(path);
- }
- if (recurse && dirent->d_type == DT_DIR && strcmp(dirent->d_name, ".") != 0 &&
- strcmp(dirent->d_name, "..") != 0) {
- auto sub_vector = FindFiles(path, recurse, predicate);
- if (!sub_vector) {
- closedir(dir);
- return nullptr;
- }
- vector->insert(vector->end(), sub_vector->begin(), sub_vector->end());
- }
- }
- closedir(dir);
-
- return vector;
-}
-
-std::unique_ptr<std::string> ReadFile(const std::string& path) {
- std::unique_ptr<std::string> str(new std::string());
- std::ifstream fin(path);
- str->append({std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>()});
- fin.close();
- return str;
-}
-
-std::unique_ptr<std::string> ReadFile(int fd) {
- static constexpr const size_t kBufSize = 1024;
-
- std::unique_ptr<std::string> str(new std::string());
- char buf[kBufSize];
- ssize_t r;
- while ((r = read(fd, buf, sizeof(buf))) > 0) {
- str->append(buf, r);
- }
- return r == 0 ? std::move(str) : nullptr;
-}
-
#ifdef __ANDROID__
bool UidHasWriteAccessToPath(uid_t uid, const std::string& path) {
// resolve symlinks and relative paths; the directories must exist
diff --git a/cmds/idmap2/libidmap2/PolicyUtils.cpp b/cmds/idmap2/libidmap2/PolicyUtils.cpp
index fc5182af61c1..4e3f54d2583e 100644
--- a/cmds/idmap2/libidmap2/PolicyUtils.cpp
+++ b/cmds/idmap2/libidmap2/PolicyUtils.cpp
@@ -17,6 +17,8 @@
#include "include/idmap2/PolicyUtils.h"
#include <sstream>
+#include <string>
+#include <vector>
#include "android-base/strings.h"
#include "idmap2/Policies.h"
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 34589a1c39dc..fd8b4eb86b4a 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -61,10 +61,13 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
const ResourceId& target_resource) {
static constexpr const PolicyBitmask sDefaultPolicies =
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
- PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
+ PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
+ PolicyFlags::CONFIG_SIGNATURE;
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
- // the overlay is preinstalled or signed with the same signature as the target.
+ // the overlay is preinstalled, signed with the same signature as the target or signed with the
+ // same signature as reference package defined in SystemConfig under 'overlay-config-signature'
+ // tag.
if (!target_package.DefinesOverlayable()) {
return (sDefaultPolicies & fulfilled_policies) != 0
? Result<Unit>({})
diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
index 5bd353af4ad3..cdce45191094 100644
--- a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
+++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
@@ -14,11 +14,12 @@
* limitations under the License.
*/
-#ifndef IDMAP2_INCLUDE_IDMAP2_POLICIES_H_
-#define IDMAP2_INCLUDE_IDMAP2_POLICIES_H_
+#ifndef IDMAP2_LIBIDMAP2_POLICIES_INCLUDE_IDMAP2_POLICIES_H_
+#define IDMAP2_LIBIDMAP2_POLICIES_INCLUDE_IDMAP2_POLICIES_H_
#include <array>
#include <string>
+#include <utility>
#include <vector>
#include "android-base/stringprintf.h"
@@ -37,16 +38,18 @@ constexpr const char* kPolicyOdm = "odm";
constexpr const char* kPolicyOem = "oem";
constexpr const char* kPolicyProduct = "product";
constexpr const char* kPolicyPublic = "public";
+constexpr const char* kPolicyConfigSignature = "config_signature";
constexpr const char* kPolicySignature = "signature";
constexpr const char* kPolicySystem = "system";
constexpr const char* kPolicyVendor = "vendor";
-inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicyStringToFlag = {
+inline static const std::array<std::pair<StringPiece, PolicyFlags>, 9> kPolicyStringToFlag = {
std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
{kPolicyOdm, PolicyFlags::ODM_PARTITION},
{kPolicyOem, PolicyFlags::OEM_PARTITION},
{kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
{kPolicyPublic, PolicyFlags::PUBLIC},
+ {kPolicyConfigSignature, PolicyFlags::CONFIG_SIGNATURE},
{kPolicySignature, PolicyFlags::SIGNATURE},
{kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
{kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
@@ -76,4 +79,4 @@ inline static std::string PoliciesToDebugString(PolicyBitmask policies) {
} // namespace android::idmap2::policy
-#endif // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_
+#endif // IDMAP2_LIBIDMAP2_POLICIES_INCLUDE_IDMAP2_POLICIES_H_
diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp
index 8af4037be954..5750ca1f49c5 100644
--- a/cmds/idmap2/tests/FileUtilsTests.cpp
+++ b/cmds/idmap2/tests/FileUtilsTests.cpp
@@ -14,73 +14,16 @@
* limitations under the License.
*/
-#include <dirent.h>
-#include <fcntl.h>
-
-#include <set>
#include <string>
#include "TestHelpers.h"
-#include "android-base/macros.h"
#include "android-base/stringprintf.h"
-#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "idmap2/FileUtils.h"
#include "private/android_filesystem_config.h"
-using ::testing::NotNull;
-
namespace android::idmap2::utils {
-TEST(FileUtilsTests, FindFilesFindEverythingNonRecursive) {
- const auto& root = GetTestDataPath();
- auto v = utils::FindFiles(root, false,
- [](unsigned char type ATTRIBUTE_UNUSED,
- const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; });
- ASSERT_THAT(v, NotNull());
- ASSERT_EQ(v->size(), 7U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({
- root + "/.",
- root + "/..",
- root + "/overlay",
- root + "/target",
- root + "/signature-overlay",
- root + "/system-overlay",
- root + "/system-overlay-invalid",
- }));
-}
-
-TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) {
- const auto& root = GetTestDataPath();
- auto v = utils::FindFiles(root, true, [](unsigned char type, const std::string& path) -> bool {
- return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0;
- });
- ASSERT_THAT(v, NotNull());
- ASSERT_EQ(v->size(), 11U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
- std::set<std::string>(
- {root + "/target/target.apk", root + "/target/target-no-overlayable.apk",
- root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk",
- root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-shared.apk",
- root + "/overlay/overlay-static-1.apk", root + "/overlay/overlay-static-2.apk",
- root + "/signature-overlay/signature-overlay.apk",
- root + "/system-overlay/system-overlay.apk",
- root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
-}
-
-TEST(FileUtilsTests, ReadFile) {
- int pipefd[2];
- ASSERT_EQ(pipe2(pipefd, O_CLOEXEC), 0);
-
- ASSERT_EQ(write(pipefd[1], "foobar", 6), 6);
- close(pipefd[1]);
-
- auto data = ReadFile(pipefd[0]);
- ASSERT_THAT(data, NotNull());
- ASSERT_EQ(*data, "foobar");
- close(pipefd[0]);
-}
-
#ifdef __ANDROID__
TEST(FileUtilsTests, UidHasWriteAccessToPath) {
constexpr const char* tmp_path = "/data/local/tmp/test@idmap";
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index d896cf9c11ba..61751b33dcba 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -159,131 +159,6 @@ TEST_F(Idmap2BinaryTests, Dump) {
unlink(GetIdmapPath().c_str());
}
-TEST_F(Idmap2BinaryTests, Scan) {
- SKIP_TEST_IF_CANT_EXEC_IDMAP2;
-
- const std::string overlay_static_no_name_apk_path =
- GetTestDataPath() + "/overlay/overlay-no-name-static.apk";
- const std::string overlay_static_1_apk_path = GetTestDataPath() + "/overlay/overlay-static-1.apk";
- const std::string overlay_static_2_apk_path = GetTestDataPath() + "/overlay/overlay-static-2.apk";
- const std::string idmap_static_no_name_path =
- Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_no_name_apk_path);
- const std::string idmap_static_1_path =
- Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_1_apk_path);
- const std::string idmap_static_2_path =
- Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_2_apk_path);
-
- // single input directory, recursive
- // clang-format off
- auto result = ExecuteBinary({"idmap2",
- "scan",
- "--input-directory", GetTestDataPath(),
- "--recursive",
- "--target-package-name", "test.target",
- "--target-apk-path", GetTargetApkPath(),
- "--output-directory", GetTempDirPath(),
- "--override-policy", "public"});
- // clang-format on
- ASSERT_THAT(result, NotNull());
- ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- std::stringstream expected;
- expected << idmap_static_no_name_path << std::endl;
- expected << idmap_static_1_path << std::endl;
- expected << idmap_static_2_path << std::endl;
- ASSERT_EQ(result->stdout, expected.str());
-
- auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path);
- auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string);
- auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream);
- ASSERT_TRUE(idmap_static_no_name);
- ASSERT_IDMAP(**idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path);
-
- auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path);
- auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string);
- auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream);
- ASSERT_TRUE(idmap_static_1);
- ASSERT_IDMAP(**idmap_static_1, GetTargetApkPath(), overlay_static_1_apk_path);
-
- auto idmap_static_2_raw_string = utils::ReadFile(idmap_static_2_path);
- auto idmap_static_2_raw_stream = std::istringstream(*idmap_static_2_raw_string);
- auto idmap_static_2 = Idmap::FromBinaryStream(idmap_static_2_raw_stream);
- ASSERT_TRUE(idmap_static_2);
- ASSERT_IDMAP(**idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path);
-
- unlink(idmap_static_no_name_path.c_str());
- unlink(idmap_static_2_path.c_str());
- unlink(idmap_static_1_path.c_str());
-
- // multiple input directories, non-recursive
- // clang-format off
- result = ExecuteBinary({"idmap2",
- "scan",
- "--input-directory", GetTestDataPath() + "/target",
- "--input-directory", GetTestDataPath() + "/overlay",
- "--target-package-name", "test.target",
- "--target-apk-path", GetTargetApkPath(),
- "--output-directory", GetTempDirPath(),
- "--override-policy", "public"});
- // clang-format on
- ASSERT_THAT(result, NotNull());
- ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- ASSERT_EQ(result->stdout, expected.str());
- unlink(idmap_static_no_name_path.c_str());
- unlink(idmap_static_2_path.c_str());
- unlink(idmap_static_1_path.c_str());
-
- // the same input directory given twice, but no duplicate entries
- // clang-format off
- result = ExecuteBinary({"idmap2",
- "scan",
- "--input-directory", GetTestDataPath(),
- "--input-directory", GetTestDataPath(),
- "--recursive",
- "--target-package-name", "test.target",
- "--target-apk-path", GetTargetApkPath(),
- "--output-directory", GetTempDirPath(),
- "--override-policy", "public"});
- // clang-format on
- ASSERT_THAT(result, NotNull());
- ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- ASSERT_EQ(result->stdout, expected.str());
- unlink(idmap_static_no_name_path.c_str());
- unlink(idmap_static_2_path.c_str());
- unlink(idmap_static_1_path.c_str());
-
- // no APKs in input-directory: ok, but no output
- // clang-format off
- result = ExecuteBinary({"idmap2",
- "scan",
- "--input-directory", GetTempDirPath(),
- "--target-package-name", "test.target",
- "--target-apk-path", GetTargetApkPath(),
- "--output-directory", GetTempDirPath(),
- "--override-policy", "public"});
- // clang-format on
- ASSERT_THAT(result, NotNull());
- ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- ASSERT_EQ(result->stdout, "");
-
- // the signature idmap failing to generate should not cause scanning to fail
- // clang-format off
- result = ExecuteBinary({"idmap2",
- "scan",
- "--input-directory", GetTestDataPath(),
- "--recursive",
- "--target-package-name", "test.target",
- "--target-apk-path", GetTargetApkPath(),
- "--output-directory", GetTempDirPath(),
- "--override-policy", "public"});
- // clang-format on
- ASSERT_THAT(result, NotNull());
- ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
- ASSERT_EQ(result->stdout, expected.str());
- unlink(idmap_static_no_name_path.c_str());
- unlink(idmap_static_2_path.c_str());
- unlink(idmap_static_1_path.c_str());
-}
-
TEST_F(Idmap2BinaryTests, Lookup) {
SKIP_TEST_IF_CANT_EXEC_IDMAP2;
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index aed263a49aa3..854b57fb22aa 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-#ifndef IDMAP2_TESTS_R_H
-#define IDMAP2_TESTS_R_H
+#ifndef IDMAP2_TESTS_R_H_
+#define IDMAP2_TESTS_R_H_
-#include <idmap2/ResourceUtils.h>
+#include <string>
+
+#include "idmap2/ResourceUtils.h"
namespace android::idmap2 {
@@ -29,42 +31,43 @@ static std::string hexify(ResourceId id) {
// clang-format off
namespace R::target {
- namespace integer {
+ namespace integer { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId int1 = 0x7f010000;
- namespace literal {
+ namespace literal { // NOLINT(runtime/indentation_namespace)
inline const std::string int1 = hexify(R::target::integer::int1);
}
}
- namespace string {
+ namespace string { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId not_overlayable = 0x7f020003;
constexpr ResourceId other = 0x7f020004;
constexpr ResourceId policy_actor = 0x7f020005;
- constexpr ResourceId policy_odm = 0x7f020006;
- constexpr ResourceId policy_oem = 0x7f020007;
- constexpr ResourceId policy_product = 0x7f020008;
- constexpr ResourceId policy_public = 0x7f020009;
- constexpr ResourceId policy_signature = 0x7f02000a;
- constexpr ResourceId policy_system = 0x7f02000b;
- constexpr ResourceId policy_system_vendor = 0x7f02000c;
- constexpr ResourceId str1 = 0x7f02000d;
- constexpr ResourceId str3 = 0x7f02000f;
- constexpr ResourceId str4 = 0x7f020010;
+ constexpr ResourceId policy_config_signature = 0x7f020006;
+ constexpr ResourceId policy_odm = 0x7f020007;
+ constexpr ResourceId policy_oem = 0x7f020008;
+ constexpr ResourceId policy_product = 0x7f020009;
+ constexpr ResourceId policy_public = 0x7f02000a;
+ constexpr ResourceId policy_signature = 0x7f02000b;
+ constexpr ResourceId policy_system = 0x7f02000c;
+ constexpr ResourceId policy_system_vendor = 0x7f02000d;
+ constexpr ResourceId str1 = 0x7f02000e;
+ constexpr ResourceId str3 = 0x7f020010;
+ constexpr ResourceId str4 = 0x7f020011;
- namespace literal {
+ namespace literal { // NOLINT(runtime/indentation_namespace)
inline const std::string str1 = hexify(R::target::string::str1);
inline const std::string str3 = hexify(R::target::string::str3);
inline const std::string str4 = hexify(R::target::string::str4);
}
- }
-}
+ } // namespace string
+} // namespace R::target
namespace R::overlay {
- namespace integer {
+ namespace integer { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId int1 = 0x7f010000;
}
- namespace string {
+ namespace string { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId str1 = 0x7f020000;
constexpr ResourceId str3 = 0x7f020001;
constexpr ResourceId str4 = 0x7f020002;
@@ -72,10 +75,10 @@ namespace R::overlay {
}
namespace R::overlay_shared {
- namespace integer {
+ namespace integer { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId int1 = 0x00010000;
}
- namespace string {
+ namespace string { // NOLINT(runtime/indentation_namespace)
constexpr ResourceId str1 = 0x00020000;
constexpr ResourceId str3 = 0x00020001;
constexpr ResourceId str4 = 0x00020002;
@@ -92,16 +95,17 @@ namespace R::system_overlay_invalid::string {
constexpr ResourceId not_overlayable = 0x7f010000;
constexpr ResourceId other = 0x7f010001;
constexpr ResourceId policy_actor = 0x7f010002;
- constexpr ResourceId policy_odm = 0x7f010003;
- constexpr ResourceId policy_oem = 0x7f010004;
- constexpr ResourceId policy_product = 0x7f010005;
- constexpr ResourceId policy_public = 0x7f010006;
- constexpr ResourceId policy_signature = 0x7f010007;
- constexpr ResourceId policy_system = 0x7f010008;
- constexpr ResourceId policy_system_vendor = 0x7f010009;
-};
+ constexpr ResourceId policy_config_signature = 0x7f010003;
+ constexpr ResourceId policy_odm = 0x7f010004;
+ constexpr ResourceId policy_oem = 0x7f010005;
+ constexpr ResourceId policy_product = 0x7f010006;
+ constexpr ResourceId policy_public = 0x7f010007;
+ constexpr ResourceId policy_signature = 0x7f010008;
+ constexpr ResourceId policy_system = 0x7f010009;
+ constexpr ResourceId policy_system_vendor = 0x7f01000a;
+} // namespace R::system_overlay_invalid::string
// clang-format on
} // namespace android::idmap2
-#endif // IDMAP2_TESTS_R_H
+#endif // IDMAP2_TESTS_R_H_
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index de039f440e33..3ec6ac24b238 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -237,7 +237,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(res.GetTargetToOverlayMap().size(), 10U);
+ ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
@@ -256,6 +256,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+ Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_config_signature,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
@@ -298,8 +302,9 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
}
-// Overlays that are pre-installed or are signed with the same signature as the target can overlay
-// packages that have not defined overlayable resources.
+// Overlays that are pre-installed or are signed with the same signature as the target or are signed
+// with the same signature as the reference package can overlay packages that have not defined
+// overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
@@ -309,7 +314,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
+ ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
@@ -330,6 +335,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+ Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_config_signature,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
@@ -342,6 +351,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
};
CheckEntries(PolicyFlags::SIGNATURE);
+ CheckEntries(PolicyFlags::CONFIG_SIGNATURE);
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
CheckEntries(PolicyFlags::VENDOR_PARTITION);
diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h
index 6bc924e5ac3c..9641f6b55670 100644
--- a/cmds/idmap2/tests/TestConstants.h
+++ b/cmds/idmap2/tests/TestConstants.h
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-#ifndef IDMAP2_TESTS_TESTCONSTANTS_H
-#define IDMAP2_TESTS_TESTCONSTANTS_H
+#ifndef IDMAP2_TESTS_TESTCONSTANTS_H_
+#define IDMAP2_TESTS_TESTCONSTANTS_H_
namespace android::idmap2::TestConstants {
-constexpr const auto TARGET_CRC = 0x41c60c8c;
-constexpr const auto TARGET_CRC_STRING = "41c60c8c";
+constexpr const auto TARGET_CRC = 0x7c2d4719;
+constexpr const auto TARGET_CRC_STRING = "7c2d4719";
-constexpr const auto OVERLAY_CRC = 0xc054fb26;
-constexpr const auto OVERLAY_CRC_STRING = "c054fb26";
+constexpr const auto OVERLAY_CRC = 0x5afff726;
+constexpr const auto OVERLAY_CRC_STRING = "5afff726";
} // namespace android::idmap2::TestConstants
-#endif // IDMAP2_TESTS_TESTCONSTANTS_H
+#endif // IDMAP2_TESTS_TESTCONSTANTS_H_
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
index 7c25985e5a61..dab25b1f8131 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
index c75f3e1dbddf..c8b95c2601ad 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
index 93dcc82f9358..0a8b7372172e 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-shared.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
index 5b8a6e4a90ed..fd41182f8493 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
index 698a1fd6e702..b24765fc666a 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk
index 1db303ff05b5..870575efa10c 100644
--- a/cmds/idmap2/tests/data/overlay/overlay.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
index 51e19de082ed..e0fd20499671 100644
--- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
+++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
index 7119d8283061..ebaf49c34762 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
@@ -26,6 +26,7 @@
<string name="policy_odm">policy_odm</string>
<string name="policy_oem">policy_oem</string>
<string name="policy_actor">policy_actor</string>
+ <string name="policy_config_signature">policy_config_signature</string>
<!-- Requests to overlay a resource that is not declared as overlayable. -->
<string name="not_overlayable">not_overlayable</string>
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
index bd990983693c..a63daf86caf5 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
index a0fba4378b57..90d2803a1eca 100644
--- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
+++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index ad4cd4882632..57e6c439c23c 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -45,6 +45,10 @@
<item type="string" name="policy_actor" />
</policy>
+ <policy type="config_signature">
+ <item type="string" name="policy_config_signature"/>
+ </policy>
+
<!-- Resources publicly overlayable -->
<policy type="public">
<item type="string" name="policy_public" />
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index 5230e25e626b..00909a9e481c 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -37,6 +37,7 @@
<string name="policy_system">policy_system</string>
<string name="policy_system_vendor">policy_system_vendor</string>
<string name="policy_actor">policy_actor</string>
+ <string name="policy_config_signature">policy_config_signature</string>
<string name="other">other</string>
</resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 58504a74a83a..cc3491de894d 100644
--- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk
index c80e5eb65ff2..4a58c5e28f49 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ
diff --git a/cmds/idmap2/valgrind.sh b/cmds/idmap2/valgrind.sh
index b4ebab0c7ffe..84daeecdb21e 100755
--- a/cmds/idmap2/valgrind.sh
+++ b/cmds/idmap2/valgrind.sh
@@ -53,7 +53,5 @@ valgrind="valgrind --error-exitcode=1 -q --track-origins=yes --leak-check=full"
_eval "idmap2 create" "$valgrind idmap2 create --policy public --target-apk-path $target_path --overlay-apk-path $overlay_path --idmap-path $idmap_path"
_eval "idmap2 dump" "$valgrind idmap2 dump --idmap-path $idmap_path"
_eval "idmap2 lookup" "$valgrind idmap2 lookup --idmap-path $idmap_path --config '' --resid test.target:string/str1"
-_eval "idmap2 scan" "$valgrind idmap2 scan --input-directory ${prefix}/tests/data/overlay --recursive --target-package-name test.target --target-apk-path $target_path --output-directory /tmp --override-policy public"
-_eval "idmap2 verify" "$valgrind idmap2 verify --idmap-path $idmap_path"
_eval "idmap2_tests" "$valgrind $ANDROID_HOST_OUT/nativetest64/idmap2_tests/idmap2_tests"
exit $errors
diff --git a/cmds/input/Android.bp b/cmds/input/Android.bp
index a0ebde63eb6e..1ee9dd355290 100644
--- a/cmds/input/Android.bp
+++ b/cmds/input/Android.bp
@@ -1,8 +1,7 @@
// Copyright 2008 The Android Open Source Project
//
-java_binary {
+sh_binary {
name: "input",
- wrapper: "input",
- srcs: ["**/*.java"],
+ src: "input",
}
diff --git a/cmds/input/input b/cmds/input/input
index 2625eba17153..d7d041431b49 100755
--- a/cmds/input/input
+++ b/cmds/input/input
@@ -1,3 +1,2 @@
#!/system/bin/sh
-export CLASSPATH=/system/framework/input.jar
-exec app_process /system/bin com.android.commands.input.Input "$@"
+cmd input "$@"
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
deleted file mode 100644
index 08216d9b3f1d..000000000000
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2007 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.commands.input;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.INVALID_DISPLAY;
-
-import android.hardware.input.InputManager;
-import android.os.SystemClock;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-
-import com.android.internal.os.BaseCommand;
-
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Command that sends key events to the device, either by their keycode, or by
- * desired character output.
- */
-
-public class Input extends BaseCommand {
- private static final String TAG = "Input";
- private static final String INVALID_ARGUMENTS = "Error: Invalid arguments for command: ";
- private static final String INVALID_DISPLAY_ARGUMENTS =
- "Error: Invalid arguments for display ID.";
-
- private static final float DEFAULT_PRESSURE = 1.0f;
- private static final float NO_PRESSURE = 0.0f;
-
- private static final Map<String, Integer> SOURCES = new HashMap<String, Integer>() {{
- put("keyboard", InputDevice.SOURCE_KEYBOARD);
- put("dpad", InputDevice.SOURCE_DPAD);
- put("gamepad", InputDevice.SOURCE_GAMEPAD);
- put("touchscreen", InputDevice.SOURCE_TOUCHSCREEN);
- put("mouse", InputDevice.SOURCE_MOUSE);
- put("stylus", InputDevice.SOURCE_STYLUS);
- put("trackball", InputDevice.SOURCE_TRACKBALL);
- put("touchpad", InputDevice.SOURCE_TOUCHPAD);
- put("touchnavigation", InputDevice.SOURCE_TOUCH_NAVIGATION);
- put("joystick", InputDevice.SOURCE_JOYSTICK);
- }};
-
- private static final Map<String, InputCmd> COMMANDS = new HashMap<String, InputCmd>();
-
- /**
- * Command-line entry point.
- *
- * @param args The command-line arguments
- */
- public static void main(String[] args) {
- (new Input()).run(args);
- }
-
- Input() {
- COMMANDS.put("text", new InputText());
- COMMANDS.put("keyevent", new InputKeyEvent());
- COMMANDS.put("tap", new InputTap());
- COMMANDS.put("swipe", new InputSwipe());
- COMMANDS.put("draganddrop", new InputDragAndDrop());
- COMMANDS.put("press", new InputPress());
- COMMANDS.put("roll", new InputRoll());
- COMMANDS.put("motionevent", new InputMotionEvent());
- }
-
- @Override
- public void onRun() throws Exception {
- String arg = nextArgRequired();
- int inputSource = InputDevice.SOURCE_UNKNOWN;
-
- // Get source (optional).
- if (SOURCES.containsKey(arg)) {
- inputSource = SOURCES.get(arg);
- arg = nextArgRequired();
- }
-
- // Get displayId (optional).
- int displayId = INVALID_DISPLAY;
- if ("-d".equals(arg)) {
- displayId = getDisplayId();
- arg = nextArgRequired();
- }
-
- // Get command and run.
- InputCmd cmd = COMMANDS.get(arg);
- if (cmd != null) {
- try {
- cmd.run(inputSource, displayId);
- return;
- } catch (NumberFormatException ex) {
- throw new IllegalArgumentException(INVALID_ARGUMENTS + arg);
- }
- }
-
- throw new IllegalArgumentException("Error: Unknown command: " + arg);
- }
-
- private int getDisplayId() {
- String displayArg = nextArgRequired();
- if ("INVALID_DISPLAY".equalsIgnoreCase(displayArg)) {
- return INVALID_DISPLAY;
- } else if ("DEFAULT_DISPLAY".equalsIgnoreCase(displayArg)) {
- return DEFAULT_DISPLAY;
- } else {
- try {
- final int displayId = Integer.parseInt(displayArg);
- if (displayId == INVALID_DISPLAY) {
- return INVALID_DISPLAY;
- }
- return Math.max(displayId, 0);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(INVALID_DISPLAY_ARGUMENTS);
- }
- }
- }
-
- class InputText implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
- sendText(inputSource, nextArgRequired(), displayId);
- }
-
- /**
- * Convert the characters of string text into key event's and send to
- * device.
- *
- * @param text is a string of characters you want to input to the device.
- */
- private void sendText(int source, final String text, int displayId) {
- final StringBuffer buff = new StringBuffer(text);
- boolean escapeFlag = false;
- for (int i = 0; i < buff.length(); i++) {
- if (escapeFlag) {
- escapeFlag = false;
- if (buff.charAt(i) == 's') {
- buff.setCharAt(i, ' ');
- buff.deleteCharAt(--i);
- }
- }
- if (buff.charAt(i) == '%') {
- escapeFlag = true;
- }
- }
-
- final char[] chars = buff.toString().toCharArray();
- final KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
- final KeyEvent[] events = kcm.getEvents(chars);
- for (int i = 0; i < events.length; i++) {
- KeyEvent e = events[i];
- if (source != e.getSource()) {
- e.setSource(source);
- }
- e.setDisplayId(displayId);
- injectKeyEvent(e);
- }
- }
- }
-
- class InputKeyEvent implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- String arg = nextArgRequired();
- final boolean longpress = "--longpress".equals(arg);
- if (longpress) {
- arg = nextArgRequired();
- }
-
- do {
- final int keycode = KeyEvent.keyCodeFromString(arg);
- sendKeyEvent(inputSource, keycode, longpress, displayId);
- } while ((arg = nextArg()) != null);
- }
-
- private void sendKeyEvent(int inputSource, int keyCode, boolean longpress, int displayId) {
- final long now = SystemClock.uptimeMillis();
- int repeatCount = 0;
-
- KeyEvent event = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, repeatCount,
- 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
- inputSource);
- event.setDisplayId(displayId);
-
- injectKeyEvent(event);
- if (longpress) {
- repeatCount++;
- injectKeyEvent(KeyEvent.changeTimeRepeat(event, now, repeatCount,
- KeyEvent.FLAG_LONG_PRESS));
- }
- injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
- }
- }
-
- class InputTap implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
- sendTap(inputSource, Float.parseFloat(nextArgRequired()),
- Float.parseFloat(nextArgRequired()), displayId);
- }
-
- void sendTap(int inputSource, float x, float y, int displayId) {
- final long now = SystemClock.uptimeMillis();
- injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, now, x, y, 1.0f,
- displayId);
- injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, now, x, y, 0.0f, displayId);
- }
- }
-
- class InputPress extends InputTap {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
- sendTap(inputSource, 0.0f, 0.0f, displayId);
- }
- }
-
- class InputSwipe implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
- sendSwipe(inputSource, displayId, false);
- }
-
- void sendSwipe(int inputSource, int displayId, boolean isDragDrop) {
- // Parse two points and duration.
- final float x1 = Float.parseFloat(nextArgRequired());
- final float y1 = Float.parseFloat(nextArgRequired());
- final float x2 = Float.parseFloat(nextArgRequired());
- final float y2 = Float.parseFloat(nextArgRequired());
- String durationArg = nextArg();
- int duration = durationArg != null ? Integer.parseInt(durationArg) : -1;
- if (duration < 0) {
- duration = 300;
- }
-
- final long down = SystemClock.uptimeMillis();
- injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, down, down, x1, y1, 1.0f,
- displayId);
- if (isDragDrop) {
- // long press until drag start.
- try {
- Thread.sleep(ViewConfiguration.getLongPressTimeout());
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- long now = SystemClock.uptimeMillis();
- final long endTime = down + duration;
- while (now < endTime) {
- final long elapsedTime = now - down;
- final float alpha = (float) elapsedTime / duration;
- injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, down, now,
- lerp(x1, x2, alpha), lerp(y1, y2, alpha), 1.0f, displayId);
- now = SystemClock.uptimeMillis();
- }
- injectMotionEvent(inputSource, MotionEvent.ACTION_UP, down, now, x2, y2, 0.0f,
- displayId);
- }
- }
-
- class InputDragAndDrop extends InputSwipe {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
- sendSwipe(inputSource, displayId, true);
- }
- }
-
- class InputRoll implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
- sendMove(inputSource, Float.parseFloat(nextArgRequired()),
- Float.parseFloat(nextArgRequired()), displayId);
- }
-
- /**
- * Sends a simple zero-pressure move event.
- *
- * @param inputSource the InputDevice.SOURCE_* sending the input event
- * @param dx change in x coordinate due to move
- * @param dy change in y coordinate due to move
- */
- private void sendMove(int inputSource, float dx, float dy, int displayId) {
- final long now = SystemClock.uptimeMillis();
- injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, now, dx, dy, 0.0f,
- displayId);
- }
- }
-
- class InputMotionEvent implements InputCmd {
- @Override
- public void run(int inputSource, int displayId) {
- inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
- sendMotionEvent(inputSource, nextArgRequired(), Float.parseFloat(nextArgRequired()),
- Float.parseFloat(nextArgRequired()), displayId);
- }
-
- private void sendMotionEvent(int inputSource, String motionEventType, float x, float y,
- int displayId) {
- final int action;
- final float pressure;
-
- switch (motionEventType.toUpperCase()) {
- case "DOWN":
- action = MotionEvent.ACTION_DOWN;
- pressure = DEFAULT_PRESSURE;
- break;
- case "UP":
- action = MotionEvent.ACTION_UP;
- pressure = NO_PRESSURE;
- break;
- case "MOVE":
- action = MotionEvent.ACTION_MOVE;
- pressure = DEFAULT_PRESSURE;
- break;
- default:
- throw new IllegalArgumentException("Unknown motionevent " + motionEventType);
- }
-
- final long now = SystemClock.uptimeMillis();
- injectMotionEvent(inputSource, action, now, now, x, y, pressure, displayId);
- }
- }
-
- /**
- * Abstract class for command
- * use nextArgRequired or nextArg to check next argument if necessary.
- */
- private interface InputCmd {
- void run(int inputSource, int displayId);
- }
-
- private static void injectKeyEvent(KeyEvent event) {
- InputManager.getInstance().injectInputEvent(event,
- InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
- }
-
- private static int getInputDeviceId(int inputSource) {
- final int DEFAULT_DEVICE_ID = 0;
- int[] devIds = InputDevice.getDeviceIds();
- for (int devId : devIds) {
- InputDevice inputDev = InputDevice.getDevice(devId);
- if (inputDev.supportsSource(inputSource)) {
- return devId;
- }
- }
- return DEFAULT_DEVICE_ID;
- }
-
- /**
- * Builds a MotionEvent and injects it into the event stream.
- *
- * @param inputSource the InputDevice.SOURCE_* sending the input event
- * @param action the MotionEvent.ACTION_* for the event
- * @param downTime the value of the ACTION_DOWN event happened
- * @param when the value of SystemClock.uptimeMillis() at which the event happened
- * @param x x coordinate of event
- * @param y y coordinate of event
- * @param pressure pressure of event
- */
- private static void injectMotionEvent(int inputSource, int action, long downTime, long when,
- float x, float y, float pressure, int displayId) {
- final float DEFAULT_SIZE = 1.0f;
- final int DEFAULT_META_STATE = 0;
- final float DEFAULT_PRECISION_X = 1.0f;
- final float DEFAULT_PRECISION_Y = 1.0f;
- final int DEFAULT_EDGE_FLAGS = 0;
- MotionEvent event = MotionEvent.obtain(downTime, when, action, x, y, pressure, DEFAULT_SIZE,
- DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,
- getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);
- event.setSource(inputSource);
- if (displayId == INVALID_DISPLAY && (inputSource & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- displayId = DEFAULT_DISPLAY;
- }
- event.setDisplayId(displayId);
- InputManager.getInstance().injectInputEvent(event,
- InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
- }
-
- private static final float lerp(float a, float b, float alpha) {
- return (b - a) * alpha + a;
- }
-
- private static final int getSource(int inputSource, int defaultSource) {
- return inputSource == InputDevice.SOURCE_UNKNOWN ? defaultSource : inputSource;
- }
-
- @Override
- public void onShowUsage(PrintStream out) {
- out.println("Usage: input [<source>] [-d DISPLAY_ID] <command> [<arg>...]");
- out.println();
- out.println("The sources are: ");
- for (String src : SOURCES.keySet()) {
- out.println(" " + src);
- }
- out.println();
- out.printf("-d: specify the display ID.\n"
- + " (Default: %d for key event, %d for motion event if not specified.)",
- INVALID_DISPLAY, DEFAULT_DISPLAY);
- out.println();
- out.println("The commands and default sources are:");
- out.println(" text <string> (Default: touchscreen)");
- out.println(" keyevent [--longpress] <key code number or name> ..."
- + " (Default: keyboard)");
- out.println(" tap <x> <y> (Default: touchscreen)");
- out.println(" swipe <x1> <y1> <x2> <y2> [duration(ms)]"
- + " (Default: touchscreen)");
- out.println(" draganddrop <x1> <y1> <x2> <y2> [duration(ms)]"
- + " (Default: touchscreen)");
- out.println(" press (Default: trackball)");
- out.println(" roll <dx> <dy> (Default: trackball)");
- out.println(" motionevent <DOWN|UP|MOVE> <x> <y> (Default: touchscreen)");
- }
-}
diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING
index 56f5cc034f05..c1cba5f7f22d 100644
--- a/cmds/locksettings/TEST_MAPPING
+++ b/cmds/locksettings/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit-devicepolicy": [
+ "presubmit": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
diff --git a/cmds/screencap/Android.bp b/cmds/screencap/Android.bp
index 248c67589696..fc628a696afa 100644
--- a/cmds/screencap/Android.bp
+++ b/cmds/screencap/Android.bp
@@ -7,7 +7,7 @@ cc_binary {
"libcutils",
"libutils",
"libbinder",
- "libhwui",
+ "libjnigraphics",
"libui",
"libgui",
],
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index bb32dd2fa7ad..dec4a567fc81 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -26,6 +26,8 @@
#include <sys/mman.h>
#include <sys/wait.h>
+#include <android/bitmap.h>
+
#include <binder/ProcessState.h>
#include <gui/SurfaceComposerClient.h>
@@ -37,14 +39,6 @@
#include <system/graphics.h>
-// TODO: Fix Skia.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#include <SkImageEncoder.h>
-#include <SkData.h>
-#include <SkColorSpace.h>
-#pragma GCC diagnostic pop
-
using namespace android;
#define COLORSPACE_UNKNOWN 0
@@ -57,33 +51,20 @@ static void usage(const char* pname, PhysicalDisplayId displayId)
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
" -h: this message\n"
" -p: save the file as a png.\n"
- " -d: specify the physical display ID to capture (default: %"
- ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ")\n"
+ " -d: specify the physical display ID to capture (default: %s)\n"
" see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
"If FILENAME ends with .png it will be saved as a png.\n"
"If FILENAME is not given, the results will be printed to stdout.\n",
- pname, displayId);
+ pname, to_string(displayId).c_str());
}
-static SkColorType flinger2skia(PixelFormat f)
+static int32_t flinger2bitmapFormat(PixelFormat f)
{
switch (f) {
case PIXEL_FORMAT_RGB_565:
- return kRGB_565_SkColorType;
- default:
- return kN32_SkColorType;
- }
-}
-
-static sk_sp<SkColorSpace> dataSpaceToColorSpace(ui::Dataspace d)
-{
- switch (d) {
- case ui::Dataspace::V0_SRGB:
- return SkColorSpace::MakeSRGB();
- case ui::Dataspace::DISPLAY_P3:
- return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
+ return ANDROID_BITMAP_FORMAT_RGB_565;
default:
- return nullptr;
+ return ANDROID_BITMAP_FORMAT_RGBA_8888;
}
}
@@ -155,7 +136,7 @@ int main(int argc, char** argv)
png = true;
break;
case 'd':
- displayId = atoll(optarg);
+ displayId = PhysicalDisplayId(atoll(optarg));
break;
case '?':
case 'h':
@@ -192,8 +173,6 @@ int main(int argc, char** argv)
ssize_t mapsize = -1;
void* base = NULL;
- uint32_t w, s, h, f;
- size_t size = 0;
// setThreadPoolMaxThreadCount(0) actually tells the kernel it's
// not allowed to spawn any additional threads, but we still spawn
@@ -202,16 +181,17 @@ int main(int argc, char** argv)
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- ui::Dataspace outDataspace;
- sp<GraphicBuffer> outBuffer;
-
- status_t result = ScreenshotClient::capture(*displayId, &outDataspace, &outBuffer);
+ ScreenCaptureResults captureResults;
+ status_t result = ScreenshotClient::captureDisplay(displayId->value, captureResults);
if (result != NO_ERROR) {
close(fd);
return 1;
}
- result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+ ui::Dataspace dataspace = captureResults.capturedDataspace;
+ sp<GraphicBuffer> buffer = captureResults.buffer;
+
+ result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
if (base == nullptr || result != NO_ERROR) {
String8 reason;
@@ -225,33 +205,36 @@ int main(int argc, char** argv)
return 1;
}
- w = outBuffer->getWidth();
- h = outBuffer->getHeight();
- s = outBuffer->getStride();
- f = outBuffer->getPixelFormat();
- size = s * h * bytesPerPixel(f);
-
if (png) {
- const SkImageInfo info =
- SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
- dataSpaceToColorSpace(outDataspace));
- SkPixmap pixmap(info, base, s * bytesPerPixel(f));
- struct FDWStream final : public SkWStream {
- size_t fBytesWritten = 0;
- int fFd;
- FDWStream(int f) : fFd(f) {}
- size_t bytesWritten() const override { return fBytesWritten; }
- bool write(const void* buffer, size_t size) override {
- fBytesWritten += size;
- return size == 0 || ::write(fFd, buffer, size) > 0;
- }
- } fdStream(fd);
- (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kPNG, 100);
+ AndroidBitmapInfo info;
+ info.format = flinger2bitmapFormat(buffer->getPixelFormat());
+ info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
+ info.width = buffer->getWidth();
+ info.height = buffer->getHeight();
+ info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
+
+ int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
+ ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
+ [](void* fdPtr, const void* data, size_t size) -> bool {
+ int bytesWritten = write(*static_cast<int*>(fdPtr),
+ data, size);
+ return bytesWritten == size;
+ });
+
+ if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
+ fprintf(stderr, "Failed to compress PNG (error code: %d)\n", result);
+ }
+
if (fn != NULL) {
notifyMediaScanner(fn);
}
} else {
- uint32_t c = dataSpaceToInt(outDataspace);
+ uint32_t w = buffer->getWidth();
+ uint32_t h = buffer->getHeight();
+ uint32_t s = buffer->getStride();
+ uint32_t f = buffer->getPixelFormat();
+ uint32_t c = dataSpaceToInt(dataspace);
+
write(fd, &w, 4);
write(fd, &h, 4);
write(fd, &f, 4);
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 0617eb6c0e66..7c419519a558 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -85,8 +85,9 @@ cc_defaults {
"src/metrics/EventMetricProducer.cpp",
"src/metrics/GaugeMetricProducer.cpp",
"src/metrics/MetricProducer.cpp",
- "src/metrics/metrics_manager_util.cpp",
"src/metrics/MetricsManager.cpp",
+ "src/metrics/parsing_utils/config_update_utils.cpp",
+ "src/metrics/parsing_utils/metrics_manager_util.cpp",
"src/metrics/ValueMetricProducer.cpp",
"src/packages/UidMap.cpp",
"src/shell/shell_config.proto",
@@ -171,7 +172,8 @@ cc_library_static {
export_generated_headers: ["statslog_statsdtest.h"],
shared_libs: [
"libstatssocket",
- ]
+ "libstatspull",
+ ],
}
cc_library_static {
@@ -185,7 +187,11 @@ cc_library_static {
],
shared_libs: [
"libstatssocket",
- ]
+ "libstatspull",
+ ],
+ export_shared_lib_headers: [
+ "libstatspull",
+ ],
}
// =========
@@ -216,10 +222,6 @@ cc_binary {
// address: true,
//},
},
- debuggable: {
- // Add a flag to enable stats log printing from statsd on debug builds.
- cflags: ["-DVERY_VERBOSE_PRINTING"],
- },
},
proto: {
@@ -321,6 +323,8 @@ cc_test {
"tests/metrics/metrics_test_helper.cpp",
"tests/metrics/OringDurationTracker_test.cpp",
"tests/metrics/ValueMetricProducer_test.cpp",
+ "tests/metrics/parsing_utils/config_update_utils_test.cpp",
+ "tests/metrics/parsing_utils/metrics_manager_util_test.cpp",
"tests/MetricsManager_test.cpp",
"tests/shell/ShellSubscriber_test.cpp",
"tests/state/StateTracker_test.cpp",
diff --git a/cmds/statsd/TEST_MAPPING b/cmds/statsd/TEST_MAPPING
index 8dee073aca22..a7a4cf14182e 100644
--- a/cmds/statsd/TEST_MAPPING
+++ b/cmds/statsd/TEST_MAPPING
@@ -3,5 +3,15 @@
{
"name" : "statsd_test"
}
+ ],
+
+ "postsubmit" : [
+ {
+ "name" : "CtsStatsdHostTestCases"
+ },
+ {
+ "name" : "GtsStatsdHostTestCases"
+ }
]
-} \ No newline at end of file
+
+}
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index e7b32c56551a..7bee4e2d1a36 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -120,10 +120,9 @@ static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outDat
}
}
-void StatsLogProcessor::onAnomalyAlarmFired(
+void StatsLogProcessor::processFiredAnomalyAlarmsLocked(
const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
for (const auto& itr : mMetricsManagers) {
itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
}
@@ -409,11 +408,9 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
onWatchdogRollbackOccurredLocked(event);
}
-#ifdef VERY_VERBOSE_PRINTING
if (mPrintAllLogs) {
ALOGI("%s", event->ToString().c_str());
}
-#endif
resetIfConfigTtlExpiredLocked(eventElapsedTimeNs);
// Hard-coded logic to update the isolated uid's in the uid-map.
@@ -431,6 +428,20 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
return;
}
+ bool fireAlarm = false;
+ {
+ std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex);
+ if (mNextAnomalyAlarmTime != 0 &&
+ MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) {
+ mNextAnomalyAlarmTime = 0;
+ VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs);
+ fireAlarm = true;
+ }
+ }
+ if (fireAlarm) {
+ informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs));
+ }
+
int64_t curTimeSec = getElapsedRealtimeSec();
if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
@@ -515,19 +526,35 @@ void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigK
OnConfigUpdatedLocked(timestampNs, key, config);
}
-void StatsLogProcessor::OnConfigUpdatedLocked(
- const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
+void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config, bool modularUpdate) {
VLOG("Updated configuration for key %s", key.ToString().c_str());
- sp<MetricsManager> newMetricsManager =
- new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
- mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
- if (newMetricsManager->isConfigValid()) {
- newMetricsManager->init();
- mUidMap->OnConfigUpdated(key);
- newMetricsManager->refreshTtl(timestampNs);
- mMetricsManagers[key] = newMetricsManager;
- VLOG("StatsdConfig valid");
+ // Create new config if this is not a modular update or if this is a new config.
+ const auto& it = mMetricsManagers.find(key);
+ bool configValid = false;
+ if (!modularUpdate || it == mMetricsManagers.end()) {
+ sp<MetricsManager> newMetricsManager =
+ new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
+ mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
+ configValid = newMetricsManager->isConfigValid();
+ if (configValid) {
+ newMetricsManager->init();
+ mUidMap->OnConfigUpdated(key);
+ newMetricsManager->refreshTtl(timestampNs);
+ mMetricsManagers[key] = newMetricsManager;
+ VLOG("StatsdConfig valid");
+ }
} else {
+ // Preserve the existing MetricsManager, update necessary components and metadata in place.
+ configValid = it->second->updateConfig(config, mTimeBaseNs, timestampNs,
+ mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
+ if (configValid) {
+ // TODO(b/162323476): refresh TTL, ensure init() is handled properly.
+ mUidMap->OnConfigUpdated(key);
+
+ }
+ }
+ if (!configValid) {
// If there is any error in the config, don't use it.
// Remove any existing config with the same key.
ALOGE("StatsdConfig NOT valid");
@@ -1092,6 +1119,28 @@ void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
mOnDiskDataConfigs.insert(key);
}
+void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) {
+ std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
+ mNextAnomalyAlarmTime = elapsedTimeMillis;
+}
+
+void StatsLogProcessor::cancelAnomalyAlarm() {
+ std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
+ mNextAnomalyAlarmTime = 0;
+}
+
+void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) {
+ VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
+ std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
+ mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000));
+ if (alarmSet.size() > 0) {
+ VLOG("Found periodic alarm fired.");
+ processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet);
+ } else {
+ ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 23f2584655b0..383dbd9db2c1 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -66,11 +66,6 @@ public:
const DumpLatency dumpLatency,
ProtoOutputStream* proto);
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
- void onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
void onPeriodicAlarmFired(
const int64_t& timestampNs,
@@ -139,15 +134,17 @@ public:
int64_t getLastReportTimeNs(const ConfigKey& key);
inline void setPrintLogs(bool enabled) {
-#ifdef VERY_VERBOSE_PRINTING
std::lock_guard<std::mutex> lock(mMetricsMutex);
mPrintAllLogs = enabled;
-#endif
}
// Add a specific config key to the possible configs to dump ASAP.
void noteOnDiskData(const ConfigKey& key);
+ void setAnomalyAlarm(const int64_t timeMillis);
+
+ void cancelAnomalyAlarm();
+
private:
// For testing only.
inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
@@ -160,6 +157,11 @@ private:
mutable mutex mMetricsMutex;
+ // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled
+ // in the onLogEvent code path, which is locked by mMetricsMutex.
+ // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock.
+ mutable mutex mAnomalyAlarmMutex;
+
std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes;
@@ -185,8 +187,8 @@ private:
void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
- void OnConfigUpdatedLocked(
- const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
+ void OnConfigUpdatedLocked(const int64_t currentTimestampNs, const ConfigKey& key,
+ const StatsdConfig& config, bool modularUpdate = false);
void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
@@ -250,6 +252,15 @@ private:
// Reset the specified configs.
void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
+ // An anomaly alarm should have fired.
+ // Check with anomaly alarm manager to find the alarms and process the result.
+ void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis);
+
+ /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
+ void processFiredAnomalyAlarmsLocked(
+ const int64_t& timestampNs,
+ unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
+
// Function used to send a broadcast so that receiver for the config key can call getData
// to retrieve the stored data.
std::function<bool(const ConfigKey& key)> mSendBroadcast;
@@ -276,9 +287,10 @@ private:
//Last time we wrote metadata to disk.
int64_t mLastMetadataWriteNs = 0;
-#ifdef VERY_VERBOSE_PRINTING
+ // The time for the next anomaly alarm for alerts.
+ int64_t mNextAnomalyAlarmTime = 0;
+
bool mPrintAllLogs = false;
-#endif
FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 322648229d0e..68c2dd56ef13 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -91,17 +91,13 @@ Status checkUid(uid_t expectedUid) {
StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
: mAnomalyAlarmMonitor(new AlarmMonitor(
MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
- if (sc != nullptr) {
- sc->setAnomalyAlarm(timeMillis);
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
+ [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
+ mProcessor->setAnomalyAlarm(timeMillis);
+ StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
},
- [](const shared_ptr<IStatsCompanionService>& sc) {
- if (sc != nullptr) {
- sc->cancelAnomalyAlarm();
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
+ [this](const shared_ptr<IStatsCompanionService>& /*sc*/) {
+ mProcessor->cancelAnomalyAlarm();
+ StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
})),
mPeriodicAlarmMonitor(new AlarmMonitor(
MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
@@ -484,7 +480,8 @@ void StatsService::print_cmd_help(int out) {
dprintf(out, " Clear cached puller data.\n");
dprintf(out, "\n");
dprintf(out, "usage: adb shell cmd stats print-logs\n");
- dprintf(out, " Only works on eng build\n");
+ dprintf(out, " Requires root privileges.\n");
+ dprintf(out, " Can be disabled by calling adb shell cmd stats print-logs 0\n");
}
status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
@@ -865,18 +862,19 @@ status_t StatsService::cmd_clear_puller_cache(int out) {
}
status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
- VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", AIBinder_getCallingPid(),
- AIBinder_getCallingUid());
- if (checkPermission(kPermissionDump)) {
- bool enabled = true;
- if (args.size() >= 2) {
- enabled = atoi(args[1].c_str()) != 0;
- }
- mProcessor->setPrintLogs(enabled);
- return NO_ERROR;
- } else {
+ Status status = checkUid(AID_ROOT);
+ if (!status.isOk()) {
return PERMISSION_DENIED;
}
+
+ VLOG("StatsService::cmd_print_logs with pid %i, uid %i", AIBinder_getCallingPid(),
+ AIBinder_getCallingUid());
+ bool enabled = true;
+ if (args.size() >= 2) {
+ enabled = atoi(args[1].c_str()) != 0;
+ }
+ mProcessor->setPrintLogs(enabled);
+ return NO_ERROR;
}
bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
@@ -975,22 +973,6 @@ Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
return Status::ok();
}
-Status StatsService::informAnomalyAlarmFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informAnomalyAlarmFired was called");
- int64_t currentTimeSec = getElapsedRealtimeSec();
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- if (alarmSet.size() > 0) {
- VLOG("Found an anomaly alarm that fired.");
- mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
- } else {
- VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
- }
- return Status::ok();
-}
-
Status StatsService::informAlarmForSubscriberTriggeringFired() {
ENFORCE_UID(AID_SYSTEM);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 324ffbd65e51..479f4e87ec96 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -66,7 +66,6 @@ public:
virtual Status systemRunning();
virtual Status statsCompanionReady();
virtual Status bootCompleted();
- virtual Status informAnomalyAlarmFired();
virtual Status informPollAlarmFired();
virtual Status informAlarmForSubscriberTriggeringFired();
@@ -404,6 +403,10 @@ private:
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket);
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
+
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
};
} // namespace statsd
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index ab1d3cbd232f..c95f4c07f86c 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -583,9 +583,10 @@ message Atom {
SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
SettingSnapshot setting_snapshot = 10080 [(module) = "framework"];
BlobInfo blob_info = 10081 [(module) = "framework"];
- DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"];
+ DataUsageBytesTransfer data_usage_bytes_transfer =
+ 10082 [(module) = "framework", (truncate_timestamp) = true];
BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered =
- 10083 [(module) = "framework"];
+ 10083 [(module) = "framework", (truncate_timestamp) = true];
DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"];
GeneralExternalStorageAccessStats general_external_storage_access_stats =
10085 [(module) = "mediaprovider"];
@@ -4244,6 +4245,19 @@ message BinaryPushStateChanged {
INSTALL_FAILURE_STATE_MISMATCH = 24;
INSTALL_FAILURE_COMMIT = 25;
REBOOT_TRIGGERED = 26;
+ // Logged after INSTALL_REQUESTED for devices installing a train that
+ // contains no module requiring reboot.
+ REBOOT_NOT_REQUIRED = 27;
+ // Logged after INSTALL_REQUESTED for devices that are installing a train
+ // which requires reboot and eligible for soft restart.
+ SOFT_RESTART_ELIGIBLE = 28;
+ // Logged after INSTALL_REQUESTED for devices that are installing a train
+ // which requires reboot and eligible for notification restart.
+ NOTIFICATION_RESTART_ELIGIBLE = 29;
+ // Logged after INSTALL_REQUESTED for devices that are installing a train
+ // which requires reboot and not eligible for any reboot promotion strategy
+ // (e.g. soft restart, notification restart).
+ NO_REBOOT_PROMOTION_STRATEGY_ELIGIBLE = 30;
}
optional State state = 6;
// Possible experiment ids for monitoring this push.
@@ -4577,7 +4591,7 @@ message GeneralExternalStorageAccessStats {
// Includes file path and ContentResolver accesses
optional uint32 secondary_storage_accesses = 4;
// Comma-separated list of mime types that were accessed.
- optional MimeTypes mime_types_accessed = 5;
+ optional MimeTypes mime_types_accessed = 5 [(log_mode) = MODE_BYTES];
}
/**
@@ -6167,7 +6181,7 @@ message ProcessStatsAvailablePagesProto {
* Pulled from ProcessStatsService.java
*/
message ProcStats {
- optional ProcessStatsSectionProto proc_stats_section = 1;
+ optional ProcessStatsSectionProto proc_stats_section = 1 [(log_mode) = MODE_BYTES];
// Data pulled from device into this is sometimes sharded across multiple atoms to work around
// a size limit. When this happens, this shard ID will contain an increasing 1-indexed integer
// with the number of this shard.
@@ -6178,7 +6192,7 @@ message ProcStats {
* Pulled from ProcessStatsService.java
*/
message ProcStatsPkgProc {
- optional ProcessStatsSectionProto proc_stats_section = 1;
+ optional ProcessStatsSectionProto proc_stats_section = 1 [(log_mode) = MODE_BYTES];
}
// Next Tag: 2
@@ -6196,7 +6210,7 @@ message NotificationRemoteViewsProto {
* Pulled from NotificationManagerService.java
*/
message NotificationRemoteViews {
- optional NotificationRemoteViewsProto notification_remote_views = 1;
+ optional NotificationRemoteViewsProto notification_remote_views = 1 [(log_mode) = MODE_BYTES];
}
/**
@@ -6264,7 +6278,7 @@ message DNDModeProto {
// May also be "MANUAL_RULE" to indicate app-activation of the manual rule.
optional string id = 5;
optional int32 uid = 6 [(is_uid) = true]; // currently only SYSTEM_UID or 0 for other
- optional DNDPolicyProto policy = 7;
+ optional DNDPolicyProto policy = 7 [(log_mode) = MODE_BYTES];
}
/**
@@ -6429,7 +6443,7 @@ message PowerProfileProto {
* Pulled from PowerProfile.java
*/
message PowerProfile {
- optional PowerProfileProto power_profile = 1;
+ optional PowerProfileProto power_profile = 1 [(log_mode) = MODE_BYTES];
}
/**
@@ -8124,7 +8138,7 @@ message DeviceIdentifierAccessDenied {
message TrainInfo {
optional int64 train_version_code = 1;
- optional TrainExperimentIds train_experiment_id = 2;
+ optional TrainExperimentIds train_experiment_id = 2 [(log_mode) = MODE_BYTES];
optional string train_name = 3;
@@ -11172,8 +11186,8 @@ message BlobInfo {
optional int64 expiry_timestamp_millis = 3;
// List of committers of this Blob
- optional BlobCommitterListProto committers = 4;
+ optional BlobCommitterListProto committers = 4 [(log_mode) = MODE_BYTES];
// List of leasees of this Blob
- optional BlobLeaseeListProto leasees = 5;
+ optional BlobLeaseeListProto leasees = 5 [(log_mode) = MODE_BYTES];
}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 8a9ec7456e55..46c377037542 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -92,63 +92,43 @@ StatsPullerManager::StatsPullerManager()
}
bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<shared_ptr<LogEvent>>* data, bool useUids) {
+ vector<shared_ptr<LogEvent>>* data) {
std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, configKey, eventTimeNs, data, useUids);
+ return PullLocked(tagId, configKey, eventTimeNs, data);
}
bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids) {
+ vector<std::shared_ptr<LogEvent>>* data) {
std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, uids, eventTimeNs, data, useUids);
+ return PullLocked(tagId, uids, eventTimeNs, data);
}
bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
- bool useUids) {
+ const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
vector<int32_t> uids;
- if (useUids) {
- auto uidProviderIt = mPullUidProviders.find(configKey);
- if (uidProviderIt == mPullUidProviders.end()) {
- ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote();
- if (pullUidProvider == nullptr) {
- ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- uids = pullUidProvider->getPullAtomUids(tagId);
+ const auto& uidProviderIt = mPullUidProviders.find(configKey);
+ if (uidProviderIt == mPullUidProviders.end()) {
+ ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId,
+ configKey.ToString().c_str());
+ StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
+ return false;
}
- return PullLocked(tagId, uids, eventTimeNs, data, useUids);
+ sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote();
+ if (pullUidProvider == nullptr) {
+ ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId,
+ configKey.ToString().c_str());
+ StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
+ return false;
+ }
+ uids = pullUidProvider->getPullAtomUids(tagId);
+ return PullLocked(tagId, uids, eventTimeNs, data);
}
bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
- bool useUids) {
+ const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
VLOG("Initiating pulling %d", tagId);
- if (useUids) {
- for (int32_t uid : uids) {
- PullerKey key = {.atomTag = tagId, .uid = uid};
- auto pullerIt = kAllPullAtomInfo.find(key);
- if (pullerIt != kAllPullAtomInfo.end()) {
- bool ret = pullerIt->second->Pull(eventTimeNs, data);
- VLOG("pulled %zu items", data->size());
- if (!ret) {
- StatsdStats::getInstance().notePullFailed(tagId);
- }
- return ret;
- }
- }
- StatsdStats::getInstance().notePullerNotFound(tagId);
- ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
- return false; // Return early since we don't know what to pull.
- } else {
- PullerKey key = {.atomTag = tagId, .uid = -1};
+ for (int32_t uid : uids) {
+ PullerKey key = {.atomTag = tagId, .uid = uid};
auto pullerIt = kAllPullAtomInfo.find(key);
if (pullerIt != kAllPullAtomInfo.end()) {
bool ret = pullerIt->second->Pull(eventTimeNs, data);
@@ -158,9 +138,10 @@ bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
}
return ret;
}
- ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
- return false; // Return early since we don't know what to pull.
}
+ StatsdStats::getInstance().notePullerNotFound(tagId);
+ ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
+ return false; // Return early since we don't know what to pull.
}
bool StatsPullerManager::PullerForMatcherExists(int tagId) const {
@@ -352,8 +333,7 @@ int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
const int64_t coolDownNs, const int64_t timeoutNs,
const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback,
- bool useUid) {
+ const shared_ptr<IPullAtomCallback>& callback) {
std::lock_guard<std::mutex> _l(mLock);
VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
@@ -368,16 +348,15 @@ void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t a
sp<StatsCallbackPuller> puller = new StatsCallbackPuller(atomTag, callback, actualCoolDownNs,
actualTimeoutNs, additiveFields);
- PullerKey key = {.atomTag = atomTag, .uid = useUid ? uid : -1};
+ PullerKey key = {.atomTag = atomTag, .uid = uid};
AIBinder_linkToDeath(callback->asBinder().get(), mPullAtomCallbackDeathRecipient.get(),
new PullAtomCallbackDeathCookie(this, key, puller));
kAllPullAtomInfo[key] = puller;
}
-void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag,
- bool useUids) {
+void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
std::lock_guard<std::mutex> _l(mLock);
- PullerKey key = {.atomTag = atomTag, .uid = useUids ? uid : -1};
+ PullerKey key = {.atomTag = atomTag, .uid = uid};
if (kAllPullAtomInfo.find(key) != kAllPullAtomInfo.end()) {
StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag,
/*registered=*/false);
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 194a0f5edba8..489cbdbe5400 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -102,11 +102,11 @@ public:
// If the metric wants to make any change to the data, like timestamps, they
// should make a copy as this data may be shared with multiple metrics.
virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
+ vector<std::shared_ptr<LogEvent>>* data);
// Same as above, but directly specify the allowed uids to pull from.
virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
+ vector<std::shared_ptr<LogEvent>>* data);
// Clear pull data cache immediately.
int ForceClearPullerCache();
@@ -118,10 +118,9 @@ public:
void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
const int64_t timeoutNs, const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback,
- bool useUid = true);
+ const shared_ptr<IPullAtomCallback>& callback);
- void UnregisterPullAtomCallback(const int uid, const int32_t atomTag, bool useUids = true);
+ void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo;
@@ -153,10 +152,10 @@ private:
std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
+ vector<std::shared_ptr<LogEvent>>* data);
bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids);
+ vector<std::shared_ptr<LogEvent>>* data);
// locks for data receiver and StatsCompanionService changes
std::mutex mLock;
diff --git a/cmds/statsd/src/hash.h b/cmds/statsd/src/hash.h
index cfe869f60202..bd6b0cd47eaf 100644
--- a/cmds/statsd/src/hash.h
+++ b/cmds/statsd/src/hash.h
@@ -22,6 +22,7 @@ namespace android {
namespace os {
namespace statsd {
+// Uses murmur2 hashing algorithm.
extern uint32_t Hash32(const char *data, size_t n, uint32_t seed);
extern uint64_t Hash64(const char* data, size_t n, uint64_t seed);
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
index b94a9572113e..60bcc26f0873 100644
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
@@ -27,8 +27,9 @@ using std::set;
using std::unordered_map;
using std::vector;
-CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index)
- : LogMatchingTracker(id, index) {
+CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index,
+ const uint64_t protoHash)
+ : LogMatchingTracker(id, index, protoHash) {
}
CombinationLogMatchingTracker::~CombinationLogMatchingTracker() {
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
index 55bc46059fc1..6b8a7fb19cf0 100644
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
@@ -28,7 +28,7 @@ namespace statsd {
// Represents a AtomMatcher_Combination in the StatsdConfig.
class CombinationLogMatchingTracker : public virtual LogMatchingTracker {
public:
- CombinationLogMatchingTracker(const int64_t& id, const int index);
+ CombinationLogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash);
bool init(const std::vector<AtomMatcher>& allLogMatchers,
const std::vector<sp<LogMatchingTracker>>& allTrackers,
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
index 88ab4e6f683a..49a41add4560 100644
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/LogMatchingTracker.h
@@ -33,8 +33,8 @@ namespace statsd {
class LogMatchingTracker : public virtual RefBase {
public:
- LogMatchingTracker(const int64_t& id, const int index)
- : mId(id), mIndex(index), mInitialized(false){};
+ LogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash)
+ : mId(id), mIndex(index), mInitialized(false), mProtoHash(protoHash){};
virtual ~LogMatchingTracker(){};
@@ -69,10 +69,14 @@ public:
return mAtomIds;
}
- const int64_t& getId() const {
+ int64_t getId() const {
return mId;
}
+ uint64_t getProtoHash() const {
+ return mProtoHash;
+ }
+
protected:
// Name of this matching. We don't really need the name, but it makes log message easy to debug.
const int64_t mId;
@@ -87,6 +91,14 @@ protected:
// return kNotMatched when we receive an event with an id not in the list. This is especially
// useful when we have a complex CombinationLogMatcherTracker.
std::set<int> mAtomIds;
+
+ // Hash of the AtomMatcher's proto bytes from StatsdConfig.
+ // Used to determine if the definition of this matcher has changed across a config update.
+ const uint64_t mProtoHash;
+
+ FRIEND_TEST(MetricsManagerTest, TestCreateLogTrackerSimple);
+ FRIEND_TEST(MetricsManagerTest, TestCreateLogTrackerCombination);
+ FRIEND_TEST(ConfigUpdateTest, TestUpdateMatchers);
};
} // namespace statsd
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
index 082daf5a1916..ff47d35b36cc 100644
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
@@ -26,11 +26,11 @@ namespace statsd {
using std::unordered_map;
using std::vector;
-
SimpleLogMatchingTracker::SimpleLogMatchingTracker(const int64_t& id, const int index,
+ const uint64_t protoHash,
const SimpleAtomMatcher& matcher,
- const UidMap& uidMap)
- : LogMatchingTracker(id, index), mMatcher(matcher), mUidMap(uidMap) {
+ const sp<UidMap>& uidMap)
+ : LogMatchingTracker(id, index, protoHash), mMatcher(matcher), mUidMap(uidMap) {
if (!matcher.has_atom_id()) {
mInitialized = false;
} else {
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
index a0f6a888bd44..e58e01252ade 100644
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
@@ -29,9 +29,8 @@ namespace statsd {
class SimpleLogMatchingTracker : public virtual LogMatchingTracker {
public:
- SimpleLogMatchingTracker(const int64_t& id, const int index,
- const SimpleAtomMatcher& matcher,
- const UidMap& uidMap);
+ SimpleLogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash,
+ const SimpleAtomMatcher& matcher, const sp<UidMap>& uidMap);
~SimpleLogMatchingTracker();
@@ -46,7 +45,7 @@ public:
private:
const SimpleAtomMatcher mMatcher;
- const UidMap& mUidMap;
+ const sp<UidMap> mUidMap;
};
} // namespace statsd
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 2b4c6a3cbf1e..e6d91223308d 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -81,14 +81,15 @@ bool combinationMatch(const vector<int>& children, const LogicalOperation& opera
return matched;
}
-bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) {
+bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
+ const string& str_match) {
if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
int uid = fieldValue.mValue.int_value;
auto aidIt = UidMap::sAidToUidMapping.find(str_match);
if (aidIt != UidMap::sAidToUidMapping.end()) {
return ((int)aidIt->second) == uid;
}
- std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
+ std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
return packageNames.find(str_match) != packageNames.end();
} else if (fieldValue.mValue.getType() == STRING) {
return fieldValue.mValue.str_value == str_match;
@@ -96,7 +97,7 @@ bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const st
return false;
}
-bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
+bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher,
const vector<FieldValue>& values, int start, int end, int depth) {
if (depth > 2) {
ALOGE("Depth > 3 not supported");
@@ -353,7 +354,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
}
}
-bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
+bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
const LogEvent& event) {
if (event.GetTagId() != simpleMatcher.atom_id()) {
return false;
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index 1ab3e87b5fed..130b6068bd19 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -36,8 +36,8 @@ enum MatchingState {
bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
const std::vector<MatchingState>& matcherResults);
-bool matchesSimple(const UidMap& uidMap,
- const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
+bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
+ const LogEvent& wrapper);
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 60de1a24cce5..2c3deca40fa0 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -26,7 +26,8 @@
#include "guardrail/StatsdStats.h"
#include "matchers/CombinationLogMatchingTracker.h"
#include "matchers/SimpleLogMatchingTracker.h"
-#include "metrics_manager_util.h"
+#include "parsing_utils/config_update_utils.h"
+#include "parsing_utils/metrics_manager_util.h"
#include "state/StateManager.h"
#include "stats_log_util.h"
#include "stats_util.h"
@@ -76,13 +77,14 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
// Init the ttl end timestamp.
refreshTtl(timeBaseNs);
- mConfigValid = initStatsdConfig(
- key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
- mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
- mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
- mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
- mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds);
+ mConfigValid =
+ initStatsdConfig(key, config, uidMap, pullerManager, anomalyAlarmMonitor,
+ periodicAlarmMonitor, timeBaseNs, currentTimeNs, mTagIds,
+ mAllAtomMatchers, mLogTrackerMap, mAllConditionTrackers,
+ mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
+ mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
+ mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
+ mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds);
mHashStringsInReport = config.hash_strings_in_metric_report();
mVersionStringsInReport = config.version_strings_in_metric_report();
@@ -195,6 +197,22 @@ MetricsManager::~MetricsManager() {
VLOG("~MetricsManager()");
}
+bool MetricsManager::updateConfig(const StatsdConfig& config, const int64_t timeBaseNs,
+ const int64_t currentTimeNs,
+ const sp<AlarmMonitor>& anomalyAlarmMonitor,
+ const sp<AlarmMonitor>& periodicAlarmMonitor) {
+ vector<sp<LogMatchingTracker>> newAtomMatchers;
+ unordered_map<int64_t, int> newLogTrackerMap;
+ mTagIds.clear();
+ mConfigValid =
+ updateStatsdConfig(mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor,
+ periodicAlarmMonitor, timeBaseNs, currentTimeNs, mAllAtomMatchers,
+ mLogTrackerMap, mTagIds, newAtomMatchers, newLogTrackerMap);
+ mAllAtomMatchers = newAtomMatchers;
+ mLogTrackerMap = newLogTrackerMap;
+ return mConfigValid;
+}
+
void MetricsManager::initLogSourceWhiteList() {
std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
mAllowedLogSources.clear();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index ad30a88c5d19..6f9a23362033 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -46,6 +46,10 @@ public:
virtual ~MetricsManager();
+ bool updateConfig(const StatsdConfig& config, const int64_t timeBaseNs,
+ const int64_t currentTimeNs, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+ const sp<AlarmMonitor>& periodicAlarmMonitor);
+
// Return whether the configuration is valid.
bool isConfigValid() const;
@@ -235,6 +239,12 @@ private:
// Hold all periodic alarm trackers.
std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
+ // To make updating configs faster, we map the id of a LogMatchingTracker, MetricProducer, and
+ // ConditionTracker to its index in the corresponding vector.
+
+ // Maps the id of an atom matcher to its index in mAllAtomMatchers.
+ std::unordered_map<int64_t, int> mLogTrackerMap;
+
// To make the log processing more efficient, we want to do as much filtering as possible
// before we go into individual trackers and conditions to match.
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 5987a723a421..9b684f1248c5 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -733,6 +733,11 @@ bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret)
return false;
}
+bool ValueMetricProducer::multipleBucketsSkipped(const int64_t numBucketsForward) {
+ // Skip buckets if this is a pulled metric or a pushed metric that is diffed.
+ return numBucketsForward > 1 && (mIsPulled || mUseDiff);
+}
+
void ValueMetricProducer::onMatchedLogEventInternalLocked(
const size_t matcherIndex, const MetricDimensionKey& eventKey,
const ConditionKey& conditionKey, bool condition, const LogEvent& event,
@@ -910,8 +915,9 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(
interval.sampleSize += 1;
}
- // Only trigger the tracker if all intervals are correct
- if (useAnomalyDetection) {
+ // Only trigger the tracker if all intervals are correct and we have not skipped the bucket due
+ // to MULTIPLE_BUCKETS_SKIPPED.
+ if (useAnomalyDetection && !multipleBucketsSkipped(calcBucketsForwardCount(eventTimeNs))) {
// TODO: propgate proper values down stream when anomaly support doubles
long wholeBucketVal = intervals[0].value.long_value;
auto prev = mCurrentFullBucket.find(eventKey);
@@ -961,9 +967,7 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
int64_t bucketEndTime = fullBucketEndTimeNs;
int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
- // Skip buckets if this is a pulled metric or a pushed metric that is diffed.
- if (numBucketsForward > 1 && (mIsPulled || mUseDiff)) {
-
+ if (multipleBucketsSkipped(numBucketsForward)) {
VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
StatsdStats::getInstance().noteSkippedForwardBuckets(mMetricId);
// Something went wrong. Maybe the device was sleeping for a long time. It is better
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index b359af745c91..e72002e88533 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -219,6 +219,8 @@ private:
void pullAndMatchEventsLocked(const int64_t timestampNs);
+ bool multipleBucketsSkipped(const int64_t numBucketsForward);
+
void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
int64_t originalPullTimeNs, int64_t eventElapsedTimeNs);
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
new file mode 100644
index 000000000000..562e29124187
--- /dev/null
+++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG false // STOPSHIP if true
+
+#include "config_update_utils.h"
+
+#include "external/StatsPullerManager.h"
+#include "hash.h"
+#include "metrics_manager_util.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+// Recursive function to determine if a matcher needs to be updated. Populates matcherToUpdate.
+// Returns whether the function was successful or not.
+bool determineMatcherUpdateStatus(const StatsdConfig& config, const int matcherIdx,
+ const unordered_map<int64_t, int>& oldLogTrackerMap,
+ const vector<sp<LogMatchingTracker>>& oldAtomMatchers,
+ const unordered_map<int64_t, int>& newLogTrackerMap,
+ vector<UpdateStatus>& matchersToUpdate,
+ vector<bool>& cycleTracker) {
+ // Have already examined this matcher.
+ if (matchersToUpdate[matcherIdx] != UPDATE_UNKNOWN) {
+ return true;
+ }
+
+ const AtomMatcher& matcher = config.atom_matcher(matcherIdx);
+ int64_t id = matcher.id();
+ // Check if new matcher.
+ const auto& oldLogTrackerIt = oldLogTrackerMap.find(id);
+ if (oldLogTrackerIt == oldLogTrackerMap.end()) {
+ matchersToUpdate[matcherIdx] = UPDATE_REPLACE;
+ return true;
+ }
+
+ // This is an existing matcher. Check if it has changed.
+ string serializedMatcher;
+ if (!matcher.SerializeToString(&serializedMatcher)) {
+ ALOGE("Unable to serialize matcher %lld", (long long)id);
+ return false;
+ }
+ uint64_t newProtoHash = Hash64(serializedMatcher);
+ if (newProtoHash != oldAtomMatchers[oldLogTrackerIt->second]->getProtoHash()) {
+ matchersToUpdate[matcherIdx] = UPDATE_REPLACE;
+ return true;
+ }
+
+ switch (matcher.contents_case()) {
+ case AtomMatcher::ContentsCase::kSimpleAtomMatcher: {
+ matchersToUpdate[matcherIdx] = UPDATE_PRESERVE;
+ return true;
+ }
+ case AtomMatcher::ContentsCase::kCombination: {
+ // Recurse to check if children have changed.
+ cycleTracker[matcherIdx] = true;
+ UpdateStatus status = UPDATE_PRESERVE;
+ for (const int64_t childMatcherId : matcher.combination().matcher()) {
+ const auto& childIt = newLogTrackerMap.find(childMatcherId);
+ if (childIt == newLogTrackerMap.end()) {
+ ALOGW("Matcher %lld not found in the config", (long long)childMatcherId);
+ return false;
+ }
+ const int childIdx = childIt->second;
+ if (cycleTracker[childIdx]) {
+ ALOGE("Cycle detected in matcher config");
+ return false;
+ }
+ if (!determineMatcherUpdateStatus(config, childIdx, oldLogTrackerMap,
+ oldAtomMatchers, newLogTrackerMap,
+ matchersToUpdate, cycleTracker)) {
+ return false;
+ }
+
+ if (matchersToUpdate[childIdx] == UPDATE_REPLACE) {
+ status = UPDATE_REPLACE;
+ break;
+ }
+ }
+ matchersToUpdate[matcherIdx] = status;
+ cycleTracker[matcherIdx] = false;
+ return true;
+ }
+ default: {
+ ALOGE("Matcher \"%lld\" malformed", (long long)id);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool updateLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
+ const unordered_map<int64_t, int>& oldLogTrackerMap,
+ const vector<sp<LogMatchingTracker>>& oldAtomMatchers, set<int>& allTagIds,
+ unordered_map<int64_t, int>& newLogTrackerMap,
+ vector<sp<LogMatchingTracker>>& newAtomMatchers) {
+ const int atomMatcherCount = config.atom_matcher_size();
+
+ vector<AtomMatcher> matcherProtos;
+ matcherProtos.reserve(atomMatcherCount);
+ newAtomMatchers.reserve(atomMatcherCount);
+
+ // Maps matcher id to their position in the config. For fast lookup of dependencies.
+ for (int i = 0; i < atomMatcherCount; i++) {
+ const AtomMatcher& matcher = config.atom_matcher(i);
+ if (newLogTrackerMap.find(matcher.id()) != newLogTrackerMap.end()) {
+ ALOGE("Duplicate atom matcher found for id %lld", (long long)matcher.id());
+ return false;
+ }
+ newLogTrackerMap[matcher.id()] = i;
+ matcherProtos.push_back(matcher);
+ }
+
+ // For combination matchers, we need to determine if any children need to be updated.
+ vector<UpdateStatus> matchersToUpdate(atomMatcherCount, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(atomMatcherCount, false);
+ for (int i = 0; i < atomMatcherCount; i++) {
+ if (!determineMatcherUpdateStatus(config, i, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker)) {
+ return false;
+ }
+ }
+
+ for (int i = 0; i < atomMatcherCount; i++) {
+ const AtomMatcher& matcher = config.atom_matcher(i);
+ const int64_t id = matcher.id();
+ switch (matchersToUpdate[i]) {
+ case UPDATE_PRESERVE: {
+ const auto& oldLogTrackerIt = oldLogTrackerMap.find(id);
+ if (oldLogTrackerIt == oldLogTrackerMap.end()) {
+ ALOGE("Could not find AtomMatcher %lld in the previous config, but expected it "
+ "to be there",
+ (long long)id);
+ return false;
+ }
+ const int oldIndex = oldLogTrackerIt->second;
+ newAtomMatchers.push_back(oldAtomMatchers[oldIndex]);
+ break;
+ }
+ case UPDATE_REPLACE: {
+ sp<LogMatchingTracker> tracker = createLogTracker(matcher, i, uidMap);
+ if (tracker == nullptr) {
+ return false;
+ }
+ newAtomMatchers.push_back(tracker);
+ break;
+ }
+ default: {
+ ALOGE("Matcher \"%lld\" update state is unknown. This should never happen",
+ (long long)id);
+ return false;
+ }
+ }
+ }
+
+ std::fill(cycleTracker.begin(), cycleTracker.end(), false);
+ for (auto& matcher : newAtomMatchers) {
+ if (!matcher->init(matcherProtos, newAtomMatchers, newLogTrackerMap, cycleTracker)) {
+ return false;
+ }
+ // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
+ const set<int>& tagIds = matcher->getAtomIds();
+ allTagIds.insert(tagIds.begin(), tagIds.end());
+ }
+
+ return true;
+}
+
+bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
+ const sp<StatsPullerManager>& pullerManager,
+ const sp<AlarmMonitor>& anomalyAlarmMonitor,
+ const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
+ const int64_t currentTimeNs,
+ const vector<sp<LogMatchingTracker>>& oldAtomMatchers,
+ const unordered_map<int64_t, int>& oldLogTrackerMap, set<int>& allTagIds,
+ vector<sp<LogMatchingTracker>>& newAtomMatchers,
+ unordered_map<int64_t, int>& newLogTrackerMap) {
+ if (!updateLogTrackers(config, uidMap, oldLogTrackerMap, oldAtomMatchers, allTagIds,
+ newLogTrackerMap, newAtomMatchers)) {
+ ALOGE("updateLogMatchingTrackers failed");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
new file mode 100644
index 000000000000..951ab03cee47
--- /dev/null
+++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "anomaly/AlarmMonitor.h"
+#include "external/StatsPullerManager.h"
+#include "matchers/LogMatchingTracker.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+// Helper functions for MetricsManager to update itself from a new StatsdConfig.
+// *Note*: only updateStatsdConfig() should be called from outside this file.
+// All other functions are intermediate steps, created to make unit testing easier.
+
+// Possible update states for a component. PRESERVE means we should keep the existing one.
+// REPLACE means we should create a new one, either because it didn't exist or it changed.
+enum UpdateStatus {
+ UPDATE_UNKNOWN = 0,
+ UPDATE_PRESERVE = 1,
+ UPDATE_REPLACE = 2,
+};
+
+// Recursive function to determine if a matcher needs to be updated.
+// input:
+// [config]: the input StatsdConfig
+// [matcherIdx]: the index of the current matcher to be updated
+// [newLogTrackerMap]: matcher id to index mapping in the input StatsdConfig
+// [oldLogTrackerMap]: matcher id to index mapping in the existing MetricsManager
+// [oldAtomMatchers]: stores the existing LogMatchingTrackers
+// output:
+// [matchersToUpdate]: vector of the update status of each matcher. The matcherIdx index will
+// be updated from UPDATE_UNKNOWN after this call.
+// [cycleTracker]: intermediate param used during recursion.
+bool determineMatcherUpdateStatus(const StatsdConfig& config, const int matcherIdx,
+ const unordered_map<int64_t, int>& oldLogTrackerMap,
+ const vector<sp<LogMatchingTracker>>& oldAtomMatchers,
+ const unordered_map<int64_t, int>& newLogTrackerMap,
+ vector<UpdateStatus>& matchersToUpdate,
+ vector<bool>& cycleTracker);
+
+// Updates the LogMatchingTrackers.
+// input:
+// [config]: the input StatsdConfig
+// [oldLogTrackerMap]: existing matcher id to index mapping
+// [oldAtomMatchers]: stores the existing LogMatchingTrackers
+// output:
+// [allTagIds]: contains the set of all interesting tag ids to this config.
+// [newLogTrackerMap]: new matcher id to index mapping
+// [newAtomMatchers]: stores the new LogMatchingTrackers
+bool updateLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
+ const unordered_map<int64_t, int>& oldLogTrackerMap,
+ const vector<sp<LogMatchingTracker>>& oldAtomMatchers, set<int>& allTagIds,
+ unordered_map<int64_t, int>& newLogTrackerMap,
+ vector<sp<LogMatchingTracker>>& newAtomMatchers);
+
+// Updates the existing MetricsManager from a new StatsdConfig.
+// Parameters are the members of MetricsManager. See MetricsManager for declaration.
+bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
+ const sp<StatsPullerManager>& pullerManager,
+ const sp<AlarmMonitor>& anomalyAlarmMonitor,
+ const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
+ const int64_t currentTimeNs,
+ const std::vector<sp<LogMatchingTracker>>& oldAtomMatchers,
+ const unordered_map<int64_t, int>& oldLogTrackerMap,
+ std::set<int>& allTagIds,
+ std::vector<sp<LogMatchingTracker>>& newAtomMatchers,
+ unordered_map<int64_t, int>& newLogTrackerMap);
+
+} // namespace statsd
+} // namespace os
+} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
index 8917c36bb608..52ef95d19cdc 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
@@ -22,10 +22,10 @@
#include <inttypes.h>
#include "FieldValue.h"
-#include "MetricProducer.h"
#include "condition/CombinationConditionTracker.h"
#include "condition/SimpleConditionTracker.h"
#include "external/StatsPullerManager.h"
+#include "hash.h"
#include "matchers/CombinationLogMatchingTracker.h"
#include "matchers/EventMatcherWizard.h"
#include "matchers/SimpleLogMatchingTracker.h"
@@ -33,6 +33,7 @@
#include "metrics/DurationMetricProducer.h"
#include "metrics/EventMetricProducer.h"
#include "metrics/GaugeMetricProducer.h"
+#include "metrics/MetricProducer.h"
#include "metrics/ValueMetricProducer.h"
#include "state/StateManager.h"
#include "stats_util.h"
@@ -61,6 +62,28 @@ bool hasLeafNode(const FieldMatcher& matcher) {
} // namespace
+sp<LogMatchingTracker> createLogTracker(const AtomMatcher& logMatcher, const int index,
+ const sp<UidMap>& uidMap) {
+ string serializedMatcher;
+ if (!logMatcher.SerializeToString(&serializedMatcher)) {
+ ALOGE("Unable to serialize matcher %lld", (long long)logMatcher.id());
+ return nullptr;
+ }
+ uint64_t protoHash = Hash64(serializedMatcher);
+ switch (logMatcher.contents_case()) {
+ case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
+ return new SimpleLogMatchingTracker(logMatcher.id(), index, protoHash,
+ logMatcher.simple_atom_matcher(), uidMap);
+ break;
+ case AtomMatcher::ContentsCase::kCombination:
+ return new CombinationLogMatchingTracker(logMatcher.id(), index, protoHash);
+ break;
+ default:
+ ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
+ return nullptr;
+ }
+}
+
bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
const bool usedForDimension,
const vector<sp<LogMatchingTracker>>& allAtomMatchers,
@@ -184,9 +207,7 @@ bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
// to provide the producer with state about its activators and deactivators.
// Returns false if there are errors.
bool handleMetricActivation(
- const StatsdConfig& config,
- const int64_t metricId,
- const int metricIndex,
+ const StatsdConfig& config, const int64_t metricId, const int metricIndex,
const unordered_map<int64_t, int>& metricToActivationMap,
const unordered_map<int64_t, int>& logTrackerMap,
unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
@@ -210,10 +231,11 @@ bool handleMetricActivation(
return false;
}
- ActivationType activationType = (activation.has_activation_type()) ?
- activation.activation_type() : metricActivation.activation_type();
- std::shared_ptr<Activation> activationWrapper = std::make_shared<Activation>(
- activationType, activation.ttl_seconds() * NS_PER_SEC);
+ ActivationType activationType = (activation.has_activation_type())
+ ? activation.activation_type()
+ : metricActivation.activation_type();
+ std::shared_ptr<Activation> activationWrapper =
+ std::make_shared<Activation>(activationType, activation.ttl_seconds() * NS_PER_SEC);
int atomMatcherIndex = itr->second;
activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
@@ -235,7 +257,7 @@ bool handleMetricActivation(
return true;
}
-bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
+bool initLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
unordered_map<int64_t, int>& logTrackerMap,
vector<sp<LogMatchingTracker>>& allAtomMatchers, set<int>& allTagIds) {
vector<AtomMatcher> matcherConfigs;
@@ -245,22 +267,12 @@ bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
for (int i = 0; i < atomMatcherCount; i++) {
const AtomMatcher& logMatcher = config.atom_matcher(i);
-
int index = allAtomMatchers.size();
- switch (logMatcher.contents_case()) {
- case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
- allAtomMatchers.push_back(new SimpleLogMatchingTracker(
- logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap));
- break;
- case AtomMatcher::ContentsCase::kCombination:
- allAtomMatchers.push_back(
- new CombinationLogMatchingTracker(logMatcher.id(), index));
- break;
- default:
- ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
- return false;
- // continue;
+ sp<LogMatchingTracker> tracker = createLogTracker(logMatcher, index, uidMap);
+ if (tracker == nullptr) {
+ return false;
}
+ allAtomMatchers.push_back(tracker);
if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) {
ALOGE("Duplicate AtomMatcher found!");
return false;
@@ -383,7 +395,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
const MetricActivation& metricActivation = config.metric_activation(i);
int64_t metricId = metricActivation.metric_id();
if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
- ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId);
+ ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
return false;
}
metricToActivationMap.insert({metricId, i});
@@ -402,9 +414,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
metricMap.insert({metric.id(), metricIndex});
int trackerIndex;
if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
+ metric.has_dimensions_in_what(), allAtomMatchers,
+ logTrackerMap, trackerToMetricMap, trackerIndex)) {
return false;
}
@@ -438,10 +449,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
unordered_map<int, shared_ptr<Activation>> eventActivationMap;
unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
+ bool success = handleMetricActivation(
+ config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+ metricsWithActivation, eventActivationMap, eventDeactivationMap);
if (!success) return false;
sp<MetricProducer> countProducer =
@@ -544,10 +555,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
unordered_map<int, shared_ptr<Activation>> eventActivationMap;
unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
+ bool success = handleMetricActivation(
+ config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+ metricsWithActivation, eventActivationMap, eventDeactivationMap);
if (!success) return false;
sp<MetricProducer> durationMetric = new DurationMetricProducer(
@@ -591,10 +602,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
unordered_map<int, shared_ptr<Activation>> eventActivationMap;
unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
+ bool success = handleMetricActivation(
+ config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+ metricsWithActivation, eventActivationMap, eventDeactivationMap);
if (!success) return false;
sp<MetricProducer> eventMetric =
@@ -626,9 +637,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
metricMap.insert({metric.id(), metricIndex});
int trackerIndex;
if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
+ metric.has_dimensions_in_what(), allAtomMatchers,
+ logTrackerMap, trackerToMetricMap, trackerIndex)) {
return false;
}
@@ -718,9 +728,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
metricMap.insert({metric.id(), metricIndex});
int trackerIndex;
if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
+ metric.has_dimensions_in_what(), allAtomMatchers,
+ logTrackerMap, trackerToMetricMap, trackerIndex)) {
return false;
}
@@ -775,10 +784,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
unordered_map<int, shared_ptr<Activation>> eventActivationMap;
unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
+ bool success = handleMetricActivation(
+ config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+ metricsWithActivation, eventActivationMap, eventDeactivationMap);
if (!success) return false;
sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
@@ -813,8 +822,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
return true;
}
-bool initAlerts(const StatsdConfig& config,
- const unordered_map<int64_t, int>& metricProducerMap,
+bool initAlerts(const StatsdConfig& config, const unordered_map<int64_t, int>& metricProducerMap,
unordered_map<int64_t, int>& alertTrackerMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
vector<sp<MetricProducer>>& allMetricProducers,
@@ -832,8 +840,8 @@ bool initAlerts(const StatsdConfig& config,
return false;
}
if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
- ALOGW("invalid alert: threshold=%f num_buckets= %d",
- alert.trigger_if_sum_gt(), alert.num_buckets());
+ ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
+ alert.num_buckets());
return false;
}
const int metricIndex = itr->second;
@@ -853,14 +861,13 @@ bool initAlerts(const StatsdConfig& config,
}
if (subscription.subscriber_information_case() ==
Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
+ ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
return false;
}
const auto& itr = alertTrackerMap.find(subscription.rule_id());
if (itr == alertTrackerMap.end()) {
ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
+ (long long)subscription.id(), (long long)subscription.rule_id());
return false;
}
const int anomalyTrackerIndex = itr->second;
@@ -870,12 +877,11 @@ bool initAlerts(const StatsdConfig& config,
}
bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
- const sp<AlarmMonitor>& periodicAlarmMonitor,
- const int64_t timeBaseNs, const int64_t currentTimeNs,
- vector<sp<AlarmTracker>>& allAlarmTrackers) {
+ const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
+ const int64_t currentTimeNs, vector<sp<AlarmTracker>>& allAlarmTrackers) {
unordered_map<int64_t, int> alarmTrackerMap;
int64_t startMillis = timeBaseNs / 1000 / 1000;
- int64_t currentTimeMillis = currentTimeNs / 1000 /1000;
+ int64_t currentTimeMillis = currentTimeNs / 1000 / 1000;
for (int i = 0; i < config.alarm_size(); i++) {
const Alarm& alarm = config.alarm(i);
if (alarm.offset_millis() <= 0) {
@@ -888,8 +894,7 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
}
alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
allAlarmTrackers.push_back(
- new AlarmTracker(startMillis, currentTimeMillis,
- alarm, key, periodicAlarmMonitor));
+ new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor));
}
for (int i = 0; i < config.subscription_size(); ++i) {
const Subscription& subscription = config.subscription(i);
@@ -898,14 +903,13 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
}
if (subscription.subscriber_information_case() ==
Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
+ ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
return false;
}
const auto& itr = alarmTrackerMap.find(subscription.rule_id());
if (itr == alarmTrackerMap.end()) {
ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
+ (long long)subscription.id(), (long long)subscription.rule_id());
return false;
}
const int trackerIndex = itr->second;
@@ -914,12 +918,13 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
return true;
}
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
+bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
const sp<StatsPullerManager>& pullerManager,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
const int64_t currentTimeNs, set<int>& allTagIds,
vector<sp<LogMatchingTracker>>& allAtomMatchers,
+ unordered_map<int64_t, int>& logTrackerMap,
vector<sp<ConditionTracker>>& allConditionTrackers,
vector<sp<MetricProducer>>& allMetricProducers,
vector<sp<AnomalyTracker>>& allAnomalyTrackers,
@@ -930,9 +935,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap&
unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds) {
- unordered_map<int64_t, int> logTrackerMap;
+ vector<int>& metricsWithActivation, std::set<int64_t>& noReportMetricIds) {
unordered_map<int64_t, int> conditionTrackerMap;
vector<ConditionState> initialConditionCache;
unordered_map<int64_t, int> metricProducerMap;
@@ -969,8 +972,8 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap&
ALOGE("initAlerts failed");
return false;
}
- if (!initAlarms(config, key, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) {
+ if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
+ allPeriodicAlarmTrackers)) {
ALOGE("initAlarms failed");
return false;
}
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
index 96b5c26ff789..ed9951fd5ee6 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
@@ -20,16 +20,28 @@
#include <unordered_map>
#include <vector>
-#include "../anomaly/AlarmTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/LogMatchingTracker.h"
-#include "../metrics/MetricProducer.h"
+#include "anomaly/AlarmTracker.h"
+#include "condition/ConditionTracker.h"
+#include "external/StatsPullerManager.h"
+#include "matchers/LogMatchingTracker.h"
+#include "metrics/MetricProducer.h"
namespace android {
namespace os {
namespace statsd {
+// Helper functions for creating individual config components from StatsdConfig.
+// Should only be called from metrics_manager_util and config_update_utils.
+
+// Create a LogMatchingTracker.
+// input:
+// [logMatcher]: the input AtomMatcher from the StatsdConfig
+// [index]: the index of the matcher
+// output:
+// new LogMatchingTracker, or null if the tracker is unable to be created
+sp<LogMatchingTracker> createLogTracker(const AtomMatcher& logMatcher, const int index,
+ const sp<UidMap>& uidMap);
+
// Helper functions for MetricsManager to initialize from StatsdConfig.
// *Note*: only initStatsdConfig() should be called from outside.
// All other functions are intermediate
@@ -44,8 +56,7 @@ namespace statsd {
// [logTrackerMap]: this map should contain matcher name to index mapping
// [allAtomMatchers]: should store the sp to all the LogMatchingTracker
// [allTagIds]: contains the set of all interesting tag ids to this config.
-bool initLogTrackers(const StatsdConfig& config,
- const UidMap& uidMap,
+bool initLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
std::unordered_map<int64_t, int>& logTrackerMap,
std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
std::set<int>& allTagIds);
@@ -97,7 +108,7 @@ bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAt
// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
bool initMetrics(
const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
- const int64_t currentTimeNs, UidMap& uidMap, const sp<StatsPullerManager>& pullerManager,
+ const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
const std::unordered_map<int64_t, int>& logTrackerMap,
const std::unordered_map<int64_t, int>& conditionTrackerMap,
const std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
@@ -116,12 +127,13 @@ bool initMetrics(
// Initialize MetricsManager from StatsdConfig.
// Parameters are the members of MetricsManager. See MetricsManager for declaration.
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
+bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
const sp<StatsPullerManager>& pullerManager,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
const int64_t currentTimeNs, std::set<int>& allTagIds,
std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
+ std::unordered_map<int64_t, int>& logTrackerMap,
std::vector<sp<ConditionTracker>>& allConditionTrackers,
std::vector<sp<MetricProducer>>& allMetricProducers,
vector<sp<AnomalyTracker>>& allAnomalyTrackers,
@@ -132,8 +144,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap&
unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
std::unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds);
+ vector<int>& metricsWithActivation, std::set<int64_t>& noReportMetricIds);
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
index 6c50a8c41770..1bc84c5433f9 100644
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ b/cmds/statsd/src/packages/PackageInfoListener.h
@@ -17,6 +17,8 @@
#ifndef STATSD_PACKAGE_INFO_LISTENER_H
#define STATSD_PACKAGE_INFO_LISTENER_H
+#include <utils/RefBase.h>
+
#include <string>
namespace android {
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 22250aee402e..622321b804ec 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -17,7 +17,6 @@
#pragma once
#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
#include "packages/PackageInfoListener.h"
#include "stats_util.h"
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
index fd883c29dba0..9d8f0c24e253 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -191,7 +191,7 @@ void ShellSubscriber::writePulledAtomsLocked(const vector<std::shared_ptr<LogEve
mProto.clear();
int count = 0;
for (const auto& event : data) {
- if (matchesSimple(*mUidMap, matcher, *event)) {
+ if (matchesSimple(mUidMap, matcher, *event)) {
count++;
uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
@@ -209,7 +209,7 @@ void ShellSubscriber::onLogEvent(const LogEvent& event) {
mProto.clear();
for (const auto& matcher : mSubscriptionInfo->mPushedMatchers) {
- if (matchesSimple(*mUidMap, matcher, event)) {
+ if (matchesSimple(mUidMap, matcher, event)) {
uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
event.ToProto(mProto);
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 6264c075426a..92cd04f37ee0 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -110,7 +110,7 @@ void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t ti
} // anonymous namespace
TEST(AtomMatcherTest, TestSimpleMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
@@ -129,7 +129,7 @@ TEST(AtomMatcherTest, TestSimpleMatcher) {
}
TEST(AtomMatcherTest, TestAttributionMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
std::vector<int> attributionUids = {1111, 2222, 3333};
std::vector<string> attributionTags = {"location1", "location2", "location3"};
@@ -204,7 +204,7 @@ TEST(AtomMatcherTest, TestAttributionMatcher) {
"pkg0");
EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- uidMap.updateMap(
+ uidMap->updateMap(
1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
{android::String16("v1"), android::String16("v1"), android::String16("v2"),
android::String16("v1"), android::String16("v2")},
@@ -356,8 +356,8 @@ TEST(AtomMatcherTest, TestAttributionMatcher) {
}
TEST(AtomMatcherTest, TestUidFieldMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
+ sp<UidMap> uidMap = new UidMap();
+ uidMap->updateMap(
1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
{android::String16("v1"), android::String16("v1"), android::String16("v2"),
android::String16("v1"), android::String16("v2")},
@@ -392,8 +392,8 @@ TEST(AtomMatcherTest, TestUidFieldMatcher) {
}
TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
+ sp<UidMap> uidMap = new UidMap();
+ uidMap->updateMap(
1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
{android::String16("v1"), android::String16("v1"), android::String16("v2"),
android::String16("v1"), android::String16("v2")},
@@ -453,8 +453,8 @@ TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
}
TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
+ sp<UidMap> uidMap = new UidMap();
+ uidMap->updateMap(
1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
{android::String16("v1"), android::String16("v1"), android::String16("v2"),
android::String16("v1"), android::String16("v2")},
@@ -517,7 +517,7 @@ TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
}
TEST(AtomMatcherTest, TestBoolMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
auto simpleMatcher = matcher.mutable_simple_atom_matcher();
@@ -550,7 +550,7 @@ TEST(AtomMatcherTest, TestBoolMatcher) {
}
TEST(AtomMatcherTest, TestStringMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
auto simpleMatcher = matcher.mutable_simple_atom_matcher();
@@ -568,7 +568,7 @@ TEST(AtomMatcherTest, TestStringMatcher) {
}
TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
auto simpleMatcher = matcher.mutable_simple_atom_matcher();
@@ -597,7 +597,7 @@ TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
}
TEST(AtomMatcherTest, TestIntComparisonMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
auto simpleMatcher = matcher.mutable_simple_atom_matcher();
@@ -654,7 +654,7 @@ TEST(AtomMatcherTest, TestIntComparisonMatcher) {
}
TEST(AtomMatcherTest, TestFloatComparisonMatcher) {
- UidMap uidMap;
+ sp<UidMap> uidMap = new UidMap();
// Set up the matcher
AtomMatcher matcher;
auto simpleMatcher = matcher.mutable_simple_atom_matcher();
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 6259757fe092..8dd608347064 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -28,7 +28,7 @@
#include "src/metrics/GaugeMetricProducer.h"
#include "src/metrics/MetricProducer.h"
#include "src/metrics/ValueMetricProducer.h"
-#include "src/metrics/metrics_manager_util.h"
+#include "src/metrics/parsing_utils/metrics_manager_util.h"
#include "src/state/StateManager.h"
#include "statsd_test_util.h"
@@ -48,7 +48,6 @@ namespace statsd {
namespace {
const ConfigKey kConfigKey(0, 12345);
-const long kAlertId = 3;
const long timeBaseSec = 1000;
@@ -90,287 +89,6 @@ StatsdConfig buildGoodConfig() {
metric->set_bucket(ONE_MINUTE);
metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- config.add_no_report_metric(3);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCircleMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // Circle dependency
- combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
-
- return config;
-}
-
-StatsdConfig buildAlertWithUnknownMetric() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_IS_ON"));
- metric->set_bucket(ONE_MINUTE);
- metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(3);
- alert->set_metric_id(2);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildMissingMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // undefined matcher
- combination->add_matcher(StringToId("ABC"));
-
- return config;
-}
-
-StatsdConfig buildMissingPredicate() {
- StatsdConfig config;
- config.set_id(12345);
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_EVENT"));
- metric->set_bucket(ONE_MINUTE);
- metric->set_condition(StringToId("SOME_CONDITION"));
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_EVENT"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- return config;
-}
-
-StatsdConfig buildDimensionMetricsWithMultiTags() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(3);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_LOW"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
- combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
-
- // Count process state changes, slice by uid, while SCREEN_IS_OFF
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("BATTERY_LOW"));
- metric->set_bucket(ONE_MINUTE);
- // This case is interesting. We want to dimension across two atoms.
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCirclePredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
- auto condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_ON"));
- SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
- simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
- simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
-
- condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- Predicate_Combination* combination = condition->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_predicate(StringToId("SCREEN_IS_ON"));
- combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- return config;
-}
-
-StatsdConfig buildConfigWithDifferentPredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = screenOnAtomMatcher;
- auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOffAtomMatcher;
- auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = batteryNoneAtomMatcher;
- auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
- *config.add_atom_matcher() = batteryUsbAtomMatcher;
-
- // Simple condition with InitialValue set to default (unknown).
- auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnUnknownPredicate;
-
- // Simple condition with InitialValue set to false.
- auto screenOnFalsePredicate = config.add_predicate();
- screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
- SimplePredicate* simpleScreenOnFalsePredicate =
- screenOnFalsePredicate->mutable_simple_predicate();
- simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Simple condition with InitialValue set to false.
- auto onBatteryFalsePredicate = config.add_predicate();
- onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
- SimplePredicate* simpleOnBatteryFalsePredicate =
- onBatteryFalsePredicate->mutable_simple_predicate();
- simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Combination condition with both simple condition InitialValues set to false.
- auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
- screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
- screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(*screenOnFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
-
- // Combination condition with one simple condition InitialValue set to unknown and one set to
- // false.
- auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
- screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
- screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnUnknownPredicate,
- screenOnUnknownOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnUnknownOnBatteryFalsePredicate);
-
- // Simple condition metric with initial value false.
- ValueMetric* metric1 = config.add_value_metric();
- metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
- metric1->set_what(pulledAtomMatcher.id());
- *metric1->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric1->set_bucket(FIVE_MINUTES);
- metric1->set_condition(screenOnFalsePredicate->id());
-
- // Simple condition metric with initial value unknown.
- ValueMetric* metric2 = config.add_value_metric();
- metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
- metric2->set_what(pulledAtomMatcher.id());
- *metric2->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric2->set_bucket(FIVE_MINUTES);
- metric2->set_condition(screenOnUnknownPredicate.id());
-
- // Combination condition metric with initial values false and false.
- ValueMetric* metric3 = config.add_value_metric();
- metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
- metric3->set_what(pulledAtomMatcher.id());
- *metric3->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric3->set_bucket(FIVE_MINUTES);
- metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
-
- // Combination condition metric with initial values unknown and false.
- ValueMetric* metric4 = config.add_value_metric();
- metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
- metric4->set_what(pulledAtomMatcher.id());
- *metric4->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric4->set_bucket(FIVE_MINUTES);
- metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
-
return config;
}
@@ -379,274 +97,6 @@ bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
}
} // anonymous namespace
-TEST(MetricsManagerTest, TestInitialConditions) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildConfigWithDifferentPredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(
- kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers,
- allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(4u, allMetricProducers.size());
- ASSERT_EQ(5u, allConditionTrackers.size());
-
- ConditionKey queryKey;
- vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
-
- allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
-
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
-}
-
-TEST(MetricsManagerTest, TestGoodConfig) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildGoodConfig();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(1u, allMetricProducers.size());
- ASSERT_EQ(1u, allAnomalyTrackers.size());
- ASSERT_EQ(1u, noReportMetricIds.size());
- ASSERT_EQ(1u, alertTrackerMap.size());
- EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
- EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
-}
-
-TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildDimensionMetricsWithMultiTags();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCircleMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingMatchers) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingPredicate) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingPredicate();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCirclePredicateDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCirclePredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildAlertWithUnknownMetric();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
TEST(MetricsManagerTest, TestLogSources) {
string app1 = "app1";
set<int32_t> app1Uids = {1111, 11111};
@@ -680,7 +130,7 @@ TEST(MetricsManagerTest, TestLogSources) {
sp<AlarmMonitor> anomalyAlarmMonitor;
sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildGoodConfig();
+ StatsdConfig config;
config.add_allowed_log_source("AID_SYSTEM");
config.add_allowed_log_source(app1);
config.add_default_pull_packages("AID_SYSTEM");
@@ -744,7 +194,7 @@ TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
sp<AlarmMonitor> anomalyAlarmMonitor;
sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildGoodConfig();
+ StatsdConfig config;
config.add_whitelisted_atom_ids(3);
config.add_whitelisted_atom_ids(4);
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
index 95e301002a1b..70e7365ec238 100644
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
@@ -12,14 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
#include <gtest/gtest.h>
-#include "src/anomaly/DurationAnomalyTracker.h"
+#include <vector>
+
#include "src/StatsLogProcessor.h"
+#include "src/StatsService.h"
+#include "src/anomaly/DurationAnomalyTracker.h"
#include "src/stats_log_util.h"
#include "tests/statsd_test_util.h"
-#include <vector>
+using ::ndk::SharedRefBase;
namespace android {
namespace os {
@@ -29,6 +34,9 @@ namespace statsd {
namespace {
+const int kConfigKey = 789130124;
+const int kCallingUid = 0;
+
StatsdConfig CreateStatsdConfig(int num_buckets,
uint64_t threshold_ns,
DurationMetric::AggregationType aggregationType,
@@ -89,6 +97,13 @@ MetricDimensionKey dimensionKey2(
(int32_t)0x02010101), Value((int32_t)222))}),
DEFAULT_DIMENSION_KEY);
+void sendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
+ string str;
+ config.SerializeToString(&str);
+ std::vector<uint8_t> configAsVec(str.begin(), str.end());
+ service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
+}
+
} // namespace
TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
@@ -98,16 +113,18 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
const uint64_t alert_id = config.alert(0).id();
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -158,12 +175,13 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
(uint32_t)alarmFiredTimestampSec0);
+ EXPECT_EQ(alarmFiredTimestampSec0,
+ processor->getAnomalyAlarmMonitor()->getRegisteredAlarmTimeSec());
// Anomaly alarm fired.
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec0));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
+ auto alarmTriggerEvent = CreateBatterySaverOnEvent(alarmFiredTimestampSec0 * NS_PER_SEC);
+ processor->OnLogEvent(alarmTriggerEvent.get(), alarmFiredTimestampSec0 * NS_PER_SEC);
+
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
@@ -179,39 +197,39 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock wl1.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11,
- attributionUids2, attributionTags2, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11, attributionUids2,
+ attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
(uint64_t)alarmFiredTimestampSec1);
// Release wakelock wl1.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10) / NS_PER_SEC + 1,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
+ auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
static_cast<uint32_t>(alarmFiredTimestampSec1));
ASSERT_EQ(0u, alarmSet.size());
// Acquire wakelock wl1 near the end of bucket #0.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 2,
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 2,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Release the event at early bucket #1.
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Anomaly detected when stopping the alarm. The refractory period does not change.
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
@@ -236,17 +254,17 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
// Condition turns true.
screen_off_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
+ CreateScreenStateChangedEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
processor->OnLogEvent(screen_off_event.get());
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Condition turns to false.
- screen_on_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get());
+ int64_t condition_false_time = bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1;
+ screen_on_event = CreateScreenStateChangedEvent(
+ condition_false_time, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+ processor->OnLogEvent(screen_on_event.get(), condition_false_time);
// Condition turns to false. Cancelled the alarm.
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Detected one anomaly.
@@ -262,12 +280,11 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC) / NS_PER_SEC,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
}
@@ -279,16 +296,18 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
const uint64_t alert_id = config.alert(0).id();
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -298,96 +317,97 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
// Acquire wakelock "wc1" in bucket #0.
auto acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Release wakelock "wc1" in bucket #0.
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 1;
+ auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock "wc1" in bucket #1.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1,
- attributionUids2, attributionTags2, "wl1");
+ acquire_event =
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 1,
+ attributionUids2, attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 100,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 100;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock "wc2" in bucket #2.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids3, attributionTags3, "wl2");
+ acquire_event =
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + 1,
+ attributionUids3, attributionTags3, "wl2");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2,
+ EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
// Release wakelock "wc2" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
+ attributionTags3, "wl2");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC) / NS_PER_SEC,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
// Acquire wakelock "wc1" in bucket #2.
acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC,
attributionUids2, attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3 + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Release wakelock "wc1" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3.5 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (int64_t)(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC) /
- NS_PER_SEC +
- 1,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 4,
- attributionUids3, attributionTags3, "wl2");
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 4,
+ attributionUids3, attributionTags3, "wl2");
processor->OnLogEvent(acquire_event.get());
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 5,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 5,
+ attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 2,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 6,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC + 2;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
+ attributionTags3, "wl2");
+ processor->OnLogEvent(release_event.get(), release_event_time);
+ release_event = CreateReleaseWakelockEvent(release_event_time + 4, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time + 4);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
// The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
- EXPECT_EQ(refractory_period_sec + (int64_t)(bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC +
+ EXPECT_EQ(refractory_period_sec +
+ (int64_t)(roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC) /
+ NS_PER_SEC +
1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
}
@@ -396,20 +416,22 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
const int num_buckets = 2;
const uint64_t threshold_ns = 3 * NS_PER_SEC;
auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
-
const uint64_t alert_id = config.alert(0).id();
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
+
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -418,81 +440,81 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
processor->OnLogEvent(screen_off_event.get());
// Acquire wakelock "wc1" in bucket #0.
- auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 100,
+ auto acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 100,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire the wakelock "wc1" again.
acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
// The alarm does not change.
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Anomaly alarm fired late.
- const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
+ const int64_t firedAlarmTimestampNs = roundedBucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
+ auto alarmTriggerEvent = CreateBatterySaverOnEvent(firedAlarmTimestampNs);
+ processor->OnLogEvent(alarmTriggerEvent.get(), firedAlarmTimestampNs);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs - 100,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = bucketStartTimeNs + 2 * bucketSizeNs + 1;
+ auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Within the refractory period. No anomaly.
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// A new wakelock, but still within refractory period.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
+ release_event =
+ CreateReleaseWakelockEvent(roundedBucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
+ attributionUids1, attributionTags1, "wl1");
// Still in the refractory period. No anomaly.
processor->OnLogEvent(release_event.get());
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 5,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 5, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
+ EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 4,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 4;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 3,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 3, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
+ EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
}
diff --git a/cmds/statsd/tests/external/StatsPullerManager_test.cpp b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
index c76e85ec75e6..0d539f477016 100644
--- a/cmds/statsd/tests/external/StatsPullerManager_test.cpp
+++ b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
@@ -89,10 +89,10 @@ public:
sp<StatsPullerManager> createPullerManagerAndRegister() {
sp<StatsPullerManager> pullerManager = new StatsPullerManager();
shared_ptr<FakePullAtomCallback> cb1 = SharedRefBase::make<FakePullAtomCallback>(uid1);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId1, coolDownNs, timeoutNs, {}, cb1, true);
+ pullerManager->RegisterPullAtomCallback(uid1, pullTagId1, coolDownNs, timeoutNs, {}, cb1);
shared_ptr<FakePullAtomCallback> cb2 = SharedRefBase::make<FakePullAtomCallback>(uid2);
- pullerManager->RegisterPullAtomCallback(uid2, pullTagId1, coolDownNs, timeoutNs, {}, cb2, true);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId2, coolDownNs, timeoutNs, {}, cb1, true);
+ pullerManager->RegisterPullAtomCallback(uid2, pullTagId1, coolDownNs, timeoutNs, {}, cb2);
+ pullerManager->RegisterPullAtomCallback(uid1, pullTagId2, coolDownNs, timeoutNs, {}, cb1);
return pullerManager;
}
} // anonymous namespace
@@ -101,14 +101,14 @@ TEST(StatsPullerManagerTest, TestPullInvalidUid) {
sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data, true));
+ EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data));
}
TEST(StatsPullerManagerTest, TestPullChoosesCorrectUid) {
sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data, true));
+ EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data));
ASSERT_EQ(data.size(), 1);
EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
ASSERT_EQ(data[0]->getValues().size(), 1);
@@ -121,7 +121,7 @@ TEST(StatsPullerManagerTest, TestPullInvalidConfigKey) {
pullerManager->RegisterPullUidProvider(configKey, uidProvider);
vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data, true));
+ EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data));
}
TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
@@ -130,7 +130,7 @@ TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
pullerManager->RegisterPullUidProvider(configKey, uidProvider);
vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data, true));
+ EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data));
EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
ASSERT_EQ(data[0]->getValues().size(), 1);
EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid2);
@@ -142,7 +142,7 @@ TEST(StatsPullerManagerTest, TestPullConfigKeyNoPullerWithUid) {
pullerManager->RegisterPullUidProvider(configKey, uidProvider);
vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data, true));
+ EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data));
}
} // namespace statsd
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 5997bedcdf2d..d96ff8a1925b 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -47,7 +47,6 @@ namespace {
const ConfigKey kConfigKey(0, 12345);
const int tagId = 1;
const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
const int logEventMatcherIndex = 0;
const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
@@ -94,11 +93,8 @@ TEST(GaugeMetricProducerTest, TestFirstBucket) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -127,19 +123,15 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
@@ -217,12 +209,8 @@ TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
wizard, logEventMatcherIndex, eventMatcherWizard,
@@ -301,19 +289,16 @@ TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
+
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
@@ -378,17 +363,13 @@ TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(false));
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
@@ -428,21 +409,17 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
int64_t conditionChangeNs = bucketStartTimeNs + 8;
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
return true;
@@ -502,12 +479,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
dim->set_field(tagId);
dim->add_child()->set_field(1);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*wizard, query(_, _, _))
@@ -527,9 +500,9 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
return true;
@@ -566,7 +539,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(false));
GaugeMetric metric;
@@ -577,12 +550,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
gaugeFieldMatcher->set_field(tagId);
gaugeFieldMatcher->add_child()->set_field(2);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
@@ -657,24 +626,20 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
@@ -729,31 +694,27 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
@@ -807,18 +768,14 @@ TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _))
// Bucket start.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
return true;
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 5666501d7d51..5524ebc86b36 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -46,7 +46,6 @@ namespace {
const ConfigKey kConfigKey(0, 12345);
const int tagId = 1;
const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
const int logEventMatcherIndex = 0;
const int64_t bucketStartTimeNs = 10000000000;
const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
@@ -99,12 +98,8 @@ class ValueMetricProducerTestHelper {
public:
static sp<ValueMetricProducer> createValueProducerNoConditions(
sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
.WillOnce(Return());
@@ -122,12 +117,8 @@ public:
static sp<ValueMetricProducer> createValueProducerWithCondition(
sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
.WillOnce(Return());
@@ -147,12 +138,8 @@ public:
sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
vector<int32_t> slicedStateAtoms,
unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
.WillOnce(Return());
@@ -172,12 +159,8 @@ public:
vector<int32_t> slicedStateAtoms,
unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
.WillOnce(Return());
@@ -237,12 +220,8 @@ TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
int64_t startTimeBase = 11;
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -267,12 +246,8 @@ TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
TEST(ValueMetricProducerTest, TestFirstBucket) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -294,9 +269,9 @@ TEST(ValueMetricProducerTest, TestFirstBucket) {
TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
return true;
@@ -368,19 +343,19 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Initialize bucket.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
return true;
}))
// Partial bucket.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
+ const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
data->push_back(
@@ -421,22 +396,18 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) {
TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- auto keyValue = atomMatcher.add_field_value_matcher();
- keyValue->set_field(1);
- keyValue->set_eq_int(3);
+ FieldValueMatcher fvm;
+ fvm.set_field(1);
+ fvm.set_eq_int(3);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex, {fvm});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
return true;
@@ -505,7 +476,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
metric.set_use_absolute_value_on_reset(true);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(true));
sp<ValueMetricProducer> valueProducer =
ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -565,7 +536,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(false));
sp<ValueMetricProducer> valueProducer =
ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -621,23 +592,23 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 1); // Third condition change.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
@@ -698,12 +669,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -759,22 +726,18 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) {
TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150;
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Return(true))
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
+ const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
@@ -820,17 +783,13 @@ TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
metric.set_split_bucket_for_app_upgrade(false);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(true));
ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
@@ -854,16 +813,16 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to true time.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs,
bucket2StartTimeNs - 100); // Condition change to false time.
data->clear();
@@ -900,12 +859,8 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse
TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -944,12 +899,8 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1015,12 +966,8 @@ TEST(ValueMetricProducerTest, TestAnomalyDetection) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1081,11 +1028,54 @@ TEST(ValueMetricProducerTest, TestAnomalyDetection) {
std::ceil(1.0 * event6.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
}
+TEST(ValueMetricProducerTest, TestAnomalyDetectionMultipleBucketsSkipped) {
+ sp<AlarmMonitor> alarmMonitor;
+ Alert alert;
+ alert.set_id(101);
+ alert.set_metric_id(metricId);
+ alert.set_trigger_if_sum_gt(100);
+ alert.set_num_buckets(1);
+ const int32_t refPeriodSec = 3;
+ alert.set_refractory_period_secs(refPeriodSec);
+
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to true time.
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 0));
+ return true;
+ }))
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ EXPECT_EQ(eventTimeNs,
+ bucket3StartTimeNs + 100); // Condition changed to false time.
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 100, 120));
+ return true;
+ }));
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+ ConditionState::kFalse);
+ sp<AnomalyTracker> anomalyTracker = valueProducer->addAnomalyTracker(alert, alarmMonitor);
+
+ valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
+
+ // multiple buckets should be skipped here.
+ valueProducer->onConditionChanged(false, bucket3StartTimeNs + 100);
+
+ // No alert is fired when multiple buckets are skipped.
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
+}
+
// Test value metric no condition, the pull on bucket boundary come in time and too late
TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Return(true));
sp<ValueMetricProducer> valueProducer =
ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -1164,10 +1154,10 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// condition becomes true
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
@@ -1175,7 +1165,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
}))
// condition becomes false
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
@@ -1227,10 +1217,10 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// condition becomes true
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
@@ -1238,7 +1228,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
}))
// condition becomes false
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
@@ -1246,7 +1236,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
}))
// condition becomes true again
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 25);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
@@ -1317,12 +1307,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
metric.set_aggregation_type(ValueMetric::MIN);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1361,12 +1347,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
metric.set_aggregation_type(ValueMetric::MAX);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1404,12 +1386,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
metric.set_aggregation_type(ValueMetric::AVG);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1452,12 +1430,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
metric.set_aggregation_type(ValueMetric::SUM);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1496,12 +1470,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
metric.set_aggregation_type(ValueMetric::MIN);
metric.set_use_diff(true);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1568,12 +1538,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
metric.set_aggregation_type(ValueMetric::MIN);
metric.set_use_diff(true);
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1677,9 +1643,9 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
metric.set_use_zero_default_base(true);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
return true;
@@ -1753,9 +1719,9 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
metric.set_use_zero_default_base(true);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
return true;
@@ -1858,9 +1824,9 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
metric.mutable_dimensions_in_what()->add_child()->set_field(1);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
return true;
@@ -1961,9 +1927,9 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfB
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// Used by onConditionChanged.
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
return true;
@@ -1995,9 +1961,9 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // Condition change to true.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
@@ -2034,16 +2000,16 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
return false;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to false.
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
@@ -2077,9 +2043,9 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
metric.set_max_pull_delay_sec(0);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 120));
return true;
@@ -2097,12 +2063,8 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
@@ -2124,9 +2086,9 @@ TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
return true;
@@ -2156,12 +2118,12 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First onConditionChanged
.WillOnce(Return(false))
// Second onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
@@ -2233,10 +2195,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
metric.set_condition(StringToId("SCREEN_ON"));
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
for (int i = 0; i < 2000; i++) {
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
}
@@ -2290,10 +2252,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed)
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
@@ -2301,7 +2263,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed)
}))
// Second onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
@@ -2369,10 +2331,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
@@ -2380,7 +2342,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
}))
// Second onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
@@ -2442,10 +2404,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
// Start bucket.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
return true;
@@ -2475,17 +2437,17 @@ TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
return true;
@@ -2518,24 +2480,24 @@ TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 11);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 12);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
@@ -2582,10 +2544,10 @@ TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
metric.set_condition(StringToId("SCREEN_ON"));
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
// First onConditionChanged
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
return true;
@@ -2625,19 +2587,19 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketI
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Initialization.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
return true;
}))
// notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
+ const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
@@ -2681,10 +2643,10 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketI
TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Second onConditionChanged.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
@@ -2692,7 +2654,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
}))
// Third onConditionChanged.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
@@ -2752,10 +2714,10 @@ TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
// Initialization.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
return true;
@@ -2782,19 +2744,19 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucke
int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Initialization.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
return true;
}))
// notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](
- int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
+ const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
@@ -2822,10 +2784,10 @@ TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First on condition changed.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
@@ -2833,7 +2795,7 @@ TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
}))
// Second on condition changed.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
@@ -2867,10 +2829,10 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First condition change.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
@@ -2878,7 +2840,7 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
}))
// 2nd condition change.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 8);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
@@ -2886,7 +2848,7 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
}))
// 3rd condition change.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
@@ -2920,21 +2882,17 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
// Initial pull.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
return true;
@@ -2958,21 +2916,17 @@ TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
// Initial pull.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
return true;
@@ -3002,28 +2956,24 @@ TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ createEventMatcherWizard(tagId, logEventMatcherIndex);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Initial pull.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
return true;
}))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(
@@ -3069,10 +3019,10 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges
metric.set_use_diff(false);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// condition becomes true
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
@@ -3080,7 +3030,7 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges
}))
// condition becomes false
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
@@ -3119,10 +3069,10 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
metric.set_use_diff(false);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
// condition becomes true
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
return true;
@@ -3170,10 +3120,10 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
metric.set_use_diff(false);
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// condition becomes true
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
@@ -3210,10 +3160,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequeste
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
return true;
@@ -3256,10 +3206,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWron
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
return true;
@@ -3314,10 +3264,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWro
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
@@ -3325,7 +3275,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWro
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 100);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
@@ -3380,10 +3330,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown)
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
@@ -3391,7 +3341,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown)
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10000);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
@@ -3436,10 +3386,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
@@ -3486,10 +3436,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSki
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
@@ -3497,7 +3447,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSki
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket4StartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1000, 15));
@@ -3560,10 +3510,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
@@ -3571,7 +3521,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 9000000);
data->clear();
data->push_back(
@@ -3651,10 +3601,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(
@@ -3663,7 +3613,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 15 * NS_PER_SEC);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(
@@ -3740,10 +3690,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenForceBucketSplitBefor
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
@@ -3751,7 +3701,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenForceBucketSplitBefor
}))
// App Update.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1000);
data->clear();
data->push_back(
@@ -3806,10 +3756,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
// Condition change to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
return true;
@@ -3857,10 +3807,10 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// First condition change event.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
for (int i = 0; i < 2000; i++) {
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
@@ -3877,7 +3827,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
.WillOnce(Return(false))
.WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 220);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 220, 10));
@@ -3976,10 +3926,10 @@ TEST(ValueMetricProducerTest, TestSlicedState) {
// Set up ValueMetricProducer.
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// ValueMetricProducer initialized.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
@@ -3987,7 +3937,7 @@ TEST(ValueMetricProducerTest, TestSlicedState) {
}))
// Screen state change to ON.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
@@ -3995,7 +3945,7 @@ TEST(ValueMetricProducerTest, TestSlicedState) {
}))
// Screen state change to OFF.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 9));
@@ -4003,7 +3953,7 @@ TEST(ValueMetricProducerTest, TestSlicedState) {
}))
// Screen state change to ON.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
@@ -4011,7 +3961,7 @@ TEST(ValueMetricProducerTest, TestSlicedState) {
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
@@ -4178,10 +4128,10 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
// Set up ValueMetricProducer.
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// ValueMetricProducer initialized.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
@@ -4189,7 +4139,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
}))
// Screen state change to ON.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
@@ -4203,7 +4153,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
// Screen state change to OFF.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
@@ -4211,7 +4161,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
}))
// Dump report requested.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
@@ -4408,10 +4358,10 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
*fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// ValueMetricProducer initialized.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
data->clear();
data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 2 /*uid*/, 7));
@@ -4420,7 +4370,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
}))
// Uid 1 process state change from kStateUnknown -> Foreground
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
data->clear();
data->push_back(
@@ -4433,7 +4383,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
}))
// Uid 2 process state change from kStateUnknown -> Background
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40);
data->clear();
data->push_back(
@@ -4446,7 +4396,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
}))
// Uid 1 process state change from Foreground -> Background
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 20);
data->clear();
data->push_back(
@@ -4459,7 +4409,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
}))
// Uid 1 process state change from Background -> Foreground
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 40);
data->clear();
data->push_back(
@@ -4472,7 +4422,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
}))
// Dump report pull.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50);
data->clear();
data->push_back(
@@ -4852,10 +4802,10 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithConditionAndState(
"BATTERY_SAVER_MODE_STATE");
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
// Condition changed to true.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
data->clear();
data->push_back(
@@ -4864,7 +4814,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
}))
// Battery saver mode state changed to OFF.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
data->clear();
data->push_back(
@@ -4873,7 +4823,7 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
}))
// Condition changed to false.
.WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
data->clear();
data->push_back(CreateRepeatedValueLogEvent(
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index eeb38a4644fd..39232c194ada 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -38,11 +38,10 @@ public:
int64_t nextPulltimeNs, int64_t intervalNs));
MOCK_METHOD3(UnRegisterReceiver,
void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver));
- MOCK_METHOD5(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids));
- MOCK_METHOD5(Pull,
- bool(const int pullCode, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data, bool useUids));
+ MOCK_METHOD4(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data));
+ MOCK_METHOD4(Pull, bool(const int pullCode, const vector<int32_t>& uids,
+ const int64_t eventTimeNs, vector<std::shared_ptr<LogEvent>>* data));
MOCK_METHOD2(RegisterPullUidProvider,
void(const ConfigKey& configKey, wp<PullUidProvider> provider));
MOCK_METHOD2(UnregisterPullUidProvider,
diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
new file mode 100644
index 000000000000..6b50fe5387d7
--- /dev/null
+++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
@@ -0,0 +1,382 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/metrics/parsing_utils/config_update_utils.h"
+
+#include <gtest/gtest.h>
+#include <private/android_filesystem_config.h>
+#include <stdio.h>
+
+#include <set>
+#include <unordered_map>
+#include <vector>
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "src/metrics/parsing_utils/metrics_manager_util.h"
+#include "tests/statsd_test_util.h"
+
+using namespace testing;
+using android::sp;
+using android::os::statsd::Predicate;
+using std::map;
+using std::set;
+using std::unordered_map;
+using std::vector;
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+namespace {
+
+ConfigKey key(123, 456);
+const int64_t timeBaseNs = 1000;
+sp<UidMap> uidMap = new UidMap();
+sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+sp<AlarmMonitor> anomalyAlarmMonitor;
+sp<AlarmMonitor> periodicAlarmMonitor;
+set<int> allTagIds;
+vector<sp<LogMatchingTracker>> oldAtomMatchers;
+unordered_map<int64_t, int> oldLogTrackerMap;
+vector<sp<ConditionTracker>> oldConditionTrackers;
+vector<sp<MetricProducer>> oldMetricProducers;
+std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
+std::vector<sp<AlarmTracker>> oldAlarmTrackers;
+unordered_map<int, std::vector<int>> conditionToMetricMap;
+unordered_map<int, std::vector<int>> trackerToMetricMap;
+unordered_map<int, std::vector<int>> trackerToConditionMap;
+unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+unordered_map<int64_t, int> alertTrackerMap;
+vector<int> metricsWithActivation;
+std::set<int64_t> noReportMetricIds;
+
+class ConfigUpdateTest : public ::testing::Test {
+public:
+ ConfigUpdateTest() {
+ }
+
+ void SetUp() override {
+ allTagIds.clear();
+ oldAtomMatchers.clear();
+ oldLogTrackerMap.clear();
+ oldConditionTrackers.clear();
+ oldMetricProducers.clear();
+ oldAnomalyTrackers.clear();
+ oldAlarmTrackers.clear();
+ conditionToMetricMap.clear();
+ trackerToMetricMap.clear();
+ trackerToConditionMap.clear();
+ activationAtomTrackerToMetricMap.clear();
+ deactivationAtomTrackerToMetricMap.clear();
+ alertTrackerMap.clear();
+ metricsWithActivation.clear();
+ noReportMetricIds.clear();
+ }
+};
+
+bool initConfig(const StatsdConfig& config) {
+ return initStatsdConfig(key, config, uidMap, pullerManager, anomalyAlarmMonitor,
+ periodicAlarmMonitor, timeBaseNs, timeBaseNs, allTagIds,
+ oldAtomMatchers, oldLogTrackerMap, oldConditionTrackers,
+ oldMetricProducers, oldAnomalyTrackers, oldAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+ alertTrackerMap, metricsWithActivation, noReportMetricIds);
+}
+
+} // anonymous namespace
+
+TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
+ StatsdConfig config;
+ AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
+ int64_t matcherId = matcher.id();
+ *config.add_atom_matcher() = matcher;
+
+ // Create an initial config.
+ EXPECT_TRUE(initConfig(config));
+
+ vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(1, false);
+ unordered_map<int64_t, int> newLogTrackerMap;
+ newLogTrackerMap[matcherId] = 0;
+ EXPECT_TRUE(determineMatcherUpdateStatus(config, 0, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker));
+ EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
+}
+
+TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) {
+ StatsdConfig config;
+ AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
+ *config.add_atom_matcher() = matcher;
+
+ EXPECT_TRUE(initConfig(config));
+
+ StatsdConfig newConfig;
+ // Same id, different atom, so should be replaced.
+ AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11);
+ int64_t matcherId = newMatcher.id();
+ EXPECT_EQ(matcherId, matcher.id());
+ *newConfig.add_atom_matcher() = newMatcher;
+
+ vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(1, false);
+ unordered_map<int64_t, int> newLogTrackerMap;
+ newLogTrackerMap[matcherId] = 0;
+ EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker));
+ EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
+}
+
+TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) {
+ StatsdConfig config;
+ AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
+ int64_t matcher1Id = matcher1.id();
+ *config.add_atom_matcher() = matcher1;
+
+ AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
+ *config.add_atom_matcher() = matcher2;
+ int64_t matcher2Id = matcher2.id();
+
+ AtomMatcher matcher3;
+ matcher3.set_id(StringToId("TEST3"));
+ AtomMatcher_Combination* combination = matcher3.mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(matcher1Id);
+ combination->add_matcher(matcher2Id);
+ int64_t matcher3Id = matcher3.id();
+ *config.add_atom_matcher() = matcher3;
+
+ EXPECT_TRUE(initConfig(config));
+
+ StatsdConfig newConfig;
+ unordered_map<int64_t, int> newLogTrackerMap;
+ // Same matchers, different order, all should be preserved.
+ *newConfig.add_atom_matcher() = matcher2;
+ newLogTrackerMap[matcher2Id] = 0;
+ *newConfig.add_atom_matcher() = matcher3;
+ newLogTrackerMap[matcher3Id] = 1;
+ *newConfig.add_atom_matcher() = matcher1;
+ newLogTrackerMap[matcher1Id] = 2;
+
+ vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(3, false);
+ // Only update the combination. It should recurse the two child matchers and preserve all 3.
+ EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker));
+ EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
+ EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE);
+ EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE);
+}
+
+TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) {
+ StatsdConfig config;
+ AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
+ int64_t matcher1Id = matcher1.id();
+ *config.add_atom_matcher() = matcher1;
+
+ AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
+ *config.add_atom_matcher() = matcher2;
+ int64_t matcher2Id = matcher2.id();
+
+ AtomMatcher matcher3;
+ matcher3.set_id(StringToId("TEST3"));
+ AtomMatcher_Combination* combination = matcher3.mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(matcher1Id);
+ combination->add_matcher(matcher2Id);
+ int64_t matcher3Id = matcher3.id();
+ *config.add_atom_matcher() = matcher3;
+
+ EXPECT_TRUE(initConfig(config));
+
+ // Change the logical operation of the combination matcher, causing a replacement.
+ matcher3.mutable_combination()->set_operation(LogicalOperation::AND);
+
+ StatsdConfig newConfig;
+ unordered_map<int64_t, int> newLogTrackerMap;
+ *newConfig.add_atom_matcher() = matcher2;
+ newLogTrackerMap[matcher2Id] = 0;
+ *newConfig.add_atom_matcher() = matcher3;
+ newLogTrackerMap[matcher3Id] = 1;
+ *newConfig.add_atom_matcher() = matcher1;
+ newLogTrackerMap[matcher1Id] = 2;
+
+ vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(3, false);
+ // Only update the combination. The simple matchers should not be evaluated.
+ EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker));
+ EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN);
+ EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
+ EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN);
+}
+
+TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) {
+ StatsdConfig config;
+ AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
+ int64_t matcher1Id = matcher1.id();
+ *config.add_atom_matcher() = matcher1;
+
+ AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
+ *config.add_atom_matcher() = matcher2;
+ int64_t matcher2Id = matcher2.id();
+
+ AtomMatcher matcher3;
+ matcher3.set_id(StringToId("TEST3"));
+ AtomMatcher_Combination* combination = matcher3.mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(matcher1Id);
+ combination->add_matcher(matcher2Id);
+ int64_t matcher3Id = matcher3.id();
+ *config.add_atom_matcher() = matcher3;
+
+ EXPECT_TRUE(initConfig(config));
+
+ // Change a dependency of matcher 3.
+ matcher2.mutable_simple_atom_matcher()->set_atom_id(12);
+
+ StatsdConfig newConfig;
+ unordered_map<int64_t, int> newLogTrackerMap;
+ *newConfig.add_atom_matcher() = matcher2;
+ newLogTrackerMap[matcher2Id] = 0;
+ *newConfig.add_atom_matcher() = matcher3;
+ newLogTrackerMap[matcher3Id] = 1;
+ *newConfig.add_atom_matcher() = matcher1;
+ newLogTrackerMap[matcher1Id] = 2;
+
+ vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
+ vector<bool> cycleTracker(3, false);
+ // Only update the combination.
+ EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers,
+ newLogTrackerMap, matchersToUpdate, cycleTracker));
+ // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be.
+ EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
+ EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
+}
+
+TEST_F(ConfigUpdateTest, TestUpdateMatchers) {
+ StatsdConfig config;
+ // Will be preserved.
+ AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10);
+ int64_t simple1Id = simple1.id();
+ *config.add_atom_matcher() = simple1;
+
+ // Will be replaced.
+ AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11);
+ *config.add_atom_matcher() = simple2;
+ int64_t simple2Id = simple2.id();
+
+ // Will be removed.
+ AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12);
+ *config.add_atom_matcher() = simple3;
+ int64_t simple3Id = simple3.id();
+
+ // Will be preserved.
+ AtomMatcher combination1;
+ combination1.set_id(StringToId("combination1"));
+ AtomMatcher_Combination* combination = combination1.mutable_combination();
+ combination->set_operation(LogicalOperation::NOT);
+ combination->add_matcher(simple1Id);
+ int64_t combination1Id = combination1.id();
+ *config.add_atom_matcher() = combination1;
+
+ // Will be replaced since it depends on simple2.
+ AtomMatcher combination2;
+ combination2.set_id(StringToId("combination2"));
+ combination = combination2.mutable_combination();
+ combination->set_operation(LogicalOperation::AND);
+ combination->add_matcher(simple1Id);
+ combination->add_matcher(simple2Id);
+ int64_t combination2Id = combination2.id();
+ *config.add_atom_matcher() = combination2;
+
+ EXPECT_TRUE(initConfig(config));
+
+ // Change simple2, causing simple2 and combination2 to be replaced.
+ simple2.mutable_simple_atom_matcher()->set_atom_id(111);
+
+ // 2 new matchers: simple4 and combination3:
+ AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13);
+ int64_t simple4Id = simple4.id();
+
+ AtomMatcher combination3;
+ combination3.set_id(StringToId("combination3"));
+ combination = combination3.mutable_combination();
+ combination->set_operation(LogicalOperation::AND);
+ combination->add_matcher(simple4Id);
+ combination->add_matcher(simple2Id);
+ int64_t combination3Id = combination3.id();
+
+ StatsdConfig newConfig;
+ *newConfig.add_atom_matcher() = combination3;
+ *newConfig.add_atom_matcher() = simple2;
+ *newConfig.add_atom_matcher() = combination2;
+ *newConfig.add_atom_matcher() = simple1;
+ *newConfig.add_atom_matcher() = simple4;
+ *newConfig.add_atom_matcher() = combination1;
+
+ set<int> newTagIds;
+ unordered_map<int64_t, int> newLogTrackerMap;
+ vector<sp<LogMatchingTracker>> newAtomMatchers;
+ EXPECT_TRUE(updateLogTrackers(newConfig, uidMap, oldLogTrackerMap, oldAtomMatchers, newTagIds,
+ newLogTrackerMap, newAtomMatchers));
+
+ ASSERT_EQ(newTagIds.size(), 3);
+ EXPECT_EQ(newTagIds.count(10), 1);
+ EXPECT_EQ(newTagIds.count(111), 1);
+ EXPECT_EQ(newTagIds.count(13), 1);
+
+ ASSERT_EQ(newLogTrackerMap.size(), 6);
+ EXPECT_EQ(newLogTrackerMap.at(combination3Id), 0);
+ EXPECT_EQ(newLogTrackerMap.at(simple2Id), 1);
+ EXPECT_EQ(newLogTrackerMap.at(combination2Id), 2);
+ EXPECT_EQ(newLogTrackerMap.at(simple1Id), 3);
+ EXPECT_EQ(newLogTrackerMap.at(simple4Id), 4);
+ EXPECT_EQ(newLogTrackerMap.at(combination1Id), 5);
+
+ ASSERT_EQ(newAtomMatchers.size(), 6);
+ // Make sure all atom matchers are initialized:
+ for (const sp<LogMatchingTracker>& tracker : newAtomMatchers) {
+ EXPECT_TRUE(tracker->mInitialized);
+ }
+ // Make sure preserved atom matchers are the same.
+ EXPECT_EQ(oldAtomMatchers[oldLogTrackerMap.at(simple1Id)],
+ newAtomMatchers[newLogTrackerMap.at(simple1Id)]);
+ EXPECT_EQ(oldAtomMatchers[oldLogTrackerMap.at(combination1Id)],
+ newAtomMatchers[newLogTrackerMap.at(combination1Id)]);
+ // Make sure replaced matchers are different.
+ EXPECT_NE(oldAtomMatchers[oldLogTrackerMap.at(simple2Id)],
+ newAtomMatchers[newLogTrackerMap.at(simple2Id)]);
+ EXPECT_NE(oldAtomMatchers[oldLogTrackerMap.at(combination2Id)],
+ newAtomMatchers[newLogTrackerMap.at(combination2Id)]);
+
+ // Validation, make sure the matchers have the proper ids. Could do more checks here.
+ EXPECT_EQ(newAtomMatchers[0]->getId(), combination3Id);
+ EXPECT_EQ(newAtomMatchers[1]->getId(), simple2Id);
+ EXPECT_EQ(newAtomMatchers[2]->getId(), combination2Id);
+ EXPECT_EQ(newAtomMatchers[3]->getId(), simple1Id);
+ EXPECT_EQ(newAtomMatchers[4]->getId(), simple4Id);
+ EXPECT_EQ(newAtomMatchers[5]->getId(), combination1Id);
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
new file mode 100644
index 000000000000..4e97eaf6f149
--- /dev/null
+++ b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
@@ -0,0 +1,708 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/metrics/parsing_utils/metrics_manager_util.h"
+
+#include <gtest/gtest.h>
+#include <private/android_filesystem_config.h>
+#include <stdio.h>
+
+#include <set>
+#include <unordered_map>
+#include <vector>
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "src/condition/ConditionTracker.h"
+#include "src/matchers/LogMatchingTracker.h"
+#include "src/metrics/CountMetricProducer.h"
+#include "src/metrics/GaugeMetricProducer.h"
+#include "src/metrics/MetricProducer.h"
+#include "src/metrics/ValueMetricProducer.h"
+#include "src/state/StateManager.h"
+#include "tests/metrics/metrics_test_helper.h"
+#include "tests/statsd_test_util.h"
+
+using namespace testing;
+using android::sp;
+using android::os::statsd::Predicate;
+using std::map;
+using std::set;
+using std::unordered_map;
+using std::vector;
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+namespace {
+const ConfigKey kConfigKey(0, 12345);
+const long kAlertId = 3;
+
+const long timeBaseSec = 1000;
+
+StatsdConfig buildGoodConfig() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
+
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
+
+ simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
+
+ AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(StringToId("SCREEN_IS_ON"));
+ combination->add_matcher(StringToId("SCREEN_IS_OFF"));
+
+ CountMetric* metric = config.add_count_metric();
+ metric->set_id(3);
+ metric->set_what(StringToId("SCREEN_IS_ON"));
+ metric->set_bucket(ONE_MINUTE);
+ metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
+ metric->mutable_dimensions_in_what()->add_child()->set_field(1);
+
+ config.add_no_report_metric(3);
+
+ auto alert = config.add_alert();
+ alert->set_id(kAlertId);
+ alert->set_metric_id(3);
+ alert->set_num_buckets(10);
+ alert->set_refractory_period_secs(100);
+ alert->set_trigger_if_sum_gt(100);
+ return config;
+}
+
+StatsdConfig buildCircleMatchers() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
+
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
+
+ AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(StringToId("SCREEN_IS_ON"));
+ // Circle dependency
+ combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
+
+ return config;
+}
+
+StatsdConfig buildAlertWithUnknownMetric() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
+
+ CountMetric* metric = config.add_count_metric();
+ metric->set_id(3);
+ metric->set_what(StringToId("SCREEN_IS_ON"));
+ metric->set_bucket(ONE_MINUTE);
+ metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
+ metric->mutable_dimensions_in_what()->add_child()->set_field(1);
+
+ auto alert = config.add_alert();
+ alert->set_id(3);
+ alert->set_metric_id(2);
+ alert->set_num_buckets(10);
+ alert->set_refractory_period_secs(100);
+ alert->set_trigger_if_sum_gt(100);
+ return config;
+}
+
+StatsdConfig buildMissingMatchers() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
+
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
+
+ AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(StringToId("SCREEN_IS_ON"));
+ // undefined matcher
+ combination->add_matcher(StringToId("ABC"));
+
+ return config;
+}
+
+StatsdConfig buildMissingPredicate() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ CountMetric* metric = config.add_count_metric();
+ metric->set_id(3);
+ metric->set_what(StringToId("SCREEN_EVENT"));
+ metric->set_bucket(ONE_MINUTE);
+ metric->set_condition(StringToId("SOME_CONDITION"));
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_EVENT"));
+
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2);
+
+ return config;
+}
+
+StatsdConfig buildDimensionMetricsWithMultiTags() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
+ simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(3);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("BATTERY_LOW"));
+
+ AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
+ combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
+
+ // Count process state changes, slice by uid, while SCREEN_IS_OFF
+ CountMetric* metric = config.add_count_metric();
+ metric->set_id(3);
+ metric->set_what(StringToId("BATTERY_LOW"));
+ metric->set_bucket(ONE_MINUTE);
+ // This case is interesting. We want to dimension across two atoms.
+ metric->mutable_dimensions_in_what()->add_child()->set_field(1);
+
+ auto alert = config.add_alert();
+ alert->set_id(kAlertId);
+ alert->set_metric_id(3);
+ alert->set_num_buckets(10);
+ alert->set_refractory_period_secs(100);
+ alert->set_trigger_if_sum_gt(100);
+ return config;
+}
+
+StatsdConfig buildCirclePredicates() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ AtomMatcher* eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
+
+ SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
+
+ eventMatcher = config.add_atom_matcher();
+ eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
+
+ simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
+
+ auto condition = config.add_predicate();
+ condition->set_id(StringToId("SCREEN_IS_ON"));
+ SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
+ simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
+ simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
+
+ condition = config.add_predicate();
+ condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
+
+ Predicate_Combination* combination = condition->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_predicate(StringToId("SCREEN_IS_ON"));
+ combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
+
+ return config;
+}
+
+StatsdConfig buildConfigWithDifferentPredicates() {
+ StatsdConfig config;
+ config.set_id(12345);
+
+ auto pulledAtomMatcher =
+ CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
+ *config.add_atom_matcher() = pulledAtomMatcher;
+ auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
+ *config.add_atom_matcher() = screenOnAtomMatcher;
+ auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
+ *config.add_atom_matcher() = screenOffAtomMatcher;
+ auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
+ *config.add_atom_matcher() = batteryNoneAtomMatcher;
+ auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
+ *config.add_atom_matcher() = batteryUsbAtomMatcher;
+
+ // Simple condition with InitialValue set to default (unknown).
+ auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
+ *config.add_predicate() = screenOnUnknownPredicate;
+
+ // Simple condition with InitialValue set to false.
+ auto screenOnFalsePredicate = config.add_predicate();
+ screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
+ SimplePredicate* simpleScreenOnFalsePredicate =
+ screenOnFalsePredicate->mutable_simple_predicate();
+ simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
+ simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
+ simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
+
+ // Simple condition with InitialValue set to false.
+ auto onBatteryFalsePredicate = config.add_predicate();
+ onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
+ SimplePredicate* simpleOnBatteryFalsePredicate =
+ onBatteryFalsePredicate->mutable_simple_predicate();
+ simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
+ simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
+ simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
+
+ // Combination condition with both simple condition InitialValues set to false.
+ auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
+ screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
+ screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
+ LogicalOperation::AND);
+ addPredicateToPredicateCombination(*screenOnFalsePredicate,
+ screenOnFalseOnBatteryFalsePredicate);
+ addPredicateToPredicateCombination(*onBatteryFalsePredicate,
+ screenOnFalseOnBatteryFalsePredicate);
+
+ // Combination condition with one simple condition InitialValue set to unknown and one set to
+ // false.
+ auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
+ screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
+ screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
+ LogicalOperation::AND);
+ addPredicateToPredicateCombination(screenOnUnknownPredicate,
+ screenOnUnknownOnBatteryFalsePredicate);
+ addPredicateToPredicateCombination(*onBatteryFalsePredicate,
+ screenOnUnknownOnBatteryFalsePredicate);
+
+ // Simple condition metric with initial value false.
+ ValueMetric* metric1 = config.add_value_metric();
+ metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
+ metric1->set_what(pulledAtomMatcher.id());
+ *metric1->mutable_value_field() =
+ CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+ metric1->set_bucket(FIVE_MINUTES);
+ metric1->set_condition(screenOnFalsePredicate->id());
+
+ // Simple condition metric with initial value unknown.
+ ValueMetric* metric2 = config.add_value_metric();
+ metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
+ metric2->set_what(pulledAtomMatcher.id());
+ *metric2->mutable_value_field() =
+ CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+ metric2->set_bucket(FIVE_MINUTES);
+ metric2->set_condition(screenOnUnknownPredicate.id());
+
+ // Combination condition metric with initial values false and false.
+ ValueMetric* metric3 = config.add_value_metric();
+ metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
+ metric3->set_what(pulledAtomMatcher.id());
+ *metric3->mutable_value_field() =
+ CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+ metric3->set_bucket(FIVE_MINUTES);
+ metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
+
+ // Combination condition metric with initial values unknown and false.
+ ValueMetric* metric4 = config.add_value_metric();
+ metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
+ metric4->set_what(pulledAtomMatcher.id());
+ *metric4->mutable_value_field() =
+ CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+ metric4->set_bucket(FIVE_MINUTES);
+ metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
+
+ return config;
+}
+} // anonymous namespace
+
+TEST(MetricsManagerTest, TestInitialConditions) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildConfigWithDifferentPredicates();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_TRUE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+ ASSERT_EQ(4u, allMetricProducers.size());
+ ASSERT_EQ(5u, allConditionTrackers.size());
+
+ ConditionKey queryKey;
+ vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
+
+ allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
+ allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
+ EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
+ EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
+ EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
+ EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
+ EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
+
+ EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
+ EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
+ EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
+ EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
+}
+
+TEST(MetricsManagerTest, TestGoodConfig) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildGoodConfig();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_TRUE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+ ASSERT_EQ(1u, allMetricProducers.size());
+ ASSERT_EQ(1u, allAnomalyTrackers.size());
+ ASSERT_EQ(1u, noReportMetricIds.size());
+ ASSERT_EQ(1u, alertTrackerMap.size());
+ EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
+ EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
+}
+
+TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildDimensionMetricsWithMultiTags();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildCircleMatchers();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, TestMissingMatchers) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildMissingMatchers();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, TestMissingPredicate) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildMissingPredicate();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, TestCirclePredicateDependency) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildCirclePredicates();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
+ sp<UidMap> uidMap = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> periodicAlarmMonitor;
+ StatsdConfig config = buildAlertWithUnknownMetric();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allAtomMatchers;
+ unordered_map<int64_t, int> logTrackerMap;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+ std::vector<sp<AlarmTracker>> allAlarmTrackers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+ unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+ unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+ unordered_map<int64_t, int> alertTrackerMap;
+ vector<int> metricsWithActivation;
+ std::set<int64_t> noReportMetricIds;
+
+ EXPECT_FALSE(initStatsdConfig(
+ kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap,
+ allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers,
+ conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+ activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+ metricsWithActivation, noReportMetricIds));
+}
+
+TEST(MetricsManagerTest, TestCreateLogTrackerInvalidMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+ AtomMatcher matcher;
+ matcher.set_id(21);
+ EXPECT_EQ(createLogTracker(matcher, 0, uidMap), nullptr);
+}
+
+TEST(MetricsManagerTest, TestCreateLogTrackerSimple) {
+ int index = 1;
+ int64_t id = 123;
+ sp<UidMap> uidMap = new UidMap();
+ AtomMatcher matcher;
+ matcher.set_id(id);
+ SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
+ simpleAtomMatcher->set_atom_id(util::SCREEN_STATE_CHANGED);
+ simpleAtomMatcher->add_field_value_matcher()->set_field(
+ 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
+ simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
+ android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+
+ sp<LogMatchingTracker> tracker = createLogTracker(matcher, index, uidMap);
+ EXPECT_NE(tracker, nullptr);
+
+ EXPECT_TRUE(tracker->mInitialized);
+ EXPECT_EQ(tracker->getId(), id);
+ EXPECT_EQ(tracker->mIndex, index);
+ const set<int>& atomIds = tracker->getAtomIds();
+ ASSERT_EQ(atomIds.size(), 1);
+ EXPECT_EQ(atomIds.count(util::SCREEN_STATE_CHANGED), 1);
+}
+
+TEST(MetricsManagerTest, TestCreateLogTrackerCombination) {
+ int index = 1;
+ int64_t id = 123;
+ sp<UidMap> uidMap = new UidMap();
+ AtomMatcher matcher;
+ matcher.set_id(id);
+ AtomMatcher_Combination* combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher(123);
+ combination->add_matcher(223);
+
+ sp<LogMatchingTracker> tracker = createLogTracker(matcher, index, uidMap);
+ EXPECT_NE(tracker, nullptr);
+
+ // Combination matchers need to be initialized first.
+ EXPECT_FALSE(tracker->mInitialized);
+ EXPECT_EQ(tracker->getId(), id);
+ EXPECT_EQ(tracker->mIndex, index);
+ const set<int>& atomIds = tracker->getAtomIds();
+ ASSERT_EQ(atomIds.size(), 0);
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
index e384b6ac7c84..4fa4135e983f 100644
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
@@ -190,9 +190,9 @@ TEST(ShellSubscriberTest, testPulledSubscription) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
const vector<int32_t> uids = {AID_SYSTEM};
- EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _, _))
+ EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _))
.WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data, bool) {
+ vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid1, /*timeMillis=*/kCpuTime1));
data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid2, /*timeMillis=*/kCpuTime2));
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index cee83725d075..0be983f2a9b0 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -15,6 +15,8 @@
#include "statsd_test_util.h"
#include <aidl/android/util/StatsEventParcel.h>
+
+#include "matchers/SimpleLogMatchingTracker.h"
#include "stats_event.h"
using aidl::android::util::StatsEventParcel;
@@ -996,6 +998,20 @@ int64_t StringToId(const string& str) {
return static_cast<int64_t>(std::hash<std::string>()(str));
}
+sp<EventMatcherWizard> createEventMatcherWizard(
+ int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
+ sp<UidMap> uidMap = new UidMap();
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ for (const FieldValueMatcher& fvm : fieldValueMatchers) {
+ *atomMatcher.add_field_value_matcher() = fvm;
+ }
+ uint64_t matcherHash = 0x12345678;
+ int64_t matcherId = 678;
+ return new EventMatcherWizard({new SimpleLogMatchingTracker(matcherId, matcherIndex,
+ matcherHash, atomMatcher, uidMap)});
+}
+
void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
const int uid, const string& tag) {
EXPECT_EQ(value.field(), atomId);
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 3dcf4ecce054..1220019e2353 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -25,6 +25,7 @@
#include "src/StatsLogProcessor.h"
#include "src/hash.h"
#include "src/logd/LogEvent.h"
+#include "src/matchers/EventMatcherWizard.h"
#include "src/packages/UidMap.h"
#include "src/stats_log_util.h"
#include "stats_event.h"
@@ -335,6 +336,9 @@ void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
int64_t StringToId(const string& str);
+sp<EventMatcherWizard> createEventMatcherWizard(
+ int tagId, int matcherIndex, const std::vector<FieldValueMatcher>& fieldValueMatchers = {});
+
void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
const int uid, const string& tag);
void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);