diff options
| -rw-r--r-- | services/net/java/android/net/ip/IpClient.java | 41 | ||||
| -rw-r--r-- | tests/net/java/android/net/ip/IpClientTest.java | 13 |
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 |