Make ConnectivityReport Parcelable.

ConnectivityReport is defined inside ConnectivityDiagnosticsManager. In
order for ConnectivityReport to be used in aidl interfaces, it must
implement the Parcelable interface.

Bug: 143187964
Test: compiles
Test: atest FrameworksNetTests
Change-Id: I8e862c78bd84b5da14203f61ce44beb1ca4a623d
This commit is contained in:
Cody Kesting
2019-12-17 08:51:32 -08:00
parent f78c964538
commit beb41b5457
2 changed files with 296 additions and 11 deletions

View File

@@ -18,10 +18,16 @@ package android.net;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -60,25 +66,38 @@ public class ConnectivityDiagnosticsManager {
/** @hide */
public ConnectivityDiagnosticsManager() {}
/** @hide */
@VisibleForTesting
public static boolean persistableBundleEquals(
@Nullable PersistableBundle a, @Nullable PersistableBundle b) {
if (a == b) return true;
if (a == null || b == null) return false;
if (!Objects.equals(a.keySet(), b.keySet())) return false;
for (String key : a.keySet()) {
if (!Objects.equals(a.get(key), b.get(key))) return false;
}
return true;
}
/** Class that includes connectivity information for a specific Network at a specific time. */
public static class ConnectivityReport {
public static final class ConnectivityReport implements Parcelable {
/** The Network for which this ConnectivityReport applied */
@NonNull public final Network network;
@NonNull private final Network mNetwork;
/**
* The timestamp for the report. The timestamp is taken from {@link
* System#currentTimeMillis}.
*/
public final long reportTimestamp;
private final long mReportTimestamp;
/** LinkProperties available on the Network at the reported timestamp */
@NonNull public final LinkProperties linkProperties;
@NonNull private final LinkProperties mLinkProperties;
/** NetworkCapabilities available on the Network at the reported timestamp */
@NonNull public final NetworkCapabilities networkCapabilities;
@NonNull private final NetworkCapabilities mNetworkCapabilities;
/** PersistableBundle that may contain additional info about the report */
@NonNull public final PersistableBundle additionalInfo;
@NonNull private final PersistableBundle mAdditionalInfo;
/**
* Constructor for ConnectivityReport.
@@ -101,12 +120,120 @@ public class ConnectivityDiagnosticsManager {
@NonNull LinkProperties linkProperties,
@NonNull NetworkCapabilities networkCapabilities,
@NonNull PersistableBundle additionalInfo) {
this.network = network;
this.reportTimestamp = reportTimestamp;
this.linkProperties = linkProperties;
this.networkCapabilities = networkCapabilities;
this.additionalInfo = additionalInfo;
mNetwork = network;
mReportTimestamp = reportTimestamp;
mLinkProperties = linkProperties;
mNetworkCapabilities = networkCapabilities;
mAdditionalInfo = additionalInfo;
}
/**
* Returns the Network for this ConnectivityReport.
*
* @return The Network for which this ConnectivityReport applied
*/
@NonNull
public Network getNetwork() {
return mNetwork;
}
/**
* Returns the epoch timestamp (milliseconds) for when this report was taken.
*
* @return The timestamp for the report. Taken from {@link System#currentTimeMillis}.
*/
public long getReportTimestamp() {
return mReportTimestamp;
}
/**
* Returns the LinkProperties available when this report was taken.
*
* @return LinkProperties available on the Network at the reported timestamp
*/
@NonNull
public LinkProperties getLinkProperties() {
return new LinkProperties(mLinkProperties);
}
/**
* Returns the NetworkCapabilities when this report was taken.
*
* @return NetworkCapabilities available on the Network at the reported timestamp
*/
@NonNull
public NetworkCapabilities getNetworkCapabilities() {
return new NetworkCapabilities(mNetworkCapabilities);
}
/**
* Returns a PersistableBundle with additional info for this report.
*
* @return PersistableBundle that may contain additional info about the report
*/
@NonNull
public PersistableBundle getAdditionalInfo() {
return new PersistableBundle(mAdditionalInfo);
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (!(o instanceof ConnectivityReport)) return false;
final ConnectivityReport that = (ConnectivityReport) o;
// PersistableBundle is optimized to avoid unparcelling data unless fields are
// referenced. Because of this, use {@link ConnectivityDiagnosticsManager#equals} over
// {@link PersistableBundle#kindofEquals}.
return mReportTimestamp == that.mReportTimestamp
&& mNetwork.equals(that.mNetwork)
&& mLinkProperties.equals(that.mLinkProperties)
&& mNetworkCapabilities.equals(that.mNetworkCapabilities)
&& persistableBundleEquals(mAdditionalInfo, that.mAdditionalInfo);
}
@Override
public int hashCode() {
return Objects.hash(
mNetwork,
mReportTimestamp,
mLinkProperties,
mNetworkCapabilities,
mAdditionalInfo);
}
/** {@inheritDoc} */
@Override
public int describeContents() {
return 0;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeParcelable(mNetwork, flags);
dest.writeLong(mReportTimestamp);
dest.writeParcelable(mLinkProperties, flags);
dest.writeParcelable(mNetworkCapabilities, flags);
dest.writeParcelable(mAdditionalInfo, flags);
}
/** Implement the Parcelable interface */
public static final @NonNull Creator<ConnectivityReport> CREATOR =
new Creator<>() {
public ConnectivityReport createFromParcel(Parcel in) {
return new ConnectivityReport(
in.readParcelable(null),
in.readLong(),
in.readParcelable(null),
in.readParcelable(null),
in.readParcelable(null));
}
public ConnectivityReport[] newArray(int size) {
return new ConnectivityReport[size];
}
};
}
/** Class that includes information for a suspected data stall on a specific Network */

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2020 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 android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import android.os.PersistableBundle;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ConnectivityDiagnosticsManagerTest {
private static final int NET_ID = 1;
private static final long TIMESTAMP = 10L;
private static final String INTERFACE_NAME = "interface";
private static final String BUNDLE_KEY = "key";
private static final String BUNDLE_VALUE = "value";
private ConnectivityReport createSampleConnectivityReport() {
final LinkProperties linkProperties = new LinkProperties();
linkProperties.setInterfaceName(INTERFACE_NAME);
final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
final PersistableBundle bundle = new PersistableBundle();
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
return new ConnectivityReport(
new Network(NET_ID), TIMESTAMP, linkProperties, networkCapabilities, bundle);
}
private ConnectivityReport createDefaultConnectivityReport() {
return new ConnectivityReport(
new Network(0),
0L,
new LinkProperties(),
new NetworkCapabilities(),
PersistableBundle.EMPTY);
}
@Test
public void testPersistableBundleEquals() {
assertFalse(
ConnectivityDiagnosticsManager.persistableBundleEquals(
null, PersistableBundle.EMPTY));
assertFalse(
ConnectivityDiagnosticsManager.persistableBundleEquals(
PersistableBundle.EMPTY, null));
assertTrue(
ConnectivityDiagnosticsManager.persistableBundleEquals(
PersistableBundle.EMPTY, PersistableBundle.EMPTY));
final PersistableBundle a = new PersistableBundle();
a.putString(BUNDLE_KEY, BUNDLE_VALUE);
final PersistableBundle b = new PersistableBundle();
b.putString(BUNDLE_KEY, BUNDLE_VALUE);
final PersistableBundle c = new PersistableBundle();
c.putString(BUNDLE_KEY, null);
assertFalse(
ConnectivityDiagnosticsManager.persistableBundleEquals(PersistableBundle.EMPTY, a));
assertFalse(
ConnectivityDiagnosticsManager.persistableBundleEquals(a, PersistableBundle.EMPTY));
assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(a, b));
assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(b, a));
assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(a, c));
assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(c, a));
}
@Test
public void testConnectivityReportEquals() {
assertEquals(createSampleConnectivityReport(), createSampleConnectivityReport());
assertEquals(createDefaultConnectivityReport(), createDefaultConnectivityReport());
final LinkProperties linkProperties = new LinkProperties();
linkProperties.setInterfaceName(INTERFACE_NAME);
final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
final PersistableBundle bundle = new PersistableBundle();
bundle.putString(BUNDLE_KEY, BUNDLE_VALUE);
assertNotEquals(
createDefaultConnectivityReport(),
new ConnectivityReport(
new Network(NET_ID),
0L,
new LinkProperties(),
new NetworkCapabilities(),
PersistableBundle.EMPTY));
assertNotEquals(
createDefaultConnectivityReport(),
new ConnectivityReport(
new Network(0),
TIMESTAMP,
new LinkProperties(),
new NetworkCapabilities(),
PersistableBundle.EMPTY));
assertNotEquals(
createDefaultConnectivityReport(),
new ConnectivityReport(
new Network(0),
0L,
linkProperties,
new NetworkCapabilities(),
PersistableBundle.EMPTY));
assertNotEquals(
createDefaultConnectivityReport(),
new ConnectivityReport(
new Network(0),
TIMESTAMP,
new LinkProperties(),
networkCapabilities,
PersistableBundle.EMPTY));
assertNotEquals(
createDefaultConnectivityReport(),
new ConnectivityReport(
new Network(0),
TIMESTAMP,
new LinkProperties(),
new NetworkCapabilities(),
bundle));
}
@Test
public void testConnectivityReportParcelUnparcel() {
assertParcelSane(createSampleConnectivityReport(), 5);
}
}