Merge "Add EthernetPortSelector class" into main

This commit is contained in:
Chuwei He 2025-07-22 18:14:21 -07:00 • committed by Android (Google) Code Review
commit fbef6e47d7
2 changed files with 276 additions and 0 deletions

View file

@ -0,0 +1,141 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.util.Objects;
/**
* A {@link EthernetPortSelector} used to identify ethernet ports. Ports can be identified by
* matching either interface name or MAC address only.
* This selector is different from {@link EthernetNetworkSpecifier} in the way that
* {@link EthernetPortSelector} is used to identify an ethernet network which might include
* network specific configuration, such as authentication etc,. While {@link EthernetPortSelector}
* is solely used to identify an ethernet port which may or may not be connected.
* @hide
*/
public final class EthernetPortSelector implements Parcelable {
/**
* Name of the network port, or null.
*/
@Nullable
private final String mInterfaceName;
/**
* MAC address of the network port, or null.
*/
@Nullable
private final MacAddress mMacAddress;
/**
* Create a new EthernetPortSelector by interface name.
* @param interfaceName Name of the ethernet interface the specifier refers to.
* @hide
*/
public EthernetPortSelector(@NonNull String interfaceName) {
// Interface name and MAC address cannot be both invalid or both set at the same time.
if (TextUtils.isEmpty(interfaceName)) {
throw new IllegalArgumentException("Interface name cannot be empty.");
}
mInterfaceName = interfaceName;
mMacAddress = null;
}
/**
* Create a new EthernetPortSelector by MAC address.
* @param macAddress MAC address of the ethernet interface the specifier refers to, or null.
* @hide
*/
public EthernetPortSelector(@NonNull MacAddress macAddress) {
// Interface name and MAC address cannot be both invalid or both set at the same time.
if (macAddress == null) {
throw new IllegalArgumentException("MAC address cannot be null.");
}
mInterfaceName = null;
mMacAddress = macAddress;
}
/**
* Get the name of the ethernet port the selector refers to, or null.
* @hide
*/
@Nullable
public String getInterfaceName() {
return mInterfaceName;
}
/**
* Get the MAC address of the ethernet port the selector refers to, or null.
* @hide
*/
@Nullable
public MacAddress getMacAddress() {
return mMacAddress;
}
@Override
public boolean equals(@Nullable Object o) {
return (o instanceof EthernetPortSelector rhs)
&& TextUtils.equals(mInterfaceName, rhs.mInterfaceName)
&& Objects.equals(mMacAddress, rhs.mMacAddress);
}
@Override
public int hashCode() {
return Objects.hash(mMacAddress, mInterfaceName);
}
@Override
public String toString() {
String selectorInfo = mMacAddress != null ? mMacAddress.toString() : mInterfaceName;
return "EthernetPortSelector (" + selectorInfo + ")";
}
/** @hide */
@Override
public int describeContents() {
return 0;
}
/** @hide */
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mInterfaceName);
dest.writeParcelable(mMacAddress, flags);
}
/** @hide */
public static final @NonNull Parcelable.Creator<EthernetPortSelector> CREATOR =
new Parcelable.Creator<>() {
public EthernetPortSelector createFromParcel(Parcel in) {
final String ifname = in.readString();
final MacAddress addr = in.readParcelable(MacAddress.class.getClassLoader());
return ifname == null
? new EthernetPortSelector(addr) : new EthernetPortSelector(ifname);
}
public EthernetPortSelector[] newArray(int size) {
return new EthernetPortSelector[size];
}
};
}

View file

@ -0,0 +1,135 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import android.os.Build;
import androidx.test.filters.SmallTest;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
@RunWith(DevSdkIgnoreRunner.class)
public class EthernetPortSelectorTest {
private final MacAddress mTestMacAddr = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
private final String mTestIfaceName1 = "testIface";
private final String mTestIfaceName2 = "testIfaceTwo";
@Test
public void testConstructorWithIface() {
final EthernetPortSelector ns = new EthernetPortSelector(mTestIfaceName1);
assertEquals(mTestIfaceName1, ns.getInterfaceName());
assertNull(ns.getMacAddress());
}
@Test
public void testConstructorWithMacAddress() {
final EthernetPortSelector ns = new EthernetPortSelector(mTestMacAddr);
assertEquals(mTestMacAddr, ns.getMacAddress());
assertNull(ns.getInterfaceName());
}
@Test
public void testConstructorWithNullIface() {
assertThrows("Interface name cannot be empty.",
IllegalArgumentException.class,
() -> new EthernetPortSelector((String) null));
}
@Test
public void testConstructorWithNullMacAddr() {
assertThrows("MAC address cannot be null.",
IllegalArgumentException.class,
() -> new EthernetPortSelector((MacAddress) null));
}
@Test
public void testEquals() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestIfaceName1);
assertEquals(nsOne, nsTwo);
}
@Test
public void testNotEquals() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestIfaceName2);
assertNotEquals(nsOne, nsTwo);
}
@Test
public void testHashCodeOfDifferentSpecifier() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestIfaceName2);
int hash1 = nsOne.hashCode();
int hash2 = nsTwo.hashCode();
assertNotEquals(hash1, hash2);
}
@Test
public void testHashCodeOfTheSameSpecifier() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestIfaceName1);
int hash1 = nsOne.hashCode();
int hash2 = nsTwo.hashCode();
assertEquals(hash1, hash2);
}
@Test
public void testToString() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
String expectOne = "EthernetPortSelector (testIface)";
assertEquals(nsOne.toString(), expectOne);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestMacAddr);
String expectTwo = "EthernetPortSelector (aa:bb:cc:dd:ee:ff)";
assertEquals(nsTwo.toString(), expectTwo);
}
@Test
public void testParcel() {
final EthernetPortSelector nsOne =
new EthernetPortSelector(mTestIfaceName1);
assertParcelingIsLossless(nsOne);
final EthernetPortSelector nsTwo =
new EthernetPortSelector(mTestMacAddr);
assertParcelingIsLossless(nsTwo);
}
}