summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/net/java/android/net/ip/IpClient.java41
-rw-r--r--tests/net/java/android/net/ip/IpClientTest.java13
2 files changed, 45 insertions, 9 deletions
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index 63ae09a79379..7f821ffd369a 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -231,10 +231,10 @@ public class IpClient extends StateMachine {
// TODO: Find an lighter weight approach.
private class LoggingCallbackWrapper extends Callback {
private static final String PREFIX = "INVOKE ";
- private Callback mCallback;
+ private final Callback mCallback;
public LoggingCallbackWrapper(Callback callback) {
- mCallback = callback;
+ mCallback = (callback != null) ? callback : new Callback();
}
private void log(String msg) {
@@ -605,6 +605,13 @@ public class IpClient extends StateMachine {
private static final int EVENT_DHCPACTION_TIMEOUT = 11;
private static final int EVENT_READ_PACKET_FILTER_COMPLETE = 12;
+ // Internal commands to use instead of trying to call transitionTo() inside
+ // a given State's enter() method. Calling transitionTo() from enter/exit
+ // encounters a Log.wtf() that can cause trouble on eng builds.
+ private static final int CMD_JUMP_STARTED_TO_RUNNING = 100;
+ private static final int CMD_JUMP_RUNNING_TO_STOPPING = 101;
+ private static final int CMD_JUMP_STOPPING_TO_STOPPED = 102;
+
private static final int MAX_LOG_RECORDS = 500;
private static final int MAX_PACKET_RECORDS = 100;
@@ -1418,6 +1425,9 @@ public class IpClient extends StateMachine {
resetLinkProperties();
if (mStartTimeMillis > 0) {
+ // Completed a life-cycle; send a final empty LinkProperties
+ // (cleared in resetLinkProperties() above) and record an event.
+ mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
mStartTimeMillis = 0;
}
@@ -1476,13 +1486,17 @@ public class IpClient extends StateMachine {
public void enter() {
if (mDhcpClient == null) {
// There's no DHCPv4 for which to wait; proceed to stopped.
- transitionTo(mStoppedState);
+ deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
}
}
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_STOPPING_TO_STOPPED:
+ transitionTo(mStoppedState);
+ break;
+
case CMD_STOP:
break;
@@ -1516,7 +1530,7 @@ public class IpClient extends StateMachine {
}
if (readyToProceed()) {
- transitionTo(mRunningState);
+ deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
} else {
// Clear all IPv4 and IPv6 before proceeding to RunningState.
// Clean up any leftover state from an abnormal exit from
@@ -1533,6 +1547,10 @@ public class IpClient extends StateMachine {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_STARTED_TO_RUNNING:
+ transitionTo(mRunningState);
+ break;
+
case CMD_STOP:
transitionTo(mStoppingState);
break;
@@ -1561,7 +1579,7 @@ public class IpClient extends StateMachine {
return HANDLED;
}
- boolean readyToProceed() {
+ private boolean readyToProceed() {
return (!mLinkProperties.hasIPv4Address() &&
!mLinkProperties.hasGlobalIPv6Address());
}
@@ -1593,13 +1611,13 @@ public class IpClient extends StateMachine {
if (mConfiguration.mEnableIPv6 && !startIPv6()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
if (mConfiguration.mEnableIPv4 && !startIPv4()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
@@ -1607,7 +1625,7 @@ public class IpClient extends StateMachine {
if ((config != null) && !applyInitialConfig(config)) {
// TODO introduce a new IpManagerEvent constant to distinguish this error case.
doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
@@ -1621,7 +1639,7 @@ public class IpClient extends StateMachine {
if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
doImmediateProvisioningFailure(
IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
}
@@ -1658,6 +1676,10 @@ public class IpClient extends StateMachine {
resetLinkProperties();
}
+ private void enqueueJumpToStoppingState() {
+ deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
+ }
+
private ConnectivityPacketTracker createPacketTracker() {
try {
return new ConnectivityPacketTracker(
@@ -1688,6 +1710,7 @@ public class IpClient extends StateMachine {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_RUNNING_TO_STOPPING:
case CMD_STOP:
transitionTo(mStoppingState);
break;
diff --git a/tests/net/java/android/net/ip/IpClientTest.java b/tests/net/java/android/net/ip/IpClientTest.java
index e9e880d1e7c1..89453e0b13b7 100644
--- a/tests/net/java/android/net/ip/IpClientTest.java
+++ b/tests/net/java/android/net/ip/IpClientTest.java
@@ -133,9 +133,18 @@ public class IpClientTest {
verify(mNMService, times(1)).registerObserver(arg.capture());
mObserver = arg.getValue();
reset(mNMService);
+ // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
+ verify(mCb, never()).onLinkPropertiesChange(any());
+ reset(mCb);
return ipc;
}
+ private static LinkProperties makeEmptyLinkProperties(String iface) {
+ final LinkProperties empty = new LinkProperties();
+ empty.setInterfaceName(iface);
+ return empty;
+ }
+
@Test
public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
setTestInterfaceParams(null);
@@ -197,6 +206,8 @@ public class IpClientTest {
ipc.shutdown();
verify(mNMService, timeout(100).times(1)).disableIpv6(iface);
verify(mNMService, timeout(100).times(1)).clearInterfaceAddresses(iface);
+ verify(mCb, timeout(100).times(1))
+ .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface)));
}
@Test
@@ -246,6 +257,8 @@ public class IpClientTest {
ipc.shutdown();
verify(mNMService, timeout(100).times(1)).disableIpv6(iface);
verify(mNMService, timeout(100).times(1)).clearInterfaceAddresses(iface);
+ verify(mCb, timeout(100).times(1))
+ .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface)));
}
@Test