1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.vcn.routeselection;
18 
19 
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.net.LinkProperties;
23 import android.net.Network;
24 import android.net.NetworkCapabilities;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 import com.android.internal.annotations.VisibleForTesting.Visibility;
28 import com.android.internal.util.IndentingPrintWriter;
29 
30 import java.util.Objects;
31 
32 /**
33  * A record of a single underlying network, caching relevant fields.
34  *
35  * @hide
36  */
37 public class UnderlyingNetworkRecord {
38     @NonNull public final Network network;
39     @NonNull public final NetworkCapabilities networkCapabilities;
40     @NonNull public final LinkProperties linkProperties;
41     public final boolean isBlocked;
42 
43     @VisibleForTesting(visibility = Visibility.PRIVATE)
UnderlyingNetworkRecord( @onNull Network network, @NonNull NetworkCapabilities networkCapabilities, @NonNull LinkProperties linkProperties, boolean isBlocked)44     public UnderlyingNetworkRecord(
45             @NonNull Network network,
46             @NonNull NetworkCapabilities networkCapabilities,
47             @NonNull LinkProperties linkProperties,
48             boolean isBlocked) {
49         this.network = network;
50         this.networkCapabilities = networkCapabilities;
51         this.linkProperties = linkProperties;
52         this.isBlocked = isBlocked;
53     }
54 
55     @Override
equals(Object o)56     public boolean equals(Object o) {
57         if (this == o) return true;
58         if (!(o instanceof UnderlyingNetworkRecord)) return false;
59         final UnderlyingNetworkRecord that = (UnderlyingNetworkRecord) o;
60 
61         return network.equals(that.network)
62                 && networkCapabilities.equals(that.networkCapabilities)
63                 && linkProperties.equals(that.linkProperties)
64                 && isBlocked == that.isBlocked;
65     }
66 
67     @Override
hashCode()68     public int hashCode() {
69         return Objects.hash(network, networkCapabilities, linkProperties, isBlocked);
70     }
71 
72     /** Return whether two records represent the same network */
isSameNetwork( @ullable UnderlyingNetworkRecord leftRecord, @Nullable UnderlyingNetworkRecord rightRecord)73     public static boolean isSameNetwork(
74             @Nullable UnderlyingNetworkRecord leftRecord,
75             @Nullable UnderlyingNetworkRecord rightRecord) {
76         final Network left = leftRecord == null ? null : leftRecord.network;
77         final Network right = rightRecord == null ? null : rightRecord.network;
78         return Objects.equals(left, right);
79     }
80 
81     /** Dumps the state of this record for logging and debugging purposes. */
dump(IndentingPrintWriter pw)82     void dump(IndentingPrintWriter pw) {
83         pw.println("UnderlyingNetworkRecord:");
84         pw.increaseIndent();
85 
86         pw.println("mNetwork: " + network);
87         pw.println("mNetworkCapabilities: " + networkCapabilities);
88         pw.println("mLinkProperties: " + linkProperties);
89 
90         pw.decreaseIndent();
91     }
92 
93     /** Builder to incrementally construct an UnderlyingNetworkRecord. */
94     static class Builder {
95         @NonNull private final Network mNetwork;
96 
97         @Nullable private NetworkCapabilities mNetworkCapabilities;
98         @Nullable private LinkProperties mLinkProperties;
99         boolean mIsBlocked;
100         boolean mWasIsBlockedSet;
101 
Builder(@onNull Network network)102         Builder(@NonNull Network network) {
103             mNetwork = network;
104         }
105 
106         @NonNull
getNetwork()107         Network getNetwork() {
108             return mNetwork;
109         }
110 
setNetworkCapabilities(@onNull NetworkCapabilities networkCapabilities)111         void setNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
112             mNetworkCapabilities = networkCapabilities;
113         }
114 
115         @Nullable
getNetworkCapabilities()116         NetworkCapabilities getNetworkCapabilities() {
117             return mNetworkCapabilities;
118         }
119 
setLinkProperties(@onNull LinkProperties linkProperties)120         void setLinkProperties(@NonNull LinkProperties linkProperties) {
121             mLinkProperties = linkProperties;
122         }
123 
setIsBlocked(boolean isBlocked)124         void setIsBlocked(boolean isBlocked) {
125             mIsBlocked = isBlocked;
126             mWasIsBlockedSet = true;
127         }
128 
isValid()129         boolean isValid() {
130             return mNetworkCapabilities != null && mLinkProperties != null && mWasIsBlockedSet;
131         }
132 
build()133         UnderlyingNetworkRecord build() {
134             if (!isValid()) {
135                 throw new IllegalArgumentException(
136                         "Called build before UnderlyingNetworkRecord was valid");
137             }
138 
139             return new UnderlyingNetworkRecord(
140                     mNetwork, mNetworkCapabilities, mLinkProperties, mIsBlocked);
141         }
142     }
143 }
144