Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b94199b authored by Tom Chan's avatar Tom Chan
Browse files

Allow overriding data request rate limit window size from command line

This is needed in CTS to reduce the window size to a duration within
the allowed test execution time of 30 seconds

Test: atest CtsWearableSensingServiceTestCases
Bug: 324782342
Change-Id: I3ddd1c6955bbde58d4df3a7d9785e713ac39f121
parent 5319a107
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -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) {
+24 −0
Original line number Diff line number Diff line
@@ -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;
    }
}