summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tom Chan <tomchan@google.com> 2024-02-20 14:45:42 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-20 14:45:42 +0000
commitc0a4bee0682fc735a211e21ff3173535ef97fe2e (patch)
tree7065eb25e11a2d088f79c2681ad9ed9ccb982522
parentccac8f881449fe442cc534d7d8b0b71973a2e123 (diff)
parent6b94199b84380949364a911c5f37cf812a39658b (diff)
Merge "Allow overriding data request rate limit window size from command line" into main
-rw-r--r--services/core/java/com/android/server/wearable/WearableSensingManagerService.java54
-rw-r--r--services/core/java/com/android/server/wearable/WearableSensingShellCommand.java24
2 files changed, 77 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/wearable/WearableSensingManagerService.java b/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
index 00c3026b1194..d05482d75083 100644
--- a/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
+++ b/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
@@ -55,6 +55,7 @@ import com.android.server.pm.KnownPackages;
import com.android.server.utils.quota.MultiRateLimiter;
import java.io.FileDescriptor;
+import java.time.Duration;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@@ -106,7 +107,7 @@ public class WearableSensingManagerService extends
private final Context mContext;
private final AtomicInteger mNextDataRequestObserverId = new AtomicInteger(1);
private final Set<DataRequestObserverContext> mDataRequestObserverContexts = new HashSet<>();
- private final MultiRateLimiter mDataRequestRateLimiter;
+ @NonNull private volatile MultiRateLimiter mDataRequestRateLimiter;
volatile boolean mIsServiceEnabled;
public WearableSensingManagerService(Context context) {
@@ -238,6 +239,57 @@ public class WearableSensingManagerService extends
}
}
+ /**
+ * Sets the window size used in data request rate limiting.
+ *
+ * <p>The new value will not be reflected in {@link
+ * WearableSensingDataRequest#getRateLimitWindowSize()}.
+ *
+ * <p>{@code windowSize} will be automatically capped between
+ * com.android.server.utils.quota.QuotaTracker#MIN_WINDOW_SIZE_MS and
+ * com.android.server.utils.quota.QuotaTracker#MAX_WINDOW_SIZE_MS
+ *
+ * <p>The current rate limit will also be reset.
+ *
+ * <p>This method is only used for testing and must not be called in production code because
+ * it effectively bypasses the rate limiting introduced to enhance privacy protection.
+ */
+ @VisibleForTesting
+ void setDataRequestRateLimitWindowSize(@NonNull Duration windowSize) {
+ Slog.w(
+ TAG,
+ TextUtils.formatSimple(
+ "Setting the data request rate limit window size to %s. This also resets"
+ + " the current limit and should only be callable from a test.",
+ windowSize));
+ mDataRequestRateLimiter =
+ new MultiRateLimiter.Builder(mContext)
+ .addRateLimit(WearableSensingDataRequest.getRateLimit(), windowSize)
+ .build();
+ }
+
+ /**
+ * Resets the window size used in data request rate limiting back to the default value.
+ *
+ * <p>The current rate limit will also be reset.
+ *
+ * <p>This method is only used for testing and must not be called in production code because
+ * it effectively bypasses the rate limiting introduced to enhance privacy protection.
+ */
+ @VisibleForTesting
+ void resetDataRequestRateLimitWindowSize() {
+ Slog.w(
+ TAG,
+ "Resetting the data request rate limit window size back to the default value. This"
+ + " also resets the current limit and should only be callable from a test.");
+ mDataRequestRateLimiter =
+ new MultiRateLimiter.Builder(mContext)
+ .addRateLimit(
+ WearableSensingDataRequest.getRateLimit(),
+ WearableSensingDataRequest.getRateLimitWindowSize())
+ .build();
+ }
+
private DataRequestObserverContext getDataRequestObserverContext(
int dataType, int userId, PendingIntent dataRequestPendingIntent) {
synchronized (mDataRequestObserverContexts) {
diff --git a/services/core/java/com/android/server/wearable/WearableSensingShellCommand.java b/services/core/java/com/android/server/wearable/WearableSensingShellCommand.java
index 842bccbe0847..0a9cf344e7b2 100644
--- a/services/core/java/com/android/server/wearable/WearableSensingShellCommand.java
+++ b/services/core/java/com/android/server/wearable/WearableSensingShellCommand.java
@@ -29,6 +29,7 @@ import android.util.Slog;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.time.Duration;
final class WearableSensingShellCommand extends ShellCommand {
private static final String TAG = WearableSensingShellCommand.class.getSimpleName();
@@ -90,6 +91,8 @@ final class WearableSensingShellCommand extends ShellCommand {
return getBoundPackageName();
case "set-temporary-service":
return setTemporaryService();
+ case "set-data-request-rate-limit-window-size":
+ return setDataRequestRateLimitWindowSize();
default:
return handleDefaultCommands(cmd);
}
@@ -114,6 +117,11 @@ final class WearableSensingShellCommand extends ShellCommand {
pw.println(" set-temporary-service USER_ID [PACKAGE_NAME] [COMPONENT_NAME DURATION]");
pw.println(" Temporarily (for DURATION ms) changes the service implementation.");
pw.println(" To reset, call with just the USER_ID argument.");
+ pw.println(" set-data-request-rate-limit-window-size WINDOW_SIZE");
+ pw.println(" Set the window size used in data request rate limiting to WINDOW_SIZE"
+ + " seconds.");
+ pw.println(" positive WINDOW_SIZE smaller than 20 will be automatically set to 20.");
+ pw.println(" To reset, call with 0 or a negative WINDOW_SIZE.");
}
private int createDataStream() {
@@ -209,4 +217,20 @@ final class WearableSensingShellCommand extends ShellCommand {
resultPrinter.println(componentName == null ? "" : componentName.getPackageName());
return 0;
}
+
+ private int setDataRequestRateLimitWindowSize() {
+ Slog.d(TAG, "setDataRequestRateLimitWindowSize");
+ int windowSizeSeconds = Integer.parseInt(getNextArgRequired());
+ if (windowSizeSeconds <= 0) {
+ mService.resetDataRequestRateLimitWindowSize();
+ } else {
+ // 20 is the minimum window size supported by the rate limiter.
+ // It is defined by com.android.server.utils.quota.QuotaTracker#MIN_WINDOW_SIZE_MS
+ if (windowSizeSeconds < 20) {
+ windowSizeSeconds = 20;
+ }
+ mService.setDataRequestRateLimitWindowSize(Duration.ofSeconds(windowSizeSeconds));
+ }
+ return 0;
+ }
}