Merge "Dumps last five attention check results instead of one."

This commit is contained in:
Yi Jiang
2019-11-05 19:06:24 +00:00
committed by Android (Google) Code Review
2 changed files with 103 additions and 18 deletions

View File

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

View File

@@ -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;
}