Merge "Make members final in TetheringService"

This commit is contained in:
Treehugger Robot
2020-05-13 16:04:58 +00:00
committed by Gerrit Code Review
4 changed files with 140 additions and 158 deletions

View File

@@ -109,8 +109,10 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
import android.os.SystemProperties;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings;
import android.telephony.PhoneStateListener; import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
@@ -228,6 +230,7 @@ public class Tethering {
private final ConnectedClientsTracker mConnectedClientsTracker; private final ConnectedClientsTracker mConnectedClientsTracker;
private final TetheringThreadExecutor mExecutor; private final TetheringThreadExecutor mExecutor;
private final TetheringNotificationUpdater mNotificationUpdater; private final TetheringNotificationUpdater mNotificationUpdater;
private final UserManager mUserManager;
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
// All the usage of mTetheringEventCallback should run in the same thread. // All the usage of mTetheringEventCallback should run in the same thread.
private ITetheringEventCallback mTetheringEventCallback = null; private ITetheringEventCallback mTetheringEventCallback = null;
@@ -305,23 +308,24 @@ public class Tethering {
mStateReceiver = new StateReceiver(); mStateReceiver = new StateReceiver();
final UserManager userManager = (UserManager) mContext.getSystemService( mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Context.USER_SERVICE);
mTetheringRestriction = new UserRestrictionActionListener( mTetheringRestriction = new UserRestrictionActionListener(
userManager, this, mNotificationUpdater); mUserManager, this, mNotificationUpdater);
mExecutor = new TetheringThreadExecutor(mHandler); mExecutor = new TetheringThreadExecutor(mHandler);
mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor); mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
mNetdCallback = new NetdCallback(); mNetdCallback = new NetdCallback();
// Load tethering configuration. // Load tethering configuration.
updateConfiguration(); updateConfiguration();
startStateMachineUpdaters();
} }
/** /**
* Start to register callbacks. * Start to register callbacks.
* Call this function when tethering is ready to handle callback events. * Call this function when tethering is ready to handle callback events.
*/ */
public void startStateMachineUpdaters() { private void startStateMachineUpdaters() {
try { try {
mNetd.registerUnsolicitedEventListener(mNetdCallback); mNetd.registerUnsolicitedEventListener(mNetdCallback);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -779,7 +783,7 @@ public class Tethering {
// TODO: Figure out how to update for local hotspot mode interfaces. // TODO: Figure out how to update for local hotspot mode interfaces.
private void sendTetherStateChangedBroadcast() { private void sendTetherStateChangedBroadcast() {
if (!mDeps.isTetheringSupported()) return; if (!isTetheringSupported()) return;
final ArrayList<String> availableList = new ArrayList<>(); final ArrayList<String> availableList = new ArrayList<>();
final ArrayList<String> tetherList = new ArrayList<>(); final ArrayList<String> tetherList = new ArrayList<>();
@@ -1020,14 +1024,14 @@ public class Tethering {
@VisibleForTesting @VisibleForTesting
protected static class UserRestrictionActionListener { protected static class UserRestrictionActionListener {
private final UserManager mUserManager; private final UserManager mUserMgr;
private final Tethering mWrapper; private final Tethering mWrapper;
private final TetheringNotificationUpdater mNotificationUpdater; private final TetheringNotificationUpdater mNotificationUpdater;
public boolean mDisallowTethering; public boolean mDisallowTethering;
public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper, public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
@NonNull TetheringNotificationUpdater updater) { @NonNull TetheringNotificationUpdater updater) {
mUserManager = um; mUserMgr = um;
mWrapper = wrapper; mWrapper = wrapper;
mNotificationUpdater = updater; mNotificationUpdater = updater;
mDisallowTethering = false; mDisallowTethering = false;
@@ -1037,7 +1041,7 @@ public class Tethering {
// getUserRestrictions gets restriction for this process' user, which is the primary // 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. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
// user. See UserManager.DISALLOW_CONFIG_TETHERING. // user. See UserManager.DISALLOW_CONFIG_TETHERING.
final Bundle restrictions = mUserManager.getUserRestrictions(); final Bundle restrictions = mUserMgr.getUserRestrictions();
final boolean newlyDisallowed = final boolean newlyDisallowed =
restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
final boolean prevDisallowed = mDisallowTethering; final boolean prevDisallowed = mDisallowTethering;
@@ -1988,7 +1992,7 @@ public class Tethering {
mHandler.post(() -> { mHandler.post(() -> {
mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission)); mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel(); final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
parcel.tetheringSupported = mDeps.isTetheringSupported(); parcel.tetheringSupported = isTetheringSupported();
parcel.upstreamNetwork = mTetherUpstream; parcel.upstreamNetwork = mTetherUpstream;
parcel.config = mConfig.toStableParcelable(); parcel.config = mConfig.toStableParcelable();
parcel.states = 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) { void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
// Binder.java closes the resource for us. // Binder.java closes the resource for us.
@SuppressWarnings("resource") @SuppressWarnings("resource")

View File

@@ -40,15 +40,12 @@ import android.net.TetheringRequestParcel;
import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServerCallbacks;
import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.DhcpServingParamsParcel;
import android.net.ip.IpServer; import android.net.ip.IpServer;
import android.net.util.SharedLog;
import android.os.Binder; import android.os.Binder;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.util.Log; import android.util.Log;
@@ -68,21 +65,14 @@ import java.io.PrintWriter;
public class TetheringService extends Service { public class TetheringService extends Service {
private static final String TAG = TetheringService.class.getSimpleName(); private static final String TAG = TetheringService.class.getSimpleName();
private final SharedLog mLog = new SharedLog(TAG);
private TetheringConnector mConnector; private TetheringConnector mConnector;
private Context mContext;
private TetheringDependencies mDeps;
private Tethering mTethering;
private UserManager mUserManager;
@Override @Override
public void onCreate() { public void onCreate() {
mLog.mark("onCreate"); final TetheringDependencies deps = makeTetheringDependencies();
mDeps = getTetheringDependencies(); // The Tethering object needs a fully functional context to start, so this can't be done
mContext = mDeps.getContext(); // in the constructor.
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
mTethering = makeTethering(mDeps);
mTethering.startStateMachineUpdaters();
} }
/** /**
@@ -94,21 +84,10 @@ public class TetheringService extends Service {
return new Tethering(deps); 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 @NonNull
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
mLog.mark("onBind"); return mConnector;
return makeConnector();
} }
private static class TetheringConnector extends ITetheringConnector.Stub { private static class TetheringConnector extends ITetheringConnector.Stub {
@@ -248,7 +227,7 @@ public class TetheringService extends Service {
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
return true; return true;
} }
if (!mService.isTetheringSupported()) { if (!mTethering.isTetheringSupported()) {
listener.onResult(TETHER_ERROR_UNSUPPORTED); listener.onResult(TETHER_ERROR_UNSUPPORTED);
return true; return true;
} }
@@ -266,7 +245,7 @@ public class TetheringService extends Service {
receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null); receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
return true; return true;
} }
if (!mService.isTetheringSupported()) { if (!mTethering.isTetheringSupported()) {
receiver.send(TETHER_ERROR_UNSUPPORTED, null); receiver.send(TETHER_ERROR_UNSUPPORTED, null);
return true; 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 * Check if the package is a allowed to write settings. This also accounts that such an access
* happened. * happened.
@@ -332,87 +297,79 @@ public class TetheringService extends Service {
* An injection method for testing. * An injection method for testing.
*/ */
@VisibleForTesting @VisibleForTesting
public TetheringDependencies getTetheringDependencies() { public TetheringDependencies makeTetheringDependencies() {
if (mDeps == null) { return new TetheringDependencies() {
mDeps = new TetheringDependencies() { @Override
@Override public NetworkRequest getDefaultNetworkRequest() {
public NetworkRequest getDefaultNetworkRequest() { // TODO: b/147280869, add a proper system API to replace this.
// TODO: b/147280869, add a proper system API to replace this. final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder() .clearCapabilities()
.clearCapabilities() .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build();
.build(); return trackDefaultRequest;
return trackDefaultRequest; }
}
@Override @Override
public Looper getTetheringLooper() { public Looper getTetheringLooper() {
final HandlerThread tetherThread = new HandlerThread("android.tethering"); final HandlerThread tetherThread = new HandlerThread("android.tethering");
tetherThread.start(); tetherThread.start();
return tetherThread.getLooper(); return tetherThread.getLooper();
} }
@Override @Override
public boolean isTetheringSupported() { public Context getContext() {
return TetheringService.this.isTetheringSupported(); return TetheringService.this;
} }
@Override @Override
public Context getContext() { public IpServer.Dependencies getIpServerDependencies() {
return TetheringService.this; return new IpServer.Dependencies() {
} @Override
public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
DhcpServerCallbacks cb) {
try {
final INetworkStackConnector service = getNetworkStackConnector();
if (service == null) return;
@Override service.makeDhcpServer(ifName, params, cb);
public IpServer.Dependencies getIpServerDependencies() { } catch (RemoteException e) {
return new IpServer.Dependencies() { Log.e(TAG, "Fail to make dhcp server");
@Override
public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
DhcpServerCallbacks cb) {
try { try {
final INetworkStackConnector service = getNetworkStackConnector(); cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
if (service == null) return; } catch (RemoteException re) { }
service.makeDhcpServer(ifName, params, cb);
} catch (RemoteException e) {
Log.e(TAG, "Fail to make dhcp server");
try {
cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
} catch (RemoteException re) { }
}
} }
};
}
// TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
// networkStackClient.
static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
private INetworkStackConnector getNetworkStackConnector() {
IBinder connector;
try {
final long before = System.currentTimeMillis();
while ((connector = NetworkStack.getService()) == null) {
if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
return null;
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
return null;
} }
return INetworkStackConnector.Stub.asInterface(connector); };
} }
@Override // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
public BluetoothAdapter getBluetoothAdapter() { // networkStackClient.
return BluetoothAdapter.getDefaultAdapter(); static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
private INetworkStackConnector getNetworkStackConnector() {
IBinder connector;
try {
final long before = System.currentTimeMillis();
while ((connector = NetworkStack.getService()) == null) {
if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
return null;
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
return null;
} }
}; return INetworkStackConnector.Stub.asInterface(connector);
} }
return mDeps;
@Override
public BluetoothAdapter getBluetoothAdapter() {
return BluetoothAdapter.getDefaultAdapter();
}
};
} }
} }

View File

@@ -83,8 +83,7 @@ public final class TetheringServiceTest {
mTetheringConnector = mockConnector.getTetheringConnector(); mTetheringConnector = mockConnector.getTetheringConnector();
final MockTetheringService service = mockConnector.getService(); final MockTetheringService service = mockConnector.getService();
mTethering = service.getTethering(); mTethering = service.getTethering();
verify(mTethering).startStateMachineUpdaters(); when(mTethering.isTetheringSupported()).thenReturn(true);
when(mTethering.hasTetherableConfiguration()).thenReturn(true);
} }
@After @After
@@ -97,7 +96,7 @@ public final class TetheringServiceTest {
when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR); when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).tether(TEST_IFACE_NAME); verify(mTethering).tether(TEST_IFACE_NAME);
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -109,7 +108,7 @@ public final class TetheringServiceTest {
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
result); result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).untether(TEST_IFACE_NAME); verify(mTethering).untether(TEST_IFACE_NAME);
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -121,7 +120,7 @@ public final class TetheringServiceTest {
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
TEST_ATTRIBUTION_TAG, result); TEST_ATTRIBUTION_TAG, result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).setUsbTethering(true /* enable */); verify(mTethering).setUsbTethering(true /* enable */);
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -133,7 +132,7 @@ public final class TetheringServiceTest {
final TetheringRequestParcel request = new TetheringRequestParcel(); final TetheringRequestParcel request = new TetheringRequestParcel();
request.tetheringType = TETHERING_WIFI; request.tetheringType = TETHERING_WIFI;
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).startTethering(eq(request), eq(result)); verify(mTethering).startTethering(eq(request), eq(result));
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
} }
@@ -143,7 +142,7 @@ public final class TetheringServiceTest {
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
result); result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).stopTethering(TETHERING_WIFI); verify(mTethering).stopTethering(TETHERING_WIFI);
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -154,7 +153,7 @@ public final class TetheringServiceTest {
final ResultReceiver result = new ResultReceiver(null); final ResultReceiver result = new ResultReceiver(null);
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result, mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG); true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI), verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
eq(result), eq(true) /* showEntitlementUi */); eq(result), eq(true) /* showEntitlementUi */);
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
@@ -181,7 +180,7 @@ public final class TetheringServiceTest {
public void testStopAllTethering() throws Exception { public void testStopAllTethering() throws Exception {
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verify(mTethering).untetherAll(); verify(mTethering).untetherAll();
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -191,7 +190,7 @@ public final class TetheringServiceTest {
public void testIsTetheringSupported() throws Exception { public void testIsTetheringSupported() throws Exception {
final TestTetheringResult result = new TestTetheringResult(); final TestTetheringResult result = new TestTetheringResult();
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
verify(mTethering).hasTetherableConfiguration(); verify(mTethering).isTetheringSupported();
verifyNoMoreInteractions(mTethering); verifyNoMoreInteractions(mTethering);
result.assertResult(TETHER_ERROR_NO_ERROR); result.assertResult(TETHER_ERROR_NO_ERROR);
} }

View File

@@ -485,18 +485,6 @@ public class TetheringTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mResources.getStringArray(R.array.config_tether_dhcp_range)) when(mResources.getStringArray(R.array.config_tether_dhcp_range))
.thenReturn(new String[0]); .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( when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false); false);
when(mNetd.interfaceGetList()) when(mNetd.interfaceGetList())
@@ -515,6 +503,7 @@ public class TetheringTest {
mServiceContext = new TestContext(mContext); mServiceContext = new TestContext(mContext);
mContentResolver = new MockContentResolver(mServiceContext); mContentResolver = new MockContentResolver(mServiceContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
setTetheringSupported(true /* supported */);
mIntents = new Vector<>(); mIntents = new Vector<>();
mBroadcastReceiver = new BroadcastReceiver() { mBroadcastReceiver = new BroadcastReceiver() {
@Override @Override
@@ -525,7 +514,6 @@ public class TetheringTest {
mServiceContext.registerReceiver(mBroadcastReceiver, mServiceContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(ACTION_TETHER_STATE_CHANGED)); new IntentFilter(ACTION_TETHER_STATE_CHANGED));
mTethering = makeTethering(); mTethering = makeTethering();
mTethering.startStateMachineUpdaters();
verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any()); verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
verify(mNetd).registerUnsolicitedEventListener(any()); verify(mNetd).registerUnsolicitedEventListener(any());
final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -536,6 +524,31 @@ public class TetheringTest {
mPhoneStateListener = phoneListenerCaptor.getValue(); 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() { private Tethering makeTethering() {
mTetheringDependencies.reset(); mTetheringDependencies.reset();
return new Tethering(mTetheringDependencies); return new Tethering(mTetheringDependencies);
@@ -672,9 +685,7 @@ public class TetheringTest {
} }
private void prepareUsbTethering(UpstreamNetworkState upstreamState) { private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState); initTetheringUpstream(upstreamState);
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
.thenReturn(upstreamState);
// Emulate pressing the USB tethering button in Settings UI. // Emulate pressing the USB tethering button in Settings UI.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null); mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
@@ -700,7 +711,7 @@ public class TetheringTest {
verify(mNetd, times(1)).interfaceGetList(); verify(mNetd, times(1)).interfaceGetList();
// UpstreamNetworkMonitor should receive selected upstream // UpstreamNetworkMonitor should receive selected upstream
verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any()); verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
} }
@@ -872,8 +883,7 @@ public class TetheringTest {
// Then 464xlat comes up // Then 464xlat comes up
upstreamState = buildMobile464xlatUpstreamState(); upstreamState = buildMobile464xlatUpstreamState();
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) initTetheringUpstream(upstreamState);
.thenReturn(upstreamState);
// Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES. // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage( mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
@@ -1344,9 +1354,7 @@ public class TetheringTest {
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
// 2. Enable wifi tethering. // 2. Enable wifi tethering.
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState); initTetheringUpstream(upstreamState);
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
.thenReturn(upstreamState);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
mLooper.dispatchAll(); mLooper.dispatchAll();
@@ -1723,7 +1731,7 @@ public class TetheringTest {
final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM) final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM; mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState); initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true); stateMachine.chooseUpstreamType(true);
verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network)); verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
@@ -1735,7 +1743,7 @@ public class TetheringTest {
final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM) final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
mTetheringDependencies.mUpstreamNetworkMonitorMasterSM; mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState); initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true); stateMachine.chooseUpstreamType(true);
stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);