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

Commit dbe15f0b authored by Alex Salo's avatar Alex Salo
Browse files

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
parent 82bc48af
Loading
Loading
Loading
Loading
+41 −6
Original line number Diff line number Diff line
@@ -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;
    }

    /**
+34 −0
Original line number Diff line number Diff line
@@ -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);