Loading packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +14 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ package com.android.systemui.qs.tileimpl; import static androidx.lifecycle.Lifecycle.State.CREATED; import static androidx.lifecycle.Lifecycle.State.DESTROYED; import static androidx.lifecycle.Lifecycle.State.RESUMED; import static androidx.lifecycle.Lifecycle.State.STARTED; Loading Loading @@ -173,6 +174,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mState = newTileState(); mTmpState = newTileState(); mUiHandler.post(() -> mLifecycle.setCurrentState(CREATED)); } protected final void resetStates() { Loading Loading @@ -453,6 +455,9 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (DEBUG) Log.d(TAG, "handleSetListening true"); handleSetListening(listening); mUiHandler.post(() -> { // This tile has been destroyed, the state should not change anymore and we // should not refresh it anymore. if (mLifecycle.getCurrentState().equals(DESTROYED)) return; mLifecycle.setCurrentState(RESUMED); refreshState(); // Ensure we get at least one refresh after listening. }); Loading @@ -461,7 +466,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (mListeners.remove(listener) && mListeners.size() == 0) { if (DEBUG) Log.d(TAG, "handleSetListening false"); handleSetListening(listening); mUiHandler.post(() -> mLifecycle.setCurrentState(STARTED)); mUiHandler.post(() -> { // This tile has been destroyed, the state should not change anymore. if (mLifecycle.getCurrentState().equals(DESTROYED)) return; mLifecycle.setCurrentState(STARTED); }); } } updateIsFullQs(); Loading @@ -488,11 +497,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy"); if (mListeners.size() != 0) { handleSetListening(false); mListeners.clear(); } mCallbacks.clear(); mHandler.removeCallbacksAndMessages(null); // This will force it to be removed from all controllers that may have it registered. mUiHandler.post(() -> { mLifecycle.setCurrentState(DESTROYED); }); } protected void checkIfRestrictionEnforcedByAdminOnly(State state, String userRestriction) { Loading packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ public class QSTileImplTest extends SysuiTestCase { assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); mTile.handleDestroy(); mTestableLooper.processAllMessages(); assertEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } Loading Loading @@ -298,6 +300,25 @@ public class QSTileImplTest extends SysuiTestCase { assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } @Test public void testRefreshStateAfterDestroyedDoesNotCrash() { mTile.destroy(); mTile.refreshState(); mTestableLooper.processAllMessages(); } @Test public void testSetListeningAfterDestroyedDoesNotCrash() { Object o = new Object(); mTile.destroy(); mTile.setListening(o, true); mTile.setListening(o, false); mTestableLooper.processAllMessages(); } private void assertEvent(UiEventLogger.UiEventEnum eventType, UiEventLoggerFake.FakeUiEvent fakeEvent) { assertEquals(eventType.getId(), fakeEvent.eventId); Loading Loading
packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +14 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ package com.android.systemui.qs.tileimpl; import static androidx.lifecycle.Lifecycle.State.CREATED; import static androidx.lifecycle.Lifecycle.State.DESTROYED; import static androidx.lifecycle.Lifecycle.State.RESUMED; import static androidx.lifecycle.Lifecycle.State.STARTED; Loading Loading @@ -173,6 +174,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mState = newTileState(); mTmpState = newTileState(); mUiHandler.post(() -> mLifecycle.setCurrentState(CREATED)); } protected final void resetStates() { Loading Loading @@ -453,6 +455,9 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (DEBUG) Log.d(TAG, "handleSetListening true"); handleSetListening(listening); mUiHandler.post(() -> { // This tile has been destroyed, the state should not change anymore and we // should not refresh it anymore. if (mLifecycle.getCurrentState().equals(DESTROYED)) return; mLifecycle.setCurrentState(RESUMED); refreshState(); // Ensure we get at least one refresh after listening. }); Loading @@ -461,7 +466,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (mListeners.remove(listener) && mListeners.size() == 0) { if (DEBUG) Log.d(TAG, "handleSetListening false"); handleSetListening(listening); mUiHandler.post(() -> mLifecycle.setCurrentState(STARTED)); mUiHandler.post(() -> { // This tile has been destroyed, the state should not change anymore. if (mLifecycle.getCurrentState().equals(DESTROYED)) return; mLifecycle.setCurrentState(STARTED); }); } } updateIsFullQs(); Loading @@ -488,11 +497,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy"); if (mListeners.size() != 0) { handleSetListening(false); mListeners.clear(); } mCallbacks.clear(); mHandler.removeCallbacksAndMessages(null); // This will force it to be removed from all controllers that may have it registered. mUiHandler.post(() -> { mLifecycle.setCurrentState(DESTROYED); }); } protected void checkIfRestrictionEnforcedByAdminOnly(State state, String userRestriction) { Loading
packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ public class QSTileImplTest extends SysuiTestCase { assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); mTile.handleDestroy(); mTestableLooper.processAllMessages(); assertEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } Loading Loading @@ -298,6 +300,25 @@ public class QSTileImplTest extends SysuiTestCase { assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } @Test public void testRefreshStateAfterDestroyedDoesNotCrash() { mTile.destroy(); mTile.refreshState(); mTestableLooper.processAllMessages(); } @Test public void testSetListeningAfterDestroyedDoesNotCrash() { Object o = new Object(); mTile.destroy(); mTile.setListening(o, true); mTile.setListening(o, false); mTestableLooper.processAllMessages(); } private void assertEvent(UiEventLogger.UiEventEnum eventType, UiEventLoggerFake.FakeUiEvent fakeEvent) { assertEquals(eventType.getId(), fakeEvent.eventId); Loading