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

Commit 626f24c7 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Gerrit Code Review
Browse files

Merge "Add ability to override subscriber capabilities."

parents 0464627f 99e1eab9
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.internal.telephony.dataconnection;

import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;

import android.app.PendingIntent;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -173,6 +176,7 @@ public class DataConnection extends StateMachine {
    private DcFailCause mLastFailCause;
    private static final String NULL_IP = "0.0.0.0";
    private Object mUserData;
    private int mSubscriptionOverride;
    private int mRilRat = Integer.MAX_VALUE;
    private int mDataRegState = Integer.MAX_VALUE;
    private NetworkInfo mNetworkInfo;
@@ -203,9 +207,10 @@ public class DataConnection extends StateMachine {
    static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14;
    static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15;
    static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16;
    static final int EVENT_DATA_CONNECTION_OVERRIDE_CHANGED = BASE + 17;

    private static final int CMD_TO_STRING_COUNT =
            EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE + 1;
            EVENT_DATA_CONNECTION_OVERRIDE_CHANGED - BASE + 1;

    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
    static {
@@ -229,6 +234,8 @@ public class DataConnection extends StateMachine {
                "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED";
        sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] =
                "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED";
        sCmdToString[EVENT_DATA_CONNECTION_OVERRIDE_CHANGED - BASE] =
                "EVENT_DATA_CONNECTION_OVERRIDE_CHANGED";
    }
    // Convert cmd to string or null if unknown
    static String cmdToString(int cmd) {
@@ -511,6 +518,12 @@ public class DataConnection extends StateMachine {
        mPhone.mCi.setupDataCall(cp.mRilRat, dp, isModemRoaming, allowRoaming, msg);
    }

    public void onSubscriptionOverride(int overrideMask, int overrideValue) {
        mSubscriptionOverride = (mSubscriptionOverride & ~overrideMask)
                | (overrideValue & overrideMask);
        sendMessage(obtainMessage(EVENT_DATA_CONNECTION_OVERRIDE_CHANGED));
    }

    /**
     * TearDown the data connection when the deactivation is complete a Message with
     * msg.what == EVENT_DEACTIVATE_DONE and msg.obj == AsyncResult with AsyncResult.obj
@@ -1006,14 +1019,19 @@ public class DataConnection extends StateMachine {

        result.setNetworkSpecifier(new StringNetworkSpecifier(Integer.toString(mPhone.getSubId())));

        if (!mPhone.getServiceState().getDataRoaming()) {
            result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        } else {
            result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        }
        result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
                !mPhone.getServiceState().getDataRoaming());

        result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);

        // Override values set above when requested by policy
        if ((mSubscriptionOverride & OVERRIDE_UNMETERED) != 0) {
            result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        }
        if ((mSubscriptionOverride & OVERRIDE_CONGESTED) != 0) {
            result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
        }

        return result;
    }

@@ -1343,6 +1361,7 @@ public class DataConnection extends StateMachine {
                    break;
                case EVENT_DATA_CONNECTION_ROAM_ON:
                case EVENT_DATA_CONNECTION_ROAM_OFF:
                case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED:
                    updateNetworkInfo();
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
@@ -1791,7 +1810,8 @@ public class DataConnection extends StateMachine {
                    break;
                }
                case EVENT_DATA_CONNECTION_ROAM_ON:
                case EVENT_DATA_CONNECTION_ROAM_OFF: {
                case EVENT_DATA_CONNECTION_ROAM_OFF:
                case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED: {
                    updateNetworkInfo();
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
@@ -2237,6 +2257,7 @@ public class DataConnection extends StateMachine {
        pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime));
        pw.println("mLastFailCause=" + mLastFailCause);
        pw.println("mUserData=" + mUserData);
        pw.println("mSubscriptionOverride=" + Integer.toHexString(mSubscriptionOverride));
        pw.println("mInstanceNumber=" + mInstanceNumber);
        pw.println("mAc=" + mAc);
        pw.println("Network capabilities changed history:");
+72 −21
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.internal.telephony.dataconnection;

import android.content.Context;
import android.net.INetworkPolicyListener;
import android.net.LinkAddress;
import android.net.LinkProperties.CompareResult;
import android.net.NetworkPolicyManager;
import android.net.NetworkUtils;
import android.os.AsyncResult;
import android.os.Build;
@@ -55,9 +57,10 @@ public class DcController extends StateMachine {
    private DcTesterDeactivateAll mDcTesterDeactivateAll;

    // package as its used by Testing code
    ArrayList<DataConnection> mDcListAll = new ArrayList<DataConnection>();
    private HashMap<Integer, DataConnection> mDcListActiveByCid =
            new HashMap<Integer, DataConnection>();
    // @GuardedBy("mDcListAll")
    final ArrayList<DataConnection> mDcListAll = new ArrayList<>();
    // @GuardedBy("mDcListAll")
    private final HashMap<Integer, DataConnection> mDcListActiveByCid = new HashMap<>();

    /**
     * Constants for the data connection activity:
@@ -72,7 +75,9 @@ public class DcController extends StateMachine {

    private DccDefaultState mDccDefaultState = new DccDefaultState();

    TelephonyManager mTelephonyManager;
    final TelephonyManager mTelephonyManager;
    final NetworkPolicyManager mNetworkPolicyManager;

    private PhoneStateListener mPhoneStateListener;

    //mExecutingCarrierChange tracks whether the phone is currently executing
@@ -105,7 +110,11 @@ public class DcController extends StateMachine {
            }
        };

        mTelephonyManager = (TelephonyManager) phone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyManager = (TelephonyManager) phone.getContext()
                .getSystemService(Context.TELEPHONY_SERVICE);
        mNetworkPolicyManager = (NetworkPolicyManager) phone.getContext()
                .getSystemService(Context.NETWORK_POLICY_SERVICE);

        if (mTelephonyManager != null) {
            mTelephonyManager.listen(mPhoneStateListener,
                    PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
@@ -125,36 +134,61 @@ public class DcController extends StateMachine {
    }

    void addDc(DataConnection dc) {
        synchronized (mDcListAll) {
            mDcListAll.add(dc);
        }
    }

    void removeDc(DataConnection dc) {
        synchronized (mDcListAll) {
            mDcListActiveByCid.remove(dc.mCid);
            mDcListAll.remove(dc);
        }
    }

    public void addActiveDcByCid(DataConnection dc) {
        if (DBG && dc.mCid < 0) {
            log("addActiveDcByCid dc.mCid < 0 dc=" + dc);
        }
        synchronized (mDcListAll) {
            mDcListActiveByCid.put(dc.mCid, dc);
        }
    }

    public DataConnection getActiveDcByCid(int cid) {
        synchronized (mDcListAll) {
            return mDcListActiveByCid.get(cid);
        }
    }

    void removeActiveDcByCid(DataConnection dc) {
        synchronized (mDcListAll) {
            DataConnection removedDc = mDcListActiveByCid.remove(dc.mCid);
            if (DBG && removedDc == null) {
                log("removeActiveDcByCid removedDc=null dc=" + dc);
            }
        }
    }

    boolean isExecutingCarrierChange() {
        return mExecutingCarrierChange;
    }

    private final INetworkPolicyListener mListener = new NetworkPolicyManager.Listener() {
        @Override
        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) {
            if (mPhone == null || mPhone.getSubId() != subId) return;

            final HashMap<Integer, DataConnection> dcListActiveByCid;
            synchronized (mDcListAll) {
                dcListActiveByCid = new HashMap<>(mDcListActiveByCid);
            }
            for (DataConnection dc : dcListActiveByCid.values()) {
                dc.onSubscriptionOverride(overrideMask, overrideValue);
            }
        }
    };

    private class DccDefaultState extends State {
        @Override
        public void enter() {
@@ -166,6 +200,9 @@ public class DcController extends StateMachine {
                mDcTesterDeactivateAll =
                        new DcTesterDeactivateAll(mPhone, DcController.this, getHandler());
            }
            if (mNetworkPolicyManager != null) {
                mNetworkPolicyManager.registerListener(mListener);
            }
        }

        @Override
@@ -177,6 +214,9 @@ public class DcController extends StateMachine {
            if (mDcTesterDeactivateAll != null) {
                mDcTesterDeactivateAll.dispose();
            }
            if (mNetworkPolicyManager != null) {
                mNetworkPolicyManager.unregisterListener(mListener);
            }
        }

        @Override
@@ -214,12 +254,19 @@ public class DcController extends StateMachine {
         * @param dcsList as sent by RIL_UNSOL_DATA_CALL_LIST_CHANGED
         */
        private void onDataStateChanged(ArrayList<DataCallResponse> dcsList) {
            final ArrayList<DataConnection> dcListAll;
            final HashMap<Integer, DataConnection> dcListActiveByCid;
            synchronized (mDcListAll) {
                dcListAll = new ArrayList<>(mDcListAll);
                dcListActiveByCid = new HashMap<>(mDcListActiveByCid);
            }

            if (DBG) {
                lr("onDataStateChanged: dcsList=" + dcsList
                        + " mDcListActiveByCid=" + mDcListActiveByCid);
                        + " dcListActiveByCid=" + dcListActiveByCid);
            }
            if (VDBG) {
                log("onDataStateChanged: mDcListAll=" + mDcListAll);
                log("onDataStateChanged: mDcListAll=" + dcListAll);
            }

            // Create hashmap of cid to DataCallResponse
@@ -232,7 +279,7 @@ public class DcController extends StateMachine {
            // Add a DC that is active but not in the
            // dcsList to the list of DC's to retry
            ArrayList<DataConnection> dcsToRetry = new ArrayList<DataConnection>();
            for (DataConnection dc : mDcListActiveByCid.values()) {
            for (DataConnection dc : dcListActiveByCid.values()) {
                if (dataCallResponseListByCid.get(dc.mCid) == null) {
                    if (DBG) log("onDataStateChanged: add to retry dc=" + dc);
                    dcsToRetry.add(dc);
@@ -249,7 +296,7 @@ public class DcController extends StateMachine {

            for (DataCallResponse newState : dcsList) {

                DataConnection dc = mDcListActiveByCid.get(newState.getCallId());
                DataConnection dc = dcListActiveByCid.get(newState.getCallId());
                if (dc == null) {
                    // UNSOL_DATA_CALL_LIST_CHANGED arrived before SETUP_DATA_CALL completed.
                    loge("onDataStateChanged: no associated DC yet, ignore");
@@ -437,14 +484,18 @@ public class DcController extends StateMachine {

    @Override
    public String toString() {
        synchronized (mDcListAll) {
            return "mDcListAll=" + mDcListAll + " mDcListActiveByCid=" + mDcListActiveByCid;
        }
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        super.dump(fd, pw, args);
        pw.println(" mPhone=" + mPhone);
        synchronized (mDcListAll) {
            pw.println(" mDcListAll=" + mDcListAll);
            pw.println(" mDcListActiveByCid=" + mDcListActiveByCid);
        }
    }
}
+49 −2
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.internal.telephony.dataconnection;

import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;

import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
@@ -26,8 +31,8 @@ import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_P
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -362,6 +367,48 @@ public class DataConnectionTest extends TelephonyTest {
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
    }

    @Test
    public void testOverrideUnmetered() throws Exception {
        mContextFixture.getCarrierConfigBundle().putStringArray(
                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                new String[] { "default" });
        testConnectEvent();

        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));

        mDc.onSubscriptionOverride(OVERRIDE_UNMETERED, OVERRIDE_UNMETERED);

        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));

        mDc.onSubscriptionOverride(OVERRIDE_UNMETERED, 0);

        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
    }

    @Test
    public void testOverrideCongested() throws Exception {
        mContextFixture.getCarrierConfigBundle().putStringArray(
                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                new String[] { "default" });
        testConnectEvent();

        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));

        mDc.onSubscriptionOverride(OVERRIDE_CONGESTED, OVERRIDE_CONGESTED);

        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));

        mDc.onSubscriptionOverride(OVERRIDE_CONGESTED, 0);

        assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
        assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
    }

    @SmallTest
    public void testIsIpAddress() throws Exception {
        // IPv4