Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a1cb80b authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Simplified data network controller callback am: bf0dd4d1 am: 9c69bfc1

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/2019195

Change-Id: I36fc35317ee3fa3e382e9c0318d23f5f991c6ba6
parents f23e3c3d 9c69bfc1
Loading
Loading
Loading
Loading
+43 −17
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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())
@@ -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
@@ -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);
@@ -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;
                }
@@ -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);
+50 −169
Original line number Diff line number Diff line
@@ -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;

@@ -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.
     */
@@ -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;
@@ -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);
        }

        /**
@@ -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) {}
    }

    /**
@@ -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();
@@ -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)));
        }
    }

    /**
@@ -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);
@@ -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(
@@ -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)));
        }
    }

@@ -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);
@@ -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));
    }
@@ -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.
        }
    }

@@ -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));
    }

@@ -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);
+2 −4
Original line number Diff line number Diff line
@@ -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) {
@@ -205,8 +204,7 @@ public class DataStallRecoveryManager extends Handler {
                    public void onInternetDataNetworkDisconnected() {
                        // onInternetDataNetworkDisconnected();
                    }
                },
                false);
                });
        mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
    }

+26 −52

File changed.

Preview size limit exceeded, changes collapsed.

+1 −6
Original line number Diff line number Diff line
@@ -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.verify;
@@ -41,8 +40,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 {
@@ -87,9 +84,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(