Merge "Use AppSearchConfig in PlatformLogger" into sc-dev
This commit is contained in:
@@ -44,6 +44,8 @@ import java.util.concurrent.Executor;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class AppSearchConfig implements AutoCloseable {
|
public final class AppSearchConfig implements AutoCloseable {
|
||||||
|
private static volatile AppSearchConfig sConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It would be used as default min time interval between samples in millis if there is no value
|
* 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.
|
* set for {@link AppSearchConfig#KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS} in DeviceConfig.
|
||||||
@@ -101,12 +103,16 @@ public final class AppSearchConfig implements AutoCloseable {
|
|||||||
updateCachedValues(properties);
|
updateCachedValues(properties);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private AppSearchConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of {@link AppSearchConfig}.
|
* Creates an instance of {@link AppSearchConfig}.
|
||||||
*
|
*
|
||||||
* @param executor used to fetch and cache the flag values from DeviceConfig during creation or
|
* @param executor used to fetch and cache the flag values from DeviceConfig during creation or
|
||||||
* config change.
|
* config change.
|
||||||
*/
|
*/
|
||||||
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
||||||
@NonNull
|
@NonNull
|
||||||
public static AppSearchConfig create(@NonNull Executor executor) {
|
public static AppSearchConfig create(@NonNull Executor executor) {
|
||||||
Objects.requireNonNull(executor);
|
Objects.requireNonNull(executor);
|
||||||
@@ -115,7 +121,23 @@ public final class AppSearchConfig implements AutoCloseable {
|
|||||||
return configManager;
|
return configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AppSearchConfig() {
|
/**
|
||||||
|
* Gets an instance of {@link AppSearchConfig} to be used.
|
||||||
|
*
|
||||||
|
* <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
|
||||||
|
* existing instance will be returned.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static AppSearchConfig getInstance(@NonNull Executor executor) {
|
||||||
|
Objects.requireNonNull(executor);
|
||||||
|
if (sConfig == null) {
|
||||||
|
synchronized (AppSearchConfig.class) {
|
||||||
|
if (sConfig == null) {
|
||||||
|
sConfig = create(executor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
|
if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
|
||||||
// Only clear the package's data if AppSearch exists for this user.
|
// Only clear the package's data if AppSearch exists for this user.
|
||||||
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
|
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
|
||||||
userHandle);
|
userHandle, AppSearchConfig.getInstance(EXECUTOR));
|
||||||
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
|
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
|
||||||
userHandle, logger);
|
userHandle, logger);
|
||||||
//TODO(b/145759910) clear visibility setting for package.
|
//TODO(b/145759910) clear visibility setting for package.
|
||||||
@@ -1147,7 +1147,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUser);
|
verifyUserUnlocked(callingUser);
|
||||||
logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
||||||
mContext, callingUser);
|
mContext, callingUser,
|
||||||
|
AppSearchConfig.getInstance(EXECUTOR));
|
||||||
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
|
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
|
||||||
++operationSuccessCount;
|
++operationSuccessCount;
|
||||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
||||||
@@ -1313,7 +1314,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
verifyUserUnlocked(userHandle);
|
verifyUserUnlocked(userHandle);
|
||||||
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
||||||
mContext, userHandle);
|
mContext, userHandle,
|
||||||
|
AppSearchConfig.getInstance(EXECUTOR));
|
||||||
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
|
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
|
||||||
mContext, userHandle, logger);
|
mContext, userHandle, logger);
|
||||||
stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
|
stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
|
||||||
@@ -1341,7 +1343,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
||||||
mContext, userHandle);
|
mContext, userHandle,
|
||||||
|
AppSearchConfig.getInstance(EXECUTOR));
|
||||||
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
|
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
|
||||||
mContext, userHandle, logger);
|
mContext, userHandle, logger);
|
||||||
for (int i = 0; i < packagesForUid.length; i++) {
|
for (int i = 0; i < packagesForUid.length; i++) {
|
||||||
@@ -1370,7 +1373,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
|
||||||
mContext, userHandle);
|
mContext, userHandle,
|
||||||
|
AppSearchConfig.getInstance(EXECUTOR));
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
|
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
|
||||||
for (int i = 0; i < packagesForUser.size(); i++) {
|
for (int i = 0; i < packagesForUser.size(); i++) {
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import android.annotation.NonNull;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.SparseIntArray;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.server.appsearch.AppSearchConfig;
|
||||||
import com.android.server.appsearch.AppSearchManagerService;
|
import com.android.server.appsearch.AppSearchManagerService;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -34,12 +34,6 @@ import java.util.Objects;
|
|||||||
* <p>These instances are managed per unique device-user.
|
* <p>These instances are managed per unique device-user.
|
||||||
*/
|
*/
|
||||||
public final class LoggerInstanceManager {
|
public final class LoggerInstanceManager {
|
||||||
// TODO(b/173532925) flags to control those three
|
|
||||||
// So probably we can't pass those three in the constructor but need to fetch the latest value
|
|
||||||
// every time we need them in the logger.
|
|
||||||
private static final int MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
|
|
||||||
private static final int DEFAULT_SAMPLING_RATIO = 10;
|
|
||||||
|
|
||||||
private static volatile LoggerInstanceManager sLoggerInstanceManager;
|
private static volatile LoggerInstanceManager sLoggerInstanceManager;
|
||||||
|
|
||||||
@GuardedBy("mInstancesLocked")
|
@GuardedBy("mInstancesLocked")
|
||||||
@@ -76,17 +70,13 @@ public final class LoggerInstanceManager {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public PlatformLogger getOrCreatePlatformLogger(
|
public PlatformLogger getOrCreatePlatformLogger(
|
||||||
@NonNull Context context, @NonNull UserHandle userHandle) {
|
@NonNull Context context, @NonNull UserHandle userHandle,
|
||||||
|
@NonNull AppSearchConfig config) {
|
||||||
Objects.requireNonNull(userHandle);
|
Objects.requireNonNull(userHandle);
|
||||||
synchronized (mInstancesLocked) {
|
synchronized (mInstancesLocked) {
|
||||||
PlatformLogger instance = mInstancesLocked.get(userHandle);
|
PlatformLogger instance = mInstancesLocked.get(userHandle);
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new PlatformLogger(context, userHandle, new PlatformLogger.Config(
|
instance = new PlatformLogger(context, userHandle, config);
|
||||||
MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
DEFAULT_SAMPLING_RATIO,
|
|
||||||
// TODO(b/173532925) re-enable sampling ratios for different stats types
|
|
||||||
// once we have P/H flag manager setup in ag/13977824
|
|
||||||
/*samplingRatios=*/ new SparseIntArray()));
|
|
||||||
mInstancesLocked.put(userHandle, instance);
|
mInstancesLocked.put(userHandle, instance);
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.util.SparseIntArray;
|
|||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.server.appsearch.AppSearchConfig;
|
||||||
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
|
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
@@ -60,15 +61,15 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
// User we're logging for.
|
// User we're logging for.
|
||||||
private final UserHandle mUserHandle;
|
private final UserHandle mUserHandle;
|
||||||
|
|
||||||
// Configuration for the logger
|
// Manager holding the configuration flags
|
||||||
private final Config mConfig;
|
private final AppSearchConfig mConfig;
|
||||||
|
|
||||||
private final Random mRng = new Random();
|
private final Random mRng = new Random();
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SparseArray to track how many stats we skipped due to
|
* SparseArray to track how many stats we skipped due to
|
||||||
* {@link Config#mMinTimeIntervalBetweenSamplesMillis}.
|
* {@link AppSearchConfig#getCachedMinTimeIntervalBetweenSamplesMillis()}.
|
||||||
*
|
*
|
||||||
* <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:
|
||||||
@@ -97,53 +98,6 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private long mLastPushTimeMillisLocked = 0;
|
private long mLastPushTimeMillisLocked = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to configure the {@link PlatformLogger}
|
|
||||||
*/
|
|
||||||
public static final class Config {
|
|
||||||
// Minimum time interval (in millis) since last message logged to Westworld before
|
|
||||||
// logging again.
|
|
||||||
private final long mMinTimeIntervalBetweenSamplesMillis;
|
|
||||||
|
|
||||||
// Default sampling interval for all types of stats
|
|
||||||
private final int mDefaultSamplingInterval;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sampling intervals for different types of stats
|
|
||||||
*
|
|
||||||
* <p>This SparseArray is passed by client and is READ-ONLY. The key to that SparseArray is
|
|
||||||
* {@link CallStats.CallType}
|
|
||||||
*
|
|
||||||
* <p>If sampling interval is missing for certain stats type,
|
|
||||||
* {@link Config#mDefaultSamplingInterval} will be used.
|
|
||||||
*
|
|
||||||
* <p>E.g. sampling interval=10 means that one out of every 10 stats was logged. If sampling
|
|
||||||
* interval is 1, we will log each sample and it acts as if the sampling is disabled.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
private final SparseIntArray mSamplingIntervals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for {@link PlatformLogger}
|
|
||||||
*
|
|
||||||
* @param minTimeIntervalBetweenSamplesMillis minimum time interval apart in Milliseconds
|
|
||||||
* required for two consecutive stats logged
|
|
||||||
* @param defaultSamplingInterval default sampling interval
|
|
||||||
* @param samplingIntervals SparseArray to customize sampling interval for
|
|
||||||
* different stat types
|
|
||||||
*/
|
|
||||||
public Config(long minTimeIntervalBetweenSamplesMillis,
|
|
||||||
int defaultSamplingInterval,
|
|
||||||
@NonNull SparseIntArray samplingIntervals) {
|
|
||||||
// TODO(b/173532925) Probably we can get rid of those three after we have p/h flags
|
|
||||||
// for them.
|
|
||||||
// e.g. we can just call DeviceConfig.get(SAMPLING_INTERVAL_FOR_PUT_DOCUMENTS).
|
|
||||||
mMinTimeIntervalBetweenSamplesMillis = minTimeIntervalBetweenSamplesMillis;
|
|
||||||
mDefaultSamplingInterval = defaultSamplingInterval;
|
|
||||||
mSamplingIntervals = samplingIntervals;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to hold platform specific stats for Westworld.
|
* Helper class to hold platform specific stats for Westworld.
|
||||||
*/
|
*/
|
||||||
@@ -166,7 +120,8 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
* Westworld constructor
|
* Westworld constructor
|
||||||
*/
|
*/
|
||||||
public PlatformLogger(
|
public PlatformLogger(
|
||||||
@NonNull Context context, @NonNull UserHandle userHandle, @NonNull Config config) {
|
@NonNull Context context, @NonNull UserHandle userHandle,
|
||||||
|
@NonNull AppSearchConfig config) {
|
||||||
mContext = Objects.requireNonNull(context);
|
mContext = Objects.requireNonNull(context);
|
||||||
mUserHandle = Objects.requireNonNull(userHandle);
|
mUserHandle = Objects.requireNonNull(userHandle);
|
||||||
mConfig = Objects.requireNonNull(config);
|
mConfig = Objects.requireNonNull(config);
|
||||||
@@ -430,9 +385,12 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
packageUid = getPackageUidAsUserLocked(packageName);
|
packageUid = getPackageUidAsUserLocked(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int samplingInterval = mConfig.mSamplingIntervals.get(callType,
|
// The sampling ratio here might be different from the one used in
|
||||||
mConfig.mDefaultSamplingInterval);
|
// shouldLogForTypeLocked if there is a config change in the middle.
|
||||||
|
// Since it is only one sample, we can just ignore this difference.
|
||||||
|
// Or we can retrieve samplingRatio at beginning and pass along
|
||||||
|
// as function parameter, but it will make code less cleaner with some duplication.
|
||||||
|
int samplingInterval = getSamplingIntervalFromConfig(callType);
|
||||||
int skippedSampleCount = mSkippedSampleCountLocked.get(callType,
|
int skippedSampleCount = mSkippedSampleCountLocked.get(callType,
|
||||||
/*valueOfKeyIfNotFound=*/ 0);
|
/*valueOfKeyIfNotFound=*/ 0);
|
||||||
mSkippedSampleCountLocked.put(callType, 0);
|
mSkippedSampleCountLocked.put(callType, 0);
|
||||||
@@ -452,9 +410,7 @@ 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 samplingInterval = mConfig.mSamplingIntervals.get(callType,
|
int samplingInterval = getSamplingIntervalFromConfig(callType);
|
||||||
mConfig.mDefaultSamplingInterval);
|
|
||||||
|
|
||||||
// Sampling
|
// Sampling
|
||||||
if (!shouldSample(samplingInterval)) {
|
if (!shouldSample(samplingInterval)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -464,7 +420,7 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
// Check the timestamp to see if it is too close to last logged sample
|
// Check the timestamp to see if it is too close to last logged sample
|
||||||
long currentTimeMillis = SystemClock.elapsedRealtime();
|
long currentTimeMillis = SystemClock.elapsedRealtime();
|
||||||
if (mLastPushTimeMillisLocked
|
if (mLastPushTimeMillisLocked
|
||||||
> currentTimeMillis - mConfig.mMinTimeIntervalBetweenSamplesMillis) {
|
> currentTimeMillis - mConfig.getCachedMinTimeIntervalBetweenSamplesMillis()) {
|
||||||
int count = mSkippedSampleCountLocked.get(callType, /*valueOfKeyIfNotFound=*/ 0);
|
int count = mSkippedSampleCountLocked.get(callType, /*valueOfKeyIfNotFound=*/ 0);
|
||||||
++count;
|
++count;
|
||||||
mSkippedSampleCountLocked.put(callType, count);
|
mSkippedSampleCountLocked.put(callType, count);
|
||||||
@@ -504,6 +460,32 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
return packageUid;
|
return packageUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns sampling ratio for stats type specified form {@link AppSearchConfig}. */
|
||||||
|
private int getSamplingIntervalFromConfig(@CallStats.CallType int statsType) {
|
||||||
|
switch (statsType) {
|
||||||
|
case CallStats.CALL_TYPE_PUT_DOCUMENTS:
|
||||||
|
case CallStats.CALL_TYPE_GET_DOCUMENTS:
|
||||||
|
case CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID:
|
||||||
|
case CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH:
|
||||||
|
return mConfig.getCachedSamplingIntervalForBatchCallStats();
|
||||||
|
case CallStats.CALL_TYPE_PUT_DOCUMENT:
|
||||||
|
return mConfig.getCachedSamplingIntervalForPutDocumentStats();
|
||||||
|
case CallStats.CALL_TYPE_UNKNOWN:
|
||||||
|
case CallStats.CALL_TYPE_INITIALIZE:
|
||||||
|
case CallStats.CALL_TYPE_SET_SCHEMA:
|
||||||
|
case CallStats.CALL_TYPE_GET_DOCUMENT:
|
||||||
|
case CallStats.CALL_TYPE_REMOVE_DOCUMENT_BY_ID:
|
||||||
|
case CallStats.CALL_TYPE_SEARCH:
|
||||||
|
case CallStats.CALL_TYPE_OPTIMIZE:
|
||||||
|
case CallStats.CALL_TYPE_FLUSH:
|
||||||
|
case CallStats.CALL_TYPE_GLOBAL_SEARCH:
|
||||||
|
case CallStats.CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH:
|
||||||
|
// TODO(b/173532925) Some of them above will have dedicated sampling ratio config
|
||||||
|
default:
|
||||||
|
return mConfig.getCachedSamplingIntervalDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions below are used for tests only
|
// Functions below are used for tests only
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ android_test {
|
|||||||
"service-permission.impl",
|
"service-permission.impl",
|
||||||
"service-blobstore",
|
"service-blobstore",
|
||||||
"service-appsearch",
|
"service-appsearch",
|
||||||
|
"androidx.test.core",
|
||||||
"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,235 @@
|
|||||||
|
/*
|
||||||
|
* 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.stats;
|
||||||
|
|
||||||
|
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.server.appsearch.AppSearchConfig;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
|
import com.android.server.testables.TestableDeviceConfig;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests covering the functionalities in {@link PlatformLogger} requiring overriding some flags
|
||||||
|
* in {@link DeviceConfig}.
|
||||||
|
*
|
||||||
|
* <p>To add tests NOT rely on overriding the configs, please add them in
|
||||||
|
* the tests for {@link PlatformLogger} in servicetests.
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PlatformLoggerTest {
|
||||||
|
private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
|
||||||
|
private static final int TEST_DEFAULT_SAMPLING_INTERVAL = 10;
|
||||||
|
private static final String TEST_PACKAGE_NAME = "packageName";
|
||||||
|
private AppSearchConfig mAppSearchConfig;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final TestableDeviceConfig.TestableDeviceConfigRule
|
||||||
|
mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
mAppSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() {
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
|
mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(TEST_DEFAULT_SAMPLING_INTERVAL),
|
||||||
|
false);
|
||||||
|
|
||||||
|
// Make sure default sampling interval is used if there is no config set.
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_UNKNOWN).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateExtraStatsLocked_samplingIntervalSet_returnsConfigured() {
|
||||||
|
int putDocumentSamplingInterval = 1;
|
||||||
|
int batchCallSamplingInterval = 2;
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Integer.toString(TEST_DEFAULT_SAMPLING_INTERVAL),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
|
||||||
|
Integer.toString(putDocumentSamplingInterval),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
|
||||||
|
Integer.toString(batchCallSamplingInterval),
|
||||||
|
false);
|
||||||
|
|
||||||
|
// The default sampling interval should be used if no sampling interval is
|
||||||
|
// provided for certain call type.
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
||||||
|
TEST_DEFAULT_SAMPLING_INTERVAL);
|
||||||
|
|
||||||
|
// The configured sampling interval is used if sampling interval is available
|
||||||
|
// for certain call type.
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSamplingInterval).isEqualTo(
|
||||||
|
putDocumentSamplingInterval);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENTS).mSamplingInterval).isEqualTo(
|
||||||
|
batchCallSamplingInterval);
|
||||||
|
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
||||||
|
CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH).mSamplingInterval).isEqualTo(
|
||||||
|
batchCallSamplingInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldLogForTypeLocked_trueWhenSampleIntervalIsOne() {
|
||||||
|
final String testPackageName = "packageName";
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
|
mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Long.toString(1),
|
||||||
|
false);
|
||||||
|
|
||||||
|
// 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.createExtraStatsLocked(testPackageName,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldLogForTypeLocked_falseWhenSampleIntervalIsNegative() {
|
||||||
|
final String testPackageName = "packageName";
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
|
mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Long.toString(-1),
|
||||||
|
false);
|
||||||
|
|
||||||
|
// Makes sure sample will be excluded due to sampling if sample interval is negative.
|
||||||
|
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
||||||
|
// Skipped count should be 0 since it doesn't pass the sampling.
|
||||||
|
assertThat(logger.createExtraStatsLocked(testPackageName,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldLogForTypeLocked_falseWhenWithinCoolOffInterval() {
|
||||||
|
// Next sample won't be excluded due to sampling.
|
||||||
|
final int samplingInterval = 1;
|
||||||
|
// Next sample would guaranteed to be too close.
|
||||||
|
final int minTimeIntervalBetweenSamplesMillis = Integer.MAX_VALUE;
|
||||||
|
final String testPackageName = "packageName";
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
|
mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Long.toString(samplingInterval),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(minTimeIntervalBetweenSamplesMillis),
|
||||||
|
false);
|
||||||
|
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
||||||
|
|
||||||
|
// Makes sure sample will be excluded due to rate limiting if samples are too close.
|
||||||
|
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
||||||
|
assertThat(logger.createExtraStatsLocked(testPackageName,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldLogForTypeLocked_trueWhenOutsideOfCoolOffInterval() {
|
||||||
|
// Next sample won't be excluded due to sampling.
|
||||||
|
final int samplingInterval = 1;
|
||||||
|
// Next sample would guaranteed to be included.
|
||||||
|
final int minTimeIntervalBetweenSamplesMillis = 0;
|
||||||
|
final String testPackageName = "packageName";
|
||||||
|
PlatformLogger logger = new PlatformLogger(
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
UserHandle.of(UserHandle.USER_NULL),
|
||||||
|
mAppSearchConfig);
|
||||||
|
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
|
||||||
|
Long.toString(samplingInterval),
|
||||||
|
false);
|
||||||
|
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
|
||||||
|
AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
||||||
|
Long.toString(minTimeIntervalBetweenSamplesMillis),
|
||||||
|
false);
|
||||||
|
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
||||||
|
|
||||||
|
// Makes sure sample will be logged if it is not too close to previous sample.
|
||||||
|
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
|
||||||
|
assertThat(logger.createExtraStatsLocked(testPackageName,
|
||||||
|
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.appsearch.stats;
|
package com.android.server.appsearch.stats;
|
||||||
|
|
||||||
|
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
@@ -28,13 +30,12 @@ import android.annotation.NonNull;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContextWrapper;
|
import android.content.ContextWrapper;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.SparseIntArray;
|
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.server.appsearch.AppSearchConfig;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -48,11 +49,14 @@ import java.security.MessageDigest;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests covering the functionalities in {@link PlatformLogger} NOT requiring overriding any flags
|
||||||
|
* in {@link android.provider.DeviceConfig}.
|
||||||
|
*
|
||||||
|
* <p>To add tests rely on overriding the flags, please add them in the
|
||||||
|
* tests for {@link PlatformLogger} in mockingservicestests.
|
||||||
|
*/
|
||||||
public class PlatformLoggerTest {
|
public class PlatformLoggerTest {
|
||||||
private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
|
|
||||||
private static final int TEST_DEFAULT_SAMPLING_INTERVAL = 10;
|
|
||||||
private static final String TEST_PACKAGE_NAME = "packageName";
|
|
||||||
|
|
||||||
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@@ -72,66 +76,6 @@ public class PlatformLoggerTest {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateExtraStatsLocked_nullSamplingIntervalMap_returnsDefault() {
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
|
|
||||||
// Make sure default sampling interval is used if samplingMap is not provided.
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_UNKNOWN).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateExtraStatsLocked_with_samplingIntervalMap_returnsConfigured() {
|
|
||||||
int putDocumentSamplingInterval = 1;
|
|
||||||
int querySamplingInterval = 2;
|
|
||||||
final SparseIntArray samplingIntervals = new SparseIntArray();
|
|
||||||
samplingIntervals.put(CallStats.CALL_TYPE_PUT_DOCUMENT, putDocumentSamplingInterval);
|
|
||||||
samplingIntervals.put(CallStats.CALL_TYPE_SEARCH, querySamplingInterval);
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL,
|
|
||||||
samplingIntervals));
|
|
||||||
|
|
||||||
// The default sampling interval should be used if no sampling interval is
|
|
||||||
// provided for certain call type.
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL);
|
|
||||||
|
|
||||||
// The configured sampling interval is used if sampling interval is available
|
|
||||||
// for certain call type.
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSamplingInterval).isEqualTo(
|
|
||||||
putDocumentSamplingInterval);
|
|
||||||
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
|
|
||||||
CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
|
|
||||||
querySamplingInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalculateHashCode_MD5_int32_shortString()
|
public void testCalculateHashCode_MD5_int32_shortString()
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
@@ -202,87 +146,6 @@ public class PlatformLoggerTest {
|
|||||||
assertThat(PlatformLogger.calculateHashCodeMd5(/*str=*/ null)).isEqualTo(-1);
|
assertThat(PlatformLogger.calculateHashCodeMd5(/*str=*/ null)).isEqualTo(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldLogForTypeLocked_trueWhenSampleIntervalIsOne() {
|
|
||||||
final int samplingInterval = 1;
|
|
||||||
final String testPackageName = "packageName";
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
samplingInterval,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
|
|
||||||
// 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.createExtraStatsLocked(testPackageName,
|
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldLogForTypeLocked_falseWhenSampleIntervalIsNegative() {
|
|
||||||
final int samplingInterval = -1;
|
|
||||||
final String testPackageName = "packageName";
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
samplingInterval,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
|
|
||||||
// Makes sure sample will be excluded due to sampling if sample interval is negative.
|
|
||||||
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
|
||||||
// Skipped count should be 0 since it doesn't pass the sampling.
|
|
||||||
assertThat(logger.createExtraStatsLocked(testPackageName,
|
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldLogForTypeLocked_falseWhenWithinCoolOffInterval() {
|
|
||||||
// Next sample won't be excluded due to sampling.
|
|
||||||
final int samplingInterval = 1;
|
|
||||||
// Next sample would guaranteed to be too close.
|
|
||||||
final int minTimeIntervalBetweenSamplesMillis = Integer.MAX_VALUE;
|
|
||||||
final String testPackageName = "packageName";
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
minTimeIntervalBetweenSamplesMillis,
|
|
||||||
samplingInterval,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
|
||||||
|
|
||||||
// Makes sure sample will be excluded due to rate limiting if samples are too close.
|
|
||||||
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
|
|
||||||
assertThat(logger.createExtraStatsLocked(testPackageName,
|
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldLogForTypeLocked_trueWhenOutsideOfCoolOffInterval() {
|
|
||||||
// Next sample won't be excluded due to sampling.
|
|
||||||
final int samplingInterval = 1;
|
|
||||||
// Next sample would guaranteed to be included.
|
|
||||||
final int minTimeIntervalBetweenSamplesMillis = 0;
|
|
||||||
final String testPackageName = "packageName";
|
|
||||||
PlatformLogger logger = new PlatformLogger(
|
|
||||||
ApplicationProvider.getApplicationContext(),
|
|
||||||
UserHandle.of(UserHandle.USER_NULL),
|
|
||||||
new PlatformLogger.Config(
|
|
||||||
minTimeIntervalBetweenSamplesMillis,
|
|
||||||
samplingInterval,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
|
|
||||||
|
|
||||||
// Makes sure sample will be logged if it is not too close to previous sample.
|
|
||||||
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
|
|
||||||
assertThat(logger.createExtraStatsLocked(testPackageName,
|
|
||||||
CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes sure the caching works while getting the UID for calling package. */
|
/** Makes sure the caching works while getting the UID for calling package. */
|
||||||
@Test
|
@Test
|
||||||
public void testGetPackageUidAsUser() throws Exception {
|
public void testGetPackageUidAsUser() throws Exception {
|
||||||
@@ -291,10 +154,7 @@ public class PlatformLoggerTest {
|
|||||||
PlatformLogger logger = new PlatformLogger(
|
PlatformLogger logger = new PlatformLogger(
|
||||||
mContext,
|
mContext,
|
||||||
mContext.getUser(),
|
mContext.getUser(),
|
||||||
new PlatformLogger.Config(
|
AppSearchConfig.create(DIRECT_EXECUTOR));
|
||||||
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
|
|
||||||
TEST_DEFAULT_SAMPLING_INTERVAL,
|
|
||||||
/*samplingIntervals=*/ new SparseIntArray()));
|
|
||||||
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
|
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
|
||||||
when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid);
|
when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user