blob: 7ae9e95a520f10b913ed439b4a3b824a7568fba0 [file] [log] [blame]
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09001/*
2 * Copyright (C) 2019 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
17package com.android.server;
18
Chalard Jean52638ac42020-01-14 22:46:36 +090019import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +090020import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
21import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
22import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
23import static android.net.NetworkCapabilities.TRANSPORT_VPN;
24import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
25import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
26
27import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
28
29import static junit.framework.Assert.assertTrue;
30
31import static org.junit.Assert.assertEquals;
32import static org.junit.Assert.assertNotEquals;
33
34import android.content.Context;
35import android.net.ConnectivityManager;
36import android.net.LinkProperties;
37import android.net.Network;
38import android.net.NetworkAgent;
Lorenzo Colittid9696562020-01-12 22:28:37 +090039import android.net.NetworkAgentConfig;
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +090040import android.net.NetworkCapabilities;
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +090041import android.net.NetworkInfo;
Lorenzo Colitti6654b082020-01-10 00:40:28 +090042import android.net.NetworkProvider;
Chalard Jeana27e1ee2020-01-14 17:03:42 +090043import android.net.NetworkScore;
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +090044import android.net.NetworkSpecifier;
45import android.net.SocketKeepalive;
46import android.net.UidRange;
47import android.os.ConditionVariable;
48import android.os.HandlerThread;
49import android.os.Message;
50import android.util.Log;
51
52import com.android.server.connectivity.ConnectivityConstants;
53import com.android.testutils.HandlerUtilsKt;
54import com.android.testutils.TestableNetworkCallback;
55
56import java.util.Set;
57
58public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
59 private final NetworkInfo mNetworkInfo;
60 private final NetworkCapabilities mNetworkCapabilities;
61 private final HandlerThread mHandlerThread;
62 private final Context mContext;
63 private final String mLogTag;
64
65 private final ConditionVariable mDisconnected = new ConditionVariable();
66 private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
67 private int mScore;
68 private NetworkAgent mNetworkAgent;
69 private int mStartKeepaliveError = SocketKeepalive.ERROR_UNSUPPORTED;
70 private int mStopKeepaliveError = SocketKeepalive.NO_KEEPALIVE;
71 private Integer mExpectedKeepaliveSlot = null;
72
73 public NetworkAgentWrapper(int transport, LinkProperties linkProperties, Context context)
74 throws Exception {
75 final int type = transportToLegacyType(transport);
76 final String typeName = ConnectivityManager.getNetworkTypeName(type);
77 mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
78 mNetworkCapabilities = new NetworkCapabilities();
Chalard Jean52638ac42020-01-14 22:46:36 +090079 mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +090080 mNetworkCapabilities.addTransportType(transport);
81 switch (transport) {
82 case TRANSPORT_ETHERNET:
83 mScore = 70;
84 break;
85 case TRANSPORT_WIFI:
86 mScore = 60;
87 break;
88 case TRANSPORT_CELLULAR:
89 mScore = 50;
90 break;
91 case TRANSPORT_WIFI_AWARE:
92 mScore = 20;
93 break;
94 case TRANSPORT_VPN:
95 mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
96 mScore = ConnectivityConstants.VPN_DEFAULT_SCORE;
97 break;
98 default:
99 throw new UnsupportedOperationException("unimplemented network type");
100 }
101 mContext = context;
102 mLogTag = "Mock-" + typeName;
103 mHandlerThread = new HandlerThread(mLogTag);
104 mHandlerThread.start();
105
106 mNetworkAgent = makeNetworkAgent(linkProperties);
107 }
108
109 protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties)
110 throws Exception {
111 return new InstrumentedNetworkAgent(this, linkProperties);
112 }
113
114 public static class InstrumentedNetworkAgent extends NetworkAgent {
115 private final NetworkAgentWrapper mWrapper;
116
117 public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp) {
118 super(wrapper.mHandlerThread.getLooper(), wrapper.mContext, wrapper.mLogTag,
119 wrapper.mNetworkInfo, wrapper.mNetworkCapabilities, lp, wrapper.mScore,
Lorenzo Colittid9696562020-01-12 22:28:37 +0900120 new NetworkAgentConfig(), NetworkProvider.ID_NONE);
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900121 mWrapper = wrapper;
122 }
123
124 @Override
125 public void unwanted() {
126 mWrapper.mDisconnected.open();
127 }
128
129 @Override
130 public void startSocketKeepalive(Message msg) {
131 int slot = msg.arg1;
132 if (mWrapper.mExpectedKeepaliveSlot != null) {
133 assertEquals((int) mWrapper.mExpectedKeepaliveSlot, slot);
134 }
135 onSocketKeepaliveEvent(slot, mWrapper.mStartKeepaliveError);
136 }
137
138 @Override
139 public void stopSocketKeepalive(Message msg) {
140 onSocketKeepaliveEvent(msg.arg1, mWrapper.mStopKeepaliveError);
141 }
142
143 @Override
144 protected void preventAutomaticReconnect() {
145 mWrapper.mPreventReconnectReceived.open();
146 }
147
148 @Override
149 protected void addKeepalivePacketFilter(Message msg) {
150 Log.i(mWrapper.mLogTag, "Add keepalive packet filter.");
151 }
152
153 @Override
154 protected void removeKeepalivePacketFilter(Message msg) {
155 Log.i(mWrapper.mLogTag, "Remove keepalive packet filter.");
156 }
157 }
158
Chalard Jeana27e1ee2020-01-14 17:03:42 +0900159 private NetworkScore makeNetworkScore(final int legacyScore) {
160 return new NetworkScore.Builder().setLegacyScore(legacyScore).build();
161 }
162
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900163 public void adjustScore(int change) {
164 mScore += change;
Chalard Jeana27e1ee2020-01-14 17:03:42 +0900165 mNetworkAgent.sendNetworkScore(makeNetworkScore(mScore));
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900166 }
167
168 public int getScore() {
169 return mScore;
170 }
171
172 public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
173 mNetworkAgent.explicitlySelected(explicitlySelected, acceptUnvalidated);
174 }
175
176 public void addCapability(int capability) {
177 mNetworkCapabilities.addCapability(capability);
178 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
179 }
180
181 public void removeCapability(int capability) {
182 mNetworkCapabilities.removeCapability(capability);
183 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
184 }
185
186 public void setUids(Set<UidRange> uids) {
187 mNetworkCapabilities.setUids(uids);
188 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
189 }
190
191 public void setSignalStrength(int signalStrength) {
192 mNetworkCapabilities.setSignalStrength(signalStrength);
193 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
194 }
195
196 public void setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
197 mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
198 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
199 }
200
201 public void setNetworkCapabilities(NetworkCapabilities nc, boolean sendToConnectivityService) {
202 mNetworkCapabilities.set(nc);
203 if (sendToConnectivityService) {
204 mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
205 }
206 }
207
208 public void connect() {
209 assertNotEquals("MockNetworkAgents can only be connected once",
210 getNetworkInfo().getDetailedState(), NetworkInfo.DetailedState.CONNECTED);
211 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
212 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
213 }
214
215 public void suspend() {
Chalard Jean52638ac42020-01-14 22:46:36 +0900216 removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900217 }
218
219 public void resume() {
Chalard Jean52638ac42020-01-14 22:46:36 +0900220 addCapability(NET_CAPABILITY_NOT_SUSPENDED);
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900221 }
222
223 public void disconnect() {
224 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
225 mNetworkAgent.sendNetworkInfo(mNetworkInfo);
226 }
227
228 @Override
229 public Network getNetwork() {
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900230 return mNetworkAgent.getNetwork();
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900231 }
232
233 public void expectPreventReconnectReceived(long timeoutMs) {
234 assertTrue(mPreventReconnectReceived.block(timeoutMs));
235 }
236
237 public void expectDisconnected(long timeoutMs) {
238 assertTrue(mDisconnected.block(timeoutMs));
239 }
240
241 public void sendLinkProperties(LinkProperties lp) {
242 mNetworkAgent.sendLinkProperties(lp);
243 }
244
245 public void setStartKeepaliveEvent(int reason) {
246 mStartKeepaliveError = reason;
247 }
248
249 public void setStopKeepaliveEvent(int reason) {
250 mStopKeepaliveError = reason;
251 }
252
253 public void setExpectedKeepaliveSlot(Integer slot) {
254 mExpectedKeepaliveSlot = slot;
255 }
256
257 public NetworkAgent getNetworkAgent() {
258 return mNetworkAgent;
259 }
260
261 public NetworkInfo getNetworkInfo() {
262 return mNetworkInfo;
263 }
264
265 public NetworkCapabilities getNetworkCapabilities() {
266 return mNetworkCapabilities;
267 }
268
269 public void waitForIdle(long timeoutMs) {
270 HandlerUtilsKt.waitForIdle(mHandlerThread, timeoutMs);
271 }
272}