Merge "Do not use mStaleListener if tile is listening" into tm-dev am: 5834bd57e7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18368340

Change-Id: Ief46566053e26c33b751678e229964fca68304c4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Fabian Kozynski
2022-05-18 22:21:33 +00:00
committed by Automerger Merge Worker
12 changed files with 144 additions and 23 deletions

View File

@@ -33,7 +33,7 @@ public interface QS extends FragmentBase {
String ACTION = "com.android.systemui.action.PLUGIN_QS";
int VERSION = 14;
int VERSION = 15;
String TAG = "QS";
@@ -50,6 +50,14 @@ public interface QS extends FragmentBase {
void setOverscrolling(boolean overscrolling);
void setExpanded(boolean qsExpanded);
void setListening(boolean listening);
/**
* Set whether QQS/QS is visible or not.
*
* This is different from setExpanded, as it will be true when QQS is visible. In particular,
* it should be false when device is locked and only notifications (in lockscreen) are visible.
*/
void setQsVisible(boolean qsVisible);
boolean isShowingDetail();
void closeDetail();
void animateHeaderSlidingOut();

View File

@@ -72,6 +72,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private static final boolean DEBUG = false;
private static final String EXTRA_EXPANDED = "expanded";
private static final String EXTRA_LISTENING = "listening";
private static final String EXTRA_VISIBLE = "visible";
private final Rect mQsBounds = new Rect();
private final StatusBarStateController mStatusBarStateController;
@@ -148,6 +149,10 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private boolean mOverScrolling;
// Whether QQS or QS is visible. When in lockscreen, this is true if and only if QQS or QS is
// visible;
private boolean mQsVisible;
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
QSTileHost qsTileHost,
@@ -224,6 +229,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mQSCustomizerController.init();
mQSCustomizerController.setQs(this);
if (savedInstanceState != null) {
setQsVisible(savedInstanceState.getBoolean(EXTRA_VISIBLE));
setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
setEditLocation(view);
@@ -285,6 +291,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
super.onSaveInstanceState(outState);
outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
outState.putBoolean(EXTRA_LISTENING, mListening);
outState.putBoolean(EXTRA_VISIBLE, mQsVisible);
if (mQSCustomizerController != null) {
mQSCustomizerController.saveInstanceState(outState);
}
@@ -303,6 +310,11 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
return mQsExpanded;
}
@VisibleForTesting
boolean isQsVisible() {
return mQsVisible;
}
@Override
public View getHeader() {
return mHeader;
@@ -458,7 +470,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public void setExpanded(boolean expanded) {
if (DEBUG) Log.d(TAG, "setExpanded " + expanded);
mQsExpanded = expanded;
mQSPanelController.setListening(mListening, mQsExpanded);
updateQsPanelControllerListening();
updateQsState();
}
@@ -486,9 +498,20 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public void setListening(boolean listening) {
if (DEBUG) Log.d(TAG, "setListening " + listening);
mListening = listening;
mQSContainerImplController.setListening(listening);
mQSFooterActionController.setListening(listening);
mQSPanelController.setListening(mListening, mQsExpanded);
mQSContainerImplController.setListening(listening && mQsVisible);
mQSFooterActionController.setListening(listening && mQsVisible);
updateQsPanelControllerListening();
}
private void updateQsPanelControllerListening() {
mQSPanelController.setListening(mListening && mQsVisible, mQsExpanded);
}
@Override
public void setQsVisible(boolean visible) {
if (DEBUG) Log.d(TAG, "setQsVisible " + visible);
mQsVisible = visible;
setListening(mListening);
}
@Override
@@ -836,6 +859,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
indentingPw.println("mHeaderAnimating: " + mHeaderAnimating);
indentingPw.println("mStackScrollerOverscrolling: " + mStackScrollerOverscrolling);
indentingPw.println("mListening: " + mListening);
indentingPw.println("mQsVisible: " + mQsVisible);
indentingPw.println("mLayoutDirection: " + mLayoutDirection);
indentingPw.println("mLastQSExpansion: " + mLastQSExpansion);
indentingPw.println("mLastPanelFraction: " + mLastPanelFraction);

View File

@@ -161,9 +161,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
/** */
public void setListening(boolean listening, boolean expanded) {
setListening(listening && expanded);
if (mView.isListening()) {
refreshAllTiles();
}
// Set the listening as soon as the QS fragment starts listening regardless of the
//expansion, so it will update the current brightness before the slider is visible.

View File

@@ -308,12 +308,17 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
}
void setListening(boolean listening) {
if (mView.isListening() == listening) return;
mView.setListening(listening);
if (mView.getTileLayout() != null) {
mQSLogger.logAllTilesChangeListening(listening, mView.getDumpableTag(), mCachedSpecs);
mView.getTileLayout().setListening(listening, mUiEventLogger);
}
if (mView.isListening()) {
refreshAllTiles();
}
}
boolean switchTileLayout(boolean force) {

View File

@@ -104,15 +104,6 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
}
@Override
void setListening(boolean listening) {
super.setListening(listening);
}
public boolean isListening() {
return mView.isListening();
}
private void setMaxTiles(int parseNumTiles) {
mView.setMaxTiles(parseNumTiles);
setTiles();

View File

@@ -175,9 +175,6 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mListening = listening;
mQuickQSPanelController.setListening(listening);
if (mQuickQSPanelController.isListening()) {
mQuickQSPanelController.refreshAllTiles();
}
if (mQuickQSPanelController.switchTileLayout(false)) {
mView.updateResources();

View File

@@ -233,7 +233,13 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
@VisibleForTesting
protected void handleStale() {
setListening(mStaleListener, true);
if (!mListeners.isEmpty()) {
// If the tile is already listening (it's been a long time since it refreshed), just
// force a refresh. Don't add the staleListener because there's already a listener there
refreshState();
} else {
setListening(mStaleListener, true);
}
}
public String getTileSpec() {

View File

@@ -2571,6 +2571,7 @@ public class NotificationPanelViewController extends PanelViewController {
mQsClipTop = (int) (top - currentTranslation - mQsFrame.getTop());
mQsClipBottom = (int) (bottom - currentTranslation - mQsFrame.getTop());
mQsVisible = qsVisible;
mQs.setQsVisible(mQsVisible);
mQs.setFancyClipping(
mQsClipTop,
mQsClipBottom,

View File

@@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -161,6 +163,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
QSFragment qs = (QSFragment) mFragment;
qs.setListening(true);
qs.setExpanded(true);
qs.setQsVisible(true);
processAllMessages();
recreateFragment();
processAllMessages();
@@ -169,6 +172,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
qs = (QSFragment) mFragment;
assertTrue(qs.isListening());
assertTrue(qs.isExpanded());
assertTrue(qs.isQsVisible());
}
@Test
@@ -333,6 +337,54 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
assertThat(mQsFragmentView.getTranslationY()).isEqualTo(0);
}
@Test
public void setListeningFalse_notVisible() {
QSFragment fragment = resumeAndGetFragment();
fragment.setQsVisible(false);
clearInvocations(mQSContainerImplController, mQSPanelController, mQSFooterActionController);
fragment.setListening(false);
verify(mQSContainerImplController).setListening(false);
verify(mQSFooterActionController).setListening(false);
verify(mQSPanelController).setListening(eq(false), anyBoolean());
}
@Test
public void setListeningTrue_notVisible() {
QSFragment fragment = resumeAndGetFragment();
fragment.setQsVisible(false);
clearInvocations(mQSContainerImplController, mQSPanelController, mQSFooterActionController);
fragment.setListening(true);
verify(mQSContainerImplController).setListening(false);
verify(mQSFooterActionController).setListening(false);
verify(mQSPanelController).setListening(eq(false), anyBoolean());
}
@Test
public void setListeningFalse_visible() {
QSFragment fragment = resumeAndGetFragment();
fragment.setQsVisible(true);
clearInvocations(mQSContainerImplController, mQSPanelController, mQSFooterActionController);
fragment.setListening(false);
verify(mQSContainerImplController).setListening(false);
verify(mQSFooterActionController).setListening(false);
verify(mQSPanelController).setListening(eq(false), anyBoolean());
}
@Test
public void setListeningTrue_visible() {
QSFragment fragment = resumeAndGetFragment();
fragment.setQsVisible(true);
clearInvocations(mQSContainerImplController, mQSPanelController, mQSFooterActionController);
fragment.setListening(true);
verify(mQSContainerImplController).setListening(true);
verify(mQSFooterActionController).setListening(true);
verify(mQSPanelController).setListening(eq(true), anyBoolean());
}
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
MockitoAnnotations.initMocks(this);

View File

@@ -137,6 +137,10 @@ public class QSPanelControllerBaseTest extends SysuiTestCase {
when(mMediaHost.getDisappearParameters()).thenReturn(new DisappearParameters());
when(mQSPanel.getResources()).thenReturn(mResources);
when(mResources.getConfiguration()).thenReturn(mConfiguration);
doAnswer(invocation -> {
when(mQSPanel.isListening()).thenReturn(invocation.getArgument(0));
return null;
}).when(mQSPanel).setListening(anyBoolean());
mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
mQSCustomizerController, mMediaHost,

View File

@@ -21,6 +21,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.any
@@ -62,6 +63,9 @@ class QSPanelControllerTest : SysuiTestCase() {
whenever(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
whenever(qsPanel.resources).thenReturn(mContext.orCreateTestableResources.resources)
whenever(statusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false)
whenever(qsPanel.setListening(anyBoolean())).then {
whenever(qsPanel.isListening).thenReturn(it.getArgument(0))
}
controller = QSPanelController(
qsPanel,
@@ -100,7 +104,6 @@ class QSPanelControllerTest : SysuiTestCase() {
controller.setTiles()
whenever(tile.isListening()).thenReturn(false)
whenever(otherTile.isListening()).thenReturn(true)
whenever(qsPanel.isListening).thenReturn(true)
controller.setListening(true, true)

View File

@@ -379,6 +379,34 @@ public class QSTileImplTest extends SysuiTestCase {
assertFalse(mTile.isListening());
}
@Test
public void testStaleTriggeredWhileListening() throws Exception {
Object o = new Object();
mTile.clearRefreshes();
mTile.setListening(o, true); // +1 refresh
mTestableLooper.processAllMessages();
mTestableLooper.runWithLooper(() -> mTile.handleStale()); // +1 refresh
mTestableLooper.processAllMessages();
mTile.setListening(o, false);
mTestableLooper.processAllMessages();
assertFalse(mTile.isListening());
assertThat(mTile.mRefreshes).isEqualTo(2);
}
@Test
public void testStaleTriggeredWhileNotListening() throws Exception {
mTile.clearRefreshes();
mTestableLooper.runWithLooper(() -> mTile.handleStale()); // +1 refresh
mTestableLooper.processAllMessages();
assertFalse(mTile.isListening());
assertThat(mTile.mRefreshes).isEqualTo(1);
}
private void assertEvent(UiEventLogger.UiEventEnum eventType,
UiEventLoggerFake.FakeUiEvent fakeEvent) {
assertEquals(eventType.getId(), fakeEvent.eventId);
@@ -418,9 +446,9 @@ public class QSTileImplTest extends SysuiTestCase {
return mInvalid;
}
}
private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
boolean mClicked;
int mRefreshes = 0;
protected TileImpl(
QSHost host,
@@ -453,6 +481,11 @@ public class QSTileImplTest extends SysuiTestCase {
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
mRefreshes++;
}
void clearRefreshes() {
mRefreshes = 0;
}
@Override