1fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey/*
2fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * Copyright (C) 2012 The Android Open Source Project
3fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey *
4fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * you may not use this file except in compliance with the License.
6fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * You may obtain a copy of the License at
7fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey *
8fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey *
10fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * See the License for the specific language governing permissions and
14fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * limitations under the License.
15fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey */
16fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
17fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeypackage com.android.server;
18fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
19f851d6dd2a15b74f63c85403afad0ed747f7311cErik Klineimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
20fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_MOBILE;
21fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
22fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.getNetworkTypeName;
2385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
2485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
2585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
2685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
2785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
2885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_IA;
2985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
30d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
3185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
3285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
3385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
3485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
3585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
3685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
3785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
38d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
3985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
4085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
41d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
42d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport static android.net.NetworkCapabilities.TRANSPORT_WIFI;
433671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Matchers.anyInt;
443671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Matchers.eq;
453671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Matchers.isA;
463671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.doNothing;
473671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.doReturn;
483671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.doThrow;
493671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.mock;
503671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.reset;
513671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport static org.mockito.Mockito.verify;
52fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
53bb2e0e98160f099261876794518d4db62e309aecPaul Jensenimport android.app.PendingIntent;
54d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.content.BroadcastReceiver;
55fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.content.Context;
56d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.content.ContextWrapper;
57d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.content.Intent;
58d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.content.IntentFilter;
59d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.ConnectivityManager;
60d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.ConnectivityManager.NetworkCallback;
61fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.INetworkPolicyManager;
62fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.INetworkStatsService;
63fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.LinkProperties;
64d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.Network;
65d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.NetworkAgent;
66d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.NetworkCapabilities;
67fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.NetworkConfig;
68348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwaltimport android.net.NetworkFactory;
69fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.NetworkInfo;
70fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.NetworkInfo.DetailedState;
71d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.NetworkMisc;
72d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.net.NetworkRequest;
73fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.net.RouteInfo;
74d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.os.ConditionVariable;
75fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.os.Handler;
76348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwaltimport android.os.HandlerThread;
77d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport android.os.Looper;
78fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.os.INetworkManagementService;
79fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.test.AndroidTestCase;
80fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest;
81fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.util.Log;
82fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport android.util.LogPrinter;
83fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
84cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensenimport com.android.server.connectivity.NetworkAgentInfo;
85d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensenimport com.android.server.connectivity.NetworkMonitor;
86d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
873671b1e910e4d297bebcd3ceaa2682bfb4b1f4a1Jeff Sharkeyimport org.mockito.ArgumentCaptor;
88fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
89fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport java.net.InetAddress;
90fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport java.util.concurrent.Future;
91348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwaltimport java.util.concurrent.atomic.AtomicBoolean;
92fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
93fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey/**
94fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey * Tests for {@link ConnectivityService}.
95d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen *
96d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen * Build, install and run with:
97d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen *  runtest frameworks-services -c com.android.server.ConnectivityServiceTest
98fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey */
99fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeypublic class ConnectivityServiceTest extends AndroidTestCase {
100fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static final String TAG = "ConnectivityServiceTest";
101fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
102fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static final String MOBILE_IFACE = "rmnet3";
103fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static final String WIFI_IFACE = "wlan6";
104fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
105e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"),
106e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                             MOBILE_IFACE);
107e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"),
108e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                             MOBILE_IFACE);
109e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti
110e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"),
111e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                           parse("192.168.0.1"),
112e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                           WIFI_IFACE);
113e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti    private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"),
114e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                           parse("fd00::"),
115e16713597661c326d2bb6586a8b13e27520c4227Lorenzo Colitti                                                                           WIFI_IFACE);
116fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
117fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private INetworkManagementService mNetManager;
118fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private INetworkStatsService mStatsService;
119fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private INetworkPolicyManager mPolicyService;
120fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
121fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private BroadcastInterceptingContext mServiceContext;
122cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    private WrappedConnectivityService mService;
123d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private ConnectivityManager mCm;
124d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private MockNetworkAgent mWiFiNetworkAgent;
125d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private MockNetworkAgent mCellNetworkAgent;
126d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
127d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private class MockContext extends BroadcastInterceptingContext {
128d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        MockContext(Context base) {
129d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            super(base);
130d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
131d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
132d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        @Override
133d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
134d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            // PendingIntents sent by the AlarmManager are not intercepted by
135d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            // BroadcastInterceptingContext so we must really register the receiver.
136d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            // This shouldn't effect the real NetworkMonitors as the action contains a random token.
137d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            if (filter.getAction(0).startsWith("android.net.netmon.lingerExpired")) {
138d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                return getBaseContext().registerReceiver(receiver, filter);
139d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            } else {
140d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                return super.registerReceiver(receiver, filter);
141d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            }
142d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
143d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
144d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        @Override
145d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public Object getSystemService (String name) {
146d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            if (name == Context.CONNECTIVITY_SERVICE) return mCm;
147d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            return super.getSystemService(name);
148d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
149d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
150d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
151d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private class MockNetworkAgent {
152cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final WrappedNetworkMonitor mWrappedNetworkMonitor;
153d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        private final NetworkInfo mNetworkInfo;
154d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        private final NetworkCapabilities mNetworkCapabilities;
155d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        private final Thread mThread;
156e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        private final ConditionVariable mDisconnected = new ConditionVariable();
1573d911469a190437fe936103e861bfa171841fbd6Paul Jensen        private int mScore;
158d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        private NetworkAgent mNetworkAgent;
159d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
160d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        MockNetworkAgent(int transport) {
161d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            final int type = transportToLegacyType(transport);
162d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            final String typeName = ConnectivityManager.getNetworkTypeName(type);
163d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
164d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mNetworkCapabilities = new NetworkCapabilities();
165d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mNetworkCapabilities.addTransportType(transport);
166d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            switch (transport) {
167d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                case TRANSPORT_WIFI:
1683d911469a190437fe936103e861bfa171841fbd6Paul Jensen                    mScore = 60;
169d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    break;
170d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                case TRANSPORT_CELLULAR:
1713d911469a190437fe936103e861bfa171841fbd6Paul Jensen                    mScore = 50;
172d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    break;
173d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                default:
174d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    throw new UnsupportedOperationException("unimplemented network type");
175d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            }
176d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            final ConditionVariable initComplete = new ConditionVariable();
177cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            final ConditionVariable networkMonitorAvailable = mService.getNetworkMonitorCreatedCV();
178d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mThread = new Thread() {
179d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                public void run() {
180d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    Looper.prepare();
181d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext,
182d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                            "Mock" + typeName, mNetworkInfo, mNetworkCapabilities,
1833d911469a190437fe936103e861bfa171841fbd6Paul Jensen                            new LinkProperties(), mScore, new NetworkMisc()) {
184e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                        public void unwanted() { mDisconnected.open(); }
185d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    };
186d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    initComplete.open();
187d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    Looper.loop();
188d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                }
189d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            };
190d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mThread.start();
1913d911469a190437fe936103e861bfa171841fbd6Paul Jensen            waitFor(initComplete);
192cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            waitFor(networkMonitorAvailable);
193cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
1943d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
1953d911469a190437fe936103e861bfa171841fbd6Paul Jensen
1963d911469a190437fe936103e861bfa171841fbd6Paul Jensen        public void adjustScore(int change) {
1973d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mScore += change;
1983d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mNetworkAgent.sendNetworkScore(mScore);
199d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
200d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
20185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        public void addCapability(int capability) {
20285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            mNetworkCapabilities.addCapability(capability);
20385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
20485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        }
20585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen
206e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        public void connectWithoutInternet() {
207e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen            mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
208e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
209e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        }
210e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
211d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        /**
212e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen         * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET.
213d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen         * @param validated Indicate if network should pretend to be validated.
214d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen         */
215d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public void connect(boolean validated) {
216d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            assertEquals(mNetworkInfo.getDetailedState(), DetailedState.IDLE);
217d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET));
218d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
219d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            NetworkCallback callback = null;
220d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            final ConditionVariable validatedCv = new ConditionVariable();
221d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            if (validated) {
222cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                mWrappedNetworkMonitor.gen204ProbeResult = 204;
223d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                NetworkRequest request = new NetworkRequest.Builder()
224d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                        .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
225d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                        .build();
226d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                callback = new NetworkCallback() {
227d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    public void onCapabilitiesChanged(Network network,
228d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                            NetworkCapabilities networkCapabilities) {
229cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                        if (network.equals(getNetwork()) &&
230cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                            networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
231d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                            validatedCv.open();
232d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                        }
233d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    }
234d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                };
235cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                mCm.registerNetworkCallback(request, callback);
236d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            }
237cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            addCapability(NET_CAPABILITY_INTERNET);
238d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
239e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen            connectWithoutInternet();
240d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
241d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            if (validated) {
242d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                // Wait for network to validate.
2433d911469a190437fe936103e861bfa171841fbd6Paul Jensen                waitFor(validatedCv);
244cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                mWrappedNetworkMonitor.gen204ProbeResult = 500;
245d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            }
246d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
247d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            if (callback != null) mCm.unregisterNetworkCallback(callback);
248d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
249d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
250cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public void connectWithCaptivePortal() {
251cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mWrappedNetworkMonitor.gen204ProbeResult = 200;
252cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            connect(false);
253cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            waitFor(new Criteria() { public boolean get() {
254cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork());
255cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} });
256cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mWrappedNetworkMonitor.gen204ProbeResult = 500;
257cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
258cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
259d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public void disconnect() {
260d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
261d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
262d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
263d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
264d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public Network getNetwork() {
265d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            return new Network(mNetworkAgent.netId);
266d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
267e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
268e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        public ConditionVariable getDisconnectedCV() {
269e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen            return mDisconnected;
270e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        }
271cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
272cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public WrappedNetworkMonitor getWrappedNetworkMonitor() {
273cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            return mWrappedNetworkMonitor;
274cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
275d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
276d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
277348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    private static class MockNetworkFactory extends NetworkFactory {
278cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
279cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
280cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final ConditionVariable mNetworkRequestedCV = new ConditionVariable();
281cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final ConditionVariable mNetworkReleasedCV = new ConditionVariable();
282cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
283348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
284348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        public MockNetworkFactory(Looper looper, Context context, String logTag,
285348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt                NetworkCapabilities filter) {
286348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            super(looper, context, logTag, filter);
287348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
288348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
289348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        public int getMyRequestCount() {
290348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            return getRequestCount();
291348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
292348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
293348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        protected void startNetwork() {
294348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            mNetworkStarted.set(true);
2950a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkStartedCV.open();
296348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
297348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
298348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        protected void stopNetwork() {
299348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            mNetworkStarted.set(false);
3000a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkStoppedCV.open();
301348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
302348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
303348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        public boolean getMyStartRequested() {
304348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            return mNetworkStarted.get();
305348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
3060a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3070a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public ConditionVariable getNetworkStartedCV() {
3080a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkStartedCV.close();
3090a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            return mNetworkStartedCV;
3100a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3110a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3120a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public ConditionVariable getNetworkStoppedCV() {
3130a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkStoppedCV.close();
3140a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            return mNetworkStoppedCV;
3150a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3160a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3170a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
3180a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            super.needNetworkFor(networkRequest, score);
3190a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkRequestedCV.open();
3200a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3210a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3220a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        protected void releaseNetworkFor(NetworkRequest networkRequest) {
3230a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            super.releaseNetworkFor(networkRequest);
3240a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkReleasedCV.open();
3250a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3260a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3270a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public ConditionVariable getNetworkRequestedCV() {
3280a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkRequestedCV.close();
3290a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            return mNetworkRequestedCV;
3300a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3310a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3320a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public ConditionVariable getNetworkReleasedCV() {
3330a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            mNetworkReleasedCV.close();
3340a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            return mNetworkReleasedCV;
3350a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
3360a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
3370a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public void waitForNetworkRequests(final int count) {
3380a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            waitFor(new Criteria() { public boolean get() { return count == getRequestCount(); } });
3390a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
340348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    }
341348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
342cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    // NetworkMonitor implementation allowing overriding of Internet connectivity probe result.
343cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    private class WrappedNetworkMonitor extends NetworkMonitor {
344cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // HTTP response code fed back to NetworkMonitor for Internet connectivity probe.
345cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public int gen204ProbeResult = 500;
346cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
347cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public WrappedNetworkMonitor(Context context, Handler handler,
348cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) {
349cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            super(context, handler, networkAgentInfo, defaultRequest);
350cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
351cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
352cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        @Override
353cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        protected int isCaptivePortal() {
354cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            return gen204ProbeResult;
355cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
356cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    }
357cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
358d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private class WrappedConnectivityService extends ConnectivityService {
359cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private final ConditionVariable mNetworkMonitorCreated = new ConditionVariable();
360cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
361cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
362d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        public WrappedConnectivityService(Context context, INetworkManagementService netManager,
363d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                INetworkStatsService statsService, INetworkPolicyManager policyManager) {
364d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            super(context, netManager, statsService, policyManager);
365d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
366d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
367d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        @Override
368d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        protected int getDefaultTcpRwnd() {
369d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            // Prevent wrapped ConnectivityService from trying to write to SystemProperties.
370d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            return 0;
371d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
37267b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen
37367b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen        @Override
37467b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen        protected int reserveNetId() {
37567b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen            while (true) {
37667b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                final int netId = super.reserveNetId();
37767b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen
37867b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks
37967b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                // can have odd side-effects, like network validations succeeding.
38067b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks();
38167b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                boolean overlaps = false;
38267b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                for (Network network : networks) {
38367b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                    if (netId == network.netId) {
38467b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                        overlaps = true;
38567b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                        break;
38667b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                    }
38767b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                }
38867b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                if (overlaps) continue;
38967b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen
39067b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen                return netId;
39167b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen            }
39267b0b0756b47c0ef0c50ce42f140d36c200f7984Paul Jensen        }
393cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
394cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        @Override
395cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
396cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                NetworkAgentInfo nai, NetworkRequest defaultRequest) {
397cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(context, handler, nai,
398cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                    defaultRequest);
399cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mLastCreatedNetworkMonitor = monitor;
400cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mNetworkMonitorCreated.open();
401cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            return monitor;
402cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
403cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
404cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
405cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            return mLastCreatedNetworkMonitor;
406cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
407cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
408cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        public ConditionVariable getNetworkMonitorCreatedCV() {
409cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            mNetworkMonitorCreated.close();
410cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            return mNetworkMonitorCreated;
411cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        }
412d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
413d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
4140a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen    private interface Criteria {
4150a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        public boolean get();
4160a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen    }
4170a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
4183d911469a190437fe936103e861bfa171841fbd6Paul Jensen    /**
4193d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * Wait up to 500ms for {@code criteria.get()} to become true, polling.
4203d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * Fails if 500ms goes by before {@code criteria.get()} to become true.
4213d911469a190437fe936103e861bfa171841fbd6Paul Jensen     */
4220a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen    static private void waitFor(Criteria criteria) {
4230a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        int delays = 0;
4240a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        while (!criteria.get()) {
4250a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            try {
4260a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen                Thread.sleep(100);
4270a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            } catch (InterruptedException e) {
4280a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            }
4290a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen            if (++delays == 5) fail();
4300a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        }
4310a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen    }
4320a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen
4333d911469a190437fe936103e861bfa171841fbd6Paul Jensen    /**
4343d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * Wait up to 500ms for {@code conditonVariable} to open.
4353d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * Fails if 500ms goes by before {@code conditionVariable} opens.
4363d911469a190437fe936103e861bfa171841fbd6Paul Jensen     */
4373d911469a190437fe936103e861bfa171841fbd6Paul Jensen    static private void waitFor(ConditionVariable conditionVariable) {
4383d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertTrue(conditionVariable.block(500));
4393d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
4403d911469a190437fe936103e861bfa171841fbd6Paul Jensen
4413d911469a190437fe936103e861bfa171841fbd6Paul Jensen    /**
4423d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * This should only be used to verify that nothing happens, in other words that no unexpected
4433d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * changes occur.  It should never be used to wait for a specific positive signal to occur.
4443d911469a190437fe936103e861bfa171841fbd6Paul Jensen     */
4453d911469a190437fe936103e861bfa171841fbd6Paul Jensen    private void shortSleep() {
4463d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // TODO: Instead of sleeping, instead wait for all message loops to idle.
4473d911469a190437fe936103e861bfa171841fbd6Paul Jensen        try {
4483d911469a190437fe936103e861bfa171841fbd6Paul Jensen            Thread.sleep(500);
4493d911469a190437fe936103e861bfa171841fbd6Paul Jensen        } catch (InterruptedException e) {
4503d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
4513d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
4523d911469a190437fe936103e861bfa171841fbd6Paul Jensen
453d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    @Override
454d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    public void setUp() throws Exception {
455d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        super.setUp();
456d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
457d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mServiceContext = new MockContext(getContext());
458d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
459d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mNetManager = mock(INetworkManagementService.class);
460d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mStatsService = mock(INetworkStatsService.class);
461d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mPolicyService = mock(INetworkPolicyManager.class);
462d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
463d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mService = new WrappedConnectivityService(
464d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                mServiceContext, mNetManager, mStatsService, mPolicyService);
465d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mService.systemReady();
466ffc42b0b7be29ee4118e0515d5ab024927bcb8caLorenzo Colitti        mCm = new ConnectivityManager(getContext(), mService);
467d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
468d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
469d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private int transportToLegacyType(int transport) {
470d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        switch (transport) {
471d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            case TRANSPORT_WIFI:
472d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                return TYPE_WIFI;
473d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            case TRANSPORT_CELLULAR:
474d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                return TYPE_MOBILE;
475d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            default:
476d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                throw new IllegalStateException("Unknown transport" + transport);
477d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
478d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
479d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
480d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private void verifyActiveNetwork(int transport) {
481d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getActiveNetworkInfo()
482d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNotNull(mCm.getActiveNetworkInfo());
483d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType());
484d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getActiveNetwork()
485d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNotNull(mCm.getActiveNetwork());
486d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        switch (transport) {
487d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            case TRANSPORT_WIFI:
488d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
489d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                break;
490d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            case TRANSPORT_CELLULAR:
491d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
492d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                break;
493d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            default:
494d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                throw new IllegalStateException("Unknown transport" + transport);
495d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
496d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getNetworkInfo(Network)
497d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
498d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
499d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getNetworkCapabilities(Network)
500d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
501d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
502d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
503d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
504d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private void verifyNoNetwork() {
505d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getActiveNetworkInfo()
506d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNull(mCm.getActiveNetworkInfo());
507d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getActiveNetwork()
508d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNull(mCm.getActiveNetwork());
509d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test getAllNetworks()
510d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(0, mCm.getAllNetworks().length);
511d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
512d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
513d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    /**
514d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen     * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION
515d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen     * broadcasts are received.
516d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen     */
517d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    private ConditionVariable waitForConnectivityBroadcasts(final int count) {
518d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        final ConditionVariable cv = new ConditionVariable();
519d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mServiceContext.registerReceiver(new BroadcastReceiver() {
520d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    private int remaining = count;
521d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    public void onReceive(Context context, Intent intent) {
522d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                        if (--remaining == 0) {
523d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                            cv.open();
524d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                            mServiceContext.unregisterReceiver(this);
525d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                        }
526d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                    }
527d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                }, new IntentFilter(CONNECTIVITY_ACTION));
528d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        return cv;
529d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
530d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
531d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    @LargeTest
532d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    public void testLingering() throws Exception {
533d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Decrease linger timeout to the minimum allowed by AlarmManagerService.
534d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        NetworkMonitor.SetDefaultLingerTime(5000);
535d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyNoNetwork();
536d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
537d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
538d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNull(mCm.getActiveNetworkInfo());
539d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertNull(mCm.getActiveNetwork());
540d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up validated cellular.
541d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
542d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.connect(true);
5433d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
544d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
545d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(2, mCm.getAllNetworks().length);
546d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
547d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
548d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) ||
549d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork()));
550d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up validated WiFi.
551d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(2);
552d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.connect(true);
5533d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
554d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
555d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(2, mCm.getAllNetworks().length);
556d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
557d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork()));
558d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
559d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen                mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
560d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test cellular linger timeout.
561d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        try {
562d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen            Thread.sleep(6000);
5630a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        } catch (InterruptedException e) {
564d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        }
565d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
566d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(1, mCm.getAllNetworks().length);
567d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
568d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test WiFi disconnect.
569d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(1);
570d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.disconnect();
5713d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
572d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyNoNetwork();
573d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
574d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
575d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    @LargeTest
576d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
577d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up unvalidated WiFi
578d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
579d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
580d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.connect(false);
5813d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
582d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
583d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up unvalidated cellular
584d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
585d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.connect(false);
5863d911469a190437fe936103e861bfa171841fbd6Paul Jensen        shortSleep();
587d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
588d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test cellular disconnect.
589d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.disconnect();
5903d911469a190437fe936103e861bfa171841fbd6Paul Jensen        shortSleep();
591d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
592d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up validated cellular
593d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
594d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(2);
595d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.connect(true);
5963d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
597d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
598d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test cellular disconnect.
599d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(2);
600d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.disconnect();
6013d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
602d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
603d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test WiFi disconnect.
604d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(1);
605d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.disconnect();
6063d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
607d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyNoNetwork();
608d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
609d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen
610d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    @LargeTest
611d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
612d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up unvalidated cellular.
613d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
614d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
615d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.connect(false);
6163d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
617d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
618d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test bringing up unvalidated WiFi.
619d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
620d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(2);
621d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.connect(false);
6223d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
623d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
624d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test WiFi disconnect.
625d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(2);
626d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mWiFiNetworkAgent.disconnect();
6273d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
628d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
629d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        // Test cellular disconnect.
630d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        cv = waitForConnectivityBroadcasts(1);
631d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        mCellNetworkAgent.disconnect();
6323d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
633d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen        verifyNoNetwork();
634d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen    }
635fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
636348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    @LargeTest
637e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testUnlingeringDoesNotValidate() throws Exception {
638cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Test bringing up unvalidated WiFi.
639cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
640e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
641cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.connect(false);
642e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
643cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
644cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
645e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
646cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Test bringing up validated cellular.
647cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
648e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
649cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCellNetworkAgent.connect(true);
650e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
651cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
652cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
653e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
654cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Test cellular disconnect.
655e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
656cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCellNetworkAgent.disconnect();
657e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
658cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
659e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Unlingering a network should not cause it to be marked as validated.
660cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
661e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
662e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
663e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
664e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
6653d911469a190437fe936103e861bfa171841fbd6Paul Jensen    public void testCellularOutscoresWeakWifi() throws Exception {
6663d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test bringing up validated cellular.
6673d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
6683d911469a190437fe936103e861bfa171841fbd6Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
6693d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.connect(true);
6703d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
6713d911469a190437fe936103e861bfa171841fbd6Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
6723d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test bringing up validated WiFi.
6733d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
6743d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(2);
6753d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.connect(true);
6763d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
6773d911469a190437fe936103e861bfa171841fbd6Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
6783d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test WiFi getting really weak.
6793d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(2);
6803d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.adjustScore(-11);
6813d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
6823d911469a190437fe936103e861bfa171841fbd6Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
6833d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test WiFi restoring signal strength.
6843d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(2);
6853d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.adjustScore(11);
6863d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
6873d911469a190437fe936103e861bfa171841fbd6Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
6883d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.disconnect();
6893d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.disconnect();
6903d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
6913d911469a190437fe936103e861bfa171841fbd6Paul Jensen
692e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
693e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testReapingNetwork() throws Exception {
694e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
695e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Expect it to be torn down immediately because it satisfies no requests.
696e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
697e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = mWiFiNetworkAgent.getDisconnectedCV();
698e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.connectWithoutInternet();
699e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
700e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up cellular without NET_CAPABILITY_INTERNET.
701e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Expect it to be torn down immediately because it satisfies no requests.
702e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
703e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = mCellNetworkAgent.getDisconnectedCV();
704e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connectWithoutInternet();
705e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
706e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up validated WiFi.
707e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
708e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(1);
709e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.connect(true);
710e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
711e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
712e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up unvalidated cellular.
713e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Expect it to be torn down because it could never be the highest scoring network
714e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // satisfying the default request even if it validated.
715e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
716e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = mCellNetworkAgent.getDisconnectedCV();
717e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connect(false);
718e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
719e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
720e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = mWiFiNetworkAgent.getDisconnectedCV();
721e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.disconnect();
722e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
723e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
724e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
725e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
726e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testCellularFallback() throws Exception {
727e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up validated cellular.
728e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
729e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
730e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connect(true);
731e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
732e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
733e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up validated WiFi.
734e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
735e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
736e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.connect(true);
737e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
738e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
739e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Reevaluate WiFi (it'll instantly fail DNS).
740e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
741e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
742e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
743e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork());
744e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Should quickly fall back to Cellular.
745e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
746e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
747e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
748e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
749e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Reevaluate cellular (it'll instantly fail DNS).
750e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
751e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
752e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
753e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
754e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Should quickly fall back to WiFi.
755e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
756e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
757e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
758e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
759e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
760e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
761e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.disconnect();
762e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.disconnect();
763e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
764e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
765e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
766e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testWiFiFallback() throws Exception {
767e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up unvalidated WiFi.
768e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
769e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
770e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.connect(false);
771e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
772e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
773e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up validated cellular.
774e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
775e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
776e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connect(true);
777e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
778e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
779e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Reevaluate cellular (it'll instantly fail DNS).
780e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(2);
781e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
782e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
783e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.reportBadNetwork(mCellNetworkAgent.getNetwork());
784e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Should quickly fall back to WiFi.
785e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
786e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
787e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                NET_CAPABILITY_VALIDATED));
788e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
789e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.disconnect();
790e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.disconnect();
791e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
792e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
7933d911469a190437fe936103e861bfa171841fbd6Paul Jensen    enum CallbackState {
7943d911469a190437fe936103e861bfa171841fbd6Paul Jensen        NONE,
7953d911469a190437fe936103e861bfa171841fbd6Paul Jensen        AVAILABLE,
7963d911469a190437fe936103e861bfa171841fbd6Paul Jensen        LOSING,
7973d911469a190437fe936103e861bfa171841fbd6Paul Jensen        LOST
7983d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
7993d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8003d911469a190437fe936103e861bfa171841fbd6Paul Jensen    private class TestNetworkCallback extends NetworkCallback {
8013d911469a190437fe936103e861bfa171841fbd6Paul Jensen        private final ConditionVariable mConditionVariable = new ConditionVariable();
8023d911469a190437fe936103e861bfa171841fbd6Paul Jensen        private CallbackState mLastCallback = CallbackState.NONE;
8033d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8043d911469a190437fe936103e861bfa171841fbd6Paul Jensen        public void onAvailable(Network network) {
8053d911469a190437fe936103e861bfa171841fbd6Paul Jensen            assertEquals(CallbackState.NONE, mLastCallback);
8063d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mLastCallback = CallbackState.AVAILABLE;
8073d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mConditionVariable.open();
8083d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
8093d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8103d911469a190437fe936103e861bfa171841fbd6Paul Jensen        public void onLosing(Network network, int maxMsToLive) {
8113d911469a190437fe936103e861bfa171841fbd6Paul Jensen            assertEquals(CallbackState.NONE, mLastCallback);
8123d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mLastCallback = CallbackState.LOSING;
8133d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mConditionVariable.open();
8143d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
8153d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8163d911469a190437fe936103e861bfa171841fbd6Paul Jensen        public void onLost(Network network) {
8173d911469a190437fe936103e861bfa171841fbd6Paul Jensen            assertEquals(CallbackState.NONE, mLastCallback);
8183d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mLastCallback = CallbackState.LOST;
8193d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mConditionVariable.open();
8203d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
8213d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8223d911469a190437fe936103e861bfa171841fbd6Paul Jensen        ConditionVariable getConditionVariable() {
8233d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mLastCallback = CallbackState.NONE;
8243d911469a190437fe936103e861bfa171841fbd6Paul Jensen            mConditionVariable.close();
8253d911469a190437fe936103e861bfa171841fbd6Paul Jensen            return mConditionVariable;
8263d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
8273d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8283d911469a190437fe936103e861bfa171841fbd6Paul Jensen        CallbackState getLastCallback() {
8293d911469a190437fe936103e861bfa171841fbd6Paul Jensen            return mLastCallback;
8303d911469a190437fe936103e861bfa171841fbd6Paul Jensen        }
8313d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
8323d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8333d911469a190437fe936103e861bfa171841fbd6Paul Jensen    @LargeTest
8343d911469a190437fe936103e861bfa171841fbd6Paul Jensen    public void testStateChangeNetworkCallbacks() throws Exception {
8353d911469a190437fe936103e861bfa171841fbd6Paul Jensen        final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
8363d911469a190437fe936103e861bfa171841fbd6Paul Jensen        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
8373d911469a190437fe936103e861bfa171841fbd6Paul Jensen        final NetworkRequest wifiRequest = new NetworkRequest.Builder()
8383d911469a190437fe936103e861bfa171841fbd6Paul Jensen                .addTransportType(TRANSPORT_WIFI).build();
8393d911469a190437fe936103e861bfa171841fbd6Paul Jensen        final NetworkRequest cellRequest = new NetworkRequest.Builder()
8403d911469a190437fe936103e861bfa171841fbd6Paul Jensen                .addTransportType(TRANSPORT_CELLULAR).build();
8413d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
8423d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
8433d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8443d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test unvalidated networks
8453d911469a190437fe936103e861bfa171841fbd6Paul Jensen        ConditionVariable cellCv = cellNetworkCallback.getConditionVariable();
8463d911469a190437fe936103e861bfa171841fbd6Paul Jensen        ConditionVariable wifiCv = wifiNetworkCallback.getConditionVariable();
8473d911469a190437fe936103e861bfa171841fbd6Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
8483d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
8493d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.connect(false);
8503d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cellCv);
8513d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
8523d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
8533d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
8543d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
8553d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8563d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
8573d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
8583d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // This should not trigger spurious onAvailable() callbacks, b/21762680.
8593d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.adjustScore(-1);
8603d911469a190437fe936103e861bfa171841fbd6Paul Jensen        shortSleep();
8613d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
8623d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
8633d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
8643d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8653d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
8663d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
8673d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(2);
8683d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
8693d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.connect(false);
8703d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(wifiCv);
8713d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
8723d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
8733d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
8743d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
8753d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8763d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
8773d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
8783d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(2);
8793d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.disconnect();
8803d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(wifiCv);
8813d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
8823d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
8833d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
8843d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8853d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
8863d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
8873d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cv = waitForConnectivityBroadcasts(1);
8883d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.disconnect();
8893d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cellCv);
8903d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
8913d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
8923d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
8933d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8943d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // Test validated networks
8953d911469a190437fe936103e861bfa171841fbd6Paul Jensen
8963d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
8973d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
8983d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
8993d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.connect(true);
9003d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cellCv);
9013d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
9023d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
9033d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
9043d911469a190437fe936103e861bfa171841fbd6Paul Jensen
9053d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
9063d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
9073d911469a190437fe936103e861bfa171841fbd6Paul Jensen        // This should not trigger spurious onAvailable() callbacks, b/21762680.
9083d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.adjustScore(-1);
9093d911469a190437fe936103e861bfa171841fbd6Paul Jensen        shortSleep();
9103d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
9113d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
9123d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
9133d911469a190437fe936103e861bfa171841fbd6Paul Jensen
9143d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
9153d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
9163d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
9173d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.connect(true);
9183d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(wifiCv);
9193d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
9203d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cellCv);
9213d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.LOSING, cellNetworkCallback.getLastCallback());
9223d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
9233d911469a190437fe936103e861bfa171841fbd6Paul Jensen
9243d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
9253d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
9263d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mWiFiNetworkAgent.disconnect();
9273d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(wifiCv);
9283d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
9293d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
9303d911469a190437fe936103e861bfa171841fbd6Paul Jensen
9313d911469a190437fe936103e861bfa171841fbd6Paul Jensen        cellCv = cellNetworkCallback.getConditionVariable();
9323d911469a190437fe936103e861bfa171841fbd6Paul Jensen        wifiCv = wifiNetworkCallback.getConditionVariable();
9333d911469a190437fe936103e861bfa171841fbd6Paul Jensen        mCellNetworkAgent.disconnect();
9343d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cellCv);
9353d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
9363d911469a190437fe936103e861bfa171841fbd6Paul Jensen        assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
9373d911469a190437fe936103e861bfa171841fbd6Paul Jensen    }
9383d911469a190437fe936103e861bfa171841fbd6Paul Jensen
93985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    private void tryNetworkFactoryRequests(int capability) throws Exception {
940487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        // Verify NOT_RESTRICTED is set appropriately
941487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
942487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen                .build().networkCapabilities;
943487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
944487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen                capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
945487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen                capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
946aae613d96134245af7c55976731a49fa59e77470Paul Jensen                capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
947487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen            assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
948487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        } else {
949487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen            assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
950487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        }
951487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen
952348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        NetworkCapabilities filter = new NetworkCapabilities();
95385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        filter.addCapability(capability);
954348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
955348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        handlerThread.start();
9560a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
957348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt                mServiceContext, "testFactory", filter);
958348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        testFactory.setScoreFilter(40);
9590a2823e539abeb037d3acb01b5d5eed7c85f4ed7Paul Jensen        ConditionVariable cv = testFactory.getNetworkStartedCV();
960348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        testFactory.register();
96185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        int expectedRequestCount = 1;
96285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        NetworkCallback networkCallback = null;
96385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // For non-INTERNET capabilities we cannot rely on the default request being present, so
96485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // add one.
96585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        if (capability != NET_CAPABILITY_INTERNET) {
96685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            testFactory.waitForNetworkRequests(1);
96785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            assertFalse(testFactory.getMyStartRequested());
96885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
96985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            networkCallback = new NetworkCallback();
97085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            mCm.requestNetwork(request, networkCallback);
97185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            expectedRequestCount++;
97285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        }
9733d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
97485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
97585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertTrue(testFactory.getMyStartRequested());
976348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
97785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Now bring in a higher scored network.
978348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
97985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Rather than create a validated network which complicates things by registering it's
98085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // own NetworkRequest during startup, just bump up the score to cancel out the
98185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // unvalidated penalty.
98285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        testAgent.adjustScore(40);
98385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        cv = testFactory.getNetworkStoppedCV();
98485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        testAgent.connect(false);
98585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        testAgent.addCapability(capability);
9863d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
98785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
98885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertFalse(testFactory.getMyStartRequested());
989348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
99085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Bring in a bunch of requests.
991348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        ConnectivityManager.NetworkCallback[] networkCallbacks =
992348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt                new ConnectivityManager.NetworkCallback[10];
993348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        for (int i = 0; i< networkCallbacks.length; i++) {
994348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            networkCallbacks[i] = new ConnectivityManager.NetworkCallback();
995348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            NetworkRequest.Builder builder = new NetworkRequest.Builder();
99685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen            builder.addCapability(capability);
997348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            mCm.requestNetwork(builder.build(), networkCallbacks[i]);
998348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
99985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        testFactory.waitForNetworkRequests(10 + expectedRequestCount);
100085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertFalse(testFactory.getMyStartRequested());
1001348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
100285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Remove the requests.
1003348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        for (int i = 0; i < networkCallbacks.length; i++) {
1004348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            mCm.unregisterNetworkCallback(networkCallbacks[i]);
1005348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        }
100685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        testFactory.waitForNetworkRequests(expectedRequestCount);
100785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertFalse(testFactory.getMyStartRequested());
1008348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
100985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Drop the higher scored network.
101085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        cv = testFactory.getNetworkStartedCV();
1011348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        testAgent.disconnect();
10123d911469a190437fe936103e861bfa171841fbd6Paul Jensen        waitFor(cv);
101385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
101485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        assertTrue(testFactory.getMyStartRequested());
1015348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
1016348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        testFactory.unregister();
101785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
1018348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        handlerThread.quit();
1019348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    }
1020348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
1021bb2e0e98160f099261876794518d4db62e309aecPaul Jensen    @LargeTest
102285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    public void testNetworkFactoryRequests() throws Exception {
102385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
102485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
102585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_DUN);
102685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_FOTA);
102785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_IMS);
102885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_CBS);
102985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P);
103085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_IA);
103185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_RCS);
103285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_XCAP);
103385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_EIMS);
103485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED);
103585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET);
103685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED);
103785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN);
103885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
103985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    }
104085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen
104185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    @LargeTest
1042bb2e0e98160f099261876794518d4db62e309aecPaul Jensen    public void testNoMutableNetworkRequests() throws Exception {
1043bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
1044bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        NetworkRequest.Builder builder = new NetworkRequest.Builder();
104585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        builder.addCapability(NET_CAPABILITY_VALIDATED);
1046bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        try {
1047bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            mCm.requestNetwork(builder.build(), new NetworkCallback());
1048bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            fail();
1049bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        } catch (IllegalArgumentException expected) {}
1050bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        try {
1051bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            mCm.requestNetwork(builder.build(), pendingIntent);
1052bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            fail();
1053bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        } catch (IllegalArgumentException expected) {}
1054bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        builder = new NetworkRequest.Builder();
105585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        builder.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
1056bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        try {
1057bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            mCm.requestNetwork(builder.build(), new NetworkCallback());
1058bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            fail();
1059bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        } catch (IllegalArgumentException expected) {}
1060bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        try {
1061bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            mCm.requestNetwork(builder.build(), pendingIntent);
1062bb2e0e98160f099261876794518d4db62e309aecPaul Jensen            fail();
1063bb2e0e98160f099261876794518d4db62e309aecPaul Jensen        } catch (IllegalArgumentException expected) {}
1064bb2e0e98160f099261876794518d4db62e309aecPaul Jensen    }
1065348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
1066e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
1067e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testMMSonWiFi() throws Exception {
1068e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up cellular without MMS NetworkRequest gets reaped
1069e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1070e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1071e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
1072e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connectWithoutInternet();
1073e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1074e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(new Criteria() {
1075e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen                public boolean get() { return mCm.getAllNetworks().length == 0; } });
1076e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyNoNetwork();
1077e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up validated WiFi.
1078e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1079e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = waitForConnectivityBroadcasts(1);
1080e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mWiFiNetworkAgent.connect(true);
1081e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1082e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
1083e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Register MMS NetworkRequest
1084e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        NetworkRequest.Builder builder = new NetworkRequest.Builder();
1085e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1086e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        final TestNetworkCallback networkCallback = new TestNetworkCallback();
1087e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.requestNetwork(builder.build(), networkCallback);
1088e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up unvalidated cellular with MMS
1089e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1090e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1091e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = networkCallback.getConditionVariable();
1092e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connectWithoutInternet();
1093e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1094e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback());
1095e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
1096e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test releasing NetworkRequest disconnects cellular with MMS
1097e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = mCellNetworkAgent.getDisconnectedCV();
1098e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.unregisterNetworkCallback(networkCallback);
1099e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1100e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_WIFI);
1101e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
1102e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
1103e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    @LargeTest
1104e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    public void testMMSonCell() throws Exception {
1105e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up cellular without MMS
1106e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1107e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        ConditionVariable cv = waitForConnectivityBroadcasts(1);
1108e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCellNetworkAgent.connect(false);
1109e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1110e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
1111e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Register MMS NetworkRequest
1112e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        NetworkRequest.Builder builder = new NetworkRequest.Builder();
1113e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1114e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        final TestNetworkCallback networkCallback = new TestNetworkCallback();
1115e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.requestNetwork(builder.build(), networkCallback);
1116e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test bringing up MMS cellular network
1117e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = networkCallback.getConditionVariable();
1118e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
1119e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
1120e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mmsNetworkAgent.connectWithoutInternet();
1121e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1122e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback());
1123e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
1124e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
1125e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        cv = mmsNetworkAgent.getDisconnectedCV();
1126e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        mCm.unregisterNetworkCallback(networkCallback);
1127e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        waitFor(cv);
1128e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        verifyActiveNetwork(TRANSPORT_CELLULAR);
1129e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen    }
1130e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen
1131cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    @LargeTest
1132cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    public void testCaptivePortal() {
1133cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
1134cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
1135cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
1136cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
1137cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1138cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        final TestNetworkCallback validatedCallback = new TestNetworkCallback();
1139cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        final NetworkRequest validatedRequest = new NetworkRequest.Builder()
1140cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen                .addCapability(NET_CAPABILITY_VALIDATED).build();
1141cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCm.registerNetworkCallback(validatedRequest, validatedCallback);
1142cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        ConditionVariable validatedCv = validatedCallback.getConditionVariable();
1143cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1144cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Bring up a network with a captive portal.
1145cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1146cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        ConditionVariable cv = captivePortalCallback.getConditionVariable();
1147cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1148cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.connectWithCaptivePortal();
1149cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(cv);
1150cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback());
1151cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1152cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Take down network.
1153cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect onLost callback.
1154cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        cv = captivePortalCallback.getConditionVariable();
1155cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.disconnect();
1156cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(cv);
1157cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback());
1158cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1159cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Bring up a network with a captive portal.
1160cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
1161cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        cv = captivePortalCallback.getConditionVariable();
1162cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
1163cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.connectWithCaptivePortal();
1164cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(cv);
1165cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback());
1166cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1167cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Make captive portal disappear then revalidate.
1168cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
1169cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        cv = captivePortalCallback.getConditionVariable();
1170cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
1171cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
1172cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(cv);
1173cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback());
1174cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1175cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
1176cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(validatedCv);
1177cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.AVAILABLE, validatedCallback.getLastCallback());
1178cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
1179cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Break network connectivity.
1180cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        // Expect NET_CAPABILITY_VALIDATED onLost callback.
1181cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        validatedCv = validatedCallback.getConditionVariable();
1182cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
1183cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
1184cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        waitFor(validatedCv);
1185cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen        assertEquals(CallbackState.LOST, validatedCallback.getLastCallback());
1186cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen    }
1187cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen
11886831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    @Override
11896831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    public void tearDown() throws Exception {
11906831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        super.tearDown();
11916831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    }
11926831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
11936831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    public void testMobileConnectedAddedRoutes() throws Exception {
11946831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        Future<?> nextConnBroadcast;
11956831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
11966831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // bring up mobile network
11976831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
11986831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.setInterfaceName(MOBILE_IFACE);
11996831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.addRoute(MOBILE_ROUTE_V4);
12006831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.addRoute(MOBILE_ROUTE_V6);
12016831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.doReturnDefaults();
12026831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
1203d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen//        cv = waitForConnectivityBroadcasts(1);
12046831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
12053d911469a190437fe936103e861bfa171841fbd6Paul Jensen//        waitFor(cv);
12066831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12076831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // verify that both routes were added
12086831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        int mobileNetId = mMobile.tracker.getNetwork().netId;
12096831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
12106831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
12116831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    }
12126831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12136831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    public void testMobileWifiHandoff() throws Exception {
12146831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        Future<?> nextConnBroadcast;
12156831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12166831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // bring up mobile network
12176831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
12186831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.setInterfaceName(MOBILE_IFACE);
12196831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.addRoute(MOBILE_ROUTE_V4);
12206831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.addRoute(MOBILE_ROUTE_V6);
12216831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.doReturnDefaults();
12226831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
1223d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen//        cv = waitForConnectivityBroadcasts(1);
12246831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
12253d911469a190437fe936103e861bfa171841fbd6Paul Jensen//        waitFor(cv);
12266831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12276831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        reset(mNetManager);
12286831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12296831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // now bring up wifi network
12306831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null);
12316831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mWifi.link.setInterfaceName(WIFI_IFACE);
12326831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mWifi.link.addRoute(WIFI_ROUTE_V4);
12336831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mWifi.link.addRoute(WIFI_ROUTE_V6);
12346831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mWifi.doReturnDefaults();
12356831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12366831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // expect that mobile will be torn down
12376831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        doReturn(true).when(mMobile.tracker).teardown();
12386831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
1239d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen//        cv = waitForConnectivityBroadcasts(1);
12406831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
12413d911469a190437fe936103e861bfa171841fbd6Paul Jensen//        waitFor(cv);
12426831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12436831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // verify that wifi routes added, and teardown requested
12446831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        int wifiNetId = mWifi.tracker.getNetwork().netId;
12456831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4));
12466831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6));
12476831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mMobile.tracker).teardown();
12486831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12496831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        int mobileNetId = mMobile.tracker.getNetwork().netId;
12506831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12516831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        reset(mNetManager, mMobile.tracker);
12526831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12536831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        // tear down mobile network, as requested
12546831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null);
12556831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.link.clear();
12566831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mMobile.doReturnDefaults();
12576831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
1258d7b6ca91e9ecac15949a4484d560cfab5833a431Paul Jensen//        cv = waitForConnectivityBroadcasts(1);
12596831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
12603d911469a190437fe936103e861bfa171841fbd6Paul Jensen//        waitFor(cv);
12616831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12626831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
12636831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//        verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
12646831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//
12656831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt//    }
1266fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
1267fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static InetAddress parse(String addr) {
1268fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        return InetAddress.parseNumericAddress(addr);
1269fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    }
12706831f1d80f9a5ad2400bd186fb6179e0e511be05Robert Greenwalt
1271fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey}
1272