Merge "Add local-only hotspot info into tether state change broadcast"
am: 4c7a999d79
Change-Id: I911be691b15604a63aa02bf4db607ae1cd701cfe
This commit is contained in:
@@ -301,7 +301,8 @@ public class ConnectivityManager {
|
||||
/**
|
||||
* Broadcast Action: A tetherable connection has come or gone.
|
||||
* Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
|
||||
* {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
|
||||
* {@code ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY},
|
||||
* {@code ConnectivityManager.EXTRA_ACTIVE_TETHER}, and
|
||||
* {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
|
||||
* the current state of tethering. Each include a list of
|
||||
* interface names in that state (may be empty).
|
||||
@@ -320,10 +321,17 @@ public class ConnectivityManager {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* gives a String[] listing all the interfaces currently tethered
|
||||
* (ie, has dhcp support and packets potentially forwarded/NATed)
|
||||
* gives a String[] listing all the interfaces currently in local-only
|
||||
* mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding)
|
||||
*/
|
||||
public static final String EXTRA_ACTIVE_TETHER = "activeArray";
|
||||
public static final String EXTRA_ACTIVE_LOCAL_ONLY = "localOnlyArray";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* gives a String[] listing all the interfaces currently tethered
|
||||
* (ie, has DHCPv4 support and packets potentially forwarded/NATed)
|
||||
*/
|
||||
public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
|
||||
@@ -623,9 +623,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
private void sendTetherStateChangedBroadcast() {
|
||||
if (!getConnectivityManager().isTetheringSupported()) return;
|
||||
|
||||
ArrayList<String> availableList = new ArrayList<String>();
|
||||
ArrayList<String> activeList = new ArrayList<String>();
|
||||
ArrayList<String> erroredList = new ArrayList<String>();
|
||||
final ArrayList<String> availableList = new ArrayList<>();
|
||||
final ArrayList<String> tetherList = new ArrayList<>();
|
||||
final ArrayList<String> localOnlyList = new ArrayList<>();
|
||||
final ArrayList<String> erroredList = new ArrayList<>();
|
||||
|
||||
boolean wifiTethered = false;
|
||||
boolean usbTethered = false;
|
||||
@@ -641,6 +642,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
erroredList.add(iface);
|
||||
} else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
|
||||
availableList.add(iface);
|
||||
} else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_HOTSPOT) {
|
||||
localOnlyList.add(iface);
|
||||
} else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
|
||||
if (cfg.isUsb(iface)) {
|
||||
usbTethered = true;
|
||||
@@ -649,25 +652,25 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
} else if (cfg.isBluetooth(iface)) {
|
||||
bluetoothTethered = true;
|
||||
}
|
||||
activeList.add(iface);
|
||||
tetherList.add(iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||
broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
|
||||
final Intent bcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||
bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
|
||||
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER,
|
||||
availableList);
|
||||
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList);
|
||||
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER,
|
||||
erroredList);
|
||||
mContext.sendStickyBroadcastAsUser(broadcast, UserHandle.ALL);
|
||||
bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, availableList);
|
||||
bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
|
||||
bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, tetherList);
|
||||
bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, erroredList);
|
||||
mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
|
||||
if (DBG) {
|
||||
Log.d(TAG, String.format(
|
||||
"sendTetherStateChangedBroadcast avail=[%s] active=[%s] error=[%s]",
|
||||
TextUtils.join(",", availableList),
|
||||
TextUtils.join(",", activeList),
|
||||
TextUtils.join(",", erroredList)));
|
||||
"sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
|
||||
"avail", TextUtils.join(",", availableList),
|
||||
"local_only", TextUtils.join(",", localOnlyList),
|
||||
"tether", TextUtils.join(",", tetherList),
|
||||
"error", TextUtils.join(",", erroredList)));
|
||||
}
|
||||
|
||||
if (usbTethered) {
|
||||
@@ -1338,7 +1341,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
mForwardedDownstreams.remove(who);
|
||||
}
|
||||
|
||||
class InitialState extends TetherMasterUtilState {
|
||||
class InitialState extends State {
|
||||
@Override
|
||||
public boolean processMessage(Message message) {
|
||||
maybeLogMessage(this, message.what);
|
||||
@@ -1516,7 +1519,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
}
|
||||
|
||||
class ErrorState extends State {
|
||||
int mErrorNotification;
|
||||
private int mErrorNotification;
|
||||
|
||||
@Override
|
||||
public boolean processMessage(Message message) {
|
||||
boolean retValue = true;
|
||||
@@ -1534,6 +1538,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
void notify(int msgType) {
|
||||
mErrorNotification = msgType;
|
||||
for (TetherInterfaceStateMachine sm : mNotifyList) {
|
||||
@@ -1542,6 +1547,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SetIpForwardingEnabledErrorState extends ErrorState {
|
||||
@Override
|
||||
public void enter() {
|
||||
|
||||
@@ -29,9 +29,11 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.net.ConnectivityManager;
|
||||
@@ -53,12 +55,16 @@ import android.telephony.CarrierConfigManager;
|
||||
|
||||
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class TetheringTest {
|
||||
@@ -81,7 +87,9 @@ public class TetheringTest {
|
||||
private final TestLooper mLooper = new TestLooper();
|
||||
private final String mTestIfname = "test_wlan0";
|
||||
|
||||
private Vector<Intent> mIntents;
|
||||
private BroadcastInterceptingContext mServiceContext;
|
||||
private BroadcastReceiver mBroadcastReceiver;
|
||||
private Tethering mTethering;
|
||||
|
||||
private class MockContext extends BroadcastInterceptingContext {
|
||||
@@ -100,7 +108,8 @@ public class TetheringTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Before public void setUp() throws Exception {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range))
|
||||
.thenReturn(new String[0]);
|
||||
@@ -118,10 +127,24 @@ public class TetheringTest {
|
||||
.thenReturn(new InterfaceConfiguration());
|
||||
|
||||
mServiceContext = new MockContext(mContext);
|
||||
mIntents = new Vector<>();
|
||||
mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mIntents.addElement(intent);
|
||||
}
|
||||
};
|
||||
mServiceContext.registerReceiver(mBroadcastReceiver,
|
||||
new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
|
||||
mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
|
||||
mLooper.getLooper(), mSystemProperties);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mServiceContext.unregisterReceiver(mBroadcastReceiver);
|
||||
}
|
||||
|
||||
private void setupForRequiredProvisioning() {
|
||||
// Produce some acceptable looking provision app setting if requested.
|
||||
when(mResources.getStringArray(
|
||||
@@ -180,6 +203,23 @@ public class TetheringTest {
|
||||
mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
|
||||
}
|
||||
|
||||
private void verifyInterfaceServingModeStarted() throws Exception {
|
||||
verify(mNMService, times(1)).listInterfaces();
|
||||
verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
|
||||
verify(mNMService, times(1))
|
||||
.setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
|
||||
verify(mNMService, times(1)).tetherInterface(mTestIfname);
|
||||
}
|
||||
|
||||
private void verifyTetheringBroadcast(String ifname, String whichExtra) {
|
||||
// Verify that ifname is in the whichExtra array of the tether state changed broadcast.
|
||||
final Intent bcast = mIntents.get(0);
|
||||
assertEquals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED, bcast.getAction());
|
||||
final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
|
||||
assertTrue(ifnames.contains(ifname));
|
||||
mIntents.remove(bcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workingLocalOnlyHotspot() throws Exception {
|
||||
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
|
||||
@@ -193,14 +233,12 @@ public class TetheringTest {
|
||||
sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
verify(mNMService, times(1)).listInterfaces();
|
||||
verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
|
||||
verify(mNMService, times(1))
|
||||
.setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
|
||||
verify(mNMService, times(1)).tetherInterface(mTestIfname);
|
||||
verifyInterfaceServingModeStarted();
|
||||
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
|
||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
||||
verify(mNMService, times(1)).startTethering(any(String[].class));
|
||||
verifyNoMoreInteractions(mNMService);
|
||||
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY);
|
||||
// UpstreamNetworkMonitor will be started, and will register two callbacks:
|
||||
// a "listen all" and a "track default".
|
||||
verify(mConnectivityManager, times(1)).registerNetworkCallback(
|
||||
@@ -252,14 +290,12 @@ public class TetheringTest {
|
||||
sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
verify(mNMService, times(1)).listInterfaces();
|
||||
verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
|
||||
verify(mNMService, times(1))
|
||||
.setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
|
||||
verify(mNMService, times(1)).tetherInterface(mTestIfname);
|
||||
verifyInterfaceServingModeStarted();
|
||||
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
|
||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
||||
verify(mNMService, times(1)).startTethering(any(String[].class));
|
||||
verifyNoMoreInteractions(mNMService);
|
||||
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_ACTIVE_TETHER);
|
||||
// UpstreamNetworkMonitor will be started, and will register two callbacks:
|
||||
// a "listen all" and a "track default".
|
||||
verify(mConnectivityManager, times(1)).registerNetworkCallback(
|
||||
|
||||
Reference in New Issue
Block a user