Snap for 8820681 from 65cde24694b87599f693be7041e28c7538f2c66d to mainline-go-resolv-release
Change-Id: Ib2416baa3112daceea3a29cd9ae46d9e8b095f60
diff --git a/lib/libstatspull/Android.bp b/lib/libstatspull/Android.bp
index c0bc46d..60f237c 100644
--- a/lib/libstatspull/Android.bp
+++ b/lib/libstatspull/Android.bp
@@ -123,7 +123,7 @@
test_suites: ["general-tests", "mts-statsd"],
test_config: "libstatspull_test.xml",
- //TODO(b/153588990): Remove when the build system properly separates
+ //TODO(b/153588990): Remove when the build system properly separates
//32bit and 64bit architectures.
compile_multilib: "both",
multilib: {
diff --git a/lib/libstatspull/stats_pull_atom_callback.cpp b/lib/libstatspull/stats_pull_atom_callback.cpp
index f85db08..8a1c89b 100644
--- a/lib/libstatspull/stats_pull_atom_callback.cpp
+++ b/lib/libstatspull/stats_pull_atom_callback.cpp
@@ -14,13 +14,6 @@
* limitations under the License.
*/
-#include <map>
-#include <thread>
-#include <vector>
-
-#include <stats_event.h>
-#include <stats_pull_atom_callback.h>
-
#include <aidl/android/os/BnPullAtomCallback.h>
#include <aidl/android/os/IPullAtomResultReceiver.h>
#include <aidl/android/os/IStatsd.h>
@@ -28,6 +21,12 @@
#include <android/binder_auto_utils.h>
#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
+#include <stats_event.h>
+#include <stats_pull_atom_callback.h>
+
+#include <map>
+#include <thread>
+#include <vector>
using Status = ::ndk::ScopedAStatus;
using aidl::android::os::BnPullAtomCallback;
@@ -159,20 +158,20 @@
};
/**
- * @brief pullAtomMutex is used to guard simultaneous access to mPullers from below threads
+ * @brief pullersMutex is used to guard simultaneous access to pullers from below threads
* Main thread
* - AStatsManager_setPullAtomCallback()
* - AStatsManager_clearPullAtomCallback()
* Binder thread:
* - StatsdProvider::binderDied()
*/
-static std::mutex pullAtomMutex;
+static std::mutex pullersMutex;
-static std::map<int32_t, std::shared_ptr<StatsPullAtomCallbackInternal>> mPullers;
+static std::map<int32_t, std::shared_ptr<StatsPullAtomCallbackInternal>> pullers;
class StatsdProvider {
public:
- StatsdProvider() : deathRecipient(AIBinder_DeathRecipient_new(binderDied)) {
+ StatsdProvider() : mDeathRecipient(AIBinder_DeathRecipient_new(binderDied)) {
}
~StatsdProvider() {
@@ -180,21 +179,21 @@
}
std::shared_ptr<IStatsd> getStatsService() {
- std::lock_guard<std::mutex> lock(statsdMutex);
- if (!statsd) {
+ std::lock_guard<std::mutex> lock(mStatsdMutex);
+ if (!mStatsd) {
// Fetch statsd
::ndk::SpAIBinder binder(AServiceManager_getService("stats"));
- statsd = IStatsd::fromBinder(binder);
- if (statsd) {
- AIBinder_linkToDeath(binder.get(), deathRecipient.get(), this);
+ mStatsd = IStatsd::fromBinder(binder);
+ if (mStatsd) {
+ AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), this);
}
}
- return statsd;
+ return mStatsd;
}
void resetStatsService() {
- std::lock_guard<std::mutex> lock(statsdMutex);
- statsd = nullptr;
+ std::lock_guard<std::mutex> lock(mStatsdMutex);
+ mStatsd = nullptr;
}
static void binderDied(void* cookie) {
@@ -210,8 +209,8 @@
// copy of the data with the lock held before iterating through the map.
std::map<int32_t, std::shared_ptr<StatsPullAtomCallbackInternal>> pullersCopy;
{
- std::lock_guard<std::mutex> lock(pullAtomMutex);
- pullersCopy = mPullers;
+ std::lock_guard<std::mutex> lock(pullersMutex);
+ pullersCopy = pullers;
}
for (const auto& it : pullersCopy) {
statsService->registerNativePullAtomCallback(it.first, it.second->getCoolDownMillis(),
@@ -222,16 +221,16 @@
private:
/**
- * @brief statsdMutex is used to guard simultaneous access to statsd from below threads:
+ * @brief mStatsdMutex is used to guard simultaneous access to mStatsd from below threads:
* Work thread
* - registerStatsPullAtomCallbackBlocking()
* - unregisterStatsPullAtomCallbackBlocking()
* Binder thread:
* - StatsdProvider::binderDied()
*/
- std::mutex statsdMutex;
- std::shared_ptr<IStatsd> statsd;
- ::ndk::ScopedAIBinder_DeathRecipient deathRecipient;
+ std::mutex mStatsdMutex;
+ std::shared_ptr<IStatsd> mStatsd;
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
};
static std::shared_ptr<StatsdProvider> statsProvider = std::make_shared<StatsdProvider>();
@@ -276,9 +275,9 @@
timeoutMillis, additiveFields);
{
- std::lock_guard<std::mutex> lg(pullAtomMutex);
+ std::lock_guard<std::mutex> lock(pullersMutex);
// Always add to the map. If statsd is dead, we will add them when it comes back.
- mPullers[atom_tag] = callbackBinder;
+ pullers[atom_tag] = callbackBinder;
}
std::thread registerThread(registerStatsPullAtomCallbackBlocking, atom_tag, statsProvider,
@@ -288,10 +287,10 @@
void AStatsManager_clearPullAtomCallback(int32_t atom_tag) {
{
- std::lock_guard<std::mutex> lg(pullAtomMutex);
+ std::lock_guard<std::mutex> lock(pullersMutex);
// Always remove the puller from our map.
// If statsd is down, we will not register it when it comes back.
- mPullers.erase(atom_tag);
+ pullers.erase(atom_tag);
}
std::thread unregisterThread(unregisterStatsPullAtomCallbackBlocking, atom_tag, statsProvider);
diff --git a/lib/libstatssocket/statsd_writer.c b/lib/libstatssocket/statsd_writer.c
index c00c978..06695fe 100644
--- a/lib/libstatssocket/statsd_writer.c
+++ b/lib/libstatssocket/statsd_writer.c
@@ -76,7 +76,7 @@
static int statsdOpen();
static void statsdClose();
static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr);
-static void statsdNoteDrop();
+static void statsdNoteDrop(int error, int tag);
static int statsdIsClosed();
struct android_log_transport_write statsdLoggerWrite = {
diff --git a/statsd/src/flags/FlagProvider.h b/statsd/src/flags/FlagProvider.h
index dcdf35f..6684ba4 100644
--- a/statsd/src/flags/FlagProvider.h
+++ b/statsd/src/flags/FlagProvider.h
@@ -126,8 +126,7 @@
FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagEmptyDefaultTrue);
FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagTrue);
FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagFalse);
- FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse);
- FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue);
+ FRIEND_TEST(MetricsManagerTest_SPlus, TestAtomMatcherOptimizationEnabledFlag);
};
} // namespace statsd
diff --git a/statsd/src/main.cpp b/statsd/src/main.cpp
index 66b4389..cd64fe7 100644
--- a/statsd/src/main.cpp
+++ b/statsd/src/main.cpp
@@ -39,20 +39,12 @@
shared_ptr<StatsService> gStatsService = nullptr;
sp<StatsSocketListener> gSocketListener = nullptr;
+int gCtrlPipe[2];
void signalHandler(int sig) {
- if (sig == SIGPIPE) {
- // ShellSubscriber uses SIGPIPE as a signal to detect the end of the
- // client process. Don't prematurely exit(1) here. Instead, ignore the
- // signal and allow the write call to return EPIPE.
- ALOGI("statsd received SIGPIPE. Ignoring signal.");
- return;
- }
-
- if (gSocketListener != nullptr) gSocketListener->stopListener();
- if (gStatsService != nullptr) gStatsService->Terminate();
ALOGW("statsd terminated on receiving signal %d.", sig);
- exit(1);
+ const char c = 'q';
+ write(gCtrlPipe[1], &c, 1);
}
void registerSignalHandlers()
@@ -60,11 +52,15 @@
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
- sa.sa_handler = signalHandler;
+
+ sa.sa_handler = SIG_IGN;
+ // ShellSubscriber uses SIGPIPE as a signal to detect the end of the
+ // client process. Don't prematurely exit(1) here. Instead, ignore the
+ // signal and allow the write call to return EPIPE.
sigaction(SIGPIPE, &sa, nullptr);
- sigaction(SIGHUP, &sa, nullptr);
- sigaction(SIGINT, &sa, nullptr);
- sigaction(SIGQUIT, &sa, nullptr);
+
+ pipe2(gCtrlPipe, O_CLOEXEC);
+ sa.sa_handler = signalHandler;
sigaction(SIGTERM, &sa, nullptr);
}
@@ -94,8 +90,6 @@
return -1;
}
- registerSignalHandlers();
-
gStatsService->sayHiToStatsCompanion();
gStatsService->Startup();
@@ -108,6 +102,22 @@
exit(1);
}
+ // Use self-pipe to notify this thread to gracefully quit
+ // when receiving SIGTERM
+ registerSignalHandlers();
+ std::thread([] {
+ while (true) {
+ char c;
+ int i = read(gCtrlPipe[0], &c, 1);
+ if (i < 0) {
+ if (errno == EINTR) continue;
+ }
+ gSocketListener->stopListener();
+ gStatsService->Terminate();
+ exit(1);
+ }
+ }).detach();
+
// Loop forever -- the reports run on this thread in a handler, and the
// binder calls remain responsive in their pool of one thread.
while (true) {
diff --git a/statsd/src/matchers/matcher_util.cpp b/statsd/src/matchers/matcher_util.cpp
index 27b9fb2..20450dd 100644
--- a/statsd/src/matchers/matcher_util.cpp
+++ b/statsd/src/matchers/matcher_util.cpp
@@ -16,9 +16,12 @@
#define STATSD_DEBUG false // STOPSHIP if true
#include "Log.h"
-#include "src/statsd_config.pb.h"
-#include "matchers/AtomMatchingTracker.h"
#include "matchers/matcher_util.h"
+
+#include <fnmatch.h>
+
+#include "matchers/AtomMatchingTracker.h"
+#include "src/statsd_config.pb.h"
#include "stats_util.h"
using std::set;
@@ -97,6 +100,33 @@
return false;
}
+bool tryMatchWildcardString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
+ const string& wildcardPattern) {
+ if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
+ int uid = fieldValue.mValue.int_value;
+ // TODO(b/236886985): replace aid/uid mapping with efficient bidirectional container
+ // AidToUidMapping will never have uids above 10000
+ if (uid < 10000) {
+ for (auto aidIt = UidMap::sAidToUidMapping.begin();
+ aidIt != UidMap::sAidToUidMapping.end(); ++aidIt) {
+ if ((int)aidIt->second == uid) {
+ // Assumes there is only one aid mapping for each uid
+ return fnmatch(wildcardPattern.c_str(), aidIt->first.c_str(), 0) == 0;
+ }
+ }
+ }
+ std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
+ for (const auto& packageName : packageNames) {
+ if (fnmatch(wildcardPattern.c_str(), packageName.c_str(), 0) == 0) {
+ return true;
+ }
+ }
+ } else if (fieldValue.mValue.getType() == STRING) {
+ return fnmatch(wildcardPattern.c_str(), fieldValue.mValue.str_value.c_str(), 0) == 0;
+ }
+ return false;
+}
+
bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher,
const vector<FieldValue>& values, int start, int end, int depth) {
if (depth > 2) {
@@ -237,13 +267,18 @@
case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
const auto& str_list = matcher.neq_any_string();
for (int i = start; i < end; i++) {
+ bool notEqAll = true;
for (const auto& str : str_list.str_value()) {
if (tryMatchString(uidMap, values[i], str)) {
- return false;
+ notEqAll = false;
+ break;
}
}
+ if (notEqAll) {
+ return true;
+ }
}
- return true;
+ return false;
}
case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
const auto& str_list = matcher.eq_any_string();
@@ -256,6 +291,41 @@
}
return false;
}
+ case FieldValueMatcher::ValueMatcherCase::kEqWildcardString: {
+ for (int i = start; i < end; i++) {
+ if (tryMatchWildcardString(uidMap, values[i], matcher.eq_wildcard_string())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ case FieldValueMatcher::ValueMatcherCase::kEqAnyWildcardString: {
+ const auto& str_list = matcher.eq_any_wildcard_string();
+ for (int i = start; i < end; i++) {
+ for (const auto& str : str_list.str_value()) {
+ if (tryMatchWildcardString(uidMap, values[i], str)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ case FieldValueMatcher::ValueMatcherCase::kNeqAnyWildcardString: {
+ const auto& str_list = matcher.neq_any_wildcard_string();
+ for (int i = start; i < end; i++) {
+ bool notEqAll = true;
+ for (const auto& str : str_list.str_value()) {
+ if (tryMatchWildcardString(uidMap, values[i], str)) {
+ notEqAll = false;
+ break;
+ }
+ }
+ if (notEqAll) {
+ return true;
+ }
+ }
+ return false;
+ }
case FieldValueMatcher::ValueMatcherCase::kEqInt: {
for (int i = start; i < end; i++) {
if (values[i].mValue.getType() == INT &&
@@ -270,6 +340,46 @@
}
return false;
}
+ case FieldValueMatcher::ValueMatcherCase::kEqAnyInt: {
+ const auto& int_list = matcher.eq_any_int();
+ for (int i = start; i < end; i++) {
+ for (const int int_value : int_list.int_value()) {
+ if (values[i].mValue.getType() == INT &&
+ (int_value == values[i].mValue.int_value)) {
+ return true;
+ }
+ // eq_any_int covers both int and long.
+ if (values[i].mValue.getType() == LONG &&
+ (int_value == values[i].mValue.long_value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ case FieldValueMatcher::ValueMatcherCase::kNeqAnyInt: {
+ const auto& int_list = matcher.neq_any_int();
+ for (int i = start; i < end; i++) {
+ bool notEqAll = true;
+ for (const int int_value : int_list.int_value()) {
+ if (values[i].mValue.getType() == INT &&
+ (int_value == values[i].mValue.int_value)) {
+ notEqAll = false;
+ break;
+ }
+ // neq_any_int covers both int and long.
+ if (values[i].mValue.getType() == LONG &&
+ (int_value == values[i].mValue.long_value)) {
+ notEqAll = false;
+ break;
+ }
+ }
+ if (notEqAll) {
+ return true;
+ }
+ }
+ return false;
+ }
case FieldValueMatcher::ValueMatcherCase::kLtInt: {
for (int i = start; i < end; i++) {
if (values[i].mValue.getType() == INT &&
diff --git a/statsd/src/metrics/MetricsManager.h b/statsd/src/metrics/MetricsManager.h
index 1eccf8d..c855a05 100644
--- a/statsd/src/metrics/MetricsManager.h
+++ b/statsd/src/metrics/MetricsManager.h
@@ -347,10 +347,9 @@
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
- FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse);
- FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue);
FRIEND_TEST(MetricsManagerTest, TestLogSources);
FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate);
+ FRIEND_TEST(MetricsManagerTest_SPlus, TestAtomMatcherOptimizationEnabledFlag);
FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
diff --git a/statsd/src/statsd_config.proto b/statsd/src/statsd_config.proto
index be733b4..b75b670 100644
--- a/statsd/src/statsd_config.proto
+++ b/statsd/src/statsd_config.proto
@@ -78,6 +78,12 @@
StringListMatcher eq_any_string = 13;
StringListMatcher neq_any_string = 14;
+ IntListMatcher eq_any_int = 15;
+ IntListMatcher neq_any_int = 16;
+
+ string eq_wildcard_string = 17;
+ StringListMatcher eq_any_wildcard_string = 18;
+ StringListMatcher neq_any_wildcard_string = 19;
}
}
@@ -89,6 +95,10 @@
repeated string str_value = 1;
}
+message IntListMatcher {
+ repeated int64 int_value = 1;
+}
+
enum LogicalOperation {
LOGICAL_OPERATION_UNSPECIFIED = 0;
AND = 1;
diff --git a/statsd/tests/LogEntryMatcher_test.cpp b/statsd/tests/LogEntryMatcher_test.cpp
index 8a4fb19..d0a063f 100644
--- a/statsd/tests/LogEntryMatcher_test.cpp
+++ b/statsd/tests/LogEntryMatcher_test.cpp
@@ -948,7 +948,7 @@
fieldValueMatcher->set_position(Position::LAST);
EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
fieldValueMatcher->set_position(Position::ANY);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
neqStringList->add_str_value("str3");
fieldValueMatcher->set_position(Position::FIRST);
@@ -956,7 +956,7 @@
fieldValueMatcher->set_position(Position::LAST);
EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
fieldValueMatcher->set_position(Position::ANY);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
neqStringList->add_str_value("str1");
fieldValueMatcher->set_position(Position::FIRST);
@@ -1204,6 +1204,303 @@
matcherResults.push_back(MatchingState::kMatched);
EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
}
+
+TEST(AtomMatcherTest, TestUidFieldMatcherWithWildcardString) {
+ 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")},
+ {android::String16("package0"), android::String16("pkg1"), android::String16("pkg1"),
+ android::String16("package2"), android::String16("package3")} /* package name list */,
+ {android::String16(""), android::String16(""), android::String16(""),
+ android::String16(""), android::String16("")},
+ /* certificateHash */ {{}, {}, {}, {}, {}});
+
+ // Set up matcher
+ AtomMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+ simpleMatcher->add_field_value_matcher()->set_field(1);
+ simpleMatcher->mutable_field_value_matcher(0)->set_eq_wildcard_string("pkg*");
+
+ // Event without is_uid annotation.
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ makeIntLogEvent(&event1, TAG_ID, 0, 1111);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
+
+ // Event where mapping from uid to package name occurs.
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID, 1111, ANNOTATION_ID_IS_UID, true);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
+
+ // Event where uid maps to package names that don't fit wildcard pattern.
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event3, TAG_ID, 3333, ANNOTATION_ID_IS_UID, true);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event3));
+
+ // Update matcher to match one AID
+ simpleMatcher->mutable_field_value_matcher(0)->set_eq_wildcard_string(
+ "AID_SYSTEM"); // uid 1000
+
+ // Event where mapping from uid to aid doesn't fit wildcard pattern.
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event4, TAG_ID, 1005, ANNOTATION_ID_IS_UID, true);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4));
+
+ // Event where mapping from uid to aid does fit wildcard pattern.
+ LogEvent event5(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event5, TAG_ID, 1000, ANNOTATION_ID_IS_UID, true);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event5));
+
+ // Update matcher to match multiple AIDs
+ simpleMatcher->mutable_field_value_matcher(0)->set_eq_wildcard_string("AID_SDCARD_*");
+
+ // Event where mapping from uid to aid doesn't fit wildcard pattern.
+ LogEvent event6(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event6, TAG_ID, 1036, ANNOTATION_ID_IS_UID, true);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event6));
+
+ // Event where mapping from uid to aid does fit wildcard pattern.
+ LogEvent event7(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event7, TAG_ID, 1034, ANNOTATION_ID_IS_UID, true);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event7));
+
+ LogEvent event8(/*uid=*/0, /*pid=*/0);
+ makeIntWithBoolAnnotationLogEvent(&event8, TAG_ID, 1035, ANNOTATION_ID_IS_UID, true);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event8));
+}
+
+TEST(AtomMatcherTest, TestWildcardStringMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+ // Set up the matcher
+ AtomMatcher matcher;
+ SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+ FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
+ fieldValueMatcher->set_field(FIELD_ID_1);
+ // Matches any string that begins with "test.string:test_" and ends with number between 0 and 9
+ // inclusive
+ fieldValueMatcher->set_eq_wildcard_string("test.string:test_[0-9]");
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event1, TAG_ID, 0, "test.string:test_0");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event1));
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event2, TAG_ID, 0, "test.string:test_19");
+ EXPECT_FALSE(
+ matchesSimple(uidMap, *simpleMatcher, event2)); // extra character at end of string
+
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event3, TAG_ID, 0, "extra.test.string:test_1");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher,
+ event3)); // extra characters at beginning of string
+
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event4, TAG_ID, 0, "test.string:test_");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher,
+ event4)); // missing character from 0-9 at end of string
+
+ LogEvent event5(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event5, TAG_ID, 0, "est.string:test_1");
+ EXPECT_FALSE(
+ matchesSimple(uidMap, *simpleMatcher, event5)); // missing 't' at beginning of string
+
+ LogEvent event6(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event6, TAG_ID, 0, "test.string:test_1extra");
+ EXPECT_FALSE(
+ matchesSimple(uidMap, *simpleMatcher, event6)); // extra characters at end of string
+
+ // Matches any string that contains "test.string:test_" + any extra characters before or after
+ fieldValueMatcher->set_eq_wildcard_string("*test.string:test_*");
+
+ LogEvent event7(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event7, TAG_ID, 0, "test.string:test_");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event7));
+
+ LogEvent event8(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event8, TAG_ID, 0, "extra.test.string:test_");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event8));
+
+ LogEvent event9(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event9, TAG_ID, 0, "test.string:test_extra");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event9));
+
+ LogEvent event10(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event10, TAG_ID, 0, "est.string:test_");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event10));
+
+ LogEvent event11(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event11, TAG_ID, 0, "test.string:test");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event11));
+}
+
+TEST(AtomMatcherTest, TestEqAnyWildcardStringMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+
+ // Set up the matcher
+ AtomMatcher matcher;
+ SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+
+ FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
+ fieldValueMatcher->set_field(FIELD_ID_1);
+ StringListMatcher* eqWildcardStrList = fieldValueMatcher->mutable_eq_any_wildcard_string();
+ eqWildcardStrList->add_str_value("first_string_*");
+ eqWildcardStrList->add_str_value("second_string_*");
+
+ // First wildcard pattern matched.
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event1, TAG_ID, 0, "first_string_1");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event1));
+
+ // Second wildcard pattern matched.
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event2, TAG_ID, 0, "second_string_1");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
+
+ // No wildcard patterns matched.
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ makeStringLogEvent(&event3, TAG_ID, 0, "third_string_1");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event3));
+}
+
+TEST(AtomMatcherTest, TestNeqAnyWildcardStringMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+
+ // Set up the log event.
+ std::vector<int> attributionUids = {1111, 2222, 3333};
+ std::vector<string> attributionTags = {"location_1", "location_2", "location"};
+ LogEvent event(/*uid=*/0, /*pid=*/0);
+ makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
+
+ // Set up the matcher. Match first tag.
+ AtomMatcher matcher;
+ SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+ FieldValueMatcher* attributionMatcher = simpleMatcher->add_field_value_matcher();
+ attributionMatcher->set_field(FIELD_ID_1);
+ attributionMatcher->set_position(Position::FIRST);
+ FieldValueMatcher* attributionTagMatcher =
+ attributionMatcher->mutable_matches_tuple()->add_field_value_matcher();
+ attributionTagMatcher->set_field(ATTRIBUTION_TAG_FIELD_ID);
+ StringListMatcher* neqWildcardStrList =
+ attributionTagMatcher->mutable_neq_any_wildcard_string();
+
+ // First tag is not matched. neq string list {"tag"}
+ neqWildcardStrList->add_str_value("tag");
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // First tag is matched. neq string list {"tag", "location_*"}
+ neqWildcardStrList->add_str_value("location_*");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Match last tag.
+ attributionMatcher->set_position(Position::LAST);
+
+ // Last tag is not matched. neq string list {"tag", "location_*"}
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Last tag is matched. neq string list {"tag", "location_*", "location*"}
+ neqWildcardStrList->add_str_value("location*");
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Match any tag.
+ attributionMatcher->set_position(Position::ANY);
+
+ // All tags are matched. neq string list {"tag", "location_*", "location*"}
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Set up another log event.
+ std::vector<string> attributionTags2 = {"location_1", "location", "string"};
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ makeAttributionLogEvent(&event2, TAG_ID, 0, attributionUids, attributionTags2, "some value");
+
+ // Tag "string" is not matched. neq string list {"tag", "location_*", "location*"}
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
+}
+
+TEST(AtomMatcherTest, TestEqAnyIntMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+
+ // Set up the matcher
+ AtomMatcher matcher;
+ SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+
+ FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
+ fieldValueMatcher->set_field(FIELD_ID_1);
+ IntListMatcher* eqIntList = fieldValueMatcher->mutable_eq_any_int();
+ eqIntList->add_int_value(3);
+ eqIntList->add_int_value(5);
+
+ // First int matched.
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ makeIntLogEvent(&event1, TAG_ID, 0, 3);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event1));
+
+ // Second int matched.
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ makeIntLogEvent(&event2, TAG_ID, 0, 5);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
+
+ // No ints matched.
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ makeIntLogEvent(&event3, TAG_ID, 0, 4);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event3));
+}
+
+TEST(AtomMatcherTest, TestNeqAnyIntMatcher) {
+ sp<UidMap> uidMap = new UidMap();
+
+ // Set up the log event.
+ std::vector<int> attributionUids = {1111, 2222, 3333};
+ std::vector<string> attributionTags = {"location1", "location2", "location3"};
+ LogEvent event(/*uid=*/0, /*pid=*/0);
+ makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
+
+ // Set up the matcher. Match first uid.
+ AtomMatcher matcher;
+ SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
+ simpleMatcher->set_atom_id(TAG_ID);
+ FieldValueMatcher* attributionMatcher = simpleMatcher->add_field_value_matcher();
+ attributionMatcher->set_field(FIELD_ID_1);
+ attributionMatcher->set_position(Position::FIRST);
+ FieldValueMatcher* attributionUidMatcher =
+ attributionMatcher->mutable_matches_tuple()->add_field_value_matcher();
+ attributionUidMatcher->set_field(ATTRIBUTION_UID_FIELD_ID);
+ IntListMatcher* neqIntList = attributionUidMatcher->mutable_neq_any_int();
+
+ // First uid is not matched. neq int list {4444}
+ neqIntList->add_int_value(4444);
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // First uid is matched. neq int list {4444, 1111}
+ neqIntList->add_int_value(1111);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Match last uid.
+ attributionMatcher->set_position(Position::LAST);
+
+ // Last uid is not matched. neq int list {4444, 1111}
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Last uid is matched. neq int list {4444, 1111, 3333}
+ neqIntList->add_int_value(3333);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // Match any uid.
+ attributionMatcher->set_position(Position::ANY);
+
+ // Uid 2222 is not matched. neq int list {4444, 1111, 3333}
+ EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+ // All uids are matched. neq int list {4444, 1111, 3333, 2222}
+ neqIntList->add_int_value(2222);
+ EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+}
+
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/statsd/tests/MetricsManager_test.cpp b/statsd/tests/MetricsManager_test.cpp
index 5cab800..9650f2d 100644
--- a/statsd/tests/MetricsManager_test.cpp
+++ b/statsd/tests/MetricsManager_test.cpp
@@ -35,6 +35,7 @@
using namespace testing;
using android::sp;
+using android::modules::sdklevel::IsAtLeastS;
using android::os::statsd::Predicate;
using std::map;
using std::set;
@@ -264,8 +265,55 @@
UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_ADB}})));
}
-TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse) {
- FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_FALSE,
+struct MetricsManagerServerFlagParam {
+ string flagValue;
+ string label;
+};
+
+class MetricsManagerTest_SPlus
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<MetricsManagerServerFlagParam> {
+protected:
+ void SetUp() override {
+ if (shouldSkipTest()) {
+ GTEST_SKIP() << skipReason();
+ }
+
+ originalFlagValue = FlagProvider::getInstance().getFlagString(
+ OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_EMPTY);
+ }
+
+ bool shouldSkipTest() const {
+ return !IsAtLeastS();
+ }
+
+ string skipReason() const {
+ return "Skipping MetricsManagerTest_SPlus because device is not S+";
+ }
+
+ void TearDown() override {
+ if (originalFlagValue) {
+ writeFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, originalFlagValue.value());
+ }
+ }
+
+ std::optional<string> originalFlagValue;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ MetricsManagerTest_SPlus, MetricsManagerTest_SPlus,
+ testing::ValuesIn<MetricsManagerServerFlagParam>({
+ // Server flag values
+ {FLAG_TRUE, "ServerFlagTrue"},
+ {FLAG_FALSE, "ServerFlagFalse"},
+ }),
+ [](const testing::TestParamInfo<MetricsManagerTest_SPlus::ParamType>& info) {
+ return info.param.label;
+ });
+
+TEST_P(MetricsManagerTest_SPlus, TestAtomMatcherOptimizationEnabledFlag) {
+ FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG,
+ GetParam().flagValue,
/*isBootFlag=*/true);
sp<UidMap> uidMap;
@@ -277,23 +325,11 @@
MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
- EXPECT_FALSE(metricsManager.mAtomMatcherOptimizationEnabled);
-}
-
-TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue) {
- FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_TRUE,
- /*isBootFlag=*/true);
-
- sp<UidMap> uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- EXPECT_TRUE(metricsManager.mAtomMatcherOptimizationEnabled);
+ if (GetParam().flagValue == FLAG_TRUE) {
+ EXPECT_TRUE(metricsManager.mAtomMatcherOptimizationEnabled);
+ } else {
+ EXPECT_FALSE(metricsManager.mAtomMatcherOptimizationEnabled);
+ }
}
TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
diff --git a/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
index d02d2c4..06034cb 100644
--- a/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ b/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
@@ -76,6 +76,7 @@
"com.google.android.apps.nexuslauncher",
"AID_KEYSTORE",
"AID_VIRTUALIZATIONSERVICE",
+ "com.google.android.permissioncontroller",
};
private static final String[] DEFAULT_PULL_SOURCES = {
"AID_KEYSTORE",