diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 7b4981e478..da9c966690 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -214,6 +214,13 @@ public class ConnectivityService extends IConnectivityManager.Stub // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS private final int mReleasePendingIntentDelayMs; + // Driver specific constants used to select packets received via + // WiFi that caused the phone to exit sleep state. Currently there + // is only one kernel implementation so we can get away with + // constants. + private static final int mWakeupPacketMark = 0x80000000; + private static final int mWakeupPacketMask = 0x80000000; + private MockableSystemProperties mSystemProperties; private Tethering mTethering; @@ -4480,7 +4487,7 @@ public class ConnectivityService extends IConnectivityManager.Stub networkAgent.clatd.fixupLinkProperties(oldLp); } - updateInterfaces(newLp, oldLp, netId); + updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities); updateMtu(newLp, oldLp); // TODO - figure out what to do for clat // for (LinkProperties lp : newLp.getStackedLinks()) { @@ -4518,7 +4525,26 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId) { + private void wakeupAddInterface(String iface, NetworkCapabilities caps) throws RemoteException { + // Marks are only available on WiFi interaces. Checking for + // marks on unsupported interfaces is harmless. + if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { + return; + } + mNetd.getNetdService().wakeupAddInterface( + iface, "iface:" + iface, mWakeupPacketMark, mWakeupPacketMask); + } + + private void wakeupDelInterface(String iface, NetworkCapabilities caps) throws RemoteException { + if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { + return; + } + mNetd.getNetdService().wakeupDelInterface( + iface, "iface:" + iface, mWakeupPacketMark, mWakeupPacketMask); + } + + private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, + NetworkCapabilities caps) { CompareResult interfaceDiff = new CompareResult(); if (oldLp != null) { interfaceDiff = oldLp.compareAllInterfaceNames(newLp); @@ -4529,6 +4555,7 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (DBG) log("Adding iface " + iface + " to network " + netId); mNetd.addInterfaceToNetwork(iface, netId); + wakeupAddInterface(iface, caps); } catch (Exception e) { loge("Exception adding interface: " + e); } @@ -4537,6 +4564,7 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (DBG) log("Removing iface " + iface + " from network " + netId); mNetd.removeInterfaceFromNetwork(iface, netId); + wakeupDelInterface(iface, caps); } catch (Exception e) { loge("Exception removing interface: " + e); }