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

Commit 3cb1aa56 authored by Yi Jiang's avatar Yi Jiang
Browse files

Dumps last five attention check results instead of one.

Bug: 132173773
Test: adb shell dumpsys attention
Change-Id: I13dc932100eb1268c239c6ab726d4de3c7c57fdd
parent bcd37b9c
Loading
Loading
Loading
Loading
+56 −13
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCE
import static android.service.attention.AttentionService.ATTENTION_FAILURE_UNKNOWN;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.attention.AttentionManagerInternal;
@@ -85,6 +86,10 @@ public class AttentionManagerService extends SystemService {
    /** If the check attention called within that period - cached value will be returned. */
    private static final long STALE_AFTER_MILLIS = 5_000;

    /** The size of the buffer that stores recent attention check results. */
    @VisibleForTesting
    protected static final int ATTENTION_CACHE_BUFFER_SIZE = 5;

    /** DeviceConfig flag name, if {@code true}, enables AttentionManagerService features. */
    private static final String SERVICE_ENABLED = "service_enabled";
    private static String sTestAttentionServicePackage;
@@ -192,7 +197,8 @@ public class AttentionManagerService extends SystemService {
            userState.bindLocked();

            // throttle frequent requests
            final AttentionCheckCache cache = userState.mAttentionCheckCache;
            final AttentionCheckCache cache = userState.mAttentionCheckCacheBuffer == null ? null
                    : userState.mAttentionCheckCacheBuffer.getLast();
            if (cache != null && now < cache.mLastComputed + STALE_AFTER_MILLIS) {
                callbackInternal.onSuccess(cache.mResult, cache.mTimestamp);
                return true;
@@ -236,9 +242,11 @@ public class AttentionManagerService extends SystemService {
                }

                synchronized (mLock) {
                    userState.mAttentionCheckCache = new AttentionCheckCache(
                            SystemClock.uptimeMillis(), result,
                            timestamp);
                    if (userState.mAttentionCheckCacheBuffer == null) {
                        userState.mAttentionCheckCacheBuffer = new AttentionCheckCacheBuffer();
                    }
                    userState.mAttentionCheckCacheBuffer.add(
                            new AttentionCheckCache(SystemClock.uptimeMillis(), result, timestamp));
                }
                StatsLog.write(
                        StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
@@ -421,7 +429,41 @@ public class AttentionManagerService extends SystemService {
        }
    }

    private static final class AttentionCheckCache {
    @VisibleForTesting
    protected static final class AttentionCheckCacheBuffer {
        private final AttentionCheckCache[] mQueue;
        private int mStartIndex;
        private int mSize;

        AttentionCheckCacheBuffer() {
            mQueue = new AttentionCheckCache[ATTENTION_CACHE_BUFFER_SIZE];
            mStartIndex = 0;
            mSize = 0;
        }

        public AttentionCheckCache getLast() {
            int lastIdx = (mStartIndex + mSize - 1) % ATTENTION_CACHE_BUFFER_SIZE;
            return mSize == 0 ? null : mQueue[lastIdx];
        }

        public void add(@NonNull AttentionCheckCache cache) {
            int nextIndex = (mStartIndex + mSize) % ATTENTION_CACHE_BUFFER_SIZE;
            mQueue[nextIndex] = cache;
            if (mSize == ATTENTION_CACHE_BUFFER_SIZE) {
                mStartIndex++;
            } else {
                mSize++;
            }
        }

        public AttentionCheckCache get(int offset) {
            return offset >= mSize ? null
                    : mQueue[(mStartIndex + offset) % ATTENTION_CACHE_BUFFER_SIZE];
        }
    }

    @VisibleForTesting
    protected static final class AttentionCheckCache {
        private final long mLastComputed;
        private final int mResult;
        private final long mTimestamp;
@@ -463,7 +505,7 @@ public class AttentionManagerService extends SystemService {
        @GuardedBy("mLock")
        AttentionCheck mCurrentAttentionCheck;
        @GuardedBy("mLock")
        AttentionCheckCache mAttentionCheckCache;
        AttentionCheckCacheBuffer mAttentionCheckCacheBuffer;
        @GuardedBy("mLock")
        private boolean mBinding;

@@ -532,16 +574,17 @@ public class AttentionManagerService extends SystemService {
                    pw.println("is fulfilled:=" + mCurrentAttentionCheck.mIsFulfilled);
                    pw.decreaseIndent();
                }
                if (mAttentionCheckCacheBuffer != null) {
                    pw.println("attention check cache:");
                if (mAttentionCheckCache != null) {
                    for (int i = 0; i < mAttentionCheckCacheBuffer.mSize; i++) {
                        pw.increaseIndent();
                    pw.println("last computed=" + mAttentionCheckCache.mLastComputed);
                    pw.println("timestamp=" + mAttentionCheckCache.mTimestamp);
                    pw.println("result=" + mAttentionCheckCache.mResult);
                        pw.println("timestamp=" + mAttentionCheckCacheBuffer.get(i).mTimestamp);
                        pw.println("result=" + mAttentionCheckCacheBuffer.get(i).mResult);
                        pw.decreaseIndent();
                    }
                }
            }
        }

        private class AttentionServiceConnection implements ServiceConnection {
            @Override
+47 −5
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.attention;

import static com.android.server.attention.AttentionManagerService.ATTENTION_CACHE_BUFFER_SIZE;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
@@ -39,6 +41,8 @@ import android.service.attention.IAttentionService;
import androidx.test.filters.SmallTest;

import com.android.server.attention.AttentionManagerService.AttentionCheck;
import com.android.server.attention.AttentionManagerService.AttentionCheckCache;
import com.android.server.attention.AttentionManagerService.AttentionCheckCacheBuffer;
import com.android.server.attention.AttentionManagerService.AttentionHandler;
import com.android.server.attention.AttentionManagerService.UserState;

@@ -56,11 +60,16 @@ public class AttentionManagerServiceTest {
    private AttentionManagerService mSpyAttentionManager;
    private UserState mSpyUserState;
    private final int mTimeout = 1000;
    @Mock private AttentionCallbackInternal mMockAttentionCallbackInternal;
    @Mock private AttentionHandler mMockHandler;
    @Mock private IAttentionCallback mMockIAttentionCallback;
    @Mock private IPowerManager mMockIPowerManager;
    @Mock Context mContext;
    @Mock
    private AttentionCallbackInternal mMockAttentionCallbackInternal;
    @Mock
    private AttentionHandler mMockHandler;
    @Mock
    private IAttentionCallback mMockIAttentionCallback;
    @Mock
    private IPowerManager mMockIPowerManager;
    @Mock
    Context mContext;

    @Before
    public void setUp() throws RemoteException {
@@ -140,12 +149,45 @@ public class AttentionManagerServiceTest {
        mSpyAttentionManager.onSwitchUser(userId);
    }

    @Test
    public void testAttentionCheckCacheBuffer_getLast_returnTheLastElement() {
        AttentionCheckCacheBuffer buffer = new AttentionCheckCacheBuffer();
        buffer.add(new AttentionCheckCache(0, 0, 1L));
        AttentionCheckCache cache = new AttentionCheckCache(0, 0, 2L);
        buffer.add(cache);
        assertThat(buffer.getLast()).isEqualTo(cache);
    }

    @Test
    public void testAttentionCheckCacheBuffer_get_returnNullWhenOutOfBoundary() {
        AttentionCheckCacheBuffer buffer = new AttentionCheckCacheBuffer();
        assertThat(buffer.get(1)).isNull();
    }

    @Test
    public void testAttentionCheckCacheBuffer_get_handleCircularIndexing() {
        AttentionCheckCacheBuffer buffer = new AttentionCheckCacheBuffer();
        AttentionCheckCache cache = new AttentionCheckCache(0L, 0, 1L);
        // Insert SIZE+1 elements.
        for (int i = 0; i <= ATTENTION_CACHE_BUFFER_SIZE; i++) {
            if (i == 1) {
                buffer.add(cache);
            } else {
                buffer.add(new AttentionCheckCache(0L, 0, i));
            }
        }
        // The element that was at index 1 should be at index 0 after inserting SIZE + 1 elements.
        assertThat(buffer.get(0)).isEqualTo(cache);
    }

    private class MockIAttentionService implements IAttentionService {
        public void checkAttention(IAttentionCallback callback) throws RemoteException {
            callback.onSuccess(0, 0);
        }

        public void cancelAttentionCheck(IAttentionCallback callback) {
        }

        public IBinder asBinder() {
            return null;
        }