Merge "Do not repeatedly connect to flaky communal sources."
This commit is contained in:
@@ -682,6 +682,9 @@
|
||||
attempts. -->
|
||||
<integer name="config_communalSourceReconnectBaseDelay">1000</integer>
|
||||
|
||||
<!-- The minimum time in milliseconds for a connection to be considered connected. Any time -->
|
||||
<integer name="config_connectionMinDuration">1000</integer>
|
||||
|
||||
<!-- Flag to activate notification to contents feature -->
|
||||
<bool name="config_notificationToContents">false</bool>
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
@@ -43,10 +44,12 @@ public class CommunalSourcePrimer extends CoreStartable {
|
||||
private static final String TAG = "CommunalSourcePrimer";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final SystemClock mSystemClock;
|
||||
private final DelayableExecutor mMainExecutor;
|
||||
private final CommunalSourceMonitor mMonitor;
|
||||
private final int mBaseReconnectDelayMs;
|
||||
private final int mMaxReconnectAttempts;
|
||||
private final int mMinConnectionDuration;
|
||||
|
||||
private int mReconnectAttempts = 0;
|
||||
private Runnable mCurrentReconnectCancelable;
|
||||
@@ -65,11 +68,13 @@ public class CommunalSourcePrimer extends CoreStartable {
|
||||
|
||||
@Inject
|
||||
public CommunalSourcePrimer(Context context, @Main Resources resources,
|
||||
SystemClock clock,
|
||||
DelayableExecutor mainExecutor,
|
||||
CommunalSourceMonitor monitor,
|
||||
Optional<CommunalSource.Connector> connector,
|
||||
Optional<CommunalSource.Observer> observer) {
|
||||
super(context);
|
||||
mSystemClock = clock;
|
||||
mMainExecutor = mainExecutor;
|
||||
mMonitor = monitor;
|
||||
mConnector = connector;
|
||||
@@ -79,6 +84,8 @@ public class CommunalSourcePrimer extends CoreStartable {
|
||||
R.integer.config_communalSourceMaxReconnectAttempts);
|
||||
mBaseReconnectDelayMs = resources.getInteger(
|
||||
R.integer.config_communalSourceReconnectBaseDelay);
|
||||
mMinConnectionDuration = resources.getInteger(
|
||||
R.integer.config_connectionMinDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,10 +152,17 @@ public class CommunalSourcePrimer extends CoreStartable {
|
||||
mGetSourceFuture = mConnector.get().connect();
|
||||
mGetSourceFuture.addListener(() -> {
|
||||
try {
|
||||
final long startTime = mSystemClock.currentTimeMillis();
|
||||
Optional<CommunalSource> result = mGetSourceFuture.get();
|
||||
if (result.isPresent()) {
|
||||
final CommunalSource source = result.get();
|
||||
source.addCallback(() -> initiateConnectionAttempt());
|
||||
source.addCallback(() -> {
|
||||
if (mSystemClock.currentTimeMillis() - startTime > mMinConnectionDuration) {
|
||||
initiateConnectionAttempt();
|
||||
} else {
|
||||
scheduleConnectionAttempt();
|
||||
}
|
||||
});
|
||||
mMonitor.setSource(source);
|
||||
} else {
|
||||
scheduleConnectionAttempt();
|
||||
|
||||
@@ -50,6 +50,7 @@ public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
private static final String TEST_COMPONENT_NAME = "com.google.tests/.CommunalService";
|
||||
private static final int MAX_RETRIES = 5;
|
||||
private static final int RETRY_DELAY_MS = 1000;
|
||||
private static final int CONNECTION_MIN_DURATION_MS = 5000;
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@@ -57,7 +58,8 @@ public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
|
||||
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
private FakeSystemClock mFakeClock = new FakeSystemClock();
|
||||
private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
|
||||
|
||||
@Mock
|
||||
private CommunalSource mSource;
|
||||
@@ -80,10 +82,14 @@ public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
.thenReturn(MAX_RETRIES);
|
||||
when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
|
||||
.thenReturn(RETRY_DELAY_MS);
|
||||
when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
|
||||
.thenReturn(RETRY_DELAY_MS);
|
||||
when(mResources.getString(R.string.config_communalSourceComponent))
|
||||
.thenReturn(TEST_COMPONENT_NAME);
|
||||
when(mResources.getInteger(R.integer.config_connectionMinDuration))
|
||||
.thenReturn(CONNECTION_MIN_DURATION_MS);
|
||||
|
||||
mPrimer = new CommunalSourcePrimer(mContext, mResources, mFakeExecutor,
|
||||
mPrimer = new CommunalSourcePrimer(mContext, mResources, mFakeClock, mFakeExecutor,
|
||||
mCommunalSourceMonitor, Optional.of(mConnector), Optional.of(mObserver));
|
||||
}
|
||||
|
||||
@@ -123,6 +129,36 @@ public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
verify(mCommunalSourceMonitor, never()).setSource(Mockito.notNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryOnDisconnectFailure() throws Exception {
|
||||
when(mConnector.connect()).thenReturn(
|
||||
CallbackToFutureAdapter.getFuture(completer -> {
|
||||
completer.set(Optional.of(mSource));
|
||||
return "test";
|
||||
}));
|
||||
|
||||
mPrimer.onBootCompleted();
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Verify attempts happen. Note that we account for the retries plus initial attempt, which
|
||||
// is not scheduled.
|
||||
for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
|
||||
verify(mConnector, times(1)).connect();
|
||||
clearInvocations(mConnector);
|
||||
ArgumentCaptor<CommunalSource.Callback> callbackCaptor =
|
||||
ArgumentCaptor.forClass(CommunalSource.Callback.class);
|
||||
verify(mSource).addCallback(callbackCaptor.capture());
|
||||
clearInvocations(mSource);
|
||||
verify(mCommunalSourceMonitor).setSource(Mockito.notNull());
|
||||
clearInvocations(mCommunalSourceMonitor);
|
||||
callbackCaptor.getValue().onDisconnected();
|
||||
mFakeExecutor.advanceClockToNext();
|
||||
mFakeExecutor.runAllReady();
|
||||
}
|
||||
|
||||
verify(mConnector, never()).connect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttemptOnPackageChange() {
|
||||
when(mConnector.connect()).thenReturn(
|
||||
@@ -161,6 +197,7 @@ public class CommunalSourcePrimerTest extends SysuiTestCase {
|
||||
verify(mSource).addCallback(callbackCaptor.capture());
|
||||
|
||||
clearInvocations(mConnector);
|
||||
mFakeClock.advanceTime(CONNECTION_MIN_DURATION_MS + 1);
|
||||
callbackCaptor.getValue().onDisconnected();
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user