diff options
7 files changed, 73 insertions, 42 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 1c5715c0296d..fd80d50c2894 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -59,6 +59,7 @@ import android.permission.PermissionManager; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.telecom.TelecomManager; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.view.IWindowManager; import android.view.ViewConfiguration; @@ -328,6 +329,12 @@ public class FrameworkServicesModule { @Provides @Singleton + static SubscriptionManager provideSubcriptionManager(Context context) { + return context.getSystemService(SubscriptionManager.class); + } + + @Provides + @Singleton @Nullable static TelecomManager provideTelecomManager(Context context) { return context.getSystemService(TelecomManager.class); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java index b96cb5e36c82..7ac6d63430d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java @@ -21,6 +21,7 @@ import android.os.Message; import android.telephony.SubscriptionInfo; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; @@ -32,6 +33,8 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + /** * Implements network listeners and forwards the calls along onto other listeners but on @@ -60,12 +63,9 @@ public class CallbackHandler extends Handler implements EmergencyListener, Signa private int mHistoryIndex; private String mLastCallback; - public CallbackHandler() { - super(Looper.getMainLooper()); - } - + @Inject @VisibleForTesting - CallbackHandler(Looper looper) { + CallbackHandler(@Main Looper looper) { super(looper); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index cfaeb0edec53..f683603c9cd5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -85,6 +85,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.concurrent.Executor; import javax.inject.Inject; @@ -171,6 +172,8 @@ public class NetworkControllerImpl extends BroadcastReceiver private NetworkCapabilities mLastDefaultNetworkCapabilities; // Handler that all broadcasts are received on. private final Handler mReceiverHandler; + private final Looper mBgLooper; + private final Executor mBgExecutor; // Handler that all callbacks are made on. private final CallbackHandler mCallbackHandler; @@ -198,6 +201,9 @@ public class NetworkControllerImpl extends BroadcastReceiver public NetworkControllerImpl( Context context, @Background Looper bgLooper, + @Background Executor bgExecutor, + SubscriptionManager subscriptionManager, + CallbackHandler callbackHandler, DeviceProvisionedController deviceProvisionedController, BroadcastDispatcher broadcastDispatcher, ConnectivityManager connectivityManager, @@ -212,8 +218,11 @@ public class NetworkControllerImpl extends BroadcastReceiver telephonyListenerManager, wifiManager, networkScoreManager, - SubscriptionManager.from(context), Config.readConfig(context), bgLooper, - new CallbackHandler(), + subscriptionManager, + Config.readConfig(context), + bgLooper, + bgExecutor, + callbackHandler, accessPointController, new DataUsageController(context), new SubscriptionDefaults(), @@ -230,6 +239,7 @@ public class NetworkControllerImpl extends BroadcastReceiver WifiManager wifiManager, NetworkScoreManager networkScoreManager, SubscriptionManager subManager, Config config, Looper bgLooper, + Executor bgExecutor, CallbackHandler callbackHandler, AccessPointControllerImpl accessPointController, DataUsageController dataUsageController, @@ -241,6 +251,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mTelephonyListenerManager = telephonyListenerManager; mConfig = config; mReceiverHandler = new Handler(bgLooper); + mBgLooper = bgLooper; + mBgExecutor = bgExecutor; mCallbackHandler = callbackHandler; mDataSaverController = new DataSaverControllerImpl(context); mBroadcastDispatcher = broadcastDispatcher; @@ -377,21 +389,23 @@ public class NetworkControllerImpl extends BroadcastReceiver // TODO: Move off of the deprecated CONNECTIVITY_ACTION broadcast and rely on callbacks // exclusively for status bar icons. mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler); - // Register the listener on our bg looper + // Run the listener on our bg looper mPhoneStateListener = subId -> { - // For data switching from A to B, we assume B is validated for up to 2 seconds iff: - // 1) A and B are in the same subscription group e.g. CBRS data switch. And - // 2) A was validated before the switch. - // This is to provide smooth transition for UI without showing cross during data - // switch. - if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) { - if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true."); - mForceCellularValidated = true; - mReceiverHandler.removeCallbacks(mClearForceValidated); - mReceiverHandler.postDelayed(mClearForceValidated, 2000); - } - mActiveMobileDataSubscription = subId; - doUpdateMobileControllers(); + mBgExecutor.execute(() -> { + // For data switching from A to B, we assume B is validated for up to 2 seconds if: + // 1) A and B are in the same subscription group e.g. CBRS data switch. And + // 2) A was validated before the switch. + // This is to provide smooth transition for UI without showing cross during data + // switch. + if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) { + if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true."); + mForceCellularValidated = true; + mReceiverHandler.removeCallbacks(mClearForceValidated); + mReceiverHandler.postDelayed(mClearForceValidated, 2000); + } + mActiveMobileDataSubscription = subId; + doUpdateMobileControllers(); + }); }; mDemoModeController.addCallback(this); @@ -428,7 +442,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mobileSignalController.registerListener(); } if (mSubscriptionListener == null) { - mSubscriptionListener = new SubListener(); + mSubscriptionListener = new SubListener(mBgLooper); } mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener); mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener); @@ -1336,6 +1350,10 @@ public class NetworkControllerImpl extends BroadcastReceiver } private class SubListener extends OnSubscriptionsChangedListener { + SubListener(Looper looper) { + super(looper); + } + @Override public void onSubscriptionsChanged() { updateMobileControllers(); @@ -1346,10 +1364,5 @@ public class NetworkControllerImpl extends BroadcastReceiver * Used to register listeners from the BG Looper, this way the PhoneStateListeners that * get created will also run on the BG Looper. */ - private final Runnable mRegisterListeners = new Runnable() { - @Override - public void run() { - registerListeners(); - } - }; + private final Runnable mRegisterListeners = () -> registerListeners(); } diff --git a/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java index 95216c559420..728907fd2d36 100644 --- a/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java +++ b/packages/SystemUI/src/com/android/systemui/telephony/TelephonyCallback.java @@ -54,9 +54,11 @@ class TelephonyCallback extends android.telephony.TelephonyCallback @Override public void onActiveDataSubscriptionIdChanged(int subId) { - mActiveDataSubscriptionIdListeners.forEach(listener -> { - listener.onActiveDataSubscriptionIdChanged(subId); - }); + List<ActiveDataSubscriptionIdListener> listeners; + synchronized (mActiveDataSubscriptionIdListeners) { + listeners = new ArrayList<>(mActiveDataSubscriptionIdListeners); + } + listeners.forEach(listener -> listener.onActiveDataSubscriptionIdChanged(subId)); } void addActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) { @@ -69,9 +71,11 @@ class TelephonyCallback extends android.telephony.TelephonyCallback @Override public void onCallStateChanged(int state) { - mCallStateListeners.forEach(listener -> { - listener.onCallStateChanged(state); - }); + List<CallStateListener> listeners; + synchronized (mCallStateListeners) { + listeners = new ArrayList<>(mCallStateListeners); + } + listeners.forEach(listener -> listener.onCallStateChanged(state)); } void addCallStateListener(CallStateListener listener) { @@ -84,9 +88,11 @@ class TelephonyCallback extends android.telephony.TelephonyCallback @Override public void onServiceStateChanged(@NonNull ServiceState serviceState) { - mServiceStateListeners.forEach(listener -> { - listener.onServiceStateChanged(serviceState); - }); + List<ServiceStateListener> listeners; + synchronized (mServiceStateListeners) { + listeners = new ArrayList<>(mServiceStateListeners); + } + listeners.forEach(listener -> listener.onServiceStateChanged(serviceState)); } void addServiceStateListener(ServiceStateListener listener) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index ef3317288e4c..566c71774709 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -77,6 +77,8 @@ import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import com.android.systemui.telephony.TelephonyListenerManager; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.After; import org.junit.Before; @@ -123,6 +125,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected DeviceProvisionedListener mUserCallback; protected Instrumentation mInstrumentation; protected DemoModeController mDemoModeController; + protected FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); protected int mSubId; @@ -222,6 +225,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { mMockSm, mConfig, TestableLooper.get(this).getLooper(), + mFakeExecutor, mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), @@ -291,7 +295,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase { NetworkControllerImpl networkControllerNoMobile = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, - mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler, + mConfig, TestableLooper.get(this).getLooper(), mFakeExecutor, + mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd, mDemoModeController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index f4ad819acf57..6219fafc98db 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -108,7 +108,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mConfig.show4gForLte = true; mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager, mMockWm, - mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler, + mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mFakeExecutor, mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd, mDemoModeController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index 3c5cbb69eef6..8d3e403f1189 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -63,7 +63,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Create a new NetworkController as this is currently handled in constructor. mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig, - Looper.getMainLooper(), mCallbackHandler, + Looper.getMainLooper(), mFakeExecutor, mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd, mDemoModeController); @@ -83,7 +83,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig, - Looper.getMainLooper(), mCallbackHandler, + Looper.getMainLooper(), mFakeExecutor, mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd, mDemoModeController); @@ -151,7 +151,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Create a new NetworkController as this is currently handled in constructor. mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig, - Looper.getMainLooper(), mCallbackHandler, + Looper.getMainLooper(), mFakeExecutor, mCallbackHandler, mock(AccessPointControllerImpl.class), mock(DataUsageController.class), mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd, mDemoModeController); |