Cache DeviceConfig's values in Attention
AttentionManagerService might be called on a critical system path, and DeviceConfig calls have some costs. To reduce these cost - cache the values for at least 4 hours. Bug: 169427927 Test: manually Change-Id: I7bfb564701e604ae2fa7544826526ef060552e56
This commit is contained in:
@@ -81,12 +81,22 @@ public class AttentionManagerService extends SystemService {
|
||||
/** Service will unbind if connection is not used for that amount of time. */
|
||||
private static final long CONNECTION_TTL_MILLIS = 60_000;
|
||||
|
||||
/**
|
||||
* We cache the DeviceConfig values to avoid frequent ashmem-related checks; if the cached
|
||||
* values are stale for more than this duration we will update the cache.
|
||||
*/
|
||||
@VisibleForTesting static final long DEVICE_CONFIG_MAX_STALENESS_MILLIS = 4 * 60 * 60 * 1000L;
|
||||
|
||||
@VisibleForTesting long mLastReadDeviceConfigMillis = Long.MIN_VALUE;
|
||||
|
||||
/** DeviceConfig flag name, if {@code true}, enables AttentionManagerService features. */
|
||||
private static final String KEY_SERVICE_ENABLED = "service_enabled";
|
||||
|
||||
/** Default value in absence of {@link DeviceConfig} override. */
|
||||
private static final boolean DEFAULT_SERVICE_ENABLED = true;
|
||||
|
||||
private boolean mIsServiceEnabledCached;
|
||||
|
||||
/**
|
||||
* DeviceConfig flag name, describes how much time we consider a result fresh; if the check
|
||||
* attention called within that period - cached value will be returned.
|
||||
@@ -98,6 +108,8 @@ public class AttentionManagerService extends SystemService {
|
||||
@VisibleForTesting
|
||||
static final long DEFAULT_STALE_AFTER_MILLIS = 1_000;
|
||||
|
||||
private long mStaleAfterMillisCached;
|
||||
|
||||
/** The size of the buffer that stores recent attention check results. */
|
||||
@VisibleForTesting
|
||||
protected static final int ATTENTION_CACHE_BUFFER_SIZE = 5;
|
||||
@@ -172,12 +184,12 @@ public class AttentionManagerService extends SystemService {
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected boolean isAttentionServiceSupported() {
|
||||
return isServiceEnabled() && isServiceConfigured(mContext);
|
||||
return isServiceEnabled();
|
||||
}
|
||||
|
||||
private boolean isServiceEnabled() {
|
||||
return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, KEY_SERVICE_ENABLED,
|
||||
DEFAULT_SERVICE_ENABLED);
|
||||
ensureDeviceConfigCachedValuesFreshness();
|
||||
return mIsServiceEnabledCached;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,16 +198,39 @@ public class AttentionManagerService extends SystemService {
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected long getStaleAfterMillis() {
|
||||
ensureDeviceConfigCachedValuesFreshness();
|
||||
return mStaleAfterMillisCached;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void ensureDeviceConfigCachedValuesFreshness() {
|
||||
final long now = SystemClock.elapsedRealtime();
|
||||
final long whenBecomesStale =
|
||||
mLastReadDeviceConfigMillis + DEVICE_CONFIG_MAX_STALENESS_MILLIS;
|
||||
if (now < whenBecomesStale) {
|
||||
if (DEBUG) {
|
||||
Slog.d(LOG_TAG,
|
||||
"Cached values are still fresh. Refreshed at=" + mLastReadDeviceConfigMillis
|
||||
+ ", now=" + now);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mIsServiceEnabledCached = DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_SERVICE_ENABLED,
|
||||
DEFAULT_SERVICE_ENABLED);
|
||||
|
||||
final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_STALE_AFTER_MILLIS,
|
||||
DEFAULT_STALE_AFTER_MILLIS);
|
||||
|
||||
if (millis < 0 || millis > 10_000) {
|
||||
Slog.w(LOG_TAG, "Bad flag value supplied for: " + KEY_STALE_AFTER_MILLIS);
|
||||
return DEFAULT_STALE_AFTER_MILLIS;
|
||||
mStaleAfterMillisCached = DEFAULT_STALE_AFTER_MILLIS;
|
||||
} else {
|
||||
mStaleAfterMillisCached = millis;
|
||||
}
|
||||
|
||||
return millis;
|
||||
mLastReadDeviceConfigMillis = now;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
|
||||
|
||||
import static com.android.server.attention.AttentionManagerService.ATTENTION_CACHE_BUFFER_SIZE;
|
||||
import static com.android.server.attention.AttentionManagerService.DEFAULT_STALE_AFTER_MILLIS;
|
||||
import static com.android.server.attention.AttentionManagerService.DEVICE_CONFIG_MAX_STALENESS_MILLIS;
|
||||
import static com.android.server.attention.AttentionManagerService.KEY_STALE_AFTER_MILLIS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -39,6 +40,7 @@ import android.os.IPowerManager;
|
||||
import android.os.IThermalService;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.service.attention.IAttentionCallback;
|
||||
import android.service.attention.IAttentionService;
|
||||
@@ -205,6 +207,38 @@ public class AttentionManagerServiceTest {
|
||||
DEFAULT_STALE_AFTER_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnsureDeviceConfigCachedValuesFreshness_doesNotCallDeviceConfigTooFrequently() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_STALE_AFTER_MILLIS, String.valueOf(DEFAULT_STALE_AFTER_MILLIS), false);
|
||||
assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
|
||||
DEFAULT_STALE_AFTER_MILLIS);
|
||||
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_STALE_AFTER_MILLIS, "123", false);
|
||||
|
||||
// New value is ignored
|
||||
assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
|
||||
DEFAULT_STALE_AFTER_MILLIS);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEnsureDeviceConfigCachedValuesFreshness_refreshesWhenStale() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_STALE_AFTER_MILLIS, String.valueOf(DEFAULT_STALE_AFTER_MILLIS), false);
|
||||
assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
|
||||
DEFAULT_STALE_AFTER_MILLIS);
|
||||
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_STALE_AFTER_MILLIS, "123", false);
|
||||
mSpyAttentionManager.mLastReadDeviceConfigMillis =
|
||||
SystemClock.elapsedRealtime() - (DEVICE_CONFIG_MAX_STALENESS_MILLIS + 1);
|
||||
|
||||
// Values are refreshed
|
||||
assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(123);
|
||||
}
|
||||
|
||||
private class MockIAttentionService implements IAttentionService {
|
||||
public void checkAttention(IAttentionCallback callback) throws RemoteException {
|
||||
callback.onSuccess(0, 0);
|
||||
|
||||
Reference in New Issue
Block a user