Add an API to bulk query broadcast response stats for all pkgs.
Bug: 217567456 Test: atest tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java Change-Id: I12853fdfb8a7b70eac935cf6aab23a388d2b7005
This commit is contained in:
@@ -2507,9 +2507,10 @@ package android.app.time {
|
||||
package android.app.usage {
|
||||
|
||||
public final class BroadcastResponseStats implements android.os.Parcelable {
|
||||
ctor public BroadcastResponseStats(@NonNull String);
|
||||
ctor public BroadcastResponseStats(@NonNull String, @IntRange(from=1) long);
|
||||
method public int describeContents();
|
||||
method @IntRange(from=0) public int getBroadcastsDispatchedCount();
|
||||
method @IntRange(from=1) public long getId();
|
||||
method @IntRange(from=0) public int getNotificationsCancelledCount();
|
||||
method @IntRange(from=0) public int getNotificationsPostedCount();
|
||||
method @IntRange(from=0) public int getNotificationsUpdatedCount();
|
||||
@@ -2566,13 +2567,13 @@ package android.app.usage {
|
||||
}
|
||||
|
||||
public final class UsageStatsManager {
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void clearBroadcastResponseStats(@NonNull String, @IntRange(from=1) long);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void clearBroadcastResponseStats(@Nullable String, @IntRange(from=0) long);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getAppStandbyBucket(String);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public java.util.Map<java.lang.String,java.lang.Integer> getAppStandbyBuckets();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long getLastTimeAnyComponentUsed(@NonNull String);
|
||||
method public int getUsageSource();
|
||||
method @RequiresPermission(android.Manifest.permission.BIND_CARRIER_SERVICES) public void onCarrierPrivilegedAppsChanged();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public android.app.usage.BroadcastResponseStats queryBroadcastResponseStats(@NonNull String, @IntRange(from=1) long);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public java.util.List<android.app.usage.BroadcastResponseStats> queryBroadcastResponseStats(@Nullable String, @IntRange(from=0) long);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @Nullable android.app.PendingIntent);
|
||||
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
|
||||
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.app.BroadcastOptions;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class containing a collection of stats related to response events started from an app
|
||||
* after receiving a broadcast.
|
||||
@@ -32,17 +34,30 @@ import android.os.Parcelable;
|
||||
@SystemApi
|
||||
public final class BroadcastResponseStats implements Parcelable {
|
||||
private final String mPackageName;
|
||||
private final long mId;
|
||||
private int mBroadcastsDispatchedCount;
|
||||
private int mNotificationsPostedCount;
|
||||
private int mNotificationsUpdatedCount;
|
||||
private int mNotificationsCancelledCount;
|
||||
|
||||
public BroadcastResponseStats(@NonNull String packageName) {
|
||||
/**
|
||||
* Creates a new {@link BroadcastResponseStats} object that contain the stats for broadcasts
|
||||
* with {@code id} (specified using
|
||||
* {@link BroadcastOptions#recordResponseEventWhileInBackground(long)} by the sender) that
|
||||
* were sent to {@code packageName}.
|
||||
*
|
||||
* @param packageName the name of the package that broadcasts were sent to.
|
||||
* @param id the ID specified by the sender using
|
||||
* {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
|
||||
*/
|
||||
public BroadcastResponseStats(@NonNull String packageName, @IntRange(from = 1) long id) {
|
||||
mPackageName = packageName;
|
||||
mId = id;
|
||||
}
|
||||
|
||||
private BroadcastResponseStats(@NonNull Parcel in) {
|
||||
mPackageName = in.readString8();
|
||||
mId = in.readLong();
|
||||
mBroadcastsDispatchedCount = in.readInt();
|
||||
mNotificationsPostedCount = in.readInt();
|
||||
mNotificationsUpdatedCount = in.readInt();
|
||||
@@ -57,6 +72,14 @@ public final class BroadcastResponseStats implements Parcelable {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ID of the broadcasts that the stats in this object correspond to.
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
public long getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of broadcasts that were dispatched to the app by the caller.
|
||||
*
|
||||
@@ -147,10 +170,36 @@ public final class BroadcastResponseStats implements Parcelable {
|
||||
incrementNotificationsCancelledCount(stats.getNotificationsCancelledCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || !(obj instanceof BroadcastResponseStats)) {
|
||||
return false;
|
||||
}
|
||||
final BroadcastResponseStats other = (BroadcastResponseStats) obj;
|
||||
return this.mBroadcastsDispatchedCount == other.mBroadcastsDispatchedCount
|
||||
&& this.mNotificationsPostedCount == other.mNotificationsPostedCount
|
||||
&& this.mNotificationsUpdatedCount == other.mNotificationsUpdatedCount
|
||||
&& this.mNotificationsCancelledCount == other.mNotificationsCancelledCount
|
||||
&& this.mId == other.mId
|
||||
&& this.mPackageName.equals(other.mPackageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mPackageName, mId, mBroadcastsDispatchedCount,
|
||||
mNotificationsPostedCount, mNotificationsUpdatedCount,
|
||||
mNotificationsCancelledCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String toString() {
|
||||
return "stats {"
|
||||
+ "broadcastsSent=" + mBroadcastsDispatchedCount
|
||||
+ "package=" + mPackageName
|
||||
+ ",id=" + mId
|
||||
+ ",broadcastsSent=" + mBroadcastsDispatchedCount
|
||||
+ ",notificationsPosted=" + mNotificationsPostedCount
|
||||
+ ",notificationsUpdated=" + mNotificationsUpdatedCount
|
||||
+ ",notificationsCancelled=" + mNotificationsCancelledCount
|
||||
@@ -165,6 +214,7 @@ public final class BroadcastResponseStats implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
|
||||
dest.writeString8(mPackageName);
|
||||
dest.writeLong(mId);
|
||||
dest.writeInt(mBroadcastsDispatchedCount);
|
||||
dest.writeInt(mNotificationsPostedCount);
|
||||
dest.writeInt(mNotificationsUpdatedCount);
|
||||
|
||||
20
core/java/android/app/usage/BroadcastResponseStatsList.aidl
Normal file
20
core/java/android/app/usage/BroadcastResponseStatsList.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 android.app.usage;
|
||||
|
||||
/** {@hide} */
|
||||
parcelable BroadcastResponseStatsList;
|
||||
83
core/java/android/app/usage/BroadcastResponseStatsList.java
Normal file
83
core/java/android/app/usage/BroadcastResponseStatsList.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 android.app.usage;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** @hide */
|
||||
public final class BroadcastResponseStatsList implements Parcelable {
|
||||
private List<BroadcastResponseStats> mBroadcastResponseStats;
|
||||
|
||||
public BroadcastResponseStatsList(
|
||||
@NonNull List<BroadcastResponseStats> broadcastResponseStats) {
|
||||
mBroadcastResponseStats = broadcastResponseStats;
|
||||
}
|
||||
|
||||
private BroadcastResponseStatsList(@NonNull Parcel in) {
|
||||
mBroadcastResponseStats = new ArrayList<>();
|
||||
final byte[] bytes = in.readBlob();
|
||||
final Parcel data = Parcel.obtain();
|
||||
try {
|
||||
data.unmarshall(bytes, 0, bytes.length);
|
||||
data.setDataPosition(0);
|
||||
data.readTypedList(mBroadcastResponseStats, BroadcastResponseStats.CREATOR);
|
||||
} finally {
|
||||
data.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<BroadcastResponseStats> getList() {
|
||||
return mBroadcastResponseStats == null ? Collections.emptyList() : mBroadcastResponseStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @ContentsFlags int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
|
||||
final Parcel data = Parcel.obtain();
|
||||
try {
|
||||
data.writeTypedList(mBroadcastResponseStats);
|
||||
dest.writeBlob(data.marshall());
|
||||
} finally {
|
||||
data.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<BroadcastResponseStatsList> CREATOR =
|
||||
new Creator<BroadcastResponseStatsList>() {
|
||||
@Override
|
||||
public @NonNull BroadcastResponseStatsList createFromParcel(
|
||||
@NonNull Parcel source) {
|
||||
return new BroadcastResponseStatsList(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull BroadcastResponseStatsList[] newArray(int size) {
|
||||
return new BroadcastResponseStatsList[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package android.app.usage;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.usage.BroadcastResponseStats;
|
||||
import android.app.usage.BroadcastResponseStatsList;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
|
||||
@@ -73,9 +74,11 @@ interface IUsageStatsManager {
|
||||
void forceUsageSourceSettingRead();
|
||||
long getLastTimeAnyComponentUsed(String packageName, String callingPackage);
|
||||
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
|
||||
BroadcastResponseStats queryBroadcastResponseStats(
|
||||
BroadcastResponseStatsList queryBroadcastResponseStats(
|
||||
String packageName, long id, String callingPackage, int userId);
|
||||
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
|
||||
void clearBroadcastResponseStats(String packageName, long id, String callingPackage,
|
||||
int userId);
|
||||
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
|
||||
void clearBroadcastEvents(String callingPackage, int userId);
|
||||
}
|
||||
|
||||
@@ -1397,29 +1397,46 @@ public final class UsageStatsManager {
|
||||
* Returns the broadcast response stats since the last boot corresponding to
|
||||
* {@code packageName} and {@code id}.
|
||||
*
|
||||
* <p>Broadcast response stats will include the aggregated data of what actions an app took upon
|
||||
* receiving a broadcast. This data will consider the broadcasts that the caller sent to
|
||||
* <p> Broadcast response stats will include the aggregated data of what actions an app took
|
||||
* upon receiving a broadcast. This data will consider the broadcasts that the caller sent to
|
||||
* {@code packageName} and explicitly requested to record the response events using
|
||||
* {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
|
||||
*
|
||||
* @param packageName The name of the package that the caller wants to query for.
|
||||
* @param id The ID corresponding to the broadcasts that the caller wants to query for. This is
|
||||
* the ID the caller specifies when requesting a broadcast response event to be
|
||||
* recorded using {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
|
||||
* <p> The returned list could one or more {@link BroadcastResponseStats} objects or be empty
|
||||
* depending on the {@code packageName} and {@code id} and whether there is any data
|
||||
* corresponding to these. If the {@code packageName} is not {@code null} and {@code id} is
|
||||
* {@code > 0}, then the returned list would contain at most one {@link BroadcastResponseStats}
|
||||
* object. Otherwise, the returned list could contain more than one
|
||||
* {@link BroadcastResponseStats} object in no particular order.
|
||||
*
|
||||
* @return the broadcast response stats corresponding to {@code packageName} and {@code id}.
|
||||
* <p> Note: It is possible that same {@code id} was used for broadcasts sent to different
|
||||
* packages. So, callers can query the data corresponding to
|
||||
* all broadcasts with a particular {@code id} by passing {@code packageName} as {@code null}.
|
||||
*
|
||||
* @param packageName The name of the package that the caller wants to query for
|
||||
* or {@code null} to indicate that data corresponding to all packages
|
||||
* should be returned.
|
||||
* @param id The ID corresponding to the broadcasts that the caller wants to query for, or
|
||||
* {@code 0} to indicate that data corresponding to all IDs should be returned.
|
||||
* This is the ID the caller specifies when requesting a broadcast response event
|
||||
* to be recorded using
|
||||
* {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
|
||||
*
|
||||
* @return the list of broadcast response stats corresponding to {@code packageName}
|
||||
* and {@code id}.
|
||||
*
|
||||
* @see #clearBroadcastResponseStats(String, long)
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
|
||||
@UserHandleAware
|
||||
@NonNull
|
||||
public BroadcastResponseStats queryBroadcastResponseStats(
|
||||
@NonNull String packageName, @IntRange(from = 1) long id) {
|
||||
public List<BroadcastResponseStats> queryBroadcastResponseStats(
|
||||
@Nullable String packageName, @IntRange(from = 0) long id) {
|
||||
try {
|
||||
return mService.queryBroadcastResponseStats(packageName, id,
|
||||
mContext.getOpPackageName(), mContext.getUserId());
|
||||
mContext.getOpPackageName(), mContext.getUserId()).getList();
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -1428,12 +1445,15 @@ public final class UsageStatsManager {
|
||||
/**
|
||||
* Clears the broadcast response stats corresponding to {@code packageName} and {@code id}.
|
||||
*
|
||||
* When a caller uses this API, stats related to the events occurring till that point will be
|
||||
* cleared and subsequent calls to {@link #queryBroadcastResponseStats(String, long)} will
|
||||
* <p> When a caller uses this API, stats related to the events occurring till that point will
|
||||
* be cleared and subsequent calls to {@link #queryBroadcastResponseStats(String, long)} will
|
||||
* return stats related to events occurring after this.
|
||||
*
|
||||
* @param packageName The name of the package that the caller wants to clear the data for.
|
||||
* @param id The ID corresponding to the broadcasts that the caller wants to clear the data for.
|
||||
* @param packageName The name of the package that the caller wants to clear the data for or
|
||||
* {@code null} to indicate that data corresponding to all packages should
|
||||
* be cleared.
|
||||
* @param id The ID corresponding to the broadcasts that the caller wants to clear the data
|
||||
* for, or {code 0} to indicate that data corresponding to all IDs should be deleted.
|
||||
* This is the ID the caller specifies when requesting a broadcast response event
|
||||
* to be recorded using
|
||||
* {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
|
||||
@@ -1444,8 +1464,8 @@ public final class UsageStatsManager {
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
|
||||
@UserHandleAware
|
||||
public void clearBroadcastResponseStats(@NonNull String packageName,
|
||||
@IntRange(from = 1) long id) {
|
||||
public void clearBroadcastResponseStats(@Nullable String packageName,
|
||||
@IntRange(from = 0) long id) {
|
||||
try {
|
||||
mService.clearBroadcastResponseStats(packageName, id,
|
||||
mContext.getOpPackageName(), mContext.getUserId());
|
||||
@@ -1453,4 +1473,19 @@ public final class UsageStatsManager {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the broadcast events that were sent by the caller uid.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
|
||||
@UserHandleAware
|
||||
public void clearBroadcastEvents() {
|
||||
try {
|
||||
mService.clearBroadcastEvents(mContext.getOpPackageName(), mContext.getUserId());
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.android.server.usage.UsageStatsService.DEBUG_RESPONSE_STATS;
|
||||
|
||||
import android.annotation.ElapsedRealtimeLong;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
@@ -39,6 +40,8 @@ import com.android.internal.util.IndentingPrintWriter;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class BroadcastResponseStatsTracker {
|
||||
private static final String TAG = "ResponseStatsTracker";
|
||||
@@ -172,28 +175,27 @@ class BroadcastResponseStatsTracker {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull BroadcastResponseStats queryBroadcastResponseStats(int callingUid,
|
||||
@NonNull String packageName, long id, @UserIdInt int userId) {
|
||||
final BroadcastResponseStats aggregatedResponseStats =
|
||||
new BroadcastResponseStats(packageName);
|
||||
@NonNull List<BroadcastResponseStats> queryBroadcastResponseStats(int callingUid,
|
||||
@Nullable String packageName, @IntRange(from = 0) long id, @UserIdInt int userId) {
|
||||
final List<BroadcastResponseStats> broadcastResponseStatsList = new ArrayList<>();
|
||||
synchronized (mLock) {
|
||||
final SparseArray<UserBroadcastResponseStats> responseStatsForCaller =
|
||||
mUserResponseStats.get(callingUid);
|
||||
if (responseStatsForCaller == null) {
|
||||
return aggregatedResponseStats;
|
||||
return broadcastResponseStatsList;
|
||||
}
|
||||
final UserBroadcastResponseStats responseStatsForUser =
|
||||
responseStatsForCaller.get(userId);
|
||||
if (responseStatsForUser == null) {
|
||||
return aggregatedResponseStats;
|
||||
return broadcastResponseStatsList;
|
||||
}
|
||||
responseStatsForUser.aggregateBroadcastResponseStats(aggregatedResponseStats,
|
||||
packageName, id);
|
||||
responseStatsForUser.populateAllBroadcastResponseStats(
|
||||
broadcastResponseStatsList, packageName, id);
|
||||
}
|
||||
return aggregatedResponseStats;
|
||||
return broadcastResponseStatsList;
|
||||
}
|
||||
|
||||
void clearBroadcastResponseStats(int callingUid, @NonNull String packageName, long id,
|
||||
void clearBroadcastResponseStats(int callingUid, @Nullable String packageName, long id,
|
||||
@UserIdInt int userId) {
|
||||
synchronized (mLock) {
|
||||
final SparseArray<UserBroadcastResponseStats> responseStatsForCaller =
|
||||
@@ -210,6 +212,16 @@ class BroadcastResponseStatsTracker {
|
||||
}
|
||||
}
|
||||
|
||||
void clearBroadcastEvents(int callingUid, @UserIdInt int userId) {
|
||||
synchronized (mLock) {
|
||||
final UserBroadcastEvents userBroadcastEvents = mUserBroadcastEvents.get(userId);
|
||||
if (userBroadcastEvents == null) {
|
||||
return;
|
||||
}
|
||||
userBroadcastEvents.clear(callingUid);
|
||||
}
|
||||
}
|
||||
|
||||
void onUserRemoved(@UserIdInt int userId) {
|
||||
synchronized (mLock) {
|
||||
mUserBroadcastEvents.remove(userId);
|
||||
|
||||
@@ -49,7 +49,7 @@ import android.app.PendingIntent;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.app.usage.AppLaunchEstimateInfo;
|
||||
import android.app.usage.AppStandbyInfo;
|
||||
import android.app.usage.BroadcastResponseStats;
|
||||
import android.app.usage.BroadcastResponseStatsList;
|
||||
import android.app.usage.ConfigurationStats;
|
||||
import android.app.usage.EventStats;
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
@@ -2686,16 +2686,15 @@ public class UsageStatsService extends SystemService implements
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public BroadcastResponseStats queryBroadcastResponseStats(
|
||||
@NonNull String packageName,
|
||||
@IntRange(from = 1) long id,
|
||||
public BroadcastResponseStatsList queryBroadcastResponseStats(
|
||||
@Nullable String packageName,
|
||||
@IntRange(from = 0) long id,
|
||||
@NonNull String callingPackage,
|
||||
@UserIdInt int userId) {
|
||||
Objects.requireNonNull(packageName);
|
||||
Objects.requireNonNull(callingPackage);
|
||||
// TODO: Move to Preconditions utility class
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException("id needs to be >0");
|
||||
if (id < 0) {
|
||||
throw new IllegalArgumentException("id needs to be >=0");
|
||||
}
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
@@ -2708,8 +2707,9 @@ public class UsageStatsService extends SystemService implements
|
||||
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), callingUid,
|
||||
userId, false /* allowAll */, false /* requireFull */,
|
||||
"queryBroadcastResponseStats" /* name */, callingPackage);
|
||||
return mResponseStatsTracker.queryBroadcastResponseStats(
|
||||
callingUid, packageName, id, userId);
|
||||
return new BroadcastResponseStatsList(
|
||||
mResponseStatsTracker.queryBroadcastResponseStats(
|
||||
callingUid, packageName, id, userId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2718,10 +2718,9 @@ public class UsageStatsService extends SystemService implements
|
||||
@IntRange(from = 1) long id,
|
||||
@NonNull String callingPackage,
|
||||
@UserIdInt int userId) {
|
||||
Objects.requireNonNull(packageName);
|
||||
Objects.requireNonNull(callingPackage);
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException("id needs to be >0");
|
||||
if (id < 0) {
|
||||
throw new IllegalArgumentException("id needs to be >=0");
|
||||
}
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
@@ -2737,6 +2736,23 @@ public class UsageStatsService extends SystemService implements
|
||||
mResponseStatsTracker.clearBroadcastResponseStats(callingUid,
|
||||
packageName, id, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBroadcastEvents(@NonNull String callingPackage, @UserIdInt int userId) {
|
||||
Objects.requireNonNull(callingPackage);
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
if (!hasPermission(callingPackage)) {
|
||||
throw new SecurityException(
|
||||
"Caller does not have the permission needed to call this API; "
|
||||
+ "callingPackage=" + callingPackage
|
||||
+ ", callingUid=" + callingUid);
|
||||
}
|
||||
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), callingUid,
|
||||
userId, false /* allowAll */, false /* requireFull */,
|
||||
"clearBroadcastResponseStats" /* name */, callingPackage);
|
||||
mResponseStatsTracker.clearBroadcastEvents(callingUid, userId);
|
||||
}
|
||||
}
|
||||
|
||||
void registerAppUsageObserver(int callingUid, int observerId, String[] packages,
|
||||
|
||||
@@ -51,6 +51,10 @@ class UserBroadcastEvents {
|
||||
}
|
||||
|
||||
void onUidRemoved(int uid) {
|
||||
clear(uid);
|
||||
}
|
||||
|
||||
void clear(int uid) {
|
||||
for (int i = mBroadcastEvents.size() - 1; i >= 0; --i) {
|
||||
final LongSparseArray<BroadcastEvent> broadcastEvents = mBroadcastEvents.valueAt(i);
|
||||
for (int j = broadcastEvents.size() - 1; j >= 0; --j) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.usage;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.usage.BroadcastResponseStats;
|
||||
@@ -23,6 +24,8 @@ import android.util.ArrayMap;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class UserBroadcastResponseStats {
|
||||
/**
|
||||
* Contains the mapping of a BroadcastEvent type to it's aggregated stats.
|
||||
@@ -39,31 +42,38 @@ class UserBroadcastResponseStats {
|
||||
BroadcastEvent broadcastEvent) {
|
||||
BroadcastResponseStats responseStats = mResponseStats.get(broadcastEvent);
|
||||
if (responseStats == null) {
|
||||
responseStats = new BroadcastResponseStats(broadcastEvent.getTargetPackage());
|
||||
responseStats = new BroadcastResponseStats(broadcastEvent.getTargetPackage(),
|
||||
broadcastEvent.getIdForResponseEvent());
|
||||
mResponseStats.put(broadcastEvent, responseStats);
|
||||
}
|
||||
return responseStats;
|
||||
}
|
||||
|
||||
void aggregateBroadcastResponseStats(
|
||||
@NonNull BroadcastResponseStats responseStats,
|
||||
@NonNull String packageName, long id) {
|
||||
void populateAllBroadcastResponseStats(
|
||||
@NonNull List<BroadcastResponseStats> broadcastResponseStatsList,
|
||||
@Nullable String packageName, @IntRange(from = 0) long id) {
|
||||
for (int i = mResponseStats.size() - 1; i >= 0; --i) {
|
||||
final BroadcastEvent broadcastEvent = mResponseStats.keyAt(i);
|
||||
if (broadcastEvent.getIdForResponseEvent() == id
|
||||
&& broadcastEvent.getTargetPackage().equals(packageName)) {
|
||||
responseStats.addCounts(mResponseStats.valueAt(i));
|
||||
if (id != 0 && id != broadcastEvent.getIdForResponseEvent()) {
|
||||
continue;
|
||||
}
|
||||
if (packageName != null && !packageName.equals(broadcastEvent.getTargetPackage())) {
|
||||
continue;
|
||||
}
|
||||
broadcastResponseStatsList.add(mResponseStats.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
void clearBroadcastResponseStats(@NonNull String packageName, long id) {
|
||||
void clearBroadcastResponseStats(@Nullable String packageName, @IntRange(from = 0) long id) {
|
||||
for (int i = mResponseStats.size() - 1; i >= 0; --i) {
|
||||
final BroadcastEvent broadcastEvent = mResponseStats.keyAt(i);
|
||||
if (broadcastEvent.getIdForResponseEvent() == id
|
||||
&& broadcastEvent.getTargetPackage().equals(packageName)) {
|
||||
mResponseStats.removeAt(i);
|
||||
if (id != 0 && id != broadcastEvent.getIdForResponseEvent()) {
|
||||
continue;
|
||||
}
|
||||
if (packageName != null && !packageName.equals(broadcastEvent.getTargetPackage())) {
|
||||
continue;
|
||||
}
|
||||
mResponseStats.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user