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

Commit cfb20f58 authored by Sarah Chin's avatar Sarah Chin Committed by Automerger Merge Worker
Browse files

New data stack wait for data disconnected on all subs for APM on am: ef824018

parents c4c0fd9a ef824018
Loading
Loading
Loading
Loading
+49 −36
Original line number Diff line number Diff line
@@ -285,7 +285,6 @@ 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;
    // Telecom has un/registered a PhoneAccount that provides OTT voice calling capability, e.g.
    // wi-fi calling.
    protected static final int EVENT_TELECOM_VOICE_SERVICE_STATE_OVERRIDE_CHANGED = 65;
@@ -620,11 +619,11 @@ public class ServiceStateTracker extends Handler {
    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.
     * Data network controller callback for all data disconnected. This is used when turning on
     * airplane mode, where service state tracker should wait for all data disconnected on all
     * subscriptions before powering down the modem.
     */
    private boolean mAnyDataExisting = false;
    private DataNetworkControllerCallback mDataDisconnectedCallback;

    public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {
        mNitzState = TelephonyComponentFactory.getInstance()
@@ -722,7 +721,15 @@ public class ServiceStateTracker extends Handler {
                CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null);

        if (mPhone.isUsingNewDataStack()) {
            sendEmptyMessage(EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED);
            mDataDisconnectedCallback = new DataNetworkControllerCallback(this::post) {
                @Override
                public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {
                    log("onAnyDataNetworkExistingChanged: anyDataExisting=" + anyDataExisting);
                    if (!anyDataExisting) {
                        sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
                    }
                }
            };
        }
    }

@@ -1471,30 +1478,26 @@ 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) {
                    if (!mPendingRadioPowerOffAfterDataOff) return;
                    boolean areAllDataDisconnectedOnAllPhones = true;
                    for (Phone phone : PhoneFactory.getPhones()) {
                        if (phone.getDataNetworkController().areAllDataDisconnected()) {
                            phone.getDataNetworkController()
                                    .unregisterDataNetworkControllerCallback(
                                            mDataDisconnectedCallback);
                        } else {
                            log("Still waiting for all data disconnected on phone: "
                                    + phone.getSubId());
                            areAllDataDisconnectedOnAllPhones = false;
                        }
                    }
                    if (areAllDataDisconnectedOnAllPhones) {
                        mPendingRadioPowerOffAfterDataOff = false;
                        removeMessages(EVENT_SET_RADIO_POWER_OFF);
                        if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
                        if (DBG) log("Data disconnected for all phones, turn radio off now.");
                        hangupAndPowerOff();
                    }
                    return;
@@ -5017,17 +5020,28 @@ public class ServiceStateTracker extends Handler {
                        mPhone.mCT.mBackgroundCall.hangupIfAlive();
                        mPhone.mCT.mForegroundCall.hangupIfAlive();
                    }
                    if (mAnyDataExisting) {
                        log("powerOffRadioSafely: Tear down all data networks.");

                    for (Phone phone : PhoneFactory.getPhones()) {
                        if (!phone.getDataNetworkController().areAllDataDisconnected()) {
                            log("powerOffRadioSafely: Data is active on phone " + phone.getSubId()
                                    + ". Wait for all data disconnect.");
                            mPendingRadioPowerOffAfterDataOff = true;
                            phone.getDataNetworkController().registerDataNetworkControllerCallback(
                                    mDataDisconnectedCallback);
                        }
                    }

                    // Tear down outside of the disconnected check to prevent race conditions.
                    mPhone.getDataNetworkController().tearDownAllDataNetworks(
                            DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);

                    if (mPendingRadioPowerOffAfterDataOff) {
                        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);
                        log("powerOffRadioSafely: No data is connected, turn off radio now.");
                        hangupAndPowerOff();
                    }
                    mPendingRadioPowerOffAfterDataOff = true;
                    return;
                }
                int dds = SubscriptionManager.getDefaultDataSubscriptionId();
@@ -5079,8 +5093,8 @@ public class ServiceStateTracker extends Handler {
                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
                    if (sendMessageDelayed(msg, 30000)) {
                        if (DBG) {
                            log("powerOffRadioSafely: Wait up to 30s for data to isconnect, then"
                                    + " turn off radio.");
                            log("powerOffRadioSafely: Wait up to 30s for data to disconnect, "
                                    + "then turn off radio.");
                        }
                        mPendingRadioPowerOffAfterDataOff = true;
                    } else {
@@ -5344,7 +5358,6 @@ 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);
+19 −3
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.internal.telephony.data;


import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -1082,7 +1081,13 @@ public class DataNetworkController extends Handler {
                onTearDownAllDataNetworks(msg.arg1);
                break;
            case EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK:
                mDataNetworkControllerCallbacks.add((DataNetworkControllerCallback) msg.obj);
                DataNetworkControllerCallback callback = (DataNetworkControllerCallback) msg.obj;
                mDataNetworkControllerCallbacks.add(callback);
                // Notify upon registering if no data networks currently exist.
                if (mDataNetworkList.isEmpty()) {
                    callback.invokeFromExecutor(
                            () -> callback.onAnyDataNetworkExistingChanged(false));
                }
                break;
            case EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK:
                mDataNetworkControllerCallbacks.remove((DataNetworkControllerCallback) msg.obj);
@@ -1337,7 +1342,7 @@ public class DataNetworkController extends Handler {
    }

    /**
     * @return {@code true} internet is unmetered.
     * @return {@code true} if internet is unmetered.
     */
    public boolean isInternetUnmetered() {
        return mDataNetworkList.stream()
@@ -1349,6 +1354,17 @@ public class DataNetworkController extends Handler {
                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
    }

    /**
     * @return {@code true} if all data networks are disconnected.
     */
    public boolean areAllDataDisconnected() {
        if (!mDataNetworkList.isEmpty()) {
            log("areAllDataDisconnected false due to: " + mDataNetworkList.stream()
                    .map(DataNetwork::name).collect(Collectors.joining(", ")));
        }
        return mDataNetworkList.isEmpty();
    }

    /**
     * @return List of the reasons why internet data is not allowed. An empty list if internet
     * is allowed.
+55 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ import androidx.test.filters.FlakyTest;

import com.android.internal.R;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.metrics.ServiceStateStats;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
@@ -235,6 +236,7 @@ public class ServiceStateTrackerTest extends TelephonyTest {
        addNetworkService();

        doReturn(true).when(mDcTracker).areAllDataDisconnected();
        doReturn(true).when(mDataNetworkController).areAllDataDisconnected();

        doReturn(new ServiceState()).when(mPhone).getServiceState();

@@ -379,6 +381,59 @@ public class ServiceStateTrackerTest extends TelephonyTest {
                != (mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON));
    }

    @Test
    public void testSetRadioPowerWaitForAllDataDisconnected() throws Exception {
        // Set up DSDS environment
        GsmCdmaPhone phone2 = Mockito.mock(GsmCdmaPhone.class);
        DataNetworkController dataNetworkController_phone2 =
                Mockito.mock(DataNetworkController.class);
        mPhones = new Phone[] {mPhone, phone2};
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        doReturn(dataNetworkController_phone2).when(phone2).getDataNetworkController();
        doReturn(mSST).when(phone2).getServiceStateTracker();
        doReturn(true).when(phone2).isUsingNewDataStack();
        doReturn(false).when(mDataNetworkController).areAllDataDisconnected();
        doReturn(false).when(dataNetworkController_phone2).areAllDataDisconnected();
        doReturn(1).when(mPhone).getSubId();
        doReturn(2).when(phone2).getSubId();

        // Start with radio on
        sst.setRadioPower(true);
        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
        assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());

        // Turn on APM and verify that both subs are waiting for all data disconnected
        sst.setRadioPower(false);
        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
        assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
        verify(mDataNetworkController).tearDownAllDataNetworks(
                eq(3 /* TEAR_DOWN_REASON_AIRPLANE_MODE_ON */));
        verify(dataNetworkController_phone2, never()).tearDownAllDataNetworks(anyInt());
        ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback1 =
                ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
        ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback2 =
                ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
        verify(mDataNetworkController, times(1)).registerDataNetworkControllerCallback(
                callback1.capture());
        verify(dataNetworkController_phone2, times(1)).registerDataNetworkControllerCallback(
                callback2.capture());

        // Data disconnected on sub 2, still waiting for data disconnected on sub 1
        doReturn(true).when(dataNetworkController_phone2).areAllDataDisconnected();
        callback2.getValue().onAnyDataNetworkExistingChanged(false);
        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
        assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
        verify(dataNetworkController_phone2, times(1)).unregisterDataNetworkControllerCallback(
                any());

        // Data disconnected on sub 1, radio should power off now
        doReturn(true).when(mDataNetworkController).areAllDataDisconnected();
        callback1.getValue().onAnyDataNetworkExistingChanged(false);
        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
        verify(mDataNetworkController, times(1)).unregisterDataNetworkControllerCallback(any());
        assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
    }

    @Test
    @SmallTest
    public void testSetRadioPowerOnForEmergencyCall() {
+1 −0
Original line number Diff line number Diff line
@@ -811,6 +811,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        mRcsRegCallback = regCallbackCaptor.getValue();

        processAllMessages();
        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);

        logd("DataNetworkControllerTest -Setup!");
    }