Merge "Add request object for querying historical ops"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bdea76f9ae
@@ -304,7 +304,7 @@ package android.app {
|
||||
}
|
||||
|
||||
public class AppOpsManager {
|
||||
method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(int, @Nullable String, @Nullable String[], long, long, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method public static String[] getOpStrs();
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
|
||||
@@ -394,6 +394,17 @@ package android.app {
|
||||
field public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR;
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalOpsRequest {
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalOpsRequest.Builder {
|
||||
ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build();
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int);
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
|
||||
|
||||
@@ -101,8 +101,8 @@ package android.app {
|
||||
public class AppOpsManager {
|
||||
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps);
|
||||
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory();
|
||||
method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(int, @Nullable String, @Nullable String[], long, long, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOpsFromDiskRaw(int, @Nullable String, @Nullable String[], long, long, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
|
||||
method public static int getNumOps();
|
||||
method public static String[] getOpStrs();
|
||||
method public boolean isOperationActive(int, int, String);
|
||||
@@ -206,6 +206,17 @@ package android.app {
|
||||
field public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR;
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalOpsRequest {
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalOpsRequest.Builder {
|
||||
ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build();
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String);
|
||||
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int);
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
|
||||
|
||||
@@ -46,6 +46,8 @@ import android.util.ArrayMap;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import com.android.internal.annotations.Immutable;
|
||||
import com.android.internal.app.IAppOpsActiveCallback;
|
||||
import com.android.internal.app.IAppOpsCallback;
|
||||
import com.android.internal.app.IAppOpsNotedCallback;
|
||||
@@ -2209,6 +2211,115 @@ public class AppOpsManager {
|
||||
void visitHistoricalOp(@NonNull HistoricalOp ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request for getting historical app op usage. The request acts
|
||||
* as a filtering criteria when querying historical op usage.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Immutable
|
||||
@TestApi
|
||||
@SystemApi
|
||||
public static final class HistoricalOpsRequest {
|
||||
private final int mUid;
|
||||
private final @Nullable String mPackageName;
|
||||
private final @Nullable List<String> mOpNames;
|
||||
private final long mBeginTimeMillis;
|
||||
private final long mEndTimeMillis;
|
||||
|
||||
private HistoricalOpsRequest(int uid, @Nullable String packageName,
|
||||
@Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis) {
|
||||
mUid = uid;
|
||||
mPackageName = packageName;
|
||||
mOpNames = opNames;
|
||||
mBeginTimeMillis = beginTimeMillis;
|
||||
mEndTimeMillis = endTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating a {@link HistoricalOpsRequest}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@SystemApi
|
||||
public static final class Builder {
|
||||
private int mUid = Process.INVALID_UID;
|
||||
private @Nullable String mPackageName;
|
||||
private @Nullable List<String> mOpNames;
|
||||
private final long mBeginTimeMillis;
|
||||
private final long mEndTimeMillis;
|
||||
|
||||
/**
|
||||
* Creates a new builder.
|
||||
*
|
||||
* @param beginTimeMillis The beginning of the interval in milliseconds since
|
||||
* epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
|
||||
* negative.
|
||||
* @param endTimeMillis The end of the interval in milliseconds since
|
||||
* epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
|
||||
* {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
|
||||
* history including ops that happen while this call is in flight.
|
||||
*/
|
||||
public Builder(long beginTimeMillis, long endTimeMillis) {
|
||||
Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
|
||||
"beginTimeMillis must be non negative and lesser than endTimeMillis");
|
||||
mBeginTimeMillis = beginTimeMillis;
|
||||
mEndTimeMillis = endTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the UID to query for.
|
||||
*
|
||||
* @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NonNull Builder setUid(int uid) {
|
||||
Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
|
||||
"uid must be " + Process.INVALID_UID + " or non negative");
|
||||
mUid = uid;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the package to query for.
|
||||
*
|
||||
* @param packageName The package name. <code>Null</code> for any package.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NonNull Builder setPackageName(@Nullable String packageName) {
|
||||
mPackageName = packageName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the op names to query for.
|
||||
*
|
||||
* @param opNames The op names. <code>Null</code> for any op.
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
|
||||
if (opNames != null) {
|
||||
final int opCount = opNames.size();
|
||||
for (int i = 0; i < opCount; i++) {
|
||||
Preconditions.checkArgument(AppOpsManager.strOpToOp(
|
||||
opNames.get(i)) != AppOpsManager.OP_NONE);
|
||||
}
|
||||
}
|
||||
mOpNames = opNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new {@link HistoricalOpsRequest}.
|
||||
*/
|
||||
public @NonNull HistoricalOpsRequest build() {
|
||||
return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
|
||||
mBeginTimeMillis, mEndTimeMillis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents historical app op state of all UIDs for a given time interval.
|
||||
*
|
||||
@@ -3671,26 +3782,7 @@ public class AppOpsManager {
|
||||
/**
|
||||
* Retrieve historical app op stats for a period.
|
||||
*
|
||||
* <p>Historical data can be obtained
|
||||
* for a specific package by specifying the <code>packageName</code> argument,
|
||||
* for a specific UID if specifying the <code>uid</code> argument, for a
|
||||
* specific package in a UID by specifying the <code>packageName</code>
|
||||
* and the <code>uid</code> arguments, for all packages by passing
|
||||
* {@link android.os.Process#INVALID_UID} and <code>null</code> for the
|
||||
* <code>uid</code> and <code>packageName</code> arguments, respectively.
|
||||
* Similarly, you can specify the <code>opNames</code> argument to get
|
||||
* data only for these ops or <code>null</code> for all ops.
|
||||
*
|
||||
* @param uid The UID to query for.
|
||||
* @param packageName The package to query for.
|
||||
* @param beginTimeMillis The beginning of the interval in milliseconds since
|
||||
* epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
|
||||
* negative.
|
||||
* @param endTimeMillis The end of the interval in milliseconds since
|
||||
* epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
|
||||
* {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
|
||||
* history including ops that happen while this call is in flight.
|
||||
* @param opNames The ops to query for. Pass {@code null} for all ops.
|
||||
* @param request A request object describing the data being queried for.
|
||||
* @param executor Executor on which to run the callback. If <code>null</code>
|
||||
* the callback is executed on the default executor running on the main thread.
|
||||
* @param callback Callback on which to deliver the result.
|
||||
@@ -3702,13 +3794,13 @@ public class AppOpsManager {
|
||||
@TestApi
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
|
||||
public void getHistoricalOps(int uid, @Nullable String packageName,
|
||||
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
|
||||
public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
|
||||
@NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
|
||||
Preconditions.checkNotNull(executor, "executor cannot be null");
|
||||
Preconditions.checkNotNull(callback, "callback cannot be null");
|
||||
try {
|
||||
mService.getHistoricalOps(uid, packageName, opNames, beginTimeMillis, endTimeMillis,
|
||||
mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
|
||||
request.mBeginTimeMillis, request.mEndTimeMillis,
|
||||
new RemoteCallback((result) -> {
|
||||
final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
@@ -3725,29 +3817,12 @@ public class AppOpsManager {
|
||||
|
||||
/**
|
||||
* Retrieve historical app op stats for a period.
|
||||
*
|
||||
* <p>Historical data can be obtained
|
||||
* for a specific package by specifying the <code>packageName</code> argument,
|
||||
* for a specific UID if specifying the <code>uid</code> argument, for a
|
||||
* specific package in a UID by specifying the <code>packageName</code>
|
||||
* and the <code>uid</code> arguments, for all packages by passing
|
||||
* {@link android.os.Process#INVALID_UID} and <code>null</code> for the
|
||||
* <code>uid</code> and <code>packageName</code> arguments, respectively.
|
||||
* Similarly, you can specify the <code>opNames</code> argument to get
|
||||
* data only for these ops or <code>null</code> for all ops.
|
||||
* <p>
|
||||
* This method queries only the on disk state and the returned ops are raw,
|
||||
* which is their times are relative to the history start as opposed to the
|
||||
* epoch start.
|
||||
*
|
||||
* @param uid The UID to query for.
|
||||
* @param packageName The package to query for.
|
||||
* @param beginTimeMillis The beginning of the interval in milliseconds since
|
||||
* history start. History time grows as one goes into the past.
|
||||
* @param endTimeMillis The end of the interval in milliseconds since
|
||||
* history start. History time grows as one goes into the past. Must be after
|
||||
* {@code beginTimeMillis}.
|
||||
* @param opNames The ops to query for. Pass {@code null} for all ops.
|
||||
* @param request A request object describing the data being queried for.
|
||||
* @param executor Executor on which to run the callback. If <code>null</code>
|
||||
* the callback is executed on the default executor running on the main thread.
|
||||
* @param callback Callback on which to deliver the result.
|
||||
@@ -3758,15 +3833,15 @@ public class AppOpsManager {
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
|
||||
public void getHistoricalOpsFromDiskRaw(int uid, @Nullable String packageName,
|
||||
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
|
||||
public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
|
||||
@Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
|
||||
Preconditions.checkNotNull(executor, "executor cannot be null");
|
||||
Preconditions.checkNotNull(callback, "callback cannot be null");
|
||||
try {
|
||||
mService.getHistoricalOpsFromDiskRaw(uid, packageName, opNames, beginTimeMillis,
|
||||
endTimeMillis, new RemoteCallback((result) -> {
|
||||
final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
|
||||
mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
|
||||
request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
|
||||
new RemoteCallback((result) -> {
|
||||
final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
executor.execute(() -> callback.accept(ops));
|
||||
|
||||
@@ -44,9 +44,9 @@ interface IAppOpsService {
|
||||
int checkPackage(int uid, String packageName);
|
||||
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
|
||||
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
|
||||
void getHistoricalOps(int uid, String packageName, in String[] ops, long beginTimeMillis,
|
||||
void getHistoricalOps(int uid, String packageName, in List<String> ops, long beginTimeMillis,
|
||||
long endTimeMillis, in RemoteCallback callback);
|
||||
void getHistoricalOpsFromDiskRaw(int uid, String packageName, in String[] ops,
|
||||
void getHistoricalOpsFromDiskRaw(int uid, String packageName, in List<String> ops,
|
||||
long beginTimeMillis, long endTimeMillis, in RemoteCallback callback);
|
||||
void offsetHistory(long duration);
|
||||
void setHistoryParameters(int mode, long baseSnapshotInterval, int compressionStep);
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.app.ActivityThread;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.AppOpsManager.HistoricalOps;
|
||||
import android.app.AppOpsManager.HistoricalOpsRequest;
|
||||
import android.app.AppOpsManagerInternal;
|
||||
import android.app.AppOpsManagerInternal.CheckOpsDelegate;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -1024,25 +1025,29 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
|
||||
@Override
|
||||
public void getHistoricalOps(int uid, @NonNull String packageName,
|
||||
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
|
||||
@Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
|
||||
@NonNull RemoteCallback callback) {
|
||||
Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
|
||||
"uid must be " + Process.INVALID_UID + " or non negative");
|
||||
Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
|
||||
"beginTimeMillis must be non negative and lesser than endTimeMillis");
|
||||
// Use the builder to validate arguments.
|
||||
final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder(
|
||||
beginTimeMillis, endTimeMillis)
|
||||
.setUid(uid)
|
||||
.setPackageName(packageName)
|
||||
.setOpNames(opNames)
|
||||
.build();
|
||||
Preconditions.checkNotNull(callback, "callback cannot be null");
|
||||
checkValidOpsOrNull(opNames);
|
||||
|
||||
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
|
||||
Binder.getCallingPid(), Binder.getCallingUid(), "getHistoricalOps");
|
||||
|
||||
final String[] opNamesArray = (opNames != null)
|
||||
? opNames.toArray(new String[opNames.size()]) : null;
|
||||
if (mHistoricalRegistry.getMode() == AppOpsManager.HISTORICAL_MODE_DISABLED) {
|
||||
// TODO (bug:122218838): Remove once the feature fully enabled.
|
||||
getHistoricalPackagesOpsCompat(uid, packageName, opNames, beginTimeMillis,
|
||||
getHistoricalPackagesOpsCompat(uid, packageName, opNamesArray, beginTimeMillis,
|
||||
endTimeMillis, callback);
|
||||
} else {
|
||||
// Must not hold the appops lock
|
||||
mHistoricalRegistry.getHistoricalOps(uid, packageName, opNames,
|
||||
mHistoricalRegistry.getHistoricalOps(uid, packageName, opNamesArray,
|
||||
beginTimeMillis, endTimeMillis, callback);
|
||||
}
|
||||
}
|
||||
@@ -1101,20 +1106,25 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
|
||||
@Override
|
||||
public void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
|
||||
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
|
||||
@Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
|
||||
@NonNull RemoteCallback callback) {
|
||||
Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
|
||||
"uid must be " + Process.INVALID_UID + " or non negative");
|
||||
Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
|
||||
"beginTimeMillis must be non negative and lesser than endTimeMillis");
|
||||
// Use the builder to validate arguments.
|
||||
final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder(
|
||||
beginTimeMillis, endTimeMillis)
|
||||
.setUid(uid)
|
||||
.setPackageName(packageName)
|
||||
.setOpNames(opNames)
|
||||
.build();
|
||||
Preconditions.checkNotNull(callback, "callback cannot be null");
|
||||
checkValidOpsOrNull(opNames);
|
||||
|
||||
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
|
||||
Binder.getCallingPid(), Binder.getCallingUid(), "getHistoricalOps");
|
||||
|
||||
final String[] opNamesArray = (opNames != null)
|
||||
? opNames.toArray(new String[opNames.size()]) : null;
|
||||
|
||||
// Must not hold the appops lock
|
||||
mHistoricalRegistry.getHistoricalOpsFromDiskRaw(uid, packageName, opNames,
|
||||
mHistoricalRegistry.getHistoricalOpsFromDiskRaw(uid, packageName, opNamesArray,
|
||||
beginTimeMillis, endTimeMillis, callback);
|
||||
}
|
||||
|
||||
@@ -4266,16 +4276,6 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
return packageNames;
|
||||
}
|
||||
|
||||
private static void checkValidOpsOrNull(String[] opNames) {
|
||||
if (opNames != null) {
|
||||
for (String opName : opNames) {
|
||||
if (AppOpsManager.strOpToOp(opName) == AppOpsManager.OP_NONE) {
|
||||
throw new IllegalArgumentException("Unknown op: " + opName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class ClientRestrictionState implements DeathRecipient {
|
||||
private final IBinder token;
|
||||
SparseArray<boolean[]> perUserRestrictions;
|
||||
|
||||
Reference in New Issue
Block a user