diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 0106609b92712..b1e14346c3fab 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -19,8 +19,6 @@ package com.android.keyguard;
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
-import static com.android.systemui.DejankUtils.whitelistIpcs;
-
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -47,6 +45,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
@@ -61,9 +60,11 @@ public class CarrierTextController {
private final boolean mIsEmergencyCallCapable;
private final Handler mMainHandler;
+ private final Handler mBgHandler;
private boolean mTelephonyCapable;
private boolean mShowMissingSim;
private boolean mShowAirplaneMode;
+ private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
@VisibleForTesting
protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private WifiManager mWifiManager;
@@ -78,12 +79,14 @@ public class CarrierTextController {
new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedWakingUp() {
- if (mCarrierTextCallback != null) mCarrierTextCallback.finishedWakingUp();
+ final CarrierTextCallback callback = mCarrierTextCallback;
+ if (callback != null) callback.finishedWakingUp();
}
@Override
public void onStartedGoingToSleep() {
- if (mCarrierTextCallback != null) mCarrierTextCallback.startedGoingToSleep();
+ final CarrierTextCallback callback = mCarrierTextCallback;
+ if (callback != null) callback.startedGoingToSleep();
}
};
@@ -131,7 +134,7 @@ public class CarrierTextController {
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mActiveMobileDataSubscription = subId;
- if (mKeyguardUpdateMonitor != null) {
+ if (mNetworkSupported.get() && mCarrierTextCallback != null) {
updateCarrierText();
}
}
@@ -173,6 +176,17 @@ public class CarrierTextController {
mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
mSimErrorState = new boolean[mSimSlotsNumber];
mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
+ mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
+ mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+ mBgHandler.post(() -> {
+ boolean supported = ConnectivityManager.from(mContext).isNetworkSupported(
+ ConnectivityManager.TYPE_MOBILE);
+ if (supported && mNetworkSupported.compareAndSet(false, supported)) {
+ // This will set/remove the listeners appropriately. Note that it will never double
+ // add the listeners.
+ handleSetListening(mCarrierTextCallback);
+ }
+ });
}
private TelephonyManager getTelephonyManager() {
@@ -221,48 +235,51 @@ public class CarrierTextController {
}
/**
- * Sets the listening status of this controller. If the callback is null, it is set to
- * not listening
+ * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
+ * (assumed false to start). In that case, the following happens:
+ *
+ * - If there was a registered callback, and the network is supported, it will register
+ * listeners.
+ *
- If there was not a registered callback, it will try to remove unregistered listeners
+ * which is a no-op
+ *
*
- * @param callback Callback to provide text updates
+ * This call will always be processed in a background thread.
*/
- public void setListening(CarrierTextCallback callback) {
+ private void handleSetListening(CarrierTextCallback callback) {
TelephonyManager telephonyManager = getTelephonyManager();
if (callback != null) {
mCarrierTextCallback = callback;
- // TODO(b/140034799)
- if (whitelistIpcs(() -> ConnectivityManager.from(mContext).isNetworkSupported(
- ConnectivityManager.TYPE_MOBILE))) {
- mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+ if (mNetworkSupported.get()) {
// Keyguard update monitor expects callbacks from main thread
- mMainHandler.post(() -> {
- if (mKeyguardUpdateMonitor != null) {
- mKeyguardUpdateMonitor.registerCallback(mCallback);
- }
- });
+ mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
telephonyManager.listen(mPhoneStateListener,
LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
} else {
// Don't listen and clear out the text when the device isn't a phone.
- mKeyguardUpdateMonitor = null;
- callback.updateCarrierInfo(new CarrierTextCallbackInfo("", null, false, null));
+ mMainHandler.post(() -> callback.updateCarrierInfo(
+ new CarrierTextCallbackInfo("", null, false, null)
+ ));
}
} else {
mCarrierTextCallback = null;
- if (mKeyguardUpdateMonitor != null) {
- // Keyguard update monitor expects callbacks from main thread
- mMainHandler.post(() -> {
- if (mKeyguardUpdateMonitor != null) {
- mKeyguardUpdateMonitor.removeCallback(mCallback);
- }
- });
- mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
- }
+ mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
+ mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
}
}
+ /**
+ * Sets the listening status of this controller. If the callback is null, it is set to
+ * not listening.
+ *
+ * @param callback Callback to provide text updates
+ */
+ public void setListening(CarrierTextCallback callback) {
+ mBgHandler.post(() -> handleSetListening(callback));
+ }
+
protected List getSubscriptionInfo() {
return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
}
@@ -500,7 +517,7 @@ public class CarrierTextController {
*/
private CarrierTextController.StatusMode getStatusForIccState(int simState) {
final boolean missingAndNotProvisioned =
- !Dependency.get(KeyguardUpdateMonitor.class).isDeviceProvisioned()
+ !mKeyguardUpdateMonitor.isDeviceProvisioned()
&& (simState == TelephonyManager.SIM_STATE_ABSENT
|| simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 870010a1fbad2..aa4122fd190a6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -134,6 +134,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {
mDependency.injectMockDependency(WakefulnessLifecycle.class);
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
new Handler(mTestableLooper.getLooper()));
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
@@ -150,6 +151,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {
// This should not start listening on any of the real dependencies but will test that
// callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
mCarrierTextController.setListening(mCarrierTextCallback);
+ mTestableLooper.processAllMessages();
}
@Test