diff options
Diffstat (limited to 'cmds')
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 Binary files differindex 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 diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk Binary files differindex c75f3e1dbddf..c8b95c2601ad 100644 --- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk +++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk Binary files differindex 93dcc82f9358..0a8b7372172e 100644 --- a/cmds/idmap2/tests/data/overlay/overlay-shared.apk +++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk Binary files differindex 5b8a6e4a90ed..fd41182f8493 100644 --- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk +++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk Binary files differindex 698a1fd6e702..b24765fc666a 100644 --- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk +++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk Binary files differindex 1db303ff05b5..870575efa10c 100644 --- a/cmds/idmap2/tests/data/overlay/overlay.apk +++ b/cmds/idmap2/tests/data/overlay/overlay.apk diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk Binary files differindex 51e19de082ed..e0fd20499671 100644 --- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk +++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk 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 Binary files differindex 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 diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk Binary files differindex a0fba4378b57..90d2803a1eca 100644 --- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk +++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk 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 Binary files differindex 58504a74a83a..cc3491de894d 100644 --- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk +++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk Binary files differindex c80e5eb65ff2..4a58c5e28f49 100644 --- a/cmds/idmap2/tests/data/target/target.apk +++ b/cmds/idmap2/tests/data/target/target.apk 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); |