From d25444ffce6cdf7069d445c38da1f9abf9aa46b7 Mon Sep 17 00:00:00 2001 From: Yang Sun Date: Tue, 24 Oct 2023 18:43:15 +0800 Subject: [PATCH] Add equals, hashCode to MulticastRoutingConfig Add helper functions to help compare if MulticastRoutingConfig has changed. Test: atest MulticastRoutingConfigTest Change-Id: I30ed4796efbaafbcf1a273c12a9231ec02bc36f0 --- .../android/net/MulticastRoutingConfig.java | 49 +++++++-- .../android/net/MulticastRoutingConfigTest.kt | 99 +++++++++++++++++++ 2 files changed, 139 insertions(+), 9 deletions(-) create mode 100644 tests/unit/java/android/net/MulticastRoutingConfigTest.kt diff --git a/framework/src/android/net/MulticastRoutingConfig.java b/framework/src/android/net/MulticastRoutingConfig.java index 1f4071cd6b..4a3e1be8fa 100644 --- a/framework/src/android/net/MulticastRoutingConfig.java +++ b/framework/src/android/net/MulticastRoutingConfig.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; @@ -30,7 +31,9 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; +import java.util.Objects; import java.util.Set; +import java.util.StringJoiner; /** * A class representing a configuration for multicast routing. @@ -162,15 +165,6 @@ public final class MulticastRoutingConfig implements Parcelable { } }; - @Override - public String toString() { - return "MulticastRoutingConfig{" - + "ForwardingMode=" + forwardingModeToString(mForwardingMode) - + ", MinScope=" + mMinScope - + ", ListeningAddresses=" + mListeningAddresses - + '}'; - } - private static String forwardingModeToString(final int forwardingMode) { switch (forwardingMode) { case FORWARD_NONE: return "NONE"; @@ -301,4 +295,41 @@ public final class MulticastRoutingConfig implements Parcelable { default: return "unknown multicast routing mode " + mode; } } + + public boolean equals(Object other) { + if (other == this) { + return true; + } else if (!(other instanceof MulticastRoutingConfig)) { + return false; + } else { + final MulticastRoutingConfig otherConfig = (MulticastRoutingConfig) other; + return mForwardingMode == otherConfig.mForwardingMode + && mMinScope == otherConfig.mMinScope + && mListeningAddresses.equals(otherConfig.mListeningAddresses); + } + } + + public int hashCode() { + return Objects.hash(mForwardingMode, mMinScope, mListeningAddresses); + } + + public String toString() { + final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}"); + + resultJoiner.add("ForwardingMode:"); + resultJoiner.add(modeToString(mForwardingMode)); + + if (mForwardingMode == FORWARD_WITH_MIN_SCOPE) { + resultJoiner.add("MinScope:"); + resultJoiner.add(Integer.toString(mMinScope)); + } + + if (mForwardingMode == FORWARD_SELECTED && !mListeningAddresses.isEmpty()) { + resultJoiner.add("ListeningAddresses: ["); + resultJoiner.add(TextUtils.join(",", mListeningAddresses)); + resultJoiner.add("]"); + } + + return resultJoiner.toString(); + } } diff --git a/tests/unit/java/android/net/MulticastRoutingConfigTest.kt b/tests/unit/java/android/net/MulticastRoutingConfigTest.kt new file mode 100644 index 0000000000..f01057b2ba --- /dev/null +++ b/tests/unit/java/android/net/MulticastRoutingConfigTest.kt @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 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.os.Build +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo +import com.android.testutils.DevSdkIgnoreRunner + +import org.junit.Test +import org.junit.runner.RunWith +import java.net.Inet6Address +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +import android.net.MulticastRoutingConfig.Builder +import android.net.MulticastRoutingConfig.FORWARD_NONE +import android.net.MulticastRoutingConfig.FORWARD_SELECTED +import android.net.MulticastRoutingConfig.FORWARD_WITH_MIN_SCOPE + +@RunWith(DevSdkIgnoreRunner::class) +@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) +class MulticastRoutingConfigTest { + + val address1 = Inet6Address.getByName("2000::8888") as Inet6Address + val address2 = Inet6Address.getByName("2000::9999") as Inet6Address + + private fun configNone() = Builder(FORWARD_NONE).build() + private fun configMinScope(scope: Int) = Builder(FORWARD_WITH_MIN_SCOPE, scope).build() + private fun configSelected() = Builder(FORWARD_SELECTED).build() + private fun configSelectedWithAddress1AndAddress2() = + Builder(FORWARD_SELECTED).addListeningAddress(address1) + .addListeningAddress(address2).build() + private fun configSelectedWithAddress2AndAddress1() = + Builder(FORWARD_SELECTED).addListeningAddress(address2) + .addListeningAddress(address1).build() + + @Test + fun equalityTests() { + + assertTrue(configNone().equals(configNone())) + + assertTrue(configSelected().equals(configSelected())) + + assertTrue(configMinScope(4).equals(configMinScope(4))) + + assertTrue(configSelectedWithAddress1AndAddress2() + .equals(configSelectedWithAddress2AndAddress1())) + } + + @Test + fun inequalityTests() { + + assertFalse(configNone().equals(configSelected())) + + assertFalse(configNone().equals(configMinScope(4))) + + assertFalse(configSelected().equals(configMinScope(4))) + + assertFalse(configMinScope(4).equals(configMinScope(5))) + + assertFalse(configSelected().equals(configSelectedWithAddress1AndAddress2())) + } + + @Test + fun toString_equalObjects_returnsEqualStrings() { + val config1 = configSelectedWithAddress1AndAddress2() + val config2 = configSelectedWithAddress2AndAddress1() + + val str1 = config1.toString() + val str2 = config2.toString() + + assertTrue(str1.equals(str2)) + } + + @Test + fun toString_unequalObjects_returnsUnequalStrings() { + val config1 = configSelected() + val config2 = configSelectedWithAddress1AndAddress2() + + val str1 = config1.toString() + val str2 = config2.toString() + + assertFalse(str1.equals(str2)) + } +}