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

Commit 4e7c3ad9 authored by Mark Chien's avatar Mark Chien Committed by android-build-merger
Browse files

Merge "Fix entitlement failed when device is on CBRS"

am: 073c203d

Change-Id: I682ec8f7b8f91be5e6735e141f4da06a18a11fe1
parents a207b449 073c203d
Loading
Loading
Loading
Loading
+30 −33
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;

import static com.android.server.ConnectivityService.SHORT_ARG;

@@ -89,6 +90,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -97,7 +100,6 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
@@ -182,12 +184,13 @@ public class Tethering extends BaseNetworkObserver {
    // into a single coherent structure.
    private final HashSet<IpServer> mForwardedDownstreams;
    private final VersionedBroadcastListener mCarrierConfigChange;
    private final VersionedBroadcastListener mDefaultSubscriptionChange;
    private final TetheringDependencies mDeps;
    private final EntitlementManager mEntitlementMgr;
    private final Handler mHandler;
    private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
            new RemoteCallbackList<>();
    private final PhoneStateListener mPhoneStateListener;
    private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;

    private volatile TetheringConfiguration mConfig;
    private InterfaceSet mCurrentUpstreamIfaceSet;
@@ -238,7 +241,6 @@ public class Tethering extends BaseNetworkObserver {
            stopTethering(downstream);
        });
        mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
            maybeDefaultDataSubChanged();
            return mConfig;
        });

@@ -250,14 +252,16 @@ public class Tethering extends BaseNetworkObserver {
                    mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
                });

        filter = new IntentFilter();
        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
        mDefaultSubscriptionChange = new VersionedBroadcastListener(
                "DefaultSubscriptionChangeListener", mContext, mHandler, filter,
                (Intent ignored) -> {
                    mLog.log("OBSERVED default data subscription change");
                    maybeDefaultDataSubChanged();
                    // To avoid launch unexpected provisioning checks, ignore re-provisioning when
        mPhoneStateListener = new PhoneStateListener(mLooper) {
            @Override
            public void onActiveDataSubscriptionIdChanged(int subId) {
                mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
                        + " to " + subId);
                if (subId == mActiveDataSubId) return;

                mActiveDataSubId = subId;
                updateConfiguration();
                // To avoid launching unexpected provisioning checks, ignore re-provisioning when
                // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
                // triggered again when CarrierConfig is loaded.
                if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
@@ -265,7 +269,9 @@ public class Tethering extends BaseNetworkObserver {
                } else {
                    mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
                }
                });
            }
        };

        mStateReceiver = new StateReceiver();

        // Load tethering configuration.
@@ -276,7 +282,8 @@ public class Tethering extends BaseNetworkObserver {

    private void startStateMachineUpdaters(Handler handler) {
        mCarrierConfigChange.startListening();
        mDefaultSubscriptionChange.startListening();
        TelephonyManager.from(mContext).listen(mPhoneStateListener,
                PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);

        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_STATE);
@@ -304,27 +311,17 @@ public class Tethering extends BaseNetworkObserver {

    // NOTE: This is always invoked on the mLooper thread.
    private void updateConfiguration() {
        final int subId = mDeps.getDefaultDataSubscriptionId();
        updateConfiguration(subId);
    }

    private void updateConfiguration(final int subId) {
        mConfig = new TetheringConfiguration(mContext, mLog, subId);
        mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
        mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
    }

    private void maybeDunSettingChanged() {
        final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
        final boolean isDunRequired = TetheringConfiguration.checkDunRequired(
                mContext, mActiveDataSubId);
        if (isDunRequired == mConfig.isDunRequired) return;
        updateConfiguration();
    }

    private void maybeDefaultDataSubChanged() {
        final int subId = mDeps.getDefaultDataSubscriptionId();
        if (subId == mConfig.subId) return;
        updateConfiguration(subId);
    }

    @Override
    public void interfaceStatusChanged(String iface, boolean up) {
        // Never called directly: only called from interfaceLinkStateChanged.
+3 −3
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public class TetheringConfiguration {
        tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs);
        tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);

        isDunRequired = checkDunRequired(ctx);
        isDunRequired = checkDunRequired(ctx, subId);

        chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic);
        preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
@@ -228,9 +228,9 @@ public class TetheringConfiguration {
    }

    /** Check whether dun is required. */
    public static boolean checkDunRequired(Context ctx) {
    public static boolean checkDunRequired(Context ctx, int id) {
        final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
        return (tm != null) ? tm.getTetherApnRequired() : false;
        return (tm != null) ? tm.getTetherApnRequired(id) : false;
    }

    private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
+4 −4
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.net.NetworkRequest;
import android.net.ip.IpServer;
import android.net.util.SharedLog;
import android.os.Handler;
import android.telephony.SubscriptionManager;

import com.android.internal.util.StateMachine;
import com.android.server.connectivity.MockableSystemProperties;
@@ -88,9 +87,10 @@ public class TetheringDependencies {
    }

    /**
     * Get default data subscription id to build TetheringConfiguration.
     * Generate a new TetheringConfiguration according to input sub Id.
     */
    public int getDefaultDataSubscriptionId() {
        return SubscriptionManager.getDefaultDataSubscriptionId();
    public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
            int subId) {
        return new TetheringConfiguration(ctx, log, subId);
    }
}
+37 −2
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;

import androidx.test.filters.SmallTest;
@@ -111,6 +113,7 @@ import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
import com.android.server.connectivity.tethering.OffloadHardwareInterface;
import com.android.server.connectivity.tethering.TetheringConfiguration;
import com.android.server.connectivity.tethering.TetheringDependencies;
import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;

@@ -118,6 +121,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -147,6 +151,7 @@ public class TetheringTest {
    @Mock private MockableSystemProperties mSystemProperties;
    @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
    @Mock private Resources mResources;
    @Mock private TelephonyManager mTelephonyManager;
    @Mock private UsbManager mUsbManager;
    @Mock private WifiManager mWifiManager;
    @Mock private CarrierConfigManager mCarrierConfigManager;
@@ -171,6 +176,7 @@ public class TetheringTest {
    private MockContentResolver mContentResolver;
    private BroadcastReceiver mBroadcastReceiver;
    private Tethering mTethering;
    private PhoneStateListener mPhoneStateListener;

    private class MockContext extends BroadcastInterceptingContext {
        MockContext(Context base) {
@@ -193,6 +199,7 @@ public class TetheringTest {
        public Object getSystemService(String name) {
            if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
            if (Context.USB_SERVICE.equals(name)) return mUsbManager;
            if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
            return super.getSystemService(name);
        }
    }
@@ -234,6 +241,17 @@ public class TetheringTest {
        }
    }

    private class MockTetheringConfiguration extends TetheringConfiguration {
        MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
            super(ctx, log, id);
        }

        @Override
        protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
            return mResources;
        }
    }

    public class MockTetheringDependencies extends TetheringDependencies {
        StateMachine upstreamNetworkMonitorMasterSM;
        ArrayList<IpServer> ipv6CoordinatorNotifyList;
@@ -276,8 +294,9 @@ public class TetheringTest {
        }

        @Override
        public int getDefaultDataSubscriptionId() {
            return INVALID_SUBSCRIPTION_ID;
        public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
                int subId) {
            return new MockTetheringConfiguration(ctx, log, subId);
        }
    }

@@ -372,6 +391,11 @@ public class TetheringTest {
        mTetheringDependencies.reset();
        mTethering = makeTethering();
        verify(mNMService).registerTetheringStatsProvider(any(), anyString());
        final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
                ArgumentCaptor.forClass(PhoneStateListener.class);
        verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
                eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
        mPhoneStateListener = phoneListenerCaptor.getValue();
    }

    private Tethering makeTethering() {
@@ -982,6 +1006,17 @@ public class TetheringTest {
        callback2.expectUpstreamChanged(upstreamState.network);
    }

    @Test
    public void testMultiSimAware() throws Exception {
        final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
        assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId);

        final int fakeSubId = 1234;
        mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
        final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
        assertEquals(fakeSubId, newConfig.subId);
    }

    // TODO: Test that a request for hotspot mode doesn't interfere with an
    // already operating tethering mode interface.
}
+6 −5
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static com.android.internal.R.array.config_tether_upstream_types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.when;

import android.content.ContentResolver;
@@ -141,7 +142,7 @@ public class TetheringConfigurationTest {

    @Test
    public void testDunFromTelephonyManagerMeansDun() {
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(true);
        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(true);

        final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
        final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -165,7 +166,7 @@ public class TetheringConfigurationTest {

    @Test
    public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);

        final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
        final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -208,7 +209,7 @@ public class TetheringConfigurationTest {
    @Test
    public void testNoDefinedUpstreamTypesAddsEthernet() {
        when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{});
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);

        final TetheringConfiguration cfg = new TetheringConfiguration(
                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -231,7 +232,7 @@ public class TetheringConfigurationTest {
    public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
        when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(
                new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);

        final TetheringConfiguration cfg = new TetheringConfiguration(
                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -249,7 +250,7 @@ public class TetheringConfigurationTest {
    public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
        when(mResources.getIntArray(config_tether_upstream_types))
                .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);

        final TetheringConfiguration cfg = new TetheringConfiguration(
                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);