Loading packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java +80 −9 Original line number Diff line number Diff line Loading @@ -18,11 +18,16 @@ package com.android.systemui.qs; import static com.android.systemui.Dependency.BG_HANDLER; import static com.android.systemui.Dependency.BG_HANDLER_NAME; import static com.android.systemui.Dependency.MAIN_LOOPER; import static com.android.systemui.Dependency.MAIN_LOOPER_NAME; import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.annotation.MainThread; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.util.AttributeSet; Loading @@ -39,6 +44,8 @@ import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.NetworkController; import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Named; Loading @@ -46,7 +53,6 @@ import javax.inject.Named; * Displays Carrier name and network status in QS */ public class QSCarrierGroup extends LinearLayout implements CarrierTextController.CarrierTextCallback, NetworkController.SignalCallback, View.OnClickListener { private static final String TAG = "QSCarrierGroup"; Loading @@ -56,12 +62,14 @@ public class QSCarrierGroup extends LinearLayout implements private static final int SIM_SLOTS = 3; private final NetworkController mNetworkController; private final Handler mBgHandler; private final H mMainHandler; private View[] mCarrierDividers = new View[SIM_SLOTS - 1]; private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS]; private TextView mNoSimTextView; private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS]; private CarrierTextController mCarrierTextController; private CarrierTextController.CarrierTextCallback mCallback; private ActivityStarter mActivityStarter; private boolean mListening; Loading @@ -69,11 +77,19 @@ public class QSCarrierGroup extends LinearLayout implements @Inject public QSCarrierGroup(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, NetworkController networkController, ActivityStarter activityStarter, @Named(BG_HANDLER_NAME) Handler handler) { @Named(BG_HANDLER_NAME) Handler handler, @Named(MAIN_LOOPER_NAME) Looper looper) { super(context, attrs); mNetworkController = networkController; mActivityStarter = activityStarter; mBgHandler = handler; mMainHandler = new H(looper, this::handleUpdateCarrierInfo, this::handleUpdateState); mCallback = new Callback(mMainHandler); } @VisibleForTesting protected CarrierTextController.CarrierTextCallback getCallback() { return mCallback; } @VisibleForTesting Loading @@ -81,7 +97,8 @@ public class QSCarrierGroup extends LinearLayout implements this(context, attrs, Dependency.get(NetworkController.class), Dependency.get(ActivityStarter.class), Dependency.get(BG_HANDLER)); Dependency.get(BG_HANDLER), Dependency.get(MAIN_LOOPER)); } @Override Loading Loading @@ -136,14 +153,20 @@ public class QSCarrierGroup extends LinearLayout implements if (mNetworkController.hasVoiceCallingFeature()) { mNetworkController.addCallback(this); } mCarrierTextController.setListening(this); mCarrierTextController.setListening(mCallback); } else { mNetworkController.removeCallback(this); mCarrierTextController.setListening(null); } } @MainThread private void handleUpdateState() { if (!mMainHandler.getLooper().isCurrentThread()) { mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); return; } for (int i = 0; i < SIM_SLOTS; i++) { mCarrierGroups[i].updateState(mInfos[i]); } Loading @@ -163,8 +186,13 @@ public class QSCarrierGroup extends LinearLayout implements return SubscriptionManager.getSlotIndex(subscriptionId); } @Override public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { @MainThread private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { if (!mMainHandler.getLooper().isCurrentThread()) { mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); return; } mNoSimTextView.setVisibility(View.GONE); if (!info.airplaneMode && info.anySimReady) { boolean[] slotSeen = new boolean[SIM_SLOTS]; Loading Loading @@ -207,7 +235,7 @@ public class QSCarrierGroup extends LinearLayout implements mNoSimTextView.setText(info.carrierText); mNoSimTextView.setVisibility(View.VISIBLE); } handleUpdateState(); handleUpdateState(); // handleUpdateCarrierInfo is always called from main thread. } @Override Loading @@ -230,7 +258,7 @@ public class QSCarrierGroup extends LinearLayout implements mInfos[slotIndex].contentDescription = statusIcon.contentDescription; mInfos[slotIndex].typeContentDescription = typeContentDescription; mInfos[slotIndex].roaming = roaming; handleUpdateState(); mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); } @Override Loading @@ -240,7 +268,7 @@ public class QSCarrierGroup extends LinearLayout implements mInfos[i].visible = false; } } handleUpdateState(); mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); } static final class CellSignalState { Loading @@ -250,4 +278,47 @@ public class QSCarrierGroup extends LinearLayout implements String typeContentDescription; boolean roaming; } private static class H extends Handler { private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo; private Runnable mUpdateState; static final int MSG_UPDATE_CARRIER_INFO = 0; static final int MSG_UPDATE_STATE = 1; H(Looper looper, Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo, Runnable updateState) { super(looper); mUpdateCarrierInfo = updateCarrierInfo; mUpdateState = updateState; } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_CARRIER_INFO: mUpdateCarrierInfo.accept( (CarrierTextController.CarrierTextCallbackInfo) msg.obj); break; case MSG_UPDATE_STATE: mUpdateState.run(); break; default: super.handleMessage(msg); } } } private static class Callback implements CarrierTextController.CarrierTextCallback { private H mMainHandler; Callback(H handler) { mMainHandler = handler; } @Override public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); } } } packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java +23 −10 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.os.Handler; import android.telephony.SubscriptionManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -28,6 +29,7 @@ import android.view.LayoutInflater; import androidx.test.filters.SmallTest; import com.android.keyguard.CarrierTextController; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.utils.leaks.LeakCheckedTest; Loading @@ -45,13 +47,20 @@ import org.mockito.stubbing.Answer; public class QSCarrierGroupTest extends LeakCheckedTest { private QSCarrierGroup mCarrierGroup; private CarrierTextController.CarrierTextCallback mCallback; private TestableLooper mTestableLooper; @Before public void setup() throws Exception { injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); TestableLooper.get(this).runWithLooper( mTestableLooper = TestableLooper.get(this); mDependency.injectTestDependency( Dependency.BG_HANDLER, new Handler(mTestableLooper.getLooper())); mDependency.injectTestDependency(Dependency.MAIN_LOOPER, mTestableLooper.getLooper()); mTestableLooper.runWithLooper( () -> mCarrierGroup = (QSCarrierGroup) LayoutInflater.from(mContext).inflate( R.layout.qs_carrier_group, null)); mCallback = mCarrierGroup.getCallback(); } @Test // throws no Exception Loading @@ -72,7 +81,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, false, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c1); mCallback.updateCarrierInfo(c1); // listOfCarriers length 1, subscriptionIds length 1, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -81,7 +90,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, true, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c2); mCallback.updateCarrierInfo(c2); // listOfCarriers length 2, subscriptionIds length 2, anySims false CarrierTextController.CarrierTextCallbackInfo Loading @@ -90,7 +99,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, false, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c3); mCallback.updateCarrierInfo(c3); // listOfCarriers length 2, subscriptionIds length 2, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -99,7 +108,9 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading @@ -120,7 +131,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, false, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c1); mCallback.updateCarrierInfo(c1); // listOfCarriers length 2, subscriptionIds length 1, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -129,7 +140,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c2); mCallback.updateCarrierInfo(c2); // listOfCarriers length 1, subscriptionIds length 2, anySims false CarrierTextController.CarrierTextCallbackInfo Loading @@ -138,7 +149,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, false, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c3); mCallback.updateCarrierInfo(c3); // listOfCarriers length 1, subscriptionIds length 2, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -147,7 +158,8 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading @@ -161,7 +173,8 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading Loading
packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java +80 −9 Original line number Diff line number Diff line Loading @@ -18,11 +18,16 @@ package com.android.systemui.qs; import static com.android.systemui.Dependency.BG_HANDLER; import static com.android.systemui.Dependency.BG_HANDLER_NAME; import static com.android.systemui.Dependency.MAIN_LOOPER; import static com.android.systemui.Dependency.MAIN_LOOPER_NAME; import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.annotation.MainThread; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.util.AttributeSet; Loading @@ -39,6 +44,8 @@ import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.NetworkController; import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Named; Loading @@ -46,7 +53,6 @@ import javax.inject.Named; * Displays Carrier name and network status in QS */ public class QSCarrierGroup extends LinearLayout implements CarrierTextController.CarrierTextCallback, NetworkController.SignalCallback, View.OnClickListener { private static final String TAG = "QSCarrierGroup"; Loading @@ -56,12 +62,14 @@ public class QSCarrierGroup extends LinearLayout implements private static final int SIM_SLOTS = 3; private final NetworkController mNetworkController; private final Handler mBgHandler; private final H mMainHandler; private View[] mCarrierDividers = new View[SIM_SLOTS - 1]; private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS]; private TextView mNoSimTextView; private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS]; private CarrierTextController mCarrierTextController; private CarrierTextController.CarrierTextCallback mCallback; private ActivityStarter mActivityStarter; private boolean mListening; Loading @@ -69,11 +77,19 @@ public class QSCarrierGroup extends LinearLayout implements @Inject public QSCarrierGroup(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, NetworkController networkController, ActivityStarter activityStarter, @Named(BG_HANDLER_NAME) Handler handler) { @Named(BG_HANDLER_NAME) Handler handler, @Named(MAIN_LOOPER_NAME) Looper looper) { super(context, attrs); mNetworkController = networkController; mActivityStarter = activityStarter; mBgHandler = handler; mMainHandler = new H(looper, this::handleUpdateCarrierInfo, this::handleUpdateState); mCallback = new Callback(mMainHandler); } @VisibleForTesting protected CarrierTextController.CarrierTextCallback getCallback() { return mCallback; } @VisibleForTesting Loading @@ -81,7 +97,8 @@ public class QSCarrierGroup extends LinearLayout implements this(context, attrs, Dependency.get(NetworkController.class), Dependency.get(ActivityStarter.class), Dependency.get(BG_HANDLER)); Dependency.get(BG_HANDLER), Dependency.get(MAIN_LOOPER)); } @Override Loading Loading @@ -136,14 +153,20 @@ public class QSCarrierGroup extends LinearLayout implements if (mNetworkController.hasVoiceCallingFeature()) { mNetworkController.addCallback(this); } mCarrierTextController.setListening(this); mCarrierTextController.setListening(mCallback); } else { mNetworkController.removeCallback(this); mCarrierTextController.setListening(null); } } @MainThread private void handleUpdateState() { if (!mMainHandler.getLooper().isCurrentThread()) { mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); return; } for (int i = 0; i < SIM_SLOTS; i++) { mCarrierGroups[i].updateState(mInfos[i]); } Loading @@ -163,8 +186,13 @@ public class QSCarrierGroup extends LinearLayout implements return SubscriptionManager.getSlotIndex(subscriptionId); } @Override public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { @MainThread private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { if (!mMainHandler.getLooper().isCurrentThread()) { mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); return; } mNoSimTextView.setVisibility(View.GONE); if (!info.airplaneMode && info.anySimReady) { boolean[] slotSeen = new boolean[SIM_SLOTS]; Loading Loading @@ -207,7 +235,7 @@ public class QSCarrierGroup extends LinearLayout implements mNoSimTextView.setText(info.carrierText); mNoSimTextView.setVisibility(View.VISIBLE); } handleUpdateState(); handleUpdateState(); // handleUpdateCarrierInfo is always called from main thread. } @Override Loading @@ -230,7 +258,7 @@ public class QSCarrierGroup extends LinearLayout implements mInfos[slotIndex].contentDescription = statusIcon.contentDescription; mInfos[slotIndex].typeContentDescription = typeContentDescription; mInfos[slotIndex].roaming = roaming; handleUpdateState(); mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); } @Override Loading @@ -240,7 +268,7 @@ public class QSCarrierGroup extends LinearLayout implements mInfos[i].visible = false; } } handleUpdateState(); mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); } static final class CellSignalState { Loading @@ -250,4 +278,47 @@ public class QSCarrierGroup extends LinearLayout implements String typeContentDescription; boolean roaming; } private static class H extends Handler { private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo; private Runnable mUpdateState; static final int MSG_UPDATE_CARRIER_INFO = 0; static final int MSG_UPDATE_STATE = 1; H(Looper looper, Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo, Runnable updateState) { super(looper); mUpdateCarrierInfo = updateCarrierInfo; mUpdateState = updateState; } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_CARRIER_INFO: mUpdateCarrierInfo.accept( (CarrierTextController.CarrierTextCallbackInfo) msg.obj); break; case MSG_UPDATE_STATE: mUpdateState.run(); break; default: super.handleMessage(msg); } } } private static class Callback implements CarrierTextController.CarrierTextCallback { private H mMainHandler; Callback(H handler) { mMainHandler = handler; } @Override public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget(); } } }
packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java +23 −10 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.os.Handler; import android.telephony.SubscriptionManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -28,6 +29,7 @@ import android.view.LayoutInflater; import androidx.test.filters.SmallTest; import com.android.keyguard.CarrierTextController; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.utils.leaks.LeakCheckedTest; Loading @@ -45,13 +47,20 @@ import org.mockito.stubbing.Answer; public class QSCarrierGroupTest extends LeakCheckedTest { private QSCarrierGroup mCarrierGroup; private CarrierTextController.CarrierTextCallback mCallback; private TestableLooper mTestableLooper; @Before public void setup() throws Exception { injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); TestableLooper.get(this).runWithLooper( mTestableLooper = TestableLooper.get(this); mDependency.injectTestDependency( Dependency.BG_HANDLER, new Handler(mTestableLooper.getLooper())); mDependency.injectTestDependency(Dependency.MAIN_LOOPER, mTestableLooper.getLooper()); mTestableLooper.runWithLooper( () -> mCarrierGroup = (QSCarrierGroup) LayoutInflater.from(mContext).inflate( R.layout.qs_carrier_group, null)); mCallback = mCarrierGroup.getCallback(); } @Test // throws no Exception Loading @@ -72,7 +81,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, false, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c1); mCallback.updateCarrierInfo(c1); // listOfCarriers length 1, subscriptionIds length 1, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -81,7 +90,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, true, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c2); mCallback.updateCarrierInfo(c2); // listOfCarriers length 2, subscriptionIds length 2, anySims false CarrierTextController.CarrierTextCallbackInfo Loading @@ -90,7 +99,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, false, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c3); mCallback.updateCarrierInfo(c3); // listOfCarriers length 2, subscriptionIds length 2, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -99,7 +108,9 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading @@ -120,7 +131,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, false, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c1); mCallback.updateCarrierInfo(c1); // listOfCarriers length 2, subscriptionIds length 1, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -129,7 +140,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0}); spiedCarrierGroup.updateCarrierInfo(c2); mCallback.updateCarrierInfo(c2); // listOfCarriers length 1, subscriptionIds length 2, anySims false CarrierTextController.CarrierTextCallbackInfo Loading @@ -138,7 +149,7 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, false, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c3); mCallback.updateCarrierInfo(c3); // listOfCarriers length 1, subscriptionIds length 2, anySims true CarrierTextController.CarrierTextCallbackInfo Loading @@ -147,7 +158,8 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading @@ -161,7 +173,8 @@ public class QSCarrierGroupTest extends LeakCheckedTest { new CharSequence[]{"", ""}, true, new int[]{0, 1}); spiedCarrierGroup.updateCarrierInfo(c4); mCallback.updateCarrierInfo(c4); mTestableLooper.processAllMessages(); } @Test // throws no Exception Loading