Merge "Add AppSearchConfig in AppSearch" into sc-dev am: b7d75ad788
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14237405 Change-Id: I93cb7b095dccaa670d305d1c1f745eca9c27b4c8
This commit is contained in:
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 com.android.server.appsearch;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
import android.provider.DeviceConfig.OnPropertiesChangedListener;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It contains all the keys for the flags, as well as caches some of latest flag values from
|
||||||
|
* DeviceConfig.
|
||||||
|
*
|
||||||
|
* <p>Though the latest flag values can always be retrieved by calling {@code
|
||||||
|
* DeviceConfig.getProperty}, we want to cache some of those values. For example, the sampling
|
||||||
|
* intervals for logging, they are needed for each api call and it would be a little expensive to
|
||||||
|
* call
|
||||||
|
* {@code DeviceConfig.getProperty} every time.
|
||||||
|
*
|
||||||
|
* <p>Listener is registered to DeviceConfig keep the cached value up to date.
|
||||||
|
*
|
||||||
|
* <p>This class is thread-safe.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class AppSearchConfig implements AutoCloseable {
|
||||||
|
/**
|
||||||
|
* It would be used as default min time interval between samples in millis if there is no value
|
||||||
|
* set for {@link AppSearchConfig#KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS} in DeviceConfig.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static final long DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It would be used as default sampling interval if there is no value
|
||||||
|
* set for {@link AppSearchConfig#KEY_SAMPLING_INTERVAL_DEFAULT} in DeviceConfig.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static final int DEFAULT_SAMPLING_INTERVAL = 10;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keys for ALL the flags stored in DeviceConfig.
|
||||||
|
*/
|
||||||
|
public static final String KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS =
|
||||||
|
"min_time_interval_between_samples_millis";
|
||||||
|
public static final String KEY_SAMPLING_INTERVAL_DEFAULT = "sampling_interval_default";
|
||||||
|
public static final String KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS =
|
||||||
|
"sampling_interval_for_batch_call_stats";
|
||||||
|
public static final String KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS =
|
||||||
|
"sampling_interval_for_put_document_stats";
|
||||||
|
|
||||||
|
// Array contains all the corresponding keys for the cached values.
|
||||||
|
private static final String[] KEYS_TO_ALL_CACHED_VALUES = {
|
||||||
|
KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS
|
||||||
|
};
|
||||||
|
|
||||||
|
// Lock needed for all the operations in this class.
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundle to hold all the cached flag values corresponding to
|
||||||
|
* {@link AppSearchConfig#KEYS_TO_ALL_CACHED_VALUES}.
|
||||||
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private final Bundle mBundleLocked = new Bundle();
|
||||||
|
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private boolean mIsClosedLocked = false;
|
||||||
|
|
||||||
|
/** Listener to update cached flag values from DeviceConfig. */
|
||||||
|
private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
|
||||||
|
properties -> {
|
||||||
|
if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_APPSEARCH)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCachedValues(properties);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of {@link AppSearchConfig}.
|
||||||
|
*
|
||||||
|
* @param executor used to fetch and cache the flag values from DeviceConfig during creation or
|
||||||
|
* config change.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static AppSearchConfig create(@NonNull Executor executor) {
|
||||||
|
Objects.requireNonNull(executor);
|
||||||
|
AppSearchConfig configManager = new AppSearchConfig();
|
||||||
|
configManager.initialize(executor);
|
||||||
|
return configManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AppSearchConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the {@link AppSearchConfig}
|
||||||
|
*
|
||||||
|
* <p>It fetches the custom properties from DeviceConfig if available.
|
||||||
|
*
|
||||||
|
* @param executor listener would be run on to handle P/H flag change.
|
||||||
|
*/
|
||||||
|
private void initialize(@NonNull Executor executor) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
// Attach the callback to get updates on those properties.
|
||||||
|
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
executor,
|
||||||
|
mOnDeviceConfigChangedListener);
|
||||||
|
|
||||||
|
DeviceConfig.Properties properties = DeviceConfig.getProperties(
|
||||||
|
DeviceConfig.NAMESPACE_APPSEARCH, KEYS_TO_ALL_CACHED_VALUES);
|
||||||
|
updateCachedValues(properties);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(b/173532925) check this will be called. If we have a singleton instance for this
|
||||||
|
// class, probably we don't need it.
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mIsClosedLocked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceConfig.removeOnPropertiesChangedListener(mOnDeviceConfigChangedListener);
|
||||||
|
mIsClosedLocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns cached value for minTimeIntervalBetweenSamplesMillis. */
|
||||||
|
public long getCachedMinTimeIntervalBetweenSamplesMillis() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
throwIfClosedLocked();
|
||||||
|
return mBundleLocked.getLong(KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns cached value for default sampling interval for all the stats NOT listed in
|
||||||
|
* the configuration.
|
||||||
|
*
|
||||||
|
* <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
|
||||||
|
*/
|
||||||
|
public int getCachedSamplingIntervalDefault() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
throwIfClosedLocked();
|
||||||
|
return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_DEFAULT, DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns cached value for sampling interval for batch calls.
|
||||||
|
*
|
||||||
|
* <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
|
||||||
|
*/
|
||||||
|
public int getCachedSamplingIntervalForBatchCallStats() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
throwIfClosedLocked();
|
||||||
|
return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
getCachedSamplingIntervalDefault());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns cached value for sampling interval for putDocument.
|
||||||
|
*
|
||||||
|
* <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
|
||||||
|
*/
|
||||||
|
public int getCachedSamplingIntervalForPutDocumentStats() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
throwIfClosedLocked();
|
||||||
|
return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
getCachedSamplingIntervalDefault());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private void throwIfClosedLocked() {
|
||||||
|
if (mIsClosedLocked) {
|
||||||
|
throw new IllegalStateException("Trying to use a closed AppSearchConfig instance.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCachedValues(@NonNull DeviceConfig.Properties properties) {
|
||||||
|
for (String key : properties.getKeyset()) {
|
||||||
|
updateCachedValue(key, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCachedValue(@NonNull String key,
|
||||||
|
@NonNull DeviceConfig.Properties properties) {
|
||||||
|
if (properties.getString(key, /*defaultValue=*/ null) == null) {
|
||||||
|
// Key is missing or value is just null. That is not expected if the key is
|
||||||
|
// defined in the configuration.
|
||||||
|
//
|
||||||
|
// We choose NOT to put the default value in the bundle.
|
||||||
|
// Instead, we let the getters handle what default value should be returned.
|
||||||
|
//
|
||||||
|
// Also we keep the old value in the bundle. So getters can still
|
||||||
|
// return last valid value.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS:
|
||||||
|
synchronized (mLock) {
|
||||||
|
mBundleLocked.putLong(key,
|
||||||
|
properties.getLong(key,
|
||||||
|
DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_SAMPLING_INTERVAL_DEFAULT:
|
||||||
|
case KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS:
|
||||||
|
case KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS:
|
||||||
|
synchronized (mLock) {
|
||||||
|
mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_SAMPLING_INTERVAL));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,7 +72,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
*
|
*
|
||||||
* <p> We can have correct extrapolated number by adding those counts back when we log
|
* <p> We can have correct extrapolated number by adding those counts back when we log
|
||||||
* the same type of stats next time. E.g. the true count of an event could be estimated as:
|
* the same type of stats next time. E.g. the true count of an event could be estimated as:
|
||||||
* SUM(sampling_ratio * (num_skipped_sample + 1)) as est_count
|
* SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
|
||||||
*
|
*
|
||||||
* <p>The key to the SparseArray is {@link CallStats.CallType}
|
* <p>The key to the SparseArray is {@link CallStats.CallType}
|
||||||
*/
|
*/
|
||||||
@@ -105,42 +105,42 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
// logging again.
|
// logging again.
|
||||||
private final long mMinTimeIntervalBetweenSamplesMillis;
|
private final long mMinTimeIntervalBetweenSamplesMillis;
|
||||||
|
|
||||||
// Default sampling ratio for all types of stats
|
// Default sampling interval for all types of stats
|
||||||
private final int mDefaultSamplingRatio;
|
private final int mDefaultSamplingInterval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sampling ratios for different types of stats
|
* Sampling intervals for different types of stats
|
||||||
*
|
*
|
||||||
* <p>This SparseArray is passed by client and is READ-ONLY. The key to that SparseArray is
|
* <p>This SparseArray is passed by client and is READ-ONLY. The key to that SparseArray is
|
||||||
* {@link CallStats.CallType}
|
* {@link CallStats.CallType}
|
||||||
*
|
*
|
||||||
* <p>If sampling ratio is missing for certain stats type,
|
* <p>If sampling interval is missing for certain stats type,
|
||||||
* {@link Config#mDefaultSamplingRatio} will be used.
|
* {@link Config#mDefaultSamplingInterval} will be used.
|
||||||
*
|
*
|
||||||
* <p>E.g. sampling ratio=10 means that one out of every 10 stats was logged. If sampling
|
* <p>E.g. sampling interval=10 means that one out of every 10 stats was logged. If sampling
|
||||||
* ratio is 1, we will log each sample and it acts as if the sampling is disabled.
|
* interval is 1, we will log each sample and it acts as if the sampling is disabled.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private final SparseIntArray mSamplingRatios;
|
private final SparseIntArray mSamplingIntervals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for {@link PlatformLogger}
|
* Configuration for {@link PlatformLogger}
|
||||||
*
|
*
|
||||||
* @param minTimeIntervalBetweenSamplesMillis minimum time interval apart in Milliseconds
|
* @param minTimeIntervalBetweenSamplesMillis minimum time interval apart in Milliseconds
|
||||||
* required for two consecutive stats logged
|
* required for two consecutive stats logged
|
||||||
* @param defaultSamplingRatio default sampling ratio
|
* @param defaultSamplingInterval default sampling interval
|
||||||
* @param samplingRatios SparseArray to customize sampling ratio for
|
* @param samplingIntervals SparseArray to customize sampling interval for
|
||||||
* different stat types
|
* different stat types
|
||||||
*/
|
*/
|
||||||
public Config(long minTimeIntervalBetweenSamplesMillis,
|
public Config(long minTimeIntervalBetweenSamplesMillis,
|
||||||
int defaultSamplingRatio,
|
int defaultSamplingInterval,
|
||||||
@NonNull SparseIntArray samplingRatios) {
|
@NonNull SparseIntArray samplingIntervals) {
|
||||||
// TODO(b/173532925) Probably we can get rid of those three after we have p/h flags
|
// TODO(b/173532925) Probably we can get rid of those three after we have p/h flags
|
||||||
// for them.
|
// for them.
|
||||||
// e.g. we can just call DeviceConfig.get(SAMPLING_RATIO_FOR_PUT_DOCUMENTS).
|
// e.g. we can just call DeviceConfig.get(SAMPLING_INTERVAL_FOR_PUT_DOCUMENTS).
|
||||||
mMinTimeIntervalBetweenSamplesMillis = minTimeIntervalBetweenSamplesMillis;
|
mMinTimeIntervalBetweenSamplesMillis = minTimeIntervalBetweenSamplesMillis;
|
||||||
mDefaultSamplingRatio = defaultSamplingRatio;
|
mDefaultSamplingInterval = defaultSamplingInterval;
|
||||||
mSamplingRatios = samplingRatios;
|
mSamplingIntervals = samplingIntervals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,14 +150,14 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
static final class ExtraStats {
|
static final class ExtraStats {
|
||||||
// UID for the calling package of the stats.
|
// UID for the calling package of the stats.
|
||||||
final int mPackageUid;
|
final int mPackageUid;
|
||||||
// sampling ratio for the call type of the stats.
|
// sampling interval for the call type of the stats.
|
||||||
final int mSamplingRatio;
|
final int mSamplingInterval;
|
||||||
// number of samplings skipped before the current one for the same call type.
|
// number of samplings skipped before the current one for the same call type.
|
||||||
final int mSkippedSampleCount;
|
final int mSkippedSampleCount;
|
||||||
|
|
||||||
ExtraStats(int packageUid, int samplingRatio, int skippedSampleCount) {
|
ExtraStats(int packageUid, int samplingInterval, int skippedSampleCount) {
|
||||||
mPackageUid = packageUid;
|
mPackageUid = packageUid;
|
||||||
mSamplingRatio = samplingRatio;
|
mSamplingInterval = samplingInterval;
|
||||||
mSkippedSampleCount = skippedSampleCount;
|
mSkippedSampleCount = skippedSampleCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
*
|
*
|
||||||
* @return removed UID for the package, or {@code INVALID_UID} if package was not previously
|
* @return removed UID for the package, or {@code INVALID_UID} if package was not previously
|
||||||
* cached.
|
* cached.
|
||||||
*/
|
*/
|
||||||
public int removeCachedUidForPackage(@NonNull String packageName) {
|
public int removeCachedUidForPackage(@NonNull String packageName) {
|
||||||
// TODO(b/173532925) This needs to be called when we get PACKAGE_REMOVED intent
|
// TODO(b/173532925) This needs to be called when we get PACKAGE_REMOVED intent
|
||||||
Objects.requireNonNull(packageName);
|
Objects.requireNonNull(packageName);
|
||||||
@@ -243,7 +243,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
try {
|
try {
|
||||||
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
||||||
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_CALL_STATS_REPORTED,
|
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_CALL_STATS_REPORTED,
|
||||||
extraStats.mSamplingRatio,
|
extraStats.mSamplingInterval,
|
||||||
extraStats.mSkippedSampleCount,
|
extraStats.mSkippedSampleCount,
|
||||||
extraStats.mPackageUid,
|
extraStats.mPackageUid,
|
||||||
hashCodeForDatabase,
|
hashCodeForDatabase,
|
||||||
@@ -275,7 +275,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
try {
|
try {
|
||||||
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
||||||
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED,
|
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED,
|
||||||
extraStats.mSamplingRatio,
|
extraStats.mSamplingInterval,
|
||||||
extraStats.mSkippedSampleCount,
|
extraStats.mSkippedSampleCount,
|
||||||
extraStats.mPackageUid,
|
extraStats.mPackageUid,
|
||||||
hashCodeForDatabase,
|
hashCodeForDatabase,
|
||||||
@@ -312,7 +312,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
try {
|
try {
|
||||||
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
int hashCodeForDatabase = calculateHashCodeMd5(database);
|
||||||
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_QUERY_STATS_REPORTED,
|
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_QUERY_STATS_REPORTED,
|
||||||
extraStats.mSamplingRatio,
|
extraStats.mSamplingInterval,
|
||||||
extraStats.mSkippedSampleCount,
|
extraStats.mSkippedSampleCount,
|
||||||
extraStats.mPackageUid,
|
extraStats.mPackageUid,
|
||||||
hashCodeForDatabase,
|
hashCodeForDatabase,
|
||||||
@@ -355,7 +355,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
ExtraStats extraStats = createExtraStatsLocked(/*packageName=*/ null,
|
ExtraStats extraStats = createExtraStatsLocked(/*packageName=*/ null,
|
||||||
CallStats.CALL_TYPE_INITIALIZE);
|
CallStats.CALL_TYPE_INITIALIZE);
|
||||||
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_INITIALIZE_STATS_REPORTED,
|
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_INITIALIZE_STATS_REPORTED,
|
||||||
extraStats.mSamplingRatio,
|
extraStats.mSamplingInterval,
|
||||||
extraStats.mSkippedSampleCount,
|
extraStats.mSkippedSampleCount,
|
||||||
extraStats.mPackageUid,
|
extraStats.mPackageUid,
|
||||||
stats.getStatusCode(),
|
stats.getStatusCode(),
|
||||||
@@ -428,14 +428,14 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
packageUid = getPackageUidAsUserLocked(packageName);
|
packageUid = getPackageUidAsUserLocked(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int samplingRatio = mConfig.mSamplingRatios.get(callType,
|
int samplingInterval = mConfig.mSamplingIntervals.get(callType,
|
||||||
mConfig.mDefaultSamplingRatio);
|
mConfig.mDefaultSamplingInterval);
|
||||||
|
|
||||||
int skippedSampleCount = mSkippedSampleCountLocked.get(callType,
|
int skippedSampleCount = mSkippedSampleCountLocked.get(callType,
|
||||||
/*valueOfKeyIfNotFound=*/ 0);
|
/*valueOfKeyIfNotFound=*/ 0);
|
||||||
mSkippedSampleCountLocked.put(callType, 0);
|
mSkippedSampleCountLocked.put(callType, 0);
|
||||||
|
|
||||||
return new ExtraStats(packageUid, samplingRatio, skippedSampleCount);
|
return new ExtraStats(packageUid, samplingInterval, skippedSampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -450,11 +450,11 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
// rate limiting.
|
// rate limiting.
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean shouldLogForTypeLocked(@CallStats.CallType int callType) {
|
boolean shouldLogForTypeLocked(@CallStats.CallType int callType) {
|
||||||
int samplingRatio = mConfig.mSamplingRatios.get(callType,
|
int samplingInterval = mConfig.mSamplingIntervals.get(callType,
|
||||||
mConfig.mDefaultSamplingRatio);
|
mConfig.mDefaultSamplingInterval);
|
||||||
|
|
||||||
// Sampling
|
// Sampling
|
||||||
if (!shouldSample(samplingRatio)) {
|
if (!shouldSample(samplingInterval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,15 +475,15 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
/**
|
/**
|
||||||
* Checks if the stats should be "sampled"
|
* Checks if the stats should be "sampled"
|
||||||
*
|
*
|
||||||
* @param samplingRatio sampling ratio
|
* @param samplingInterval sampling interval
|
||||||
* @return if the stats should be sampled
|
* @return if the stats should be sampled
|
||||||
*/
|
*/
|
||||||
private boolean shouldSample(int samplingRatio) {
|
private boolean shouldSample(int samplingInterval) {
|
||||||
if (samplingRatio <= 0) {
|
if (samplingInterval <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mRng.nextInt((int) samplingRatio) == 0;
|
return mRng.nextInt((int) samplingInterval) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ android_test {
|
|||||||
name: "FrameworksMockingServicesTests",
|
name: "FrameworksMockingServicesTests",
|
||||||
defaults: ["FrameworkMockingServicesTests-jni-defaults"],
|
defaults: ["FrameworkMockingServicesTests-jni-defaults"],
|
||||||
|
|
||||||
srcs: ["src/**/*.java", "src/**/*.kt"],
|
srcs: [
|
||||||
|
"src/**/*.java",
|
||||||
|
"src/**/*.kt",
|
||||||
|
],
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"services.core",
|
"services.core",
|
||||||
@@ -41,6 +44,7 @@ android_test {
|
|||||||
"service-jobscheduler",
|
"service-jobscheduler",
|
||||||
"service-permission.impl",
|
"service-permission.impl",
|
||||||
"service-blobstore",
|
"service-blobstore",
|
||||||
|
"service-appsearch",
|
||||||
"androidx.test.runner",
|
"androidx.test.runner",
|
||||||
"androidx.test.ext.truth",
|
"androidx.test.ext.truth",
|
||||||
"mockito-target-extended-minus-junit4",
|
"mockito-target-extended-minus-junit4",
|
||||||
|
|||||||
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 com.android.server.appsearch;
|
||||||
|
|
||||||
|
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
|
||||||
|
import com.android.server.testables.TestableDeviceConfig;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AppSearchConfig}.
|
||||||
|
*
|
||||||
|
* <p>Build/Install/Run: atest FrameworksMockingServicesTests:AppSearchConfigTest
|
||||||
|
*/
|
||||||
|
public class AppSearchConfigTest {
|
||||||
|
@Rule
|
||||||
|
public final TestableDeviceConfig.TestableDeviceConfigRule
|
||||||
|
mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultValues_allCachedValue() {
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
|
||||||
|
AppSearchConfig.DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
|
||||||
|
AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomizedValue_minTimeIntervalBetweenSamplesMillis() {
|
||||||
|
final long minTimeIntervalBetweenSamplesMillis = -1;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(minTimeIntervalBetweenSamplesMillis),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
|
||||||
|
minTimeIntervalBetweenSamplesMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomizedValueOverride_minTimeIntervalBetweenSamplesMillis() {
|
||||||
|
long minTimeIntervalBetweenSamplesMillis = -1;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(minTimeIntervalBetweenSamplesMillis),
|
||||||
|
false);
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
minTimeIntervalBetweenSamplesMillis = -2;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(minTimeIntervalBetweenSamplesMillis),
|
||||||
|
false);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
|
||||||
|
minTimeIntervalBetweenSamplesMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomizedValue_allSamplingIntervals() {
|
||||||
|
final int samplingIntervalDefault = -1;
|
||||||
|
final int samplingIntervalPutDocumentStats = -2;
|
||||||
|
final int samplingIntervalBatchCallStats = -3;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
Integer.toString(samplingIntervalBatchCallStats),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
|
||||||
|
samplingIntervalDefault);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
samplingIntervalPutDocumentStats);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
samplingIntervalBatchCallStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomizedValueOverride_allSamplingIntervals() {
|
||||||
|
int samplingIntervalDefault = -1;
|
||||||
|
int samplingIntervalPutDocumentStats = -2;
|
||||||
|
int samplingIntervalBatchCallStats = -3;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
Integer.toString(samplingIntervalBatchCallStats),
|
||||||
|
false);
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
// Overrides
|
||||||
|
samplingIntervalDefault = -4;
|
||||||
|
samplingIntervalPutDocumentStats = -5;
|
||||||
|
samplingIntervalBatchCallStats = -6;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
Integer.toString(samplingIntervalBatchCallStats),
|
||||||
|
false);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
|
||||||
|
samplingIntervalDefault);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
samplingIntervalPutDocumentStats);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
samplingIntervalBatchCallStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if we fall back to {@link AppSearchConfig#DEFAULT_SAMPLING_INTERVAL} if both default
|
||||||
|
* sampling
|
||||||
|
* interval and custom value are not set in DeviceConfig, and there is some other sampling
|
||||||
|
* interval
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFallbackToDefaultSamplingValue_useHardCodedDefault() {
|
||||||
|
final int samplingIntervalPutDocumentStats = -1;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
samplingIntervalPutDocumentStats);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests if we fall back to configured default sampling interval if custom value is not set in
|
||||||
|
// DeviceConfig.
|
||||||
|
@Test
|
||||||
|
public void testFallbackDefaultSamplingValue_useConfiguredDefault() {
|
||||||
|
final int samplingIntervalPutDocumentStats = -1;
|
||||||
|
final int samplingIntervalDefault = -2;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
samplingIntervalPutDocumentStats);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
samplingIntervalDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that cached values should reflect latest values in DeviceConfig.
|
||||||
|
@Test
|
||||||
|
public void testFallbackDefaultSamplingValue_defaultValueChanged() {
|
||||||
|
int samplingIntervalPutDocumentStats = -1;
|
||||||
|
int samplingIntervalDefault = -2;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
// Sampling values changed.
|
||||||
|
samplingIntervalPutDocumentStats = -3;
|
||||||
|
samplingIntervalDefault = -4;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(samplingIntervalPutDocumentStats),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
|
||||||
|
samplingIntervalPutDocumentStats);
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
samplingIntervalDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests default sampling interval won't affect custom sampling intervals if they are set.
|
||||||
|
@Test
|
||||||
|
public void testShouldNotFallBack_ifValueConfigured() {
|
||||||
|
int samplingIntervalDefault = -1;
|
||||||
|
int samplingIntervalBatchCallStats = -2;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
Integer.toString(samplingIntervalBatchCallStats),
|
||||||
|
false);
|
||||||
|
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
// Default sampling interval changed.
|
||||||
|
samplingIntervalDefault = -3;
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(samplingIntervalDefault),
|
||||||
|
false);
|
||||||
|
|
||||||
|
assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
|
||||||
|
samplingIntervalBatchCallStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotUsable_afterClose() {
|
||||||
|
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
|
||||||
|
appSearchConfig.close();
|
||||||
|
|
||||||
|
Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
|
||||||
|
IllegalStateException.class,
|
||||||
|
() -> appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis());
|
||||||
|
Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
|
||||||
|
IllegalStateException.class,
|
||||||
|
() -> appSearchConfig.getCachedSamplingIntervalDefault());
|
||||||
|
Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
|
||||||
|
IllegalStateException.class,
|
||||||
|
() -> appSearchConfig.getCachedSamplingIntervalForBatchCallStats());
|
||||||
|
Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
|
||||||
|
IllegalStateException.class,
|
||||||
|
() -> appSearchConfig.getCachedSamplingIntervalForPutDocumentStats());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
public class PlatformLoggerTest {
|
public class PlatformLoggerTest {
|
||||||
private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
|
private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
|
||||||
private static final int TEST_DEFAULT_SAMPLING_RATIO = 10;
|
private static final int TEST_DEFAULT_SAMPLING_INTERVAL = 10;
|
||||||
private static final String TEST_PACKAGE_NAME = "packageName";
|
private static final String TEST_PACKAGE_NAME = "packageName";
|
||||||
private MockPackageManager mMockPackageManager = new MockPackageManager();
|
private MockPackageManager mMockPackageManager = new MockPackageManager();
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@@ -72,63 +72,63 @@ public class PlatformLoggerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() {
|
public void testCreateExtraStatsLocked_nullSamplingIntervalMap_returnsDefault() {
|
||||||
PlatformLogger logger = new PlatformLogger(
|
PlatformLogger logger = new PlatformLogger(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
TEST_DEFAULT_SAMPLING_RATIO,
|
TEST_DEFAULT_SAMPLING_INTERVAL,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
|
|
||||||
// Make sure default sampling ratio is used if samplingMap is not provided.
|
// Make sure default sampling interval is used if samplingMap is not provided.
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_UNKNOWN).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_UNKNOWN).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_INITIALIZE).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_SEARCH).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_FLUSH).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateExtraStatsLocked_with_samplingRatioMap_returnsConfiguredSamplingRatio() {
|
public void testCreateExtraStatsLocked_with_samplingIntervalMap_returnsConfigured() {
|
||||||
int putDocumentSamplingRatio = 1;
|
int putDocumentSamplingInterval = 1;
|
||||||
int querySamplingRatio = 2;
|
int querySamplingInterval = 2;
|
||||||
final SparseIntArray samplingRatios = new SparseIntArray();
|
final SparseIntArray samplingIntervals = new SparseIntArray();
|
||||||
samplingRatios.put(CallStats.CALL_TYPE_PUT_DOCUMENT, putDocumentSamplingRatio);
|
samplingIntervals.put(CallStats.CALL_TYPE_PUT_DOCUMENT, putDocumentSamplingInterval);
|
||||||
samplingRatios.put(CallStats.CALL_TYPE_SEARCH, querySamplingRatio);
|
samplingIntervals.put(CallStats.CALL_TYPE_SEARCH, querySamplingInterval);
|
||||||
PlatformLogger logger = new PlatformLogger(
|
PlatformLogger logger = new PlatformLogger(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
TEST_DEFAULT_SAMPLING_RATIO,
|
TEST_DEFAULT_SAMPLING_INTERVAL,
|
||||||
samplingRatios));
|
samplingIntervals));
|
||||||
|
|
||||||
// The default sampling ratio should be used if no sampling ratio is
|
// The default sampling interval should be used if no sampling interval is
|
||||||
// provided for certain call type.
|
// provided for certain call type.
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_INITIALIZE).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_FLUSH).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
||||||
TEST_DEFAULT_SAMPLING_RATIO);
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
|
||||||
// The configured sampling ratio is used if sampling ratio is available
|
// The configured sampling interval is used if sampling interval is available
|
||||||
// for certain call type.
|
// for certain call type.
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSamplingInterval).isEqualTo(
|
||||||
putDocumentSamplingRatio);
|
putDocumentSamplingInterval);
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
CallStats.CALL_TYPE_SEARCH).mSamplingRatio).isEqualTo(
|
CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
|
||||||
querySamplingRatio);
|
querySamplingInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -202,16 +202,16 @@ public class PlatformLoggerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShouldLogForTypeLocked_trueWhenSampleRatioIsOne() {
|
public void testShouldLogForTypeLocked_trueWhenSampleIntervalIsOne() {
|
||||||
final int samplingRatio = 1;
|
final int samplingInterval = 1;
|
||||||
final String testPackageName = "packageName";
|
final String testPackageName = "packageName";
|
||||||
PlatformLogger logger = new PlatformLogger(
|
PlatformLogger logger = new PlatformLogger(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
samplingRatio,
|
samplingInterval,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
|
|
||||||
// Sample should always be logged for the first time if sampling is disabled(value is one).
|
// Sample should always be logged for the first time if sampling is disabled(value is one).
|
||||||
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
|
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
|
||||||
@@ -220,18 +220,18 @@ public class PlatformLoggerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShouldLogForTypeLocked_falseWhenSampleRatioIsNegative() {
|
public void testShouldLogForTypeLocked_falseWhenSampleIntervalIsNegative() {
|
||||||
final int samplingRatio = -1;
|
final int samplingInterval = -1;
|
||||||
final String testPackageName = "packageName";
|
final String testPackageName = "packageName";
|
||||||
PlatformLogger logger = new PlatformLogger(
|
PlatformLogger logger = new PlatformLogger(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
samplingRatio,
|
samplingInterval,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
|
|
||||||
// Makes sure sample will be excluded due to sampling if sample ratio is negative.
|
// Makes sure sample will be excluded due to sampling if sample interval is negative.
|
||||||
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
||||||
// Skipped count should be 0 since it doesn't pass the sampling.
|
// Skipped count should be 0 since it doesn't pass the sampling.
|
||||||
assertThat(logger.createExtraStatsLocked(testPackageName,
|
assertThat(logger.createExtraStatsLocked(testPackageName,
|
||||||
@@ -241,7 +241,7 @@ public class PlatformLoggerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testShouldLogForTypeLocked_falseWhenWithinCoolOffInterval() {
|
public void testShouldLogForTypeLocked_falseWhenWithinCoolOffInterval() {
|
||||||
// Next sample won't be excluded due to sampling.
|
// Next sample won't be excluded due to sampling.
|
||||||
final int samplingRatio = 1;
|
final int samplingInterval = 1;
|
||||||
// Next sample would guaranteed to be too close.
|
// Next sample would guaranteed to be too close.
|
||||||
final int minTimeIntervalBetweenSamplesMillis = Integer.MAX_VALUE;
|
final int minTimeIntervalBetweenSamplesMillis = Integer.MAX_VALUE;
|
||||||
final String testPackageName = "packageName";
|
final String testPackageName = "packageName";
|
||||||
@@ -250,8 +250,8 @@ public class PlatformLoggerTest {
|
|||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
minTimeIntervalBetweenSamplesMillis,
|
minTimeIntervalBetweenSamplesMillis,
|
||||||
samplingRatio,
|
samplingInterval,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
||||||
|
|
||||||
// Makes sure sample will be excluded due to rate limiting if samples are too close.
|
// Makes sure sample will be excluded due to rate limiting if samples are too close.
|
||||||
@@ -263,7 +263,7 @@ public class PlatformLoggerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testShouldLogForTypeLocked_trueWhenOutsideOfCoolOffInterval() {
|
public void testShouldLogForTypeLocked_trueWhenOutsideOfCoolOffInterval() {
|
||||||
// Next sample won't be excluded due to sampling.
|
// Next sample won't be excluded due to sampling.
|
||||||
final int samplingRatio = 1;
|
final int samplingInterval = 1;
|
||||||
// Next sample would guaranteed to be included.
|
// Next sample would guaranteed to be included.
|
||||||
final int minTimeIntervalBetweenSamplesMillis = 0;
|
final int minTimeIntervalBetweenSamplesMillis = 0;
|
||||||
final String testPackageName = "packageName";
|
final String testPackageName = "packageName";
|
||||||
@@ -272,8 +272,8 @@ public class PlatformLoggerTest {
|
|||||||
UserHandle.of(UserHandle.USER_NULL),
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
minTimeIntervalBetweenSamplesMillis,
|
minTimeIntervalBetweenSamplesMillis,
|
||||||
samplingRatio,
|
samplingInterval,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
||||||
|
|
||||||
// Makes sure sample will be logged if it is not too close to previous sample.
|
// Makes sure sample will be logged if it is not too close to previous sample.
|
||||||
@@ -292,8 +292,8 @@ public class PlatformLoggerTest {
|
|||||||
mContext.getUser(),
|
mContext.getUser(),
|
||||||
new PlatformLogger.Config(
|
new PlatformLogger.Config(
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
TEST_DEFAULT_SAMPLING_RATIO,
|
TEST_DEFAULT_SAMPLING_INTERVAL,
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
/*samplingIntervals=*/ new SparseIntArray()));
|
||||||
mMockPackageManager.mockGetPackageUidAsUser(testPackageName, mContext.getUserId(), testUid);
|
mMockPackageManager.mockGetPackageUidAsUser(testPackageName, mContext.getUserId(), testUid);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user