API to detect which network interfaces support wake-on-lan

Add a new method in LinkProperties, isWakeOnLanEnabled() which returns
true if network interface is defined in config_wakeonlan_enabled_interfaces
string-array (config.xml)

Bug: 132705025
Test: atest LinkPropertiesTest & atest ConnectivityServiceTest
Change-Id: I3f7803aafd2f8eaf8aa18419b21339e15d4b7a0b
This commit is contained in:
Valentin Iftime 2019-09-24 13:32:13 +02:00
parent 36ad0924b9
commit c86ebbaebc
8 changed files with 121 additions and 2 deletions

View File

@ -28695,6 +28695,7 @@ package android.net {
method @Nullable public String getPrivateDnsServerName();
method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
method public boolean isPrivateDnsActive();
method public boolean isWakeOnLanSupported();
method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
method public void setDomains(@Nullable String);
method public void setHttpProxy(@Nullable android.net.ProxyInfo);
@ -47777,6 +47778,7 @@ package android.util {
ctor public ArraySet(int);
ctor public ArraySet(android.util.ArraySet<E>);
ctor public ArraySet(java.util.Collection<? extends E>);
ctor public ArraySet(@Nullable E[]);
method public boolean add(E);
method public void addAll(android.util.ArraySet<? extends E>);
method public boolean addAll(java.util.Collection<? extends E>);

View File

@ -68,6 +68,7 @@ public final class LinkProperties implements Parcelable {
// in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
private String mTcpBufferSizes;
private IpPrefix mNat64Prefix;
private boolean mWakeOnLanSupported;
private static final int MIN_MTU = 68;
private static final int MIN_MTU_V6 = 1280;
@ -193,6 +194,7 @@ public final class LinkProperties implements Parcelable {
setMtu(source.mMtu);
mTcpBufferSizes = source.mTcpBufferSizes;
mNat64Prefix = source.mNat64Prefix;
mWakeOnLanSupported = source.mWakeOnLanSupported;
}
}
@ -852,6 +854,7 @@ public final class LinkProperties implements Parcelable {
mMtu = 0;
mTcpBufferSizes = null;
mNat64Prefix = null;
mWakeOnLanSupported = false;
}
/**
@ -913,6 +916,10 @@ public final class LinkProperties implements Parcelable {
resultJoiner.add("MTU:");
resultJoiner.add(Integer.toString(mMtu));
if (mWakeOnLanSupported) {
resultJoiner.add("WakeOnLanSupported: true");
}
if (mTcpBufferSizes != null) {
resultJoiner.add("TcpBufferSizes:");
resultJoiner.add(mTcpBufferSizes);
@ -1424,6 +1431,37 @@ public final class LinkProperties implements Parcelable {
return Objects.equals(mNat64Prefix, target.mNat64Prefix);
}
/**
* Compares this {@code LinkProperties} WakeOnLan supported against the target.
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
public boolean isIdenticalWakeOnLan(LinkProperties target) {
return isWakeOnLanSupported() == target.isWakeOnLanSupported();
}
/**
* Set whether the network interface supports WakeOnLAN
*
* @param supported WakeOnLAN supported value
*
* @hide
*/
public void setWakeOnLanSupported(boolean supported) {
mWakeOnLanSupported = supported;
}
/**
* Returns whether the network interface supports WakeOnLAN
*
* @return {@code true} if interface supports WakeOnLAN, {@code false} otherwise.
*/
public boolean isWakeOnLanSupported() {
return mWakeOnLanSupported;
}
/**
* Compares this {@code LinkProperties} instance against the target
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
@ -1461,7 +1499,8 @@ public final class LinkProperties implements Parcelable {
&& isIdenticalStackedLinks(target)
&& isIdenticalMtu(target)
&& isIdenticalTcpBufferSizes(target)
&& isIdenticalNat64Prefix(target);
&& isIdenticalNat64Prefix(target)
&& isIdenticalWakeOnLan(target);
}
/**
@ -1577,7 +1616,8 @@ public final class LinkProperties implements Parcelable {
+ (mUsePrivateDns ? 57 : 0)
+ mPcscfs.size() * 67
+ ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
+ Objects.hash(mNat64Prefix);
+ Objects.hash(mNat64Prefix)
+ (mWakeOnLanSupported ? 71 : 0);
}
/**
@ -1622,6 +1662,8 @@ public final class LinkProperties implements Parcelable {
ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
dest.writeList(stackedLinks);
dest.writeBoolean(mWakeOnLanSupported);
}
/**
@ -1677,6 +1719,7 @@ public final class LinkProperties implements Parcelable {
for (LinkProperties stackedLink: stackedLinks) {
netProp.addStackedLink(stackedLink);
}
netProp.setWakeOnLanSupported(in.readBoolean());
return netProp;
}

View File

@ -16,6 +16,7 @@
package android.util;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@ -302,6 +303,18 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
}
}
/**
* Create a new ArraySet with items from the given array
*/
public ArraySet(@Nullable E[] array) {
this();
if (array != null) {
for (E value : array) {
add(value);
}
}
}
/**
* Make the array map empty. All storage is released.
*/

View File

@ -433,6 +433,14 @@
-->
</string-array>
<!-- Configuration of network interfaces that support WakeOnLAN -->
<string-array translatable="false" name="config_wakeonlan_supported_interfaces">
<!--
<item>wlan0</item>
<item>eth0</item>
-->
</string-array>
<!-- If the mobile hotspot feature requires provisioning, a package name and class name
can be provided to launch a supported application that provisions the devices.

View File

@ -743,6 +743,7 @@
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
<java-symbol type="array" name="config_ethernet_interfaces" />
<java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />

View File

@ -579,6 +579,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// the set of network types that can only be enabled by system/sig apps
private List mProtectedNetworks;
private Set<String> mWolSupportedInterfaces;
private TelephonyManager mTelephonyManager;
private KeepaliveTracker mKeepaliveTracker;
@ -1055,6 +1057,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
mWolSupportedInterfaces = new ArraySet(
mContext.getResources().getStringArray(
com.android.internal.R.array.config_wakeonlan_supported_interfaces));
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mTethering = deps.makeTethering(mContext, mNMS, mStatsService, mPolicyManager,
@ -5599,6 +5605,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
updateProxy(newLp, oldLp);
}
updateWakeOnLan(newLp);
// TODO - move this check to cover the whole function
if (!Objects.equals(newLp, oldLp)) {
synchronized (networkAgent) {
@ -5769,6 +5778,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void updateWakeOnLan(@NonNull LinkProperties lp) {
lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
}
private int getNetworkPermission(NetworkCapabilities nc) {
if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
return INetd.PERMISSION_SYSTEM;

View File

@ -99,6 +99,7 @@ public class LinkPropertiesTest {
assertFalse(lp.isIpv4Provisioned());
assertFalse(lp.isIpv6Provisioned());
assertFalse(lp.isPrivateDnsActive());
assertFalse(lp.isWakeOnLanSupported());
}
private LinkProperties makeTestObject() {
@ -120,6 +121,7 @@ public class LinkPropertiesTest {
lp.setMtu(MTU);
lp.setTcpBufferSizes(TCP_BUFFER_SIZES);
lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
lp.setWakeOnLanSupported(true);
return lp;
}
@ -158,6 +160,9 @@ public class LinkPropertiesTest {
assertTrue(source.isIdenticalTcpBufferSizes(target));
assertTrue(target.isIdenticalTcpBufferSizes(source));
assertTrue(source.isIdenticalWakeOnLan(target));
assertTrue(target.isIdenticalWakeOnLan(source));
// Check result of equals().
assertTrue(source.equals(target));
assertTrue(target.equals(source));
@ -1057,4 +1062,13 @@ public class LinkPropertiesTest {
lp.clear();
assertFalse(lp.isPrivateDnsActive());
}
@Test
public void testWakeOnLanSupported() {
final LinkProperties lp = makeTestObject();
assertTrue(lp.isWakeOnLanSupported());
lp.clear();
assertFalse(lp.isWakeOnLanSupported());
}
}

View File

@ -274,6 +274,7 @@ public class ConnectivityServiceTest {
private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
private static final String WIFI_IFNAME = "test_wlan0";
private static final String WIFI_WOL_IFNAME = "test_wlan_wol";
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private MockContext mServiceContext;
@ -343,6 +344,12 @@ public class ConnectivityServiceTest {
"mobile_mms,2,0,2,60000,true",
});
when(mResources.getStringArray(
com.android.internal.R.array.config_wakeonlan_supported_interfaces))
.thenReturn(new String[]{
WIFI_WOL_IFNAME,
});
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
}
@ -5947,6 +5954,24 @@ public class ConnectivityServiceTest {
assertContainsExactly(uidCaptor.getValue(), APP2_UID);
}
@Test
public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_WOL_IFNAME);
wifiLp.setWakeOnLanSupported(false);
// Default network switch should update ifaces.
mWiFiNetworkAgent.connect(false);
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
waitForIdle();
// ConnectivityService should have changed the WakeOnLanSupported to true
wifiLp.setWakeOnLanSupported(true);
assertEquals(wifiLp, mService.getActiveLinkProperties());
}
private TestNetworkAgentWrapper establishVpn(LinkProperties lp, int establishingUid,
Set<UidRange> vpnRange) throws Exception {