Loading src/java/com/android/internal/telephony/ServiceStateTracker.java +43 −17 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ import com.android.internal.telephony.cdma.EriManager; import com.android.internal.telephony.cdnr.CarrierDisplayNameData; import com.android.internal.telephony.cdnr.CarrierDisplayNameResolver; import com.android.internal.telephony.data.DataNetwork; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.dataconnection.DataConnection; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.TransportManager; Loading Loading @@ -284,6 +284,7 @@ public class ServiceStateTracker extends Handler { // Timeout event used when delaying radio power off to wait for IMS deregistration to happen. private static final int EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT = 62; protected static final int EVENT_RESET_LAST_KNOWN_CELL_IDENTITY = 63; private static final int EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED = 64; /** * The current service state. Loading Loading @@ -614,6 +615,13 @@ public class ServiceStateTracker extends Handler { /* Last known TAC/LAC */ private int mLastKnownAreaCode = CellInfo.UNAVAILABLE; /** * Indicating if there is any data network existing. This is used in airplane mode turning on * scenario, where service state tracker should wait all data disconnected before powering * down the modem. */ private boolean mAnyDataExisting = false; public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) { mNitzState = TelephonyComponentFactory.getInstance() .inject(NitzStateMachine.class.getName()) Loading Loading @@ -709,6 +717,10 @@ public class ServiceStateTracker extends Handler { CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null); registerForImsCapabilityChanged(mCSST, CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null); if (mPhone.isUsingNewDataStack()) { sendEmptyMessage(EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED); } } @VisibleForTesting Loading Loading @@ -1456,15 +1468,33 @@ public class ServiceStateTracker extends Handler { } break; case EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED: { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( new DataNetworkControllerCallback(this::post) { @Override public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) { if (mAnyDataExisting != anyDataExisting) { mAnyDataExisting = anyDataExisting; log("onAnyDataNetworkExistingChanged: anyDataExisting=" + anyDataExisting); if (!mAnyDataExisting) { sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } } } }); break; } case EVENT_ALL_DATA_DISCONNECTED: if (mPhone.isUsingNewDataStack()) { log("EVENT_ALL_DATA_DISCONNECTED"); if (mPendingRadioPowerOffAfterDataOff) { mPendingRadioPowerOffAfterDataOff = false; removeMessages(EVENT_SET_RADIO_POWER_OFF); if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now."); hangupAndPowerOff(); return; } return; } int dds = SubscriptionManager.getDefaultDataSubscriptionId(); ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this); Loading Loading @@ -4908,21 +4938,16 @@ public class ServiceStateTracker extends Handler { synchronized (this) { if (!mPendingRadioPowerOffAfterDataOff) { if (mPhone.isUsingNewDataStack()) { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( this::post, new DataNetworkController.DataNetworkControllerCallback() { @Override public void onAllDataNetworksDisconnected() { sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } // One time callback. If all data networks are already disconnected // upon registration, the callback will be invoked immediately. }, true); if (mAnyDataExisting) { log("powerOffRadioSafely: Tear down all data networks."); mPhone.getDataNetworkController().tearDownAllDataNetworks( DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON); sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT); } else { log("powerOffRadioSafely: No data is connected."); sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } mPendingRadioPowerOffAfterDataOff = true; return; } Loading Loading @@ -5235,6 +5260,7 @@ public class ServiceStateTracker extends Handler { dumpCellInfoList(pw); pw.flush(); pw.println(" mAllowedNetworkTypes=" + mAllowedNetworkTypes); pw.println(" mAnyDataExisting=" + mAnyDataExisting); pw.println(" mMaxDataCalls=" + mMaxDataCalls); pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls); pw.println(" mReasonDataDenied=" + mReasonDataDenied); Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +50 −169 Original line number Diff line number Diff line Loading @@ -107,7 +107,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; Loading Loading @@ -225,6 +224,9 @@ public class DataNetworkController extends Handler { */ private final @NonNull List<DataNetwork> mDataNetworkList = new ArrayList<>(); /** {@code true} indicating at least one data network exists. */ private boolean mAnyDataNetworkExisting; /** * Contain the last 10 data networks that were connected. This is for debugging purposes only. */ Loading @@ -241,11 +243,9 @@ public class DataNetworkController extends Handler { */ private @DataState int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; /** * Data network controller callback. Used for listening events from data network controller. */ private final @NonNull DataNetworkControllerCallbackList mDataNetworkControllerCallbacks = new DataNetworkControllerCallbackList(); /** Data network controller callbacks. */ private final @NonNull Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks = new ArraySet<>(); /** Indicates if packet switch data is restricted by the network. */ private boolean mPsRestricted = false; Loading Loading @@ -445,67 +445,14 @@ public class DataNetworkController extends Handler { * The data network controller callback. Note this is only used for passing information * internally in the data stack, should not be used externally. */ public static class DataNetworkControllerCallback { /** The executor of the callback. */ private @NonNull Executor mExecutor; /** * Indicates the callback is automatically unregistered after first invocation. This is * useful for the clients which only want to get the result once. */ private boolean mAutoUnregisterEnabled = false; /** * Indicates callback auto unregister should be skipped this time. This * is internally used by {@link DataNetworkControllerCallbackList}. */ private boolean mSkipAutoUnregisterThisTime = false; /** * Set the executor of the callback. * * @param executor The executor * @param enableAutoUnregister {@code true} if this callback should be unregistered * automatically after invoked the overridden callback method. */ final void init(@NonNull @CallbackExecutor Executor executor, boolean enableAutoUnregister) { Objects.requireNonNull(executor); mExecutor = executor; mAutoUnregisterEnabled = enableAutoUnregister; } /** * @return The executor of the callback. */ final @NonNull Executor getExecutor() { return mExecutor; } public static class DataNetworkControllerCallback extends DataCallback { /** * @return {@code true} if this callback should be unregistered automatically after invoked * the overridden callback method. */ final boolean isAutoUnregisterEnabled() { return mAutoUnregisterEnabled; } /** * @return {@code true} if the callback auto unregister should be skipped this time. This * is internally used by {@link DataNetworkControllerCallbackList}. */ final boolean shouldSkipAutoUnregister() { return mSkipAutoUnregisterThisTime; } /** * Set the flag that indicates whether this callback should be auto unregistered or not. * This should be only called by * Constructor * * @param skip {@code true} if this callback should be auto unregistered. * @param executor The executor of the callback. */ final void setSkipAutoUnregister(boolean skip) { mSkipAutoUnregisterThisTime = skip; public DataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor) { super(executor); } /** Loading @@ -514,93 +461,22 @@ public class DataNetworkController extends Handler { * @param validationStatus The validation status. */ public void onInternetDataNetworkValidationStatusChanged( @ValidationStatus int validationStatus) { mSkipAutoUnregisterThisTime = true; } @ValidationStatus int validationStatus) {} /** Called when internet data network is connected. */ public void onInternetDataNetworkConnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } public void onInternetDataNetworkConnected() {} /** Called when internet data network is disconnected. */ public void onInternetDataNetworkDisconnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } /** Called when all data networks are disconnected. */ public void onAllDataNetworksDisconnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } } /** * The list of all registered callbacks. */ @VisibleForTesting public class DataNetworkControllerCallbackList { /** Callbacks set. */ private final @NonNull Set<DataNetworkControllerCallback> mCallbacks = new ArraySet<>(); public void onInternetDataNetworkDisconnected() {} /** * Register the callback. * Called when any data network existing status changed. * * @param callback The callback. */ public void registerCallback(@NonNull DataNetworkControllerCallback callback) { logv("registerCallback: " + callback); mCallbacks.add(Objects.requireNonNull(callback)); if (mDataNetworkList.isEmpty()) { notifyListeners(DataNetworkControllerCallback::onAllDataNetworksDisconnected); } } /** * Unregister the callback. * * @param callback The callback. * @param anyDataExisting {@code true} indicating there is at least one data network * existing regardless of its state. {@code false} indicating all data networks are * disconnected. */ public void unregisterCallback(@NonNull DataNetworkControllerCallback callback) { logv("unregisterCallback: " + callback); mCallbacks.remove(callback); } /** * Notify the listeners * * @param callbackConsumer The consumer which contains the actual callback method. */ public void notifyListeners(Consumer<DataNetworkControllerCallback> callbackConsumer) { Iterator<DataNetworkControllerCallback> it = mCallbacks.iterator(); while (it.hasNext()) { DataNetworkControllerCallback callback = it.next(); callback.setSkipAutoUnregister(false); // Invoke the actual callback passed in consumer. callback.getExecutor().execute(() -> callbackConsumer.accept(callback)); // The client might not override this method, we should skip auto unregister in // this case. if (callback.shouldSkipAutoUnregister()) { logv("Callback " + callback + " skipped auto unregistering."); continue; } // If the callback was registered as an auto-unregistered callback, unregister now // since the callback has been invoked. if (callback.isAutoUnregisterEnabled()) { logv("Callback " + callback + " automatically removed."); it.remove(); } } } @Override public String toString() { return "[DataNetworkControllerCallbackList: " + mCallbacks + "]"; } public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {} } /** Loading Loading @@ -964,12 +840,10 @@ public class DataNetworkController extends Handler { onTearDownAllDataNetworks(msg.arg1); break; case EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: mDataNetworkControllerCallbacks .registerCallback((DataNetworkControllerCallback) msg.obj); mDataNetworkControllerCallbacks.add((DataNetworkControllerCallback) msg.obj); break; case EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: mDataNetworkControllerCallbacks.unregisterCallback( (DataNetworkControllerCallback) msg.obj); mDataNetworkControllerCallbacks.remove((DataNetworkControllerCallback) msg.obj); break; case EVENT_SUBSCRIPTION_CHANGED: onSubscriptionChanged(); Loading Loading @@ -1818,6 +1692,11 @@ public class DataNetworkController extends Handler { dataNetwork, cause, retryDelayMillis, handoverFailureMode); } })); if (!mAnyDataNetworkExisting) { mAnyDataNetworkExisting = true; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } } /** Loading @@ -1835,6 +1714,11 @@ public class DataNetworkController extends Handler { + DataFailCause.toString(cause) + "(0x" + Integer.toHexString(cause) + "), retryDelayMillis=" + retryDelayMillis + "ms."); mDataNetworkList.remove(dataNetwork); if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { mAnyDataNetworkExisting = false; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } // Data retry manager will determine if retry is needed. If needed, retry will be scheduled. mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(), dataNetwork.getTransport(), requestList, cause, retryDelayMillis); Loading @@ -1852,10 +1736,7 @@ public class DataNetworkController extends Handler { if (mPreviousConnectedDataNetworkList.size() > MAX_HISTORICAL_CONNECTED_DATA_NETWORKS) { mPreviousConnectedDataNetworkList.remove(MAX_HISTORICAL_CONNECTED_DATA_NETWORKS); } if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onInternetDataNetworkConnected); } updateOverallInternetDataState(); if (dataNetwork.getNetworkCapabilities().hasCapability( Loading Loading @@ -1965,8 +1846,8 @@ public class DataNetworkController extends Handler { // TODO: Add DataConfigManager.isRecoveryOnBadNetworkEnabled() if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners(callback -> callback.onInternetDataNetworkValidationStatusChanged(status)); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onInternetDataNetworkValidationStatusChanged(status))); } } Loading Loading @@ -1998,7 +1879,6 @@ public class DataNetworkController extends Handler { */ private void onDataNetworkDisconnected(@NonNull DataNetwork dataNetwork, @DataFailureCause int cause) { // TODO: Should perform retry here. logl("onDataNetworkDisconnected: " + dataNetwork + ", cause=" + DataFailCause.toString(cause) + "(" + cause + ")"); mDataNetworkList.remove(dataNetwork); Loading @@ -2012,19 +1892,16 @@ public class DataNetworkController extends Handler { mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; } if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onInternetDataNetworkDisconnected); } if (mDataNetworkList.isEmpty()) { if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { log("All data networks disconnected now."); mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onAllDataNetworksDisconnected); mAnyDataNetworkExisting = false; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } // Sometimes network was unsolicitedly reported lost for reasons. We should re-evaluate // and see if data network can be re-established again. //TODO: Add some dalays here sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, DataEvaluationReason.DATA_NETWORK_DISCONNECTED)); } Loading Loading @@ -2336,6 +2213,13 @@ public class DataNetworkController extends Handler { + TelephonyUtils.dataStateToString(dataNetworkState) + "."); // TODO: Create a new route to notify TelephonyRegistry. mInternetDataNetworkState = dataNetworkState; if (mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) { mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( callback::onInternetDataNetworkConnected)); } else if (mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) { mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( callback::onInternetDataNetworkDisconnected)); } // TODO: Add suspended callback if needed. } } Loading Loading @@ -2393,14 +2277,10 @@ public class DataNetworkController extends Handler { /** * Register data network controller callback. * * @param executor The executor of the callback. * @param callback The callback. * @param autoUnregister {@code true} if this callback should be unregistered automatically * after invoked the overridden callback method. */ public void registerDataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor, @NonNull DataNetworkControllerCallback callback, boolean autoUnregister) { callback.init(executor, autoUnregister); public void registerDataNetworkControllerCallback( @NonNull DataNetworkControllerCallback callback) { sendMessage(obtainMessage(EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback)); } Loading Loading @@ -2628,13 +2508,14 @@ public class DataNetworkController extends Handler { ? "registered" : "deregistered")); pw.println("mServiceState=" + mServiceState); pw.println("mPsRestricted=" + mPsRestricted); pw.println("mAnyDataNetworkExisting=" + mAnyDataNetworkExisting); pw.println("mInternetDataNetworkState=" + TelephonyUtils.dataStateToString(mInternetDataNetworkState)); pw.println("mImsDataNetworkState=" + TelephonyUtils.dataStateToString(mImsDataNetworkState)); pw.println("mDataServiceBound=" + mDataServiceBound); pw.println("mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState)); pw.println(mDataNetworkControllerCallbacks); pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks); pw.println("Local logs:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +2 −4 Original line number Diff line number Diff line Loading @@ -188,8 +188,7 @@ public class DataStallRecoveryManager extends Handler { private void registerAllEvents() { mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED); mDataNetworkController.registerDataNetworkControllerCallback( this::post, new DataNetworkControllerCallback() { new DataNetworkControllerCallback(this::post) { @Override public void onInternetDataNetworkValidationStatusChanged( @ValidationStatus int validationStatus) { Loading @@ -205,8 +204,7 @@ public class DataStallRecoveryManager extends Handler { public void onInternetDataNetworkDisconnected() { // onInternetDataNetworkDisconnected(); } }, false); }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); } Loading tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +26 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +1 −6 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.internal.telephony.data.DataNetworkController.DataNetw import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; Loading @@ -42,8 +41,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class DataStallRecoveryManagerTest extends TelephonyTest { Loading Loading @@ -88,9 +85,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { ArgumentCaptor.forClass(DataNetworkControllerCallback.class); verify(mDataNetworkController) .registerDataNetworkControllerCallback( any(Executor.class), dataNetworkControllerCallbackCaptor.capture(), eq(false)); dataNetworkControllerCallbackCaptor.capture()); DataNetworkControllerCallback dataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue(); dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged( Loading Loading
src/java/com/android/internal/telephony/ServiceStateTracker.java +43 −17 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ import com.android.internal.telephony.cdma.EriManager; import com.android.internal.telephony.cdnr.CarrierDisplayNameData; import com.android.internal.telephony.cdnr.CarrierDisplayNameResolver; import com.android.internal.telephony.data.DataNetwork; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.dataconnection.DataConnection; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.TransportManager; Loading Loading @@ -284,6 +284,7 @@ public class ServiceStateTracker extends Handler { // Timeout event used when delaying radio power off to wait for IMS deregistration to happen. private static final int EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT = 62; protected static final int EVENT_RESET_LAST_KNOWN_CELL_IDENTITY = 63; private static final int EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED = 64; /** * The current service state. Loading Loading @@ -614,6 +615,13 @@ public class ServiceStateTracker extends Handler { /* Last known TAC/LAC */ private int mLastKnownAreaCode = CellInfo.UNAVAILABLE; /** * Indicating if there is any data network existing. This is used in airplane mode turning on * scenario, where service state tracker should wait all data disconnected before powering * down the modem. */ private boolean mAnyDataExisting = false; public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) { mNitzState = TelephonyComponentFactory.getInstance() .inject(NitzStateMachine.class.getName()) Loading Loading @@ -709,6 +717,10 @@ public class ServiceStateTracker extends Handler { CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null); registerForImsCapabilityChanged(mCSST, CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null); if (mPhone.isUsingNewDataStack()) { sendEmptyMessage(EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED); } } @VisibleForTesting Loading Loading @@ -1456,15 +1468,33 @@ public class ServiceStateTracker extends Handler { } break; case EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED: { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( new DataNetworkControllerCallback(this::post) { @Override public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) { if (mAnyDataExisting != anyDataExisting) { mAnyDataExisting = anyDataExisting; log("onAnyDataNetworkExistingChanged: anyDataExisting=" + anyDataExisting); if (!mAnyDataExisting) { sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } } } }); break; } case EVENT_ALL_DATA_DISCONNECTED: if (mPhone.isUsingNewDataStack()) { log("EVENT_ALL_DATA_DISCONNECTED"); if (mPendingRadioPowerOffAfterDataOff) { mPendingRadioPowerOffAfterDataOff = false; removeMessages(EVENT_SET_RADIO_POWER_OFF); if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now."); hangupAndPowerOff(); return; } return; } int dds = SubscriptionManager.getDefaultDataSubscriptionId(); ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this); Loading Loading @@ -4908,21 +4938,16 @@ public class ServiceStateTracker extends Handler { synchronized (this) { if (!mPendingRadioPowerOffAfterDataOff) { if (mPhone.isUsingNewDataStack()) { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( this::post, new DataNetworkController.DataNetworkControllerCallback() { @Override public void onAllDataNetworksDisconnected() { sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } // One time callback. If all data networks are already disconnected // upon registration, the callback will be invoked immediately. }, true); if (mAnyDataExisting) { log("powerOffRadioSafely: Tear down all data networks."); mPhone.getDataNetworkController().tearDownAllDataNetworks( DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON); sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT); } else { log("powerOffRadioSafely: No data is connected."); sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED); } mPendingRadioPowerOffAfterDataOff = true; return; } Loading Loading @@ -5235,6 +5260,7 @@ public class ServiceStateTracker extends Handler { dumpCellInfoList(pw); pw.flush(); pw.println(" mAllowedNetworkTypes=" + mAllowedNetworkTypes); pw.println(" mAnyDataExisting=" + mAnyDataExisting); pw.println(" mMaxDataCalls=" + mMaxDataCalls); pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls); pw.println(" mReasonDataDenied=" + mReasonDataDenied); Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +50 −169 Original line number Diff line number Diff line Loading @@ -107,7 +107,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; Loading Loading @@ -225,6 +224,9 @@ public class DataNetworkController extends Handler { */ private final @NonNull List<DataNetwork> mDataNetworkList = new ArrayList<>(); /** {@code true} indicating at least one data network exists. */ private boolean mAnyDataNetworkExisting; /** * Contain the last 10 data networks that were connected. This is for debugging purposes only. */ Loading @@ -241,11 +243,9 @@ public class DataNetworkController extends Handler { */ private @DataState int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; /** * Data network controller callback. Used for listening events from data network controller. */ private final @NonNull DataNetworkControllerCallbackList mDataNetworkControllerCallbacks = new DataNetworkControllerCallbackList(); /** Data network controller callbacks. */ private final @NonNull Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks = new ArraySet<>(); /** Indicates if packet switch data is restricted by the network. */ private boolean mPsRestricted = false; Loading Loading @@ -445,67 +445,14 @@ public class DataNetworkController extends Handler { * The data network controller callback. Note this is only used for passing information * internally in the data stack, should not be used externally. */ public static class DataNetworkControllerCallback { /** The executor of the callback. */ private @NonNull Executor mExecutor; /** * Indicates the callback is automatically unregistered after first invocation. This is * useful for the clients which only want to get the result once. */ private boolean mAutoUnregisterEnabled = false; /** * Indicates callback auto unregister should be skipped this time. This * is internally used by {@link DataNetworkControllerCallbackList}. */ private boolean mSkipAutoUnregisterThisTime = false; /** * Set the executor of the callback. * * @param executor The executor * @param enableAutoUnregister {@code true} if this callback should be unregistered * automatically after invoked the overridden callback method. */ final void init(@NonNull @CallbackExecutor Executor executor, boolean enableAutoUnregister) { Objects.requireNonNull(executor); mExecutor = executor; mAutoUnregisterEnabled = enableAutoUnregister; } /** * @return The executor of the callback. */ final @NonNull Executor getExecutor() { return mExecutor; } public static class DataNetworkControllerCallback extends DataCallback { /** * @return {@code true} if this callback should be unregistered automatically after invoked * the overridden callback method. */ final boolean isAutoUnregisterEnabled() { return mAutoUnregisterEnabled; } /** * @return {@code true} if the callback auto unregister should be skipped this time. This * is internally used by {@link DataNetworkControllerCallbackList}. */ final boolean shouldSkipAutoUnregister() { return mSkipAutoUnregisterThisTime; } /** * Set the flag that indicates whether this callback should be auto unregistered or not. * This should be only called by * Constructor * * @param skip {@code true} if this callback should be auto unregistered. * @param executor The executor of the callback. */ final void setSkipAutoUnregister(boolean skip) { mSkipAutoUnregisterThisTime = skip; public DataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor) { super(executor); } /** Loading @@ -514,93 +461,22 @@ public class DataNetworkController extends Handler { * @param validationStatus The validation status. */ public void onInternetDataNetworkValidationStatusChanged( @ValidationStatus int validationStatus) { mSkipAutoUnregisterThisTime = true; } @ValidationStatus int validationStatus) {} /** Called when internet data network is connected. */ public void onInternetDataNetworkConnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } public void onInternetDataNetworkConnected() {} /** Called when internet data network is disconnected. */ public void onInternetDataNetworkDisconnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } /** Called when all data networks are disconnected. */ public void onAllDataNetworksDisconnected() { // Never remove this line. mSkipAutoUnregisterThisTime = true; } } /** * The list of all registered callbacks. */ @VisibleForTesting public class DataNetworkControllerCallbackList { /** Callbacks set. */ private final @NonNull Set<DataNetworkControllerCallback> mCallbacks = new ArraySet<>(); public void onInternetDataNetworkDisconnected() {} /** * Register the callback. * Called when any data network existing status changed. * * @param callback The callback. */ public void registerCallback(@NonNull DataNetworkControllerCallback callback) { logv("registerCallback: " + callback); mCallbacks.add(Objects.requireNonNull(callback)); if (mDataNetworkList.isEmpty()) { notifyListeners(DataNetworkControllerCallback::onAllDataNetworksDisconnected); } } /** * Unregister the callback. * * @param callback The callback. * @param anyDataExisting {@code true} indicating there is at least one data network * existing regardless of its state. {@code false} indicating all data networks are * disconnected. */ public void unregisterCallback(@NonNull DataNetworkControllerCallback callback) { logv("unregisterCallback: " + callback); mCallbacks.remove(callback); } /** * Notify the listeners * * @param callbackConsumer The consumer which contains the actual callback method. */ public void notifyListeners(Consumer<DataNetworkControllerCallback> callbackConsumer) { Iterator<DataNetworkControllerCallback> it = mCallbacks.iterator(); while (it.hasNext()) { DataNetworkControllerCallback callback = it.next(); callback.setSkipAutoUnregister(false); // Invoke the actual callback passed in consumer. callback.getExecutor().execute(() -> callbackConsumer.accept(callback)); // The client might not override this method, we should skip auto unregister in // this case. if (callback.shouldSkipAutoUnregister()) { logv("Callback " + callback + " skipped auto unregistering."); continue; } // If the callback was registered as an auto-unregistered callback, unregister now // since the callback has been invoked. if (callback.isAutoUnregisterEnabled()) { logv("Callback " + callback + " automatically removed."); it.remove(); } } } @Override public String toString() { return "[DataNetworkControllerCallbackList: " + mCallbacks + "]"; } public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {} } /** Loading Loading @@ -964,12 +840,10 @@ public class DataNetworkController extends Handler { onTearDownAllDataNetworks(msg.arg1); break; case EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: mDataNetworkControllerCallbacks .registerCallback((DataNetworkControllerCallback) msg.obj); mDataNetworkControllerCallbacks.add((DataNetworkControllerCallback) msg.obj); break; case EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK: mDataNetworkControllerCallbacks.unregisterCallback( (DataNetworkControllerCallback) msg.obj); mDataNetworkControllerCallbacks.remove((DataNetworkControllerCallback) msg.obj); break; case EVENT_SUBSCRIPTION_CHANGED: onSubscriptionChanged(); Loading Loading @@ -1818,6 +1692,11 @@ public class DataNetworkController extends Handler { dataNetwork, cause, retryDelayMillis, handoverFailureMode); } })); if (!mAnyDataNetworkExisting) { mAnyDataNetworkExisting = true; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } } /** Loading @@ -1835,6 +1714,11 @@ public class DataNetworkController extends Handler { + DataFailCause.toString(cause) + "(0x" + Integer.toHexString(cause) + "), retryDelayMillis=" + retryDelayMillis + "ms."); mDataNetworkList.remove(dataNetwork); if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { mAnyDataNetworkExisting = false; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } // Data retry manager will determine if retry is needed. If needed, retry will be scheduled. mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(), dataNetwork.getTransport(), requestList, cause, retryDelayMillis); Loading @@ -1852,10 +1736,7 @@ public class DataNetworkController extends Handler { if (mPreviousConnectedDataNetworkList.size() > MAX_HISTORICAL_CONNECTED_DATA_NETWORKS) { mPreviousConnectedDataNetworkList.remove(MAX_HISTORICAL_CONNECTED_DATA_NETWORKS); } if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onInternetDataNetworkConnected); } updateOverallInternetDataState(); if (dataNetwork.getNetworkCapabilities().hasCapability( Loading Loading @@ -1965,8 +1846,8 @@ public class DataNetworkController extends Handler { // TODO: Add DataConfigManager.isRecoveryOnBadNetworkEnabled() if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners(callback -> callback.onInternetDataNetworkValidationStatusChanged(status)); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onInternetDataNetworkValidationStatusChanged(status))); } } Loading Loading @@ -1998,7 +1879,6 @@ public class DataNetworkController extends Handler { */ private void onDataNetworkDisconnected(@NonNull DataNetwork dataNetwork, @DataFailureCause int cause) { // TODO: Should perform retry here. logl("onDataNetworkDisconnected: " + dataNetwork + ", cause=" + DataFailCause.toString(cause) + "(" + cause + ")"); mDataNetworkList.remove(dataNetwork); Loading @@ -2012,19 +1892,16 @@ public class DataNetworkController extends Handler { mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED; } if (dataNetwork.isInternetSupported()) { mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onInternetDataNetworkDisconnected); } if (mDataNetworkList.isEmpty()) { if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) { log("All data networks disconnected now."); mDataNetworkControllerCallbacks.notifyListeners( DataNetworkControllerCallback::onAllDataNetworksDisconnected); mAnyDataNetworkExisting = false; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting))); } // Sometimes network was unsolicitedly reported lost for reasons. We should re-evaluate // and see if data network can be re-established again. //TODO: Add some dalays here sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, DataEvaluationReason.DATA_NETWORK_DISCONNECTED)); } Loading Loading @@ -2336,6 +2213,13 @@ public class DataNetworkController extends Handler { + TelephonyUtils.dataStateToString(dataNetworkState) + "."); // TODO: Create a new route to notify TelephonyRegistry. mInternetDataNetworkState = dataNetworkState; if (mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) { mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( callback::onInternetDataNetworkConnected)); } else if (mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) { mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( callback::onInternetDataNetworkDisconnected)); } // TODO: Add suspended callback if needed. } } Loading Loading @@ -2393,14 +2277,10 @@ public class DataNetworkController extends Handler { /** * Register data network controller callback. * * @param executor The executor of the callback. * @param callback The callback. * @param autoUnregister {@code true} if this callback should be unregistered automatically * after invoked the overridden callback method. */ public void registerDataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor, @NonNull DataNetworkControllerCallback callback, boolean autoUnregister) { callback.init(executor, autoUnregister); public void registerDataNetworkControllerCallback( @NonNull DataNetworkControllerCallback callback) { sendMessage(obtainMessage(EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback)); } Loading Loading @@ -2628,13 +2508,14 @@ public class DataNetworkController extends Handler { ? "registered" : "deregistered")); pw.println("mServiceState=" + mServiceState); pw.println("mPsRestricted=" + mPsRestricted); pw.println("mAnyDataNetworkExisting=" + mAnyDataNetworkExisting); pw.println("mInternetDataNetworkState=" + TelephonyUtils.dataStateToString(mInternetDataNetworkState)); pw.println("mImsDataNetworkState=" + TelephonyUtils.dataStateToString(mImsDataNetworkState)); pw.println("mDataServiceBound=" + mDataServiceBound); pw.println("mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState)); pw.println(mDataNetworkControllerCallbacks); pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks); pw.println("Local logs:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +2 −4 Original line number Diff line number Diff line Loading @@ -188,8 +188,7 @@ public class DataStallRecoveryManager extends Handler { private void registerAllEvents() { mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED); mDataNetworkController.registerDataNetworkControllerCallback( this::post, new DataNetworkControllerCallback() { new DataNetworkControllerCallback(this::post) { @Override public void onInternetDataNetworkValidationStatusChanged( @ValidationStatus int validationStatus) { Loading @@ -205,8 +204,7 @@ public class DataStallRecoveryManager extends Handler { public void onInternetDataNetworkDisconnected() { // onInternetDataNetworkDisconnected(); } }, false); }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); } Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +26 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +1 −6 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.internal.telephony.data.DataNetworkController.DataNetw import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; Loading @@ -42,8 +41,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class DataStallRecoveryManagerTest extends TelephonyTest { Loading Loading @@ -88,9 +85,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { ArgumentCaptor.forClass(DataNetworkControllerCallback.class); verify(mDataNetworkController) .registerDataNetworkControllerCallback( any(Executor.class), dataNetworkControllerCallbackCaptor.capture(), eq(false)); dataNetworkControllerCallbackCaptor.capture()); DataNetworkControllerCallback dataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue(); dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged( Loading