Add .filter option to event queries.
Test: atest EventLibTest
Bug: 170458200
Change-Id: Ia88323722ef5d4275096439eb5f8da5bbd684b35
diff --git a/common/device-side/eventlib/Android.bp b/common/device-side/eventlib/Android.bp
index a98bdaa..03add1f 100644
--- a/common/device-side/eventlib/Android.bp
+++ b/common/device-side/eventlib/Android.bp
@@ -14,6 +14,9 @@
srcs: [
"src/test/java/**/*.java"
],
+ test_suites: [
+ "general-tests",
+ ],
static_libs: ["EventLib", "androidx.test.ext.junit", "ctstestrunner-axt", "truth-prebuilt"],
manifest: "src/test/AndroidManifest.xml",
}
\ No newline at end of file
diff --git a/common/device-side/eventlib/TEST_MAPPING b/common/device-side/eventlib/TEST_MAPPING
new file mode 100644
index 0000000..c19ccac
--- /dev/null
+++ b/common/device-side/eventlib/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "EventLibTest"
+ }
+ ]
+}
diff --git a/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogs.java b/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogs.java
index 29cfd5b..cd2c766 100644
--- a/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogs.java
+++ b/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogs.java
@@ -27,12 +27,6 @@
private static Instant sEarliestLogTime = null;
- /** Returns the specific implementation of {@link Event} being queried for. */
- protected abstract Class<E> eventClass();
-
- /** Returns true if {@code E} matches the custom filters for this {@link Event} subclass. */
- protected abstract boolean filter(E event);
-
/**
* Returns the {@link EventQuerier} to be used to interact with the
* appropriate {@link Event} store.
diff --git a/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java b/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java
index fc16085..dad7a6e 100644
--- a/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java
+++ b/common/device-side/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java
@@ -20,6 +20,10 @@
import androidx.test.platform.app.InstrumentationRegistry;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Function;
+
/**
* Interface to provide additional restrictions on an {@link Event} query.
*/
@@ -47,6 +51,7 @@
private final Class<E> mEventClass;
private final String mPackageName;
+ private final Set<Function<E, Boolean>> filters = new HashSet<>();
protected EventLogsQuery(Class<E> eventClass, String packageName) {
if (eventClass == null || packageName == null) {
@@ -64,7 +69,6 @@
return mPackageName;
}
- @Override
protected Class<E> eventClass() {
return mEventClass;
}
@@ -76,4 +80,24 @@
protected EventQuerier<E> getQuerier() {
return mQuerier;
}
+
+ public F filter(Function<E, Boolean> filter) {
+ filters.add(filter);
+ return (F) this;
+ }
+
+ /**
+ * Returns true if {@code E} matches custom and default filters for this {@link Event} subclass.
+ */
+ protected final boolean filterAll(E event) {
+ for (Function<E, Boolean> filter : filters) {
+ if (!filter.apply(event)) {
+ return false;
+ }
+ }
+ return filter(event);
+ }
+
+ /** Returns true if {@code E} matches the custom filters for this {@link Event} subclass. */
+ protected abstract boolean filter(E event);
}
diff --git a/common/device-side/eventlib/src/main/java/com/android/eventlib/LocalEventQuerier.java b/common/device-side/eventlib/src/main/java/com/android/eventlib/LocalEventQuerier.java
index 8780563..b98d250 100644
--- a/common/device-side/eventlib/src/main/java/com/android/eventlib/LocalEventQuerier.java
+++ b/common/device-side/eventlib/src/main/java/com/android/eventlib/LocalEventQuerier.java
@@ -28,12 +28,12 @@
/**
* Implementation of {@link EventQuerier} which queries data about the current package.
*/
-public class LocalEventQuerier<E extends Event> implements EventQuerier<E>, Events.EventListener {
- private final EventLogs<E> mEventLogs;
+public class LocalEventQuerier<E extends Event, F extends EventLogsQuery> implements EventQuerier<E>, Events.EventListener {
+ private final EventLogsQuery<E, F> mEventLogsQuery;
private final BlockingDeque<Event> mEvents;
- LocalEventQuerier(EventLogs<E> eventLogs) {
- mEventLogs = eventLogs;
+ LocalEventQuerier(EventLogsQuery<E, F> eventLogsQuery) {
+ mEventLogsQuery = eventLogsQuery;
mEvents = new LinkedBlockingDeque<>(Events.EVENTS.getEvents());
Events.EVENTS.registerEventListener(this);
}
@@ -41,13 +41,13 @@
@Override
public E get(Instant earliestLogTime) {
for (Event event : Events.EVENTS.getEvents()) {
- if (mEventLogs.eventClass().isInstance(event)) {
+ if (mEventLogsQuery.eventClass().isInstance(event)) {
if (event.mTimestamp.isBefore(earliestLogTime)) {
continue;
}
E typedEvent = (E) event;
- if (mEventLogs.filter(typedEvent)) {
+ if (mEventLogsQuery.filterAll(typedEvent)) {
return typedEvent;
}
}
@@ -60,13 +60,13 @@
while (!mEvents.isEmpty()) {
Event event = mEvents.removeFirst();
- if (mEventLogs.eventClass().isInstance(event)) {
+ if (mEventLogsQuery.eventClass().isInstance(event)) {
if (event.mTimestamp.isBefore(earliestLogTime)) {
continue;
}
E typedEvent = (E) event;
- if (mEventLogs.filter(typedEvent)) {
+ if (mEventLogsQuery.filterAll(typedEvent)) {
return typedEvent;
}
}
@@ -92,13 +92,13 @@
return null;
}
- if (mEventLogs.eventClass().isInstance(event)) {
+ if (mEventLogsQuery.eventClass().isInstance(event)) {
if (event.mTimestamp.isBefore(earliestLogTime)) {
continue;
}
E typedEvent = (E) event;
- if (mEventLogs.filter(typedEvent)) {
+ if (mEventLogsQuery.filterAll(typedEvent)) {
return typedEvent;
}
}
diff --git a/common/device-side/eventlib/src/test/java/com/android/eventlib/EventLogsTest.java b/common/device-side/eventlib/src/test/java/com/android/eventlib/EventLogsTest.java
index afc9ecd..7c5361e 100644
--- a/common/device-side/eventlib/src/test/java/com/android/eventlib/EventLogsTest.java
+++ b/common/device-side/eventlib/src/test/java/com/android/eventlib/EventLogsTest.java
@@ -417,6 +417,121 @@
assertThat(eventLogs1.poll()).isEqualTo(eventLogs2.poll());
}
+ @Test
+ public void get_obeysLambdaFilter() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()));
+
+ assertThat(eventLogs.get().tag()).isEqualTo(TEST_TAG2);
+ }
+
+ @Test
+ public void poll_obeysLambdaFilter() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()));
+
+ assertThat(eventLogs.poll().tag()).isEqualTo(TEST_TAG2);
+ assertThat(eventLogs.poll(VERY_SHORT_POLL_WAIT)).isNull();
+ }
+
+ @Test
+ public void next_obeysLambdaFilter() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()));
+
+ assertThat(eventLogs.next().tag()).isEqualTo(TEST_TAG2);
+ assertThat(eventLogs.next()).isNull();
+ }
+
+ @Test
+ public void get_obeysMultipleLambdaFilters() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .setData(DATA_1)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()))
+ .filter(e -> DATA_1.equals(e.data()));
+
+ CustomEvent event = eventLogs.get();
+ assertThat(event.tag()).isEqualTo(TEST_TAG2);
+ assertThat(event.data()).isEqualTo(DATA_1);
+ }
+
+ @Test
+ public void poll_obeysMultipleLambdaFilters() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .setData(DATA_1)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()))
+ .filter(e -> DATA_1.equals(e.data()));
+
+ CustomEvent event = eventLogs.poll();
+ assertThat(event.tag()).isEqualTo(TEST_TAG2);
+ assertThat(event.data()).isEqualTo(DATA_1);
+ assertThat(eventLogs.poll(VERY_SHORT_POLL_WAIT)).isNull();
+ }
+
+ @Test
+ public void next_obeysMultipleLambdaFilters() {
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG1)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .log();
+ CustomEvent.logger(CONTEXT)
+ .setTag(TEST_TAG2)
+ .setData(DATA_1)
+ .log();
+
+ EventLogs<CustomEvent> eventLogs = CustomEvent.queryPackage(CONTEXT.getPackageName())
+ .filter(e -> TEST_TAG2.equals(e.tag()))
+ .filter(e -> DATA_1.equals(e.data()));
+
+ CustomEvent event = eventLogs.next();
+ assertThat(event.tag()).isEqualTo(TEST_TAG2);
+ assertThat(event.data()).isEqualTo(DATA_1);
+ assertThat(eventLogs.next()).isNull();
+ }
+
private void scheduleCustomEventInOneSecond() {
hasScheduledEvents = true;
new Handler(Looper.getMainLooper()).postDelayed(() ->