Loading services/core/java/com/android/server/wearable/WearableSensingManagerService.java +53 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading services/core/java/com/android/server/wearable/WearableSensingShellCommand.java +24 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); } Loading @@ -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() { Loading Loading @@ -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; } } Loading
services/core/java/com/android/server/wearable/WearableSensingManagerService.java +53 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
services/core/java/com/android/server/wearable/WearableSensingShellCommand.java +24 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); } Loading @@ -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() { Loading Loading @@ -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; } }