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

Commit 64cda083 authored by Mark Chien's avatar Mark Chien Committed by Android (Google) Code Review
Browse files

Merge "Make members final in TetheringService" into rvc-dev-plus-aosp

parents 0a6f7704 071c3abf
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -109,8 +109,10 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -228,6 +230,7 @@ public class Tethering {
    private final ConnectedClientsTracker mConnectedClientsTracker;
    private final TetheringThreadExecutor mExecutor;
    private final TetheringNotificationUpdater mNotificationUpdater;
    private final UserManager mUserManager;
    private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
    // All the usage of mTetheringEventCallback should run in the same thread.
    private ITetheringEventCallback mTetheringEventCallback = null;
@@ -305,23 +308,24 @@ public class Tethering {

        mStateReceiver = new StateReceiver();

        final UserManager userManager = (UserManager) mContext.getSystemService(
                Context.USER_SERVICE);
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mTetheringRestriction = new UserRestrictionActionListener(
                userManager, this, mNotificationUpdater);
                mUserManager, this, mNotificationUpdater);
        mExecutor = new TetheringThreadExecutor(mHandler);
        mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
        mNetdCallback = new NetdCallback();

        // Load tethering configuration.
        updateConfiguration();

        startStateMachineUpdaters();
    }

    /**
     * Start to register callbacks.
     * Call this function when tethering is ready to handle callback events.
     */
    public void startStateMachineUpdaters() {
    private void startStateMachineUpdaters() {
        try {
            mNetd.registerUnsolicitedEventListener(mNetdCallback);
        } catch (RemoteException e) {
@@ -779,7 +783,7 @@ public class Tethering {

    // TODO: Figure out how to update for local hotspot mode interfaces.
    private void sendTetherStateChangedBroadcast() {
        if (!mDeps.isTetheringSupported()) return;
        if (!isTetheringSupported()) return;

        final ArrayList<String> availableList = new ArrayList<>();
        final ArrayList<String> tetherList = new ArrayList<>();
@@ -1020,14 +1024,14 @@ public class Tethering {

    @VisibleForTesting
    protected static class UserRestrictionActionListener {
        private final UserManager mUserManager;
        private final UserManager mUserMgr;
        private final Tethering mWrapper;
        private final TetheringNotificationUpdater mNotificationUpdater;
        public boolean mDisallowTethering;

        public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
                @NonNull TetheringNotificationUpdater updater) {
            mUserManager = um;
            mUserMgr = um;
            mWrapper = wrapper;
            mNotificationUpdater = updater;
            mDisallowTethering = false;
@@ -1037,7 +1041,7 @@ public class Tethering {
            // getUserRestrictions gets restriction for this process' user, which is the primary
            // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
            // user. See UserManager.DISALLOW_CONFIG_TETHERING.
            final Bundle restrictions = mUserManager.getUserRestrictions();
            final Bundle restrictions = mUserMgr.getUserRestrictions();
            final boolean newlyDisallowed =
                    restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
            final boolean prevDisallowed = mDisallowTethering;
@@ -1988,7 +1992,7 @@ public class Tethering {
        mHandler.post(() -> {
            mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
            final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
            parcel.tetheringSupported = mDeps.isTetheringSupported();
            parcel.tetheringSupported = isTetheringSupported();
            parcel.upstreamNetwork = mTetherUpstream;
            parcel.config = mConfig.toStableParcelable();
            parcel.states =
@@ -2111,6 +2115,20 @@ public class Tethering {
        }
    }

    // if ro.tether.denied = true we default to no tethering
    // gservices could set the secure setting to 1 though to enable it on a build where it
    // had previously been turned off.
    boolean isTetheringSupported() {
        final int defaultVal =
                SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
        final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
        final boolean tetherEnabledInSettings = tetherSupported
                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);

        return tetherEnabledInSettings && hasTetherableConfiguration();
    }

    void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
        // Binder.java closes the resource for us.
        @SuppressWarnings("resource")
+71 −114
Original line number Diff line number Diff line
@@ -40,15 +40,12 @@ import android.net.TetheringRequestParcel;
import android.net.dhcp.DhcpServerCallbacks;
import android.net.dhcp.DhcpServingParamsParcel;
import android.net.ip.IpServer;
import android.net.util.SharedLog;
import android.os.Binder;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;

@@ -68,21 +65,14 @@ import java.io.PrintWriter;
public class TetheringService extends Service {
    private static final String TAG = TetheringService.class.getSimpleName();

    private final SharedLog mLog = new SharedLog(TAG);
    private TetheringConnector mConnector;
    private Context mContext;
    private TetheringDependencies mDeps;
    private Tethering mTethering;
    private UserManager mUserManager;

    @Override
    public void onCreate() {
        mLog.mark("onCreate");
        mDeps = getTetheringDependencies();
        mContext = mDeps.getContext();
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mTethering = makeTethering(mDeps);
        mTethering.startStateMachineUpdaters();
        final TetheringDependencies deps = makeTetheringDependencies();
        // The Tethering object needs a fully functional context to start, so this can't be done
        // in the constructor.
        mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
    }

    /**
@@ -94,21 +84,10 @@ public class TetheringService extends Service {
        return new Tethering(deps);
    }

    /**
     * Create a binder connector for the system server to communicate with the tethering.
     */
    private synchronized IBinder makeConnector() {
        if (mConnector == null) {
            mConnector = new TetheringConnector(mTethering, TetheringService.this);
        }
        return mConnector;
    }

    @NonNull
    @Override
    public IBinder onBind(Intent intent) {
        mLog.mark("onBind");
        return makeConnector();
        return mConnector;
    }

    private static class TetheringConnector extends ITetheringConnector.Stub {
@@ -248,7 +227,7 @@ public class TetheringService extends Service {
                    listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
                    return true;
                }
                if (!mService.isTetheringSupported()) {
                if (!mTethering.isTetheringSupported()) {
                    listener.onResult(TETHER_ERROR_UNSUPPORTED);
                    return true;
                }
@@ -266,7 +245,7 @@ public class TetheringService extends Service {
                receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
                return true;
            }
            if (!mService.isTetheringSupported()) {
            if (!mTethering.isTetheringSupported()) {
                receiver.send(TETHER_ERROR_UNSUPPORTED, null);
                return true;
            }
@@ -300,20 +279,6 @@ public class TetheringService extends Service {
        }
    }

    // if ro.tether.denied = true we default to no tethering
    // gservices could set the secure setting to 1 though to enable it on a build where it
    // had previously been turned off.
    private boolean isTetheringSupported() {
        final int defaultVal =
                SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
        final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
        final boolean tetherEnabledInSettings = tetherSupported
                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);

        return tetherEnabledInSettings && mTethering.hasTetherableConfiguration();
    }

    /**
     * Check if the package is a allowed to write settings. This also accounts that such an access
     * happened.
@@ -332,9 +297,8 @@ public class TetheringService extends Service {
     * An injection method for testing.
     */
    @VisibleForTesting
    public TetheringDependencies getTetheringDependencies() {
        if (mDeps == null) {
            mDeps = new TetheringDependencies() {
    public TetheringDependencies makeTetheringDependencies() {
        return new TetheringDependencies() {
            @Override
            public NetworkRequest getDefaultNetworkRequest() {
                // TODO: b/147280869, add a proper system API to replace this.
@@ -355,11 +319,6 @@ public class TetheringService extends Service {
                return tetherThread.getLooper();
            }

                @Override
                public boolean isTetheringSupported() {
                    return TetheringService.this.isTetheringSupported();
                }

            @Override
            public Context getContext() {
                return TetheringService.this;
@@ -413,6 +372,4 @@ public class TetheringService extends Service {
            }
        };
    }
        return mDeps;
    }
}
+9 −10
Original line number Diff line number Diff line
@@ -83,8 +83,7 @@ public final class TetheringServiceTest {
        mTetheringConnector = mockConnector.getTetheringConnector();
        final MockTetheringService service = mockConnector.getService();
        mTethering = service.getTethering();
        verify(mTethering).startStateMachineUpdaters();
        when(mTethering.hasTetherableConfiguration()).thenReturn(true);
        when(mTethering.isTetheringSupported()).thenReturn(true);
    }

    @After
@@ -97,7 +96,7 @@ public final class TetheringServiceTest {
        when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).tether(TEST_IFACE_NAME);
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -109,7 +108,7 @@ public final class TetheringServiceTest {
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
                result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).untether(TEST_IFACE_NAME);
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -121,7 +120,7 @@ public final class TetheringServiceTest {
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
                TEST_ATTRIBUTION_TAG, result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).setUsbTethering(true /* enable */);
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -133,7 +132,7 @@ public final class TetheringServiceTest {
        final TetheringRequestParcel request = new TetheringRequestParcel();
        request.tetheringType = TETHERING_WIFI;
        mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).startTethering(eq(request), eq(result));
        verifyNoMoreInteractions(mTethering);
    }
@@ -143,7 +142,7 @@ public final class TetheringServiceTest {
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
                result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).stopTethering(TETHERING_WIFI);
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -154,7 +153,7 @@ public final class TetheringServiceTest {
        final ResultReceiver result = new ResultReceiver(null);
        mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
                true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
                eq(result), eq(true) /* showEntitlementUi */);
        verifyNoMoreInteractions(mTethering);
@@ -181,7 +180,7 @@ public final class TetheringServiceTest {
    public void testStopAllTethering() throws Exception {
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verify(mTethering).untetherAll();
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -191,7 +190,7 @@ public final class TetheringServiceTest {
    public void testIsTetheringSupported() throws Exception {
        final TestTetheringResult result = new TestTetheringResult();
        mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
        verify(mTethering).hasTetherableConfiguration();
        verify(mTethering).isTetheringSupported();
        verifyNoMoreInteractions(mTethering);
        result.assertResult(TETHER_ERROR_NO_ERROR);
    }
+32 −24
Original line number Diff line number Diff line
@@ -485,18 +485,6 @@ public class TetheringTest {
        MockitoAnnotations.initMocks(this);
        when(mResources.getStringArray(R.array.config_tether_dhcp_range))
                .thenReturn(new String[0]);
        when(mResources.getStringArray(R.array.config_tether_usb_regexs))
                .thenReturn(new String[] { "test_rndis\\d" });
        when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
                .thenReturn(new String[]{ "test_wlan\\d" });
        when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
                .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
        when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
                .thenReturn(new String[0]);
        when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
                .thenReturn(new String[] { "test_ncm\\d" });
        when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
        when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false);
        when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                false);
        when(mNetd.interfaceGetList())
@@ -515,6 +503,7 @@ public class TetheringTest {
        mServiceContext = new TestContext(mContext);
        mContentResolver = new MockContentResolver(mServiceContext);
        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
        setTetheringSupported(true /* supported */);
        mIntents = new Vector<>();
        mBroadcastReceiver = new BroadcastReceiver() {
            @Override
@@ -525,7 +514,6 @@ public class TetheringTest {
        mServiceContext.registerReceiver(mBroadcastReceiver,
                new IntentFilter(ACTION_TETHER_STATE_CHANGED));
        mTethering = makeTethering();
        mTethering.startStateMachineUpdaters();
        verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
        verify(mNetd).registerUnsolicitedEventListener(any());
        final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -536,6 +524,31 @@ public class TetheringTest {
        mPhoneStateListener = phoneListenerCaptor.getValue();
    }

    private void setTetheringSupported(final boolean supported) {
        Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
                supported ? 1 : 0);
        when(mUserManager.hasUserRestriction(
                UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
        // Setup tetherable configuration.
        when(mResources.getStringArray(R.array.config_tether_usb_regexs))
                .thenReturn(new String[] { "test_rndis\\d" });
        when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
                .thenReturn(new String[]{ "test_wlan\\d" });
        when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
                .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
        when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
                .thenReturn(new String[0]);
        when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
                .thenReturn(new String[] { "test_ncm\\d" });
        when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
        when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
    }

    private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
    }

    private Tethering makeTethering() {
        mTetheringDependencies.reset();
        return new Tethering(mTetheringDependencies);
@@ -672,9 +685,7 @@ public class TetheringTest {
    }

    private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
                .thenReturn(upstreamState);
        initTetheringUpstream(upstreamState);

        // Emulate pressing the USB tethering button in Settings UI.
        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
@@ -700,7 +711,7 @@ public class TetheringTest {
        verify(mNetd, times(1)).interfaceGetList();

        // UpstreamNetworkMonitor should receive selected upstream
        verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
        verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
        verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
    }

@@ -872,8 +883,7 @@ public class TetheringTest {

        // Then 464xlat comes up
        upstreamState = buildMobile464xlatUpstreamState();
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
                .thenReturn(upstreamState);
        initTetheringUpstream(upstreamState);

        // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
        mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
@@ -1344,9 +1354,7 @@ public class TetheringTest {
        callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
        // 2. Enable wifi tethering.
        UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
                .thenReturn(upstreamState);
        initTetheringUpstream(upstreamState);
        when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
        mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
        mLooper.dispatchAll();
@@ -1723,7 +1731,7 @@ public class TetheringTest {
        final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
                mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
        final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
        initTetheringUpstream(upstreamState);
        stateMachine.chooseUpstreamType(true);

        verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
@@ -1735,7 +1743,7 @@ public class TetheringTest {
        final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
                mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
        final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
        initTetheringUpstream(upstreamState);
        stateMachine.chooseUpstreamType(true);

        stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);