Merge "Fix ConcurrentModExc in TelephonyListenerManager" into sc-dev
This commit is contained in:
@@ -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;
|
||||
@@ -326,6 +327,12 @@ public class FrameworkServicesModule {
|
||||
return context.getSystemService(StatsManager.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
static SubscriptionManager provideSubcriptionManager(Context context) {
|
||||
return context.getSystemService(SubscriptionManager.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Nullable
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user