From 29ed19b84386864cfdc016e78a9cd1e3b725ce9b Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Fri, 22 Jul 2022 10:56:36 -0400 Subject: [PATCH] Fix QSCarrierGroup click listeners The whole view should not be clickable as a whole. Only the individual components of the view should be clickable. Test: manual Test: atest QSCarrierGroupControllerTest Fixes: 229987222 Change-Id: Ib231e3dc7468f61734dd56ef31e24a967f2fe347 --- .../qs/carrier/QSCarrierGroupController.java | 2 +- .../carrier/QSCarrierGroupControllerTest.java | 71 ++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java index 6908e5ab49e6a..209d09d0f9075 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java @@ -243,7 +243,7 @@ public class QSCarrierGroupController { mActivityStarter.postStartActivityDismissingKeyguard( new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0); }; - view.setOnClickListener(onClickListener); + mNoSimTextView = view.getNoSimTextView(); mNoSimTextView.setOnClickListener(onClickListener); mMainHandler = new H(mainLooper, this::handleUpdateCarrierInfo, this::handleUpdateState); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java index bd794d6813ec2..09ce37b4ac62d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java @@ -16,19 +16,26 @@ package com.android.systemui.qs.carrier; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; 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.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import android.content.Context; +import android.content.Intent; import android.os.Handler; +import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; @@ -50,6 +57,7 @@ import com.android.systemui.utils.os.FakeHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -85,6 +93,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { private QSCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener; private FakeSlotIndexResolver mSlotIndexResolver; + private ClickListenerTextView mNoCarrierTextView; @Before public void setup() throws Exception { @@ -108,7 +117,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { .when(mCarrierTextManager) .setListening(any(CarrierTextManager.CarrierTextCallback.class)); - when(mQSCarrierGroup.getNoSimTextView()).thenReturn(new TextView(mContext)); + mNoCarrierTextView = new ClickListenerTextView(mContext); + when(mQSCarrierGroup.getNoSimTextView()).thenReturn(mNoCarrierTextView); when(mQSCarrierGroup.getCarrier1View()).thenReturn(mQSCarrier1); when(mQSCarrierGroup.getCarrier2View()).thenReturn(mQSCarrier2); when(mQSCarrierGroup.getCarrier3View()).thenReturn(mQSCarrier3); @@ -376,6 +386,47 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean()); } + @Test + public void testOnlyInternalViewsHaveClickableListener() { + ArgumentCaptor captor = + ArgumentCaptor.forClass(View.OnClickListener.class); + + verify(mQSCarrier1).setOnClickListener(captor.capture()); + verify(mQSCarrier2).setOnClickListener(captor.getValue()); + verify(mQSCarrier3).setOnClickListener(captor.getValue()); + + assertThat(mNoCarrierTextView.getOnClickListener()).isSameInstanceAs(captor.getValue()); + verify(mQSCarrierGroup, never()).setOnClickListener(any()); + } + + @Test + public void testOnClickListenerDoesntStartActivityIfViewNotVisible() { + ArgumentCaptor captor = + ArgumentCaptor.forClass(View.OnClickListener.class); + + verify(mQSCarrier1).setOnClickListener(captor.capture()); + when(mQSCarrier1.isVisibleToUser()).thenReturn(false); + + captor.getValue().onClick(mQSCarrier1); + verifyZeroInteractions(mActivityStarter); + } + + @Test + public void testOnClickListenerLaunchesActivityIfViewVisible() { + ArgumentCaptor listenerCaptor = + ArgumentCaptor.forClass(View.OnClickListener.class); + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + + verify(mQSCarrier1).setOnClickListener(listenerCaptor.capture()); + when(mQSCarrier1.isVisibleToUser()).thenReturn(true); + + listenerCaptor.getValue().onClick(mQSCarrier1); + verify(mActivityStarter) + .postStartActivityDismissingKeyguard(intentCaptor.capture(), anyInt()); + assertThat(intentCaptor.getValue().getAction()) + .isEqualTo(Settings.ACTION_WIRELESS_SETTINGS); + } + private class FakeSlotIndexResolver implements QSCarrierGroupController.SlotIndexResolver { public boolean overrideInvalid; @@ -384,4 +435,22 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { return overrideInvalid ? -1 : subscriptionId; } } + + private class ClickListenerTextView extends TextView { + View.OnClickListener mListener = null; + + ClickListenerTextView(Context context) { + super(context); + } + + @Override + public void setOnClickListener(OnClickListener l) { + super.setOnClickListener(l); + mListener = l; + } + + View.OnClickListener getOnClickListener() { + return mListener; + } + } }