Only ONE view controller controls KeyguardIndication
If a new keyguard indication area is being set, destroy the old RotateTextViewController so that there's only one KeyguardIndicationRotateTextViewController for the keyguard indication view. The stale RotateTextViewController was causing an old charging message to surface on LS. Test: atest KeyguardIndicationControllerTest KeyguardIndicationRotateTextViewController Fixes: 279115823 Change-Id: Ic9735f0029e2055948542eaee75b6befbedea892
This commit is contained in:
@@ -23,6 +23,7 @@ import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.keyguard.logging.KeyguardLogger;
|
||||
import com.android.systemui.Dumpable;
|
||||
@@ -74,7 +75,9 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
|
||||
// Executor that will show the next message after a delay
|
||||
private final DelayableExecutor mExecutor;
|
||||
@Nullable private ShowNextIndication mShowNextIndicationRunnable;
|
||||
|
||||
@VisibleForTesting
|
||||
@Nullable ShowNextIndication mShowNextIndicationRunnable;
|
||||
|
||||
// List of indication types to show. The next indication to show is always at index 0
|
||||
private final List<Integer> mIndicationQueue = new ArrayList<>();
|
||||
@@ -111,6 +114,12 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
cancelScheduledIndication();
|
||||
}
|
||||
|
||||
/** Destroy ViewController, removing any listeners. */
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
onViewDetached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the indication type with the given String.
|
||||
* @param type of indication
|
||||
|
||||
@@ -335,6 +335,9 @@ public class KeyguardIndicationController {
|
||||
R.id.keyguard_indication_text_bottom);
|
||||
mInitialTextColorState = mTopIndicationView != null
|
||||
? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
|
||||
if (mRotateTextViewController != null) {
|
||||
mRotateTextViewController.destroy();
|
||||
}
|
||||
mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
|
||||
mLockScreenIndicationView,
|
||||
mExecutor,
|
||||
|
||||
@@ -109,6 +109,11 @@ public abstract class ViewController<T extends View> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Destroy ViewController, removing any listeners. */
|
||||
public void destroy() {
|
||||
mView.removeOnAttachStateChangeListener(mOnAttachStateListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the view is attached and a call to {@link #init()} has been made in either order.
|
||||
*/
|
||||
|
||||
@@ -23,9 +23,11 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -87,6 +89,54 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
||||
mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onViewDetached_removesStatusBarStateListener() {
|
||||
mController.onViewDetached();
|
||||
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onViewDetached_removesAllScheduledIndications() {
|
||||
// GIVEN show next indication runnable is set
|
||||
final KeyguardIndicationRotateTextViewController.ShowNextIndication mockShowNextIndication =
|
||||
mock(KeyguardIndicationRotateTextViewController.ShowNextIndication.class);
|
||||
mController.mShowNextIndicationRunnable = mockShowNextIndication;
|
||||
|
||||
// WHEN the view is detached
|
||||
mController.onViewDetached();
|
||||
|
||||
// THEN delayed execution is cancelled & runnable set to null
|
||||
verify(mockShowNextIndication).cancelDelayedExecution();
|
||||
assertNull(mController.mShowNextIndicationRunnable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destroy_removesStatusBarStateListener() {
|
||||
mController.destroy();
|
||||
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destroy_removesOnAttachStateChangeListener() {
|
||||
mController.destroy();
|
||||
verify(mView).removeOnAttachStateChangeListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destroy_removesAllScheduledIndications() {
|
||||
// GIVEN show next indication runnable is set
|
||||
final KeyguardIndicationRotateTextViewController.ShowNextIndication mockShowNextIndication =
|
||||
mock(KeyguardIndicationRotateTextViewController.ShowNextIndication.class);
|
||||
mController.mShowNextIndicationRunnable = mockShowNextIndication;
|
||||
|
||||
// WHEN the controller is destroyed
|
||||
mController.destroy();
|
||||
|
||||
// THEN delayed execution is cancelled & runnable set to null
|
||||
verify(mockShowNextIndication).cancelDelayedExecution();
|
||||
assertNull(mController.mShowNextIndicationRunnable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialState_noIndication() {
|
||||
assertFalse(mController.hasIndications());
|
||||
|
||||
@@ -324,6 +324,21 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
reset(mRotateTextViewController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() {
|
||||
// GIVEN a controller with a mocked rotate text view controlller
|
||||
final KeyguardIndicationRotateTextViewController mockedRotateTextViewController =
|
||||
mock(KeyguardIndicationRotateTextViewController.class);
|
||||
createController();
|
||||
mController.mRotateTextViewController = mockedRotateTextViewController;
|
||||
|
||||
// WHEN a new indication area is set
|
||||
mController.setIndicationArea(mIndicationArea);
|
||||
|
||||
// THEN the previous rotateTextViewController is destroyed
|
||||
verify(mockedRotateTextViewController).destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createController_addsAlignmentListener() {
|
||||
createController();
|
||||
|
||||
Reference in New Issue
Block a user