summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt6
-rw-r--r--core/java/android/app/usage/UsageEventsQuery.java51
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java5
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/src/android/app/usage/UsageEventsQueryTest.java25
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java2
6 files changed, 53 insertions, 37 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index f55de5ae2d26..91cc9f99b44e 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9379,15 +9379,15 @@ package android.app.usage {
method public int describeContents();
method public long getBeginTimeMillis();
method public long getEndTimeMillis();
- method @NonNull public java.util.Set<java.lang.Integer> getEventTypes();
+ method @NonNull public int[] getEventTypes();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.usage.UsageEventsQuery> CREATOR;
}
public static final class UsageEventsQuery.Builder {
ctor public UsageEventsQuery.Builder(long, long);
- method @NonNull public android.app.usage.UsageEventsQuery.Builder addEventTypes(@NonNull int...);
method @NonNull public android.app.usage.UsageEventsQuery build();
+ method @NonNull public android.app.usage.UsageEventsQuery.Builder setEventTypes(@NonNull int...);
}
public final class UsageStats implements android.os.Parcelable {
@@ -9414,7 +9414,7 @@ package android.app.usage {
method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long);
method public java.util.List<android.app.usage.EventStats> queryEventStats(int, long, long);
method public android.app.usage.UsageEvents queryEvents(long, long);
- method @FlaggedApi("android.app.usage.filter_based_event_query_api") @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public android.app.usage.UsageEvents queryEvents(@NonNull android.app.usage.UsageEventsQuery);
+ method @FlaggedApi("android.app.usage.filter_based_event_query_api") @Nullable @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public android.app.usage.UsageEvents queryEvents(@NonNull android.app.usage.UsageEventsQuery);
method public android.app.usage.UsageEvents queryEventsForSelf(long, long);
method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long);
field @FlaggedApi("android.app.usage.user_interaction_type_api") public static final String EXTRA_EVENT_ACTION = "android.app.usage.extra.EVENT_ACTION";
diff --git a/core/java/android/app/usage/UsageEventsQuery.java b/core/java/android/app/usage/UsageEventsQuery.java
index 3cd292392694..df6324f744a8 100644
--- a/core/java/android/app/usage/UsageEventsQuery.java
+++ b/core/java/android/app/usage/UsageEventsQuery.java
@@ -29,9 +29,6 @@ import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
/**
* An Object-Oriented representation for a {@link UsageEvents} query.
@@ -77,19 +74,17 @@ public final class UsageEventsQuery implements Parcelable {
}
/**
- * Returns the set of usage event types for the query.
- * <em>Note: An empty set indicates query for all usage events. </em>
+ * Retrieves the usage event types for the query.
+ * <p>Note that an empty array indicates querying all usage event types, and it may
+ * cause additional system overhead when calling
+ * {@link UsageStatsManager#queryEvents(UsageEventsQuery)}. Apps are encouraged to
+ * provide a list of event types via {@link Builder#setEventTypes(int...)}</p>
+ *
+ * @return an array contains the usage event types that was previously set using
+ * {@link Builder#setEventTypes(int...)} or an empty array if no value has been set.
*/
- public @NonNull Set<Integer> getEventTypes() {
- if (ArrayUtils.isEmpty(mEventTypes)) {
- return Collections.emptySet();
- }
-
- HashSet<Integer> eventTypeSet = new HashSet<>();
- for (int eventType : mEventTypes) {
- eventTypeSet.add(eventType);
- }
- return eventTypeSet;
+ public @NonNull @Event.EventType int[] getEventTypes() {
+ return Arrays.copyOf(mEventTypes, mEventTypes.length);
}
/** @hide */
@@ -125,11 +120,6 @@ public final class UsageEventsQuery implements Parcelable {
}
};
- /** @hide */
- public int[] getEventTypeFilter() {
- return Arrays.copyOf(mEventTypes, mEventTypes.length);
- }
-
/**
* Builder for UsageEventsQuery.
*/
@@ -166,12 +156,25 @@ public final class UsageEventsQuery implements Parcelable {
}
/**
- * Specifies the list of usage event types to be included in the query.
- * @param eventTypes List of the usage event types. See {@link UsageEvents.Event}
+ * Sets the list of usage event types to be included in the query.
+ *
+ * <p>Note: </p> An empty array will be returned by
+ * {@link UsageEventsQuery#getEventTypes()} without calling this method, which indicates
+ * querying for all event types. Apps are encouraged to provide a list of event types.
+ * Only the matching types supplied will be used to query.
*
- * @throws llegalArgumentException if the event type is not valid.
+ * @param eventTypes the array of the usage event types. See {@link UsageEvents.Event}.
+ * @throws NullPointerException if {@code eventTypes} is {@code null} or empty.
+ * @throws IllegalArgumentException if any of event types are invalid.
+ * @see UsageEventsQuery#getEventTypes()
+ * @see UsageStatsManager#queryEvents(UsageEventsQuery)
*/
- public @NonNull Builder addEventTypes(@NonNull @Event.EventType int... eventTypes) {
+ public @NonNull Builder setEventTypes(@NonNull @Event.EventType int... eventTypes) {
+ if (eventTypes == null || eventTypes.length == 0) {
+ throw new NullPointerException("eventTypes is null or empty");
+ }
+
+ mEventTypes.clear();
for (int i = 0; i < eventTypes.length; i++) {
final int eventType = eventTypes[i];
if (eventType < Event.NONE || eventType > Event.MAX_EVENT_TYPE) {
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 85d223d01ee8..8df913a4ca63 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -602,14 +602,15 @@ public final class UsageStatsManager {
/**
* Query for events with specific UsageEventsQuery object.
+ *
* <em>Note: if the user's device is not in an unlocked state (as defined by
* {@link UserManager#isUserUnlocked()}), then {@code null} will be returned.</em>
*
* @param query The query object used to specify the query parameters.
- * @return A {@link UsageEvents}.
+ * @return A {@link UsageEvents} which contains the events matching the query parameters.
*/
@FlaggedApi(Flags.FLAG_FILTER_BASED_EVENT_QUERY_API)
- @NonNull
+ @Nullable
@RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
public UsageEvents queryEvents(@NonNull UsageEventsQuery query) {
try {
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index e18de2e66399..d1a90aea835c 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -62,6 +62,7 @@ android_test {
"frameworks-core-util-lib",
"mockwebserver",
"guava",
+ "android.app.usage.flags-aconfig-java",
"android.view.accessibility.flags-aconfig-java",
"androidx.core_core",
"androidx.core_core-ktx",
diff --git a/core/tests/coretests/src/android/app/usage/UsageEventsQueryTest.java b/core/tests/coretests/src/android/app/usage/UsageEventsQueryTest.java
index 839b645cf352..4565978434ee 100644
--- a/core/tests/coretests/src/android/app/usage/UsageEventsQueryTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageEventsQueryTest.java
@@ -15,24 +15,34 @@
*/
package android.app.usage;
+import static android.app.usage.Flags.FLAG_FILTER_BASED_EVENT_QUERY_API;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.app.usage.UsageEvents.Event;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Random;
-import java.util.Set;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class UsageEventsQueryTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Test
+ @RequiresFlagsEnabled(FLAG_FILTER_BASED_EVENT_QUERY_API)
public void testQueryDuration() {
// Test with negative beginTimeMillis.
long beginTimeMillis = -100;
@@ -97,6 +107,7 @@ public class UsageEventsQueryTest {
}
@Test
+ @RequiresFlagsEnabled(FLAG_FILTER_BASED_EVENT_QUERY_API)
public void testQueryEventTypes() {
Random rnd = new Random();
UsageEventsQuery.Builder queryBuilder = new UsageEventsQuery.Builder(1000, 2000);
@@ -104,7 +115,7 @@ public class UsageEventsQueryTest {
// Test with invalid event type.
int eventType = Event.NONE - 1;
try {
- queryBuilder.addEventTypes(eventType);
+ queryBuilder.setEventTypes(eventType);
fail("Invalid event type: " + eventType);
} catch (IllegalArgumentException e) {
// Expected, fall through.
@@ -112,7 +123,7 @@ public class UsageEventsQueryTest {
eventType = Event.MAX_EVENT_TYPE + 1;
try {
- queryBuilder.addEventTypes(eventType);
+ queryBuilder.setEventTypes(eventType);
fail("Invalid event type: " + eventType);
} catch (IllegalArgumentException e) {
// Expected, fall through.
@@ -121,11 +132,11 @@ public class UsageEventsQueryTest {
// Test with valid and duplicate event types.
eventType = rnd.nextInt(Event.MAX_EVENT_TYPE + 1);
try {
- UsageEventsQuery query = queryBuilder.addEventTypes(eventType, eventType, eventType)
+ UsageEventsQuery query = queryBuilder.setEventTypes(eventType, eventType, eventType)
.build();
- Set<Integer> eventTypeSet = query.getEventTypes();
- assertEquals(eventTypeSet.size(), 1);
- int type = eventTypeSet.iterator().next();
+ final int[] eventTypesArray = query.getEventTypes();
+ assertEquals(eventTypesArray.length, 1);
+ int type = eventTypesArray[0];
assertEquals(type, eventType);
} catch (IllegalArgumentException e) {
fail("Valid event type: " + eventType);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 08f719e91da9..9fc64feb4b25 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2440,7 +2440,7 @@ public class UsageStatsService extends SystemService implements
}
return queryEventsHelper(userId, query.getBeginTimeMillis(),
- query.getEndTimeMillis(), callingPackage, query.getEventTypeFilter());
+ query.getEndTimeMillis(), callingPackage, query.getEventTypes());
}
@Override