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

Commit 6e6ef065 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Simplified data network controller callback"

parents 6d3a1e48 1024f9c9
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.times;
@@ -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 {
@@ -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(