Loading AndroidManifest.xml +2 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack" android:sharedUserId="android.uid.networkstack" android:versionCode="300802300" android:versionName="r_aml_300802300" android:versionCode="300802400" android:versionName="r_aml_300802400" > <!-- Permissions must be defined here, and not in the base manifest, as the network stack running in the system server process does not need any permission, and having privileged Loading src/android/net/dhcp/DhcpClient.java +30 −1 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; import android.stats.connectivity.DhcpFeature; import android.system.ErrnoException; import android.system.Os; import android.util.EventLog; Loading @@ -101,6 +102,7 @@ import com.android.networkstack.apishim.CaptivePortalDataShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.metrics.IpProvisioningMetrics; import java.io.FileDescriptor; import java.io.IOException; Loading Loading @@ -305,6 +307,8 @@ public class DhcpClient extends StateMachine { private final Context mContext; private final Random mRandom; private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); @NonNull private final IpProvisioningMetrics mMetrics; // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // be off-link as well as on-link). Loading Loading @@ -378,9 +382,11 @@ public class DhcpClient extends StateMachine { */ public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final IpProvisioningMetrics mMetrics; public Dependencies(NetworkStackIpMemoryStore store) { public Dependencies(NetworkStackIpMemoryStore store, IpProvisioningMetrics metrics) { mNetworkStackIpMemoryStore = store; mMetrics = metrics; } /** Loading @@ -406,6 +412,13 @@ public class DhcpClient extends StateMachine { return mNetworkStackIpMemoryStore; } /** * Get a IpProvisioningMetrics instance. */ public IpProvisioningMetrics getIpProvisioningMetrics() { return mMetrics; } /** * Return whether a feature guarded by a feature flag is enabled. * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) Loading Loading @@ -444,6 +457,7 @@ public class DhcpClient extends StateMachine { mController = controller; mIfaceName = iface; mIpMemoryStore = deps.getIpMemoryStore(); mMetrics = deps.getIpProvisioningMetrics(); // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); Loading Loading @@ -484,6 +498,7 @@ public class DhcpClient extends StateMachine { final boolean sendHostname = deps.getSendHostnameOption(context); mHostname = sendHostname ? new HostnameTransliterator().transliterate( deps.getDeviceName(mContext)) : null; mMetrics.setHostnameTransinfo(sendHostname, mHostname != null); } public void registerForPreDhcpNotification() { Loading Loading @@ -529,6 +544,15 @@ public class DhcpClient extends StateMachine { false /* defaultEnabled */); } private void recordMetricEnabledFeatures() { if (isDhcpLeaseCacheEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_INITREBOOT); if (isDhcpRapidCommitEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_RAPIDCOMMIT); if (isDhcpIpConflictDetectEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_DAD); if (mConfiguration.isPreconnectionEnabled) { mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_FILS); } } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); Loading Loading @@ -610,6 +634,7 @@ public class DhcpClient extends StateMachine { EventLog.writeEvent(snetTagId, bugId, uid, data); } mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetrics.addDhcpErrorCode(e.errorCode); } } Loading Loading @@ -687,6 +712,7 @@ public class DhcpClient extends StateMachine { final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); mMetrics.incrementCountForDiscover(); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } Loading @@ -705,6 +731,7 @@ public class DhcpClient extends StateMachine { String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " serverid=" + serverStr; mMetrics.incrementCountForRequest(); return transmitPacket(packet, description, encap, to); } Loading Loading @@ -937,6 +964,7 @@ public class DhcpClient extends StateMachine { } else { startInitRebootOrInit(); } recordMetricEnabledFeatures(); return HANDLED; default: return NOT_HANDLED; Loading Loading @@ -1422,6 +1450,7 @@ public class DhcpClient extends StateMachine { try { final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); if (hasIpAddressConflict(packet, mTargetIp)) { mMetrics.incrementCountForIpConflict(); sendMessage(EVENT_IP_CONFLICT); } } catch (ArpPacket.ParseException e) { Loading src/android/net/ip/IpClient.java +49 −19 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.stats.connectivity.DisconnectCode; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; Loading @@ -79,6 +80,7 @@ import com.android.internal.util.WakeupMessage; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; Loading Loading @@ -129,6 +131,7 @@ public class IpClient extends StateMachine { private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics(); /** * Dump all state machine and connectivity packet logs to the specified writer. Loading Loading @@ -527,8 +530,8 @@ public class IpClient extends StateMachine { * Get a DhcpClient Dependencies instance. */ public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { return new DhcpClient.Dependencies(ipMemoryStore); NetworkStackIpMemoryStore ipMemoryStore, IpProvisioningMetrics metrics) { return new DhcpClient.Dependencies(ipMemoryStore, metrics); } /** Loading Loading @@ -816,9 +819,12 @@ public class IpClient extends StateMachine { * Stop this IpClient. * * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. * The message "arg1" parameter is used to record the disconnect code metrics. * Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient, * consider that's the normal user termination. */ public void stop() { sendMessage(CMD_STOP); sendMessage(CMD_STOP, DisconnectCode.DC_NORMAL_TERMINATION.getNumber()); } /** Loading Loading @@ -1072,6 +1078,12 @@ public class IpClient extends StateMachine { mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); } // Record the DisconnectCode and transition to StoppingState. private void transitionToStoppingState(final DisconnectCode code) { mIpProvisioningMetrics.setDisconnectCode(code); transitionTo(mStoppingState); } // For now: use WifiStateMachine's historical notion of provisioned. @VisibleForTesting static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { Loading Loading @@ -1352,6 +1364,12 @@ public class IpClient extends StateMachine { if (Objects.equals(newLp, mLinkProperties)) { return true; } // Either success IPv4 or IPv6 provisioning triggers new LinkProperties update, // wait for the provisioning completion and record the latency. mIpProvisioningMetrics.setIPv4ProvisionedLatencyOnFirstTime(newLp.isIpv4Provisioned()); mIpProvisioningMetrics.setIPv6ProvisionedLatencyOnFirstTime(newLp.isIpv6Provisioned()); final int delta = setLinkProperties(newLp); // Most of the attributes stored in the memory store are deduced from // the link properties, therefore when the properties update the memory Loading Loading @@ -1447,10 +1465,10 @@ public class IpClient extends StateMachine { } mCallback.onNewDhcpResults(null); handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_FAIL); } private void handleProvisioningFailure() { private void handleProvisioningFailure(final DisconnectCode code) { final LinkProperties newLp = assembleLinkProperties(); int delta = setLinkProperties(newLp); // If we've gotten here and we're still not provisioned treat that as Loading @@ -1467,7 +1485,7 @@ public class IpClient extends StateMachine { dispatchCallback(delta, newLp); if (delta == PROV_CHANGE_LOST_PROVISIONING) { transitionTo(mStoppingState); transitionToStoppingState(code); } } Loading Loading @@ -1723,7 +1741,7 @@ public class IpClient extends StateMachine { private void startDhcpClient() { // Start DHCPv4. mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDependencies.getDhcpClientDependencies(mIpMemoryStore, mIpProvisioningMetrics)); // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // during DHCP, because the DHCP handshake will happen during association. In order to Loading @@ -1744,7 +1762,8 @@ public class IpClient extends StateMachine { if (mInterfaceParams == null) { logError("Failed to find InterfaceParams for " + mInterfaceName); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); deferMessage(obtainMessage(CMD_STOP)); deferMessage(obtainMessage(CMD_STOP, DisconnectCode.DC_INTERFACE_NOT_FOUND.getNumber())); return; } Loading Loading @@ -1836,6 +1855,7 @@ public class IpClient extends StateMachine { class StartedState extends State { @Override public void enter() { mIpProvisioningMetrics.reset(); mStartTimeMillis = SystemClock.elapsedRealtime(); if (mConfiguration.mProvisioningTimeoutMs > 0) { final long alarmTime = SystemClock.elapsedRealtime() Loading @@ -1847,13 +1867,17 @@ public class IpClient extends StateMachine { @Override public void exit() { mProvisioningTimeoutAlarm.cancel(); // Record metrics information once this provisioning has completed due to certain // reason (normal termination, provisioning timeout, lost provisioning and etc). mIpProvisioningMetrics.statsWrite(); } @Override public boolean processMessage(Message msg) { switch (msg.what) { case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; case CMD_UPDATE_L2KEY_CLUSTER: { Loading @@ -1875,7 +1899,7 @@ public class IpClient extends StateMachine { break; case EVENT_PROVISIONING_TIMEOUT: handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_TIMEOUT); break; default: Loading Loading @@ -1912,13 +1936,13 @@ public class IpClient extends StateMachine { if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6); return; } if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV4); return; } Loading @@ -1926,14 +1950,14 @@ 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); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_INVALID_PROVISIONING); return; } if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { doImmediateProvisioningFailure( IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPREACHABILITYMONITOR); return; } } Loading Loading @@ -1965,8 +1989,8 @@ public class IpClient extends StateMachine { resetLinkProperties(); } private void enqueueJumpToStoppingState() { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING)); private void enqueueJumpToStoppingState(final DisconnectCode code) { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING, code.getNumber())); } private ConnectivityPacketTracker createPacketTracker() { Loading Loading @@ -2001,7 +2025,7 @@ public class IpClient extends StateMachine { switch (msg.what) { case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; case CMD_START: Loading @@ -2028,8 +2052,14 @@ public class IpClient extends StateMachine { break; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: // EVENT_NETLINK_LINKPROPERTIES_CHANGED message will be received in both of // provisioning loss and normal user termination case (e.g. turn off wifi or // switch to another wifi ssid), hence, checking current interface change // status (down or up) would help distinguish. final boolean ifUp = (msg.arg1 != 0); if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { transitionTo(mStoppingState); transitionToStoppingState(ifUp ? DisconnectCode.DC_PROVISIONING_FAIL : DisconnectCode.DC_NORMAL_TERMINATION); } break; Loading Loading @@ -2109,7 +2139,7 @@ public class IpClient extends StateMachine { } else { logError("Failed to set IPv4 address."); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.DC_PROVISIONING_FAIL); } break; } Loading src/android/net/util/NetworkStackUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -436,4 +436,22 @@ public class NetworkStackUtils { return addr instanceof Inet6Address && ((addr.getAddress()[0] & 0xfe) == 0xfc); } /** * Returns the {@code int} nearest in value to {@code value}. * * @param value any {@code long} value * @return the same value cast to {@code int} if it is in the range of the {@code int} * type, {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if * it is too small */ public static int saturatedCast(long value) { if (value > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } if (value < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) value; } } src/android/net/util/Stopwatch.java +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,15 @@ public class Stopwatch { return this; } /** * Restart the Stopwatch. */ public Stopwatch restart() { mStartTimeNs = SystemClock.elapsedRealtimeNanos(); mStopTimeNs = 0; return this; } /** * Stop the Stopwatch. * @return the total time recorded, in microseconds, or 0 if not started. Loading Loading
AndroidManifest.xml +2 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack" android:sharedUserId="android.uid.networkstack" android:versionCode="300802300" android:versionName="r_aml_300802300" android:versionCode="300802400" android:versionName="r_aml_300802400" > <!-- Permissions must be defined here, and not in the base manifest, as the network stack running in the system server process does not need any permission, and having privileged Loading
src/android/net/dhcp/DhcpClient.java +30 −1 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; import android.stats.connectivity.DhcpFeature; import android.system.ErrnoException; import android.system.Os; import android.util.EventLog; Loading @@ -101,6 +102,7 @@ import com.android.networkstack.apishim.CaptivePortalDataShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.metrics.IpProvisioningMetrics; import java.io.FileDescriptor; import java.io.IOException; Loading Loading @@ -305,6 +307,8 @@ public class DhcpClient extends StateMachine { private final Context mContext; private final Random mRandom; private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); @NonNull private final IpProvisioningMetrics mMetrics; // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // be off-link as well as on-link). Loading Loading @@ -378,9 +382,11 @@ public class DhcpClient extends StateMachine { */ public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final IpProvisioningMetrics mMetrics; public Dependencies(NetworkStackIpMemoryStore store) { public Dependencies(NetworkStackIpMemoryStore store, IpProvisioningMetrics metrics) { mNetworkStackIpMemoryStore = store; mMetrics = metrics; } /** Loading @@ -406,6 +412,13 @@ public class DhcpClient extends StateMachine { return mNetworkStackIpMemoryStore; } /** * Get a IpProvisioningMetrics instance. */ public IpProvisioningMetrics getIpProvisioningMetrics() { return mMetrics; } /** * Return whether a feature guarded by a feature flag is enabled. * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) Loading Loading @@ -444,6 +457,7 @@ public class DhcpClient extends StateMachine { mController = controller; mIfaceName = iface; mIpMemoryStore = deps.getIpMemoryStore(); mMetrics = deps.getIpProvisioningMetrics(); // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); Loading Loading @@ -484,6 +498,7 @@ public class DhcpClient extends StateMachine { final boolean sendHostname = deps.getSendHostnameOption(context); mHostname = sendHostname ? new HostnameTransliterator().transliterate( deps.getDeviceName(mContext)) : null; mMetrics.setHostnameTransinfo(sendHostname, mHostname != null); } public void registerForPreDhcpNotification() { Loading Loading @@ -529,6 +544,15 @@ public class DhcpClient extends StateMachine { false /* defaultEnabled */); } private void recordMetricEnabledFeatures() { if (isDhcpLeaseCacheEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_INITREBOOT); if (isDhcpRapidCommitEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_RAPIDCOMMIT); if (isDhcpIpConflictDetectEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_DAD); if (mConfiguration.isPreconnectionEnabled) { mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_FILS); } } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); Loading Loading @@ -610,6 +634,7 @@ public class DhcpClient extends StateMachine { EventLog.writeEvent(snetTagId, bugId, uid, data); } mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetrics.addDhcpErrorCode(e.errorCode); } } Loading Loading @@ -687,6 +712,7 @@ public class DhcpClient extends StateMachine { final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); mMetrics.incrementCountForDiscover(); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } Loading @@ -705,6 +731,7 @@ public class DhcpClient extends StateMachine { String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " serverid=" + serverStr; mMetrics.incrementCountForRequest(); return transmitPacket(packet, description, encap, to); } Loading Loading @@ -937,6 +964,7 @@ public class DhcpClient extends StateMachine { } else { startInitRebootOrInit(); } recordMetricEnabledFeatures(); return HANDLED; default: return NOT_HANDLED; Loading Loading @@ -1422,6 +1450,7 @@ public class DhcpClient extends StateMachine { try { final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); if (hasIpAddressConflict(packet, mTargetIp)) { mMetrics.incrementCountForIpConflict(); sendMessage(EVENT_IP_CONFLICT); } } catch (ArpPacket.ParseException e) { Loading
src/android/net/ip/IpClient.java +49 −19 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.stats.connectivity.DisconnectCode; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; Loading @@ -79,6 +80,7 @@ import com.android.internal.util.WakeupMessage; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; Loading Loading @@ -129,6 +131,7 @@ public class IpClient extends StateMachine { private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics(); /** * Dump all state machine and connectivity packet logs to the specified writer. Loading Loading @@ -527,8 +530,8 @@ public class IpClient extends StateMachine { * Get a DhcpClient Dependencies instance. */ public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { return new DhcpClient.Dependencies(ipMemoryStore); NetworkStackIpMemoryStore ipMemoryStore, IpProvisioningMetrics metrics) { return new DhcpClient.Dependencies(ipMemoryStore, metrics); } /** Loading Loading @@ -816,9 +819,12 @@ public class IpClient extends StateMachine { * Stop this IpClient. * * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. * The message "arg1" parameter is used to record the disconnect code metrics. * Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient, * consider that's the normal user termination. */ public void stop() { sendMessage(CMD_STOP); sendMessage(CMD_STOP, DisconnectCode.DC_NORMAL_TERMINATION.getNumber()); } /** Loading Loading @@ -1072,6 +1078,12 @@ public class IpClient extends StateMachine { mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); } // Record the DisconnectCode and transition to StoppingState. private void transitionToStoppingState(final DisconnectCode code) { mIpProvisioningMetrics.setDisconnectCode(code); transitionTo(mStoppingState); } // For now: use WifiStateMachine's historical notion of provisioned. @VisibleForTesting static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { Loading Loading @@ -1352,6 +1364,12 @@ public class IpClient extends StateMachine { if (Objects.equals(newLp, mLinkProperties)) { return true; } // Either success IPv4 or IPv6 provisioning triggers new LinkProperties update, // wait for the provisioning completion and record the latency. mIpProvisioningMetrics.setIPv4ProvisionedLatencyOnFirstTime(newLp.isIpv4Provisioned()); mIpProvisioningMetrics.setIPv6ProvisionedLatencyOnFirstTime(newLp.isIpv6Provisioned()); final int delta = setLinkProperties(newLp); // Most of the attributes stored in the memory store are deduced from // the link properties, therefore when the properties update the memory Loading Loading @@ -1447,10 +1465,10 @@ public class IpClient extends StateMachine { } mCallback.onNewDhcpResults(null); handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_FAIL); } private void handleProvisioningFailure() { private void handleProvisioningFailure(final DisconnectCode code) { final LinkProperties newLp = assembleLinkProperties(); int delta = setLinkProperties(newLp); // If we've gotten here and we're still not provisioned treat that as Loading @@ -1467,7 +1485,7 @@ public class IpClient extends StateMachine { dispatchCallback(delta, newLp); if (delta == PROV_CHANGE_LOST_PROVISIONING) { transitionTo(mStoppingState); transitionToStoppingState(code); } } Loading Loading @@ -1723,7 +1741,7 @@ public class IpClient extends StateMachine { private void startDhcpClient() { // Start DHCPv4. mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDependencies.getDhcpClientDependencies(mIpMemoryStore, mIpProvisioningMetrics)); // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // during DHCP, because the DHCP handshake will happen during association. In order to Loading @@ -1744,7 +1762,8 @@ public class IpClient extends StateMachine { if (mInterfaceParams == null) { logError("Failed to find InterfaceParams for " + mInterfaceName); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); deferMessage(obtainMessage(CMD_STOP)); deferMessage(obtainMessage(CMD_STOP, DisconnectCode.DC_INTERFACE_NOT_FOUND.getNumber())); return; } Loading Loading @@ -1836,6 +1855,7 @@ public class IpClient extends StateMachine { class StartedState extends State { @Override public void enter() { mIpProvisioningMetrics.reset(); mStartTimeMillis = SystemClock.elapsedRealtime(); if (mConfiguration.mProvisioningTimeoutMs > 0) { final long alarmTime = SystemClock.elapsedRealtime() Loading @@ -1847,13 +1867,17 @@ public class IpClient extends StateMachine { @Override public void exit() { mProvisioningTimeoutAlarm.cancel(); // Record metrics information once this provisioning has completed due to certain // reason (normal termination, provisioning timeout, lost provisioning and etc). mIpProvisioningMetrics.statsWrite(); } @Override public boolean processMessage(Message msg) { switch (msg.what) { case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; case CMD_UPDATE_L2KEY_CLUSTER: { Loading @@ -1875,7 +1899,7 @@ public class IpClient extends StateMachine { break; case EVENT_PROVISIONING_TIMEOUT: handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_TIMEOUT); break; default: Loading Loading @@ -1912,13 +1936,13 @@ public class IpClient extends StateMachine { if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6); return; } if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV4); return; } Loading @@ -1926,14 +1950,14 @@ 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); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_INVALID_PROVISIONING); return; } if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { doImmediateProvisioningFailure( IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPREACHABILITYMONITOR); return; } } Loading Loading @@ -1965,8 +1989,8 @@ public class IpClient extends StateMachine { resetLinkProperties(); } private void enqueueJumpToStoppingState() { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING)); private void enqueueJumpToStoppingState(final DisconnectCode code) { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING, code.getNumber())); } private ConnectivityPacketTracker createPacketTracker() { Loading Loading @@ -2001,7 +2025,7 @@ public class IpClient extends StateMachine { switch (msg.what) { case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; case CMD_START: Loading @@ -2028,8 +2052,14 @@ public class IpClient extends StateMachine { break; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: // EVENT_NETLINK_LINKPROPERTIES_CHANGED message will be received in both of // provisioning loss and normal user termination case (e.g. turn off wifi or // switch to another wifi ssid), hence, checking current interface change // status (down or up) would help distinguish. final boolean ifUp = (msg.arg1 != 0); if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { transitionTo(mStoppingState); transitionToStoppingState(ifUp ? DisconnectCode.DC_PROVISIONING_FAIL : DisconnectCode.DC_NORMAL_TERMINATION); } break; Loading Loading @@ -2109,7 +2139,7 @@ public class IpClient extends StateMachine { } else { logError("Failed to set IPv4 address."); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.DC_PROVISIONING_FAIL); } break; } Loading
src/android/net/util/NetworkStackUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -436,4 +436,22 @@ public class NetworkStackUtils { return addr instanceof Inet6Address && ((addr.getAddress()[0] & 0xfe) == 0xfc); } /** * Returns the {@code int} nearest in value to {@code value}. * * @param value any {@code long} value * @return the same value cast to {@code int} if it is in the range of the {@code int} * type, {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if * it is too small */ public static int saturatedCast(long value) { if (value > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } if (value < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) value; } }
src/android/net/util/Stopwatch.java +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,15 @@ public class Stopwatch { return this; } /** * Restart the Stopwatch. */ public Stopwatch restart() { mStartTimeNs = SystemClock.elapsedRealtimeNanos(); mStopTimeNs = 0; return this; } /** * Stop the Stopwatch. * @return the total time recorded, in microseconds, or 0 if not started. Loading