Loading core/java/android/net/INetworkPolicyManager.aidl +0 −3 Original line number Original line Diff line number Diff line Loading @@ -57,9 +57,6 @@ interface INetworkPolicyManager { @UnsupportedAppUsage @UnsupportedAppUsage boolean getRestrictBackground(); boolean getRestrictBackground(); /** Callback used to change internal state on tethering */ void onTetheringChanged(String iface, boolean tethering); /** Gets the restrict background status based on the caller's UID: /** Gets the restrict background status based on the caller's UID: 1 - disabled 1 - disabled 2 - whitelisted 2 - whitelisted Loading packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +22 −13 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; Loading Loading @@ -64,8 +65,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.res.Resources; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback; import android.net.IpPrefix; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkAddress; Loading Loading @@ -176,7 +177,6 @@ public class Tethering { private final Context mContext; private final Context mContext; private final ArrayMap<String, TetherState> mTetherStates; private final ArrayMap<String, TetherState> mTetherStates; private final BroadcastReceiver mStateReceiver; private final BroadcastReceiver mStateReceiver; private final INetworkPolicyManager mPolicyManager; private final Looper mLooper; private final Looper mLooper; private final StateMachine mTetherMasterSM; private final StateMachine mTetherMasterSM; private final OffloadController mOffloadController; private final OffloadController mOffloadController; Loading Loading @@ -206,12 +206,12 @@ public class Tethering { private boolean mWifiTetherRequested; private boolean mWifiTetherRequested; private Network mTetherUpstream; private Network mTetherUpstream; private TetherStatesParcel mTetherStatesParcel; private TetherStatesParcel mTetherStatesParcel; private boolean mDataSaverEnabled = false; public Tethering(TetheringDependencies deps) { public Tethering(TetheringDependencies deps) { mLog.mark("Tethering.constructed"); mLog.mark("Tethering.constructed"); mDeps = deps; mDeps = deps; mContext = mDeps.getContext(); mContext = mDeps.getContext(); mPolicyManager = mDeps.getINetworkPolicyManager(); mNetd = mDeps.getINetd(mContext); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mLooper = mDeps.getTetheringLooper(); Loading Loading @@ -288,6 +288,7 @@ public class Tethering { filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED); mContext.registerReceiver(mStateReceiver, filter, null, handler); mContext.registerReceiver(mStateReceiver, filter, null, handler); } } Loading Loading @@ -484,7 +485,7 @@ public class Tethering { } } private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); final BluetoothAdapter adapter = mDeps.getBluetoothAdapter(); if (adapter == null || !adapter.isEnabled()) { if (adapter == null || !adapter.isEnabled()) { Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " + (adapter == null)); + (adapter == null)); Loading Loading @@ -775,6 +776,9 @@ public class Tethering { } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { mLog.log("OBSERVED user restrictions changed"); mLog.log("OBSERVED user restrictions changed"); handleUserRestrictionAction(); handleUserRestrictionAction(); } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) { mLog.log("OBSERVED data saver changed"); handleDataSaverChanged(); } } } } Loading Loading @@ -885,6 +889,20 @@ public class Tethering { private void handleUserRestrictionAction() { private void handleUserRestrictionAction() { mTetheringRestriction.onUserRestrictionsChanged(); mTetheringRestriction.onUserRestrictionsChanged(); } } private void handleDataSaverChanged() { final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService( Context.CONNECTIVITY_SERVICE); final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus() != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; if (mDataSaverEnabled == isDataSaverEnabled) return; mDataSaverEnabled = isDataSaverEnabled; if (mDataSaverEnabled) { untetherAll(); } } } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -1982,15 +2000,6 @@ public class Tethering { mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); try { // Notify that we're tethering (or not) this interface. // This is how data saver for instance knows if the user explicitly // turned on tethering (thus keeping us from being in data saver mode). mPolicyManager.onTetheringChanged(iface, state == IpServer.STATE_TETHERED); } catch (RemoteException e) { // Not really very much we can do here. } // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // Thus we give a chance for TetherMasterSM to recover to InitialState // Thus we give a chance for TetherMasterSM to recover to InitialState // by sending CMD_CLEAR_ERROR // by sending CMD_CLEAR_ERROR Loading packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +6 −9 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,9 @@ package com.android.server.connectivity.tethering; package com.android.server.connectivity.tethering; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Context; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.NetworkRequest; import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.net.util.SharedLog; Loading Loading @@ -105,14 +105,6 @@ public abstract class TetheringDependencies { ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); } } /** * Get a reference to INetworkPolicyManager to be used by tethering. */ public INetworkPolicyManager getINetworkPolicyManager() { return INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); } /** /** * Get a reference to INetd to be used by tethering. * Get a reference to INetd to be used by tethering. */ */ Loading @@ -130,4 +122,9 @@ public abstract class TetheringDependencies { * Get Context of TetheringSerice. * Get Context of TetheringSerice. */ */ public abstract Context getContext(); public abstract Context getContext(); /** * Get a reference to BluetoothAdapter to be used by tethering. */ public abstract BluetoothAdapter getBluetoothAdapter(); } } packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED; import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; import android.app.Service; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.net.IIntResultListener; import android.net.IIntResultListener; Loading Loading @@ -376,6 +377,11 @@ public class TetheringService extends Service { } } return INetworkStackConnector.Stub.asInterface(connector); return INetworkStackConnector.Stub.asInterface(connector); } } @Override public BluetoothAdapter getBluetoothAdapter() { return BluetoothAdapter.getDefaultAdapter(); } }; }; } } return mDeps; return mDeps; Loading packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +59 −5 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.connectivity.tethering; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; Loading Loading @@ -51,6 +54,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; Loading @@ -59,6 +63,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; Loading @@ -67,6 +72,7 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager; import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback; Loading Loading @@ -132,6 +138,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.Inet6Address; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collection; import java.util.Vector; import java.util.Vector; @RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class) Loading Loading @@ -166,6 +173,7 @@ public class TetheringTest { @Mock private INetd mNetd; @Mock private INetd mNetd; @Mock private UserManager mUserManager; @Mock private UserManager mUserManager; @Mock private NetworkRequest mNetworkRequest; @Mock private NetworkRequest mNetworkRequest; @Mock private ConnectivityManager mCm; private final MockIpServerDependencies mIpServerDependencies = private final MockIpServerDependencies mIpServerDependencies = spy(new MockIpServerDependencies()); spy(new MockIpServerDependencies()); Loading Loading @@ -217,6 +225,7 @@ public class TetheringTest { if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; return super.getSystemService(name); return super.getSystemService(name); } } Loading Loading @@ -338,11 +347,6 @@ public class TetheringTest { return mNMService; return mNMService; } } @Override public INetworkPolicyManager getINetworkPolicyManager() { return mPolicyManager; } @Override @Override public INetd getINetd(Context context) { public INetd getINetd(Context context) { return mNetd; return mNetd; Loading @@ -357,6 +361,12 @@ public class TetheringTest { public Context getContext() { public Context getContext() { return mServiceContext; return mServiceContext; } } @Override public BluetoothAdapter getBluetoothAdapter() { // TODO: add test for bluetooth tethering. return null; } } } private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, Loading Loading @@ -1348,6 +1358,50 @@ public class TetheringTest { workingWifiP2pGroupClient(false); workingWifiP2pGroupClient(false); } } private void setDataSaverEnabled(boolean enabled) { final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED); mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED : RESTRICT_BACKGROUND_STATUS_DISABLED; when(mCm.getRestrictBackgroundStatus()).thenReturn(status); mLooper.dispatchAll(); } @Test public void testDataSaverChanged() { // Start Tethering. final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); runUsbTethering(upstreamState); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // Data saver is ON. setDataSaverEnabled(true); // Verify that tethering should be disabled. verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); mTethering.interfaceRemoved(TEST_USB_IFNAME); mLooper.dispatchAll(); assertEquals(mTethering.getTetheredIfaces(), new String[0]); reset(mUsbManager); runUsbTethering(upstreamState); // Verify that user can start tethering again without turning OFF data saver. assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // If data saver is keep ON with change event, tethering should not be OFF this time. setDataSaverEnabled(true); verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // If data saver is turned OFF, it should not change tethering. setDataSaverEnabled(false); verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); } private static <T> void assertContains(Collection<T> collection, T element) { assertTrue(element + " not found in " + collection, collection.contains(element)); } // TODO: Test that a request for hotspot mode doesn't interfere with an // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. // already operating tethering mode interface. } } Loading
core/java/android/net/INetworkPolicyManager.aidl +0 −3 Original line number Original line Diff line number Diff line Loading @@ -57,9 +57,6 @@ interface INetworkPolicyManager { @UnsupportedAppUsage @UnsupportedAppUsage boolean getRestrictBackground(); boolean getRestrictBackground(); /** Callback used to change internal state on tethering */ void onTetheringChanged(String iface, boolean tethering); /** Gets the restrict background status based on the caller's UID: /** Gets the restrict background status based on the caller's UID: 1 - disabled 1 - disabled 2 - whitelisted 2 - whitelisted Loading
packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +22 −13 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; Loading Loading @@ -64,8 +65,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.res.Resources; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback; import android.net.IpPrefix; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkAddress; Loading Loading @@ -176,7 +177,6 @@ public class Tethering { private final Context mContext; private final Context mContext; private final ArrayMap<String, TetherState> mTetherStates; private final ArrayMap<String, TetherState> mTetherStates; private final BroadcastReceiver mStateReceiver; private final BroadcastReceiver mStateReceiver; private final INetworkPolicyManager mPolicyManager; private final Looper mLooper; private final Looper mLooper; private final StateMachine mTetherMasterSM; private final StateMachine mTetherMasterSM; private final OffloadController mOffloadController; private final OffloadController mOffloadController; Loading Loading @@ -206,12 +206,12 @@ public class Tethering { private boolean mWifiTetherRequested; private boolean mWifiTetherRequested; private Network mTetherUpstream; private Network mTetherUpstream; private TetherStatesParcel mTetherStatesParcel; private TetherStatesParcel mTetherStatesParcel; private boolean mDataSaverEnabled = false; public Tethering(TetheringDependencies deps) { public Tethering(TetheringDependencies deps) { mLog.mark("Tethering.constructed"); mLog.mark("Tethering.constructed"); mDeps = deps; mDeps = deps; mContext = mDeps.getContext(); mContext = mDeps.getContext(); mPolicyManager = mDeps.getINetworkPolicyManager(); mNetd = mDeps.getINetd(mContext); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mLooper = mDeps.getTetheringLooper(); Loading Loading @@ -288,6 +288,7 @@ public class Tethering { filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED); mContext.registerReceiver(mStateReceiver, filter, null, handler); mContext.registerReceiver(mStateReceiver, filter, null, handler); } } Loading Loading @@ -484,7 +485,7 @@ public class Tethering { } } private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); final BluetoothAdapter adapter = mDeps.getBluetoothAdapter(); if (adapter == null || !adapter.isEnabled()) { if (adapter == null || !adapter.isEnabled()) { Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " + (adapter == null)); + (adapter == null)); Loading Loading @@ -775,6 +776,9 @@ public class Tethering { } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { mLog.log("OBSERVED user restrictions changed"); mLog.log("OBSERVED user restrictions changed"); handleUserRestrictionAction(); handleUserRestrictionAction(); } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) { mLog.log("OBSERVED data saver changed"); handleDataSaverChanged(); } } } } Loading Loading @@ -885,6 +889,20 @@ public class Tethering { private void handleUserRestrictionAction() { private void handleUserRestrictionAction() { mTetheringRestriction.onUserRestrictionsChanged(); mTetheringRestriction.onUserRestrictionsChanged(); } } private void handleDataSaverChanged() { final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService( Context.CONNECTIVITY_SERVICE); final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus() != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; if (mDataSaverEnabled == isDataSaverEnabled) return; mDataSaverEnabled = isDataSaverEnabled; if (mDataSaverEnabled) { untetherAll(); } } } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -1982,15 +2000,6 @@ public class Tethering { mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); try { // Notify that we're tethering (or not) this interface. // This is how data saver for instance knows if the user explicitly // turned on tethering (thus keeping us from being in data saver mode). mPolicyManager.onTetheringChanged(iface, state == IpServer.STATE_TETHERED); } catch (RemoteException e) { // Not really very much we can do here. } // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // Thus we give a chance for TetherMasterSM to recover to InitialState // Thus we give a chance for TetherMasterSM to recover to InitialState // by sending CMD_CLEAR_ERROR // by sending CMD_CLEAR_ERROR Loading
packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +6 −9 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,9 @@ package com.android.server.connectivity.tethering; package com.android.server.connectivity.tethering; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Context; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.NetworkRequest; import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.net.util.SharedLog; Loading Loading @@ -105,14 +105,6 @@ public abstract class TetheringDependencies { ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); } } /** * Get a reference to INetworkPolicyManager to be used by tethering. */ public INetworkPolicyManager getINetworkPolicyManager() { return INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); } /** /** * Get a reference to INetd to be used by tethering. * Get a reference to INetd to be used by tethering. */ */ Loading @@ -130,4 +122,9 @@ public abstract class TetheringDependencies { * Get Context of TetheringSerice. * Get Context of TetheringSerice. */ */ public abstract Context getContext(); public abstract Context getContext(); /** * Get a reference to BluetoothAdapter to be used by tethering. */ public abstract BluetoothAdapter getBluetoothAdapter(); } }
packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED; import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; import android.app.Service; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.net.IIntResultListener; import android.net.IIntResultListener; Loading Loading @@ -376,6 +377,11 @@ public class TetheringService extends Service { } } return INetworkStackConnector.Stub.asInterface(connector); return INetworkStackConnector.Stub.asInterface(connector); } } @Override public BluetoothAdapter getBluetoothAdapter() { return BluetoothAdapter.getDefaultAdapter(); } }; }; } } return mDeps; return mDeps; Loading
packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +59 −5 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.connectivity.tethering; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; Loading Loading @@ -51,6 +54,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; Loading @@ -59,6 +63,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; Loading @@ -67,6 +72,7 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager; import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback; Loading Loading @@ -132,6 +138,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.Inet6Address; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collection; import java.util.Vector; import java.util.Vector; @RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class) Loading Loading @@ -166,6 +173,7 @@ public class TetheringTest { @Mock private INetd mNetd; @Mock private INetd mNetd; @Mock private UserManager mUserManager; @Mock private UserManager mUserManager; @Mock private NetworkRequest mNetworkRequest; @Mock private NetworkRequest mNetworkRequest; @Mock private ConnectivityManager mCm; private final MockIpServerDependencies mIpServerDependencies = private final MockIpServerDependencies mIpServerDependencies = spy(new MockIpServerDependencies()); spy(new MockIpServerDependencies()); Loading Loading @@ -217,6 +225,7 @@ public class TetheringTest { if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; return super.getSystemService(name); return super.getSystemService(name); } } Loading Loading @@ -338,11 +347,6 @@ public class TetheringTest { return mNMService; return mNMService; } } @Override public INetworkPolicyManager getINetworkPolicyManager() { return mPolicyManager; } @Override @Override public INetd getINetd(Context context) { public INetd getINetd(Context context) { return mNetd; return mNetd; Loading @@ -357,6 +361,12 @@ public class TetheringTest { public Context getContext() { public Context getContext() { return mServiceContext; return mServiceContext; } } @Override public BluetoothAdapter getBluetoothAdapter() { // TODO: add test for bluetooth tethering. return null; } } } private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, Loading Loading @@ -1348,6 +1358,50 @@ public class TetheringTest { workingWifiP2pGroupClient(false); workingWifiP2pGroupClient(false); } } private void setDataSaverEnabled(boolean enabled) { final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED); mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED : RESTRICT_BACKGROUND_STATUS_DISABLED; when(mCm.getRestrictBackgroundStatus()).thenReturn(status); mLooper.dispatchAll(); } @Test public void testDataSaverChanged() { // Start Tethering. final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); runUsbTethering(upstreamState); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // Data saver is ON. setDataSaverEnabled(true); // Verify that tethering should be disabled. verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); mTethering.interfaceRemoved(TEST_USB_IFNAME); mLooper.dispatchAll(); assertEquals(mTethering.getTetheredIfaces(), new String[0]); reset(mUsbManager); runUsbTethering(upstreamState); // Verify that user can start tethering again without turning OFF data saver. assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // If data saver is keep ON with change event, tethering should not be OFF this time. setDataSaverEnabled(true); verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); // If data saver is turned OFF, it should not change tethering. setDataSaverEnabled(false); verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); } private static <T> void assertContains(Collection<T> collection, T element) { assertTrue(element + " not found in " + collection, collection.contains(element)); } // TODO: Test that a request for hotspot mode doesn't interfere with an // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. // already operating tethering mode interface. } }