Fixed file descriptor leak in telephony unit tests
[android/platform/frameworks/opt/telephony.git] / tests / telephonytests / src / com / android / internal / telephony / mocks / ConnectivityServiceMock.java
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.internal.telephony.mocks;
18
19 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
20 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
21
22 import android.annotation.Nullable;
23 import android.app.PendingIntent;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.net.ConnectivityManager;
27 import android.net.IConnectivityManager;
28 import android.net.LinkProperties;
29 import android.net.Network;
30 import android.net.NetworkCapabilities;
31 import android.net.NetworkInfo;
32 import android.net.NetworkMisc;
33 import android.net.NetworkQuotaInfo;
34 import android.net.NetworkRequest;
35 import android.net.NetworkState;
36 import android.net.ProxyInfo;
37 import android.os.Binder;
38 import android.os.Bundle;
39 import android.os.Handler;
40 import android.os.HandlerThread;
41 import android.os.IBinder;
42 import android.os.Looper;
43 import android.os.Message;
44 import android.os.Messenger;
45 import android.os.ParcelFileDescriptor;
46 import android.os.RemoteException;
47 import android.os.ResultReceiver;
48 import android.util.Slog;
49
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.internal.net.LegacyVpnInfo;
52 import com.android.internal.net.VpnConfig;
53 import com.android.internal.net.VpnInfo;
54 import com.android.internal.net.VpnProfile;
55 import com.android.internal.util.AsyncChannel;
56 import com.android.server.connectivity.NetworkAgentInfo;
57 import com.android.server.connectivity.NetworkMonitor;
58
59 import java.io.FileDescriptor;
60 import java.io.PrintWriter;
61 import java.util.HashMap;
62
63 /**
64  * @hide
65  */
66 public class ConnectivityServiceMock extends IConnectivityManager.Stub
67         implements PendingIntent.OnFinished {
68     private static final String TAG = "ConnectivityServiceMock";
69     private static final boolean DBG = true;
70     private static final boolean VDBG = true;
71
72     /**
73      * used internally when registering NetworkFactories
74      * obj = NetworkFactoryInfo
75      */
76     private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
77
78     /**
79      * used internally when registering NetworkAgents
80      * obj = Messenger
81      */
82     private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
83
84     /**
85      * used to add a network request
86      * includes a NetworkRequestInfo
87      */
88     private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
89
90     /**
91      * used to add a network listener - no request
92      * includes a NetworkRequestInfo
93      */
94     private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
95
96     /**
97      * used to remove a network request, either a listener or a real request
98      * arg1 = UID of caller
99      * obj  = NetworkRequest
100      */
101     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
102
103     /**
104      * used internally when registering NetworkFactories
105      * obj = Messenger
106      */
107     private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
108
109
110     private final HandlerThread mHandlerThread;
111     /** Handler used for internal events. */
112     final private InternalHandler mHandler;
113     /** Handler used for incoming {@link NetworkStateTracker} events. */
114     final private NetworkStateTrackerHandler mTrackerHandler;
115
116     final private Context mContext;
117
118     public ConnectivityServiceMock(Context context) {
119         if (DBG) log("starting up");
120
121         mContext = context;
122         mHandlerThread = new HandlerThread("ConnectivityServiceMock");
123         mHandlerThread.start();
124         mHandler = new InternalHandler(mHandlerThread.getLooper());
125         mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
126     }
127
128     public void die() {
129         // clean up threads/handlers
130         if (mHandlerThread != null) {
131             mHandlerThread.quit();
132         }
133     }
134
135     private class InternalHandler extends Handler {
136         public InternalHandler(Looper looper) {
137             super(looper);
138         }
139
140         @Override
141         public void handleMessage(Message msg) {
142             switch (msg.what) {
143                 case EVENT_REGISTER_NETWORK_FACTORY: {
144                     handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
145                     break;
146                 }
147                 case EVENT_UNREGISTER_NETWORK_FACTORY: {
148                     handleUnregisterNetworkFactory((Messenger)msg.obj);
149                     break;
150                 }
151                 case EVENT_REGISTER_NETWORK_AGENT: {
152                     handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
153                     break;
154                 }
155                 case EVENT_REGISTER_NETWORK_REQUEST:
156                 case EVENT_REGISTER_NETWORK_LISTENER: {
157                     handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
158                     break;
159                 }
160                 case EVENT_RELEASE_NETWORK_REQUEST: {
161                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
162                     break;
163                 }
164             }
165         }
166     }
167
168     private class NetworkStateTrackerHandler extends Handler {
169         public NetworkStateTrackerHandler(Looper looper) {
170             super(looper);
171         }
172
173         @Override
174         public void handleMessage(Message msg) {
175             NetworkInfo info;
176             switch (msg.what) {
177                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
178                     handleAsyncChannelHalfConnect(msg);
179                     break;
180                 }
181                 case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
182                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
183                     if (nai != null) nai.asyncChannel.disconnect();
184                     break;
185                 }
186                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
187                     handleAsyncChannelDisconnected(msg);
188                     break;
189                 }
190             }
191         }
192     }
193
194     private boolean isRequest(NetworkRequest request) {
195         return mNetworkRequests.get(request).isRequest;
196     }
197
198     private void handleAsyncChannelHalfConnect(Message msg) {
199         AsyncChannel ac = (AsyncChannel) msg.obj;
200         if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
201             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
202                 if (VDBG) log("NetworkFactory connected");
203                 // A network factory has connected.  Send it all current NetworkRequests.
204                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
205                     if (nri.isRequest == false) continue;
206                     //NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
207                     NetworkAgentInfo nai = null;
208                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
209                             (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
210                 }
211             } else {
212                 loge("Error connecting NetworkFactory");
213                 mNetworkFactoryInfos.remove(msg.obj);
214             }
215         } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
216             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
217                 if (VDBG) log("NetworkAgent connected");
218                 // A network agent has requested a connection.  Establish the connection.
219                 mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
220                         sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
221             } else {
222                 loge("Error connecting NetworkAgent");
223                 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
224                 //if (nai != null) {
225                 //    final boolean wasDefault = isDefaultNetwork(nai);
226                 //    synchronized (mNetworkForNetId) {
227                 //        mNetworkForNetId.remove(nai.network.netId);
228                 //        mNetIdInUse.delete(nai.network.netId);
229                 //    }
230                 //    // Just in case.
231                 //    mLegacyTypeTracker.remove(nai, wasDefault);
232                 //}
233             }
234         }
235     }
236
237     private void handleAsyncChannelDisconnected(Message msg) {
238         NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
239         if (nai != null) {
240             if (DBG) {
241                 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
242             }
243             // A network agent has disconnected.
244             // TODO - if we move the logic to the network agent (have them disconnect
245             // because they lost all their requests or because their score isn't good)
246             // then they would disconnect organically, report their new state and then
247             // disconnect the channel.
248             //if (nai.networkInfo.isConnected()) {
249             //    nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
250             //            null, null);
251             //}
252             //final boolean wasDefault = isDefaultNetwork(nai);
253             //if (wasDefault) {
254             //    mDefaultInetConditionPublished = 0;
255             //}
256             //notifyIfacesChanged();
257             // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
258             // by other networks that are already connected. Perhaps that can be done by
259             // sending all CALLBACK_LOST messages (for requests, not listens) at the end
260             // of rematchAllNetworksAndRequests
261             //notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
262             //mKeepaliveTracker.handleStopAllKeepalives(nai,
263             //       ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
264             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
265             mNetworkAgentInfos.remove(msg.replyTo);
266             //updateClat(null, nai.linkProperties, nai);
267             //synchronized (mNetworkForNetId) {
268             //    // Remove the NetworkAgent, but don't mark the netId as
269             //    // available until we've told netd to delete it below.
270             //    mNetworkForNetId.remove(nai.network.netId);
271             //}
272             // Remove all previously satisfied requests.
273             //for (int i = 0; i < nai.networkRequests.size(); i++) {
274             //    NetworkRequest request = nai.networkRequests.valueAt(i);
275             //    NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
276             //    if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
277             //        mNetworkForRequestId.remove(request.requestId);
278             //        sendUpdatedScoreToFactories(request, 0);
279             //    }
280             //}
281             //if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
282             //    removeDataActivityTracking(nai);
283             //    notifyLockdownVpn(nai);
284             //    requestNetworkTransitionWakelock(nai.name());
285             //}
286             //mLegacyTypeTracker.remove(nai, wasDefault);
287             //rematchAllNetworksAndRequests(null, 0);
288             //if (nai.created) {
289             //    // Tell netd to clean up the configuration for this network
290             //    // (routing rules, DNS, etc).
291             //    // This may be slow as it requires a lot of netd shelling out to ip and
292             //    // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
293             //    // after we've rematched networks with requests which should make a potential
294             //    // fallback network the default or requested a new network from the
295             //    // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
296             //    // long time.
297             //    try {
298             //        mNetd.removeNetwork(nai.network.netId);
299             //    } catch (Exception e) {
300             //        loge("Exception removing network: " + e);
301             //    }
302             //}
303             //synchronized (mNetworkForNetId) {
304             //    mNetIdInUse.delete(nai.network.netId);
305             //}
306         } else {
307             NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
308             if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
309         }
310     }
311
312     private void log(String str) {
313         Slog.d(TAG, str);
314     }
315     private void loge(String str) {
316         Slog.e(TAG, str);
317     }
318
319     // NetworkAgentInfo keyed off its connecting messenger
320     // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
321     // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
322     private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
323             new HashMap<Messenger, NetworkAgentInfo>();
324     private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
325             new HashMap<Messenger, NetworkFactoryInfo>();
326     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
327             new HashMap<NetworkRequest, NetworkRequestInfo>();
328
329     private static class NetworkFactoryInfo {
330         public final String name;
331         public final Messenger messenger;
332         public final AsyncChannel asyncChannel;
333
334         public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
335             this.name = name;
336             this.messenger = messenger;
337             this.asyncChannel = asyncChannel;
338         }
339     }
340
341     private class NetworkRequestInfo implements IBinder.DeathRecipient {
342         static final boolean REQUEST = true;
343         static final boolean LISTEN = false;
344
345         final NetworkRequest request;
346         final PendingIntent mPendingIntent;
347         boolean mPendingIntentSent;
348         private final IBinder mBinder;
349         final int mPid;
350         final int mUid;
351         final Messenger messenger;
352         final boolean isRequest;
353
354         NetworkRequestInfo(NetworkRequest r, PendingIntent pi, boolean isRequest) {
355             request = r;
356             mPendingIntent = pi;
357             messenger = null;
358             mBinder = null;
359             mPid = getCallingPid();
360             mUid = getCallingUid();
361             this.isRequest = isRequest;
362         }
363
364         NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, boolean isRequest) {
365             super();
366             messenger = m;
367             request = r;
368             mBinder = binder;
369             mPid = getCallingPid();
370             mUid = getCallingUid();
371             this.isRequest = isRequest;
372             mPendingIntent = null;
373
374             try {
375                 mBinder.linkToDeath(this, 0);
376             } catch (RemoteException e) {
377                 binderDied();
378             }
379         }
380
381         void unlinkDeathRecipient() {
382             if (mBinder != null) {
383                 mBinder.unlinkToDeath(this, 0);
384             }
385         }
386
387         public void binderDied() {
388             log("ConnectivityService NetworkRequestInfo binderDied(" +
389                     request + ", " + mBinder + ")");
390             releaseNetworkRequest(request);
391         }
392
393         public String toString() {
394             return (isRequest ? "Request" : "Listen") +
395                     " from uid/pid:" + mUid + "/" + mPid +
396                     " for " + request +
397                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
398         }
399     }
400
401
402     // sequence number of NetworkRequests
403     private int mNextNetworkRequestId = 1;
404     private synchronized int nextNetworkRequestId() {
405         return mNextNetworkRequestId++;
406     }
407
408     @Override
409     public NetworkInfo getActiveNetworkInfo() {
410         throw new RuntimeException("not implemented");
411     }
412
413     @Override
414     public Network getActiveNetwork() {
415         throw new RuntimeException("not implemented");
416     }
417
418     @Override
419     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
420         throw new RuntimeException("not implemented");
421     }
422
423     public NetworkInfo getActiveNetworkInfoUnfiltered() {
424         throw new RuntimeException("not implemented");
425     }
426
427     @Override
428     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
429         throw new RuntimeException("not implemented");
430     }
431
432     @Override
433     public NetworkInfo getNetworkInfo(int networkType) {
434         throw new RuntimeException("not implemented");
435     }
436
437     @Override
438     public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
439         throw new RuntimeException("not implemented");
440     }
441
442     @Override
443     public NetworkInfo[] getAllNetworkInfo() {
444         throw new RuntimeException("not implemented");
445     }
446
447     @Override
448     public Network getNetworkForType(int networkType) {
449         throw new RuntimeException("not implemented");
450     }
451
452     @Override
453     public Network[] getAllNetworks() {
454         throw new RuntimeException("not implemented");
455     }
456
457     @Override
458     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
459         throw new RuntimeException("not implemented");
460     }
461
462     @Override
463     public boolean isNetworkSupported(int networkType) {
464         throw new RuntimeException("not implemented");
465     }
466
467     @Override
468     public LinkProperties getActiveLinkProperties() {
469         throw new RuntimeException("not implemented");
470     }
471
472     @Override
473     public LinkProperties getLinkPropertiesForType(int networkType) {
474         throw new RuntimeException("not implemented");
475     }
476
477     @Override
478     public LinkProperties getLinkProperties(Network network) {
479         throw new RuntimeException("not implemented");
480     }
481
482     @Override
483     public NetworkCapabilities getNetworkCapabilities(Network network) {
484         throw new RuntimeException("not implemented");
485     }
486
487     @Override
488     public NetworkState[] getAllNetworkState() {
489         throw new RuntimeException("not implemented");
490     }
491
492     @Override
493     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
494         throw new RuntimeException("not implemented");
495     }
496
497     @Override
498     public boolean isActiveNetworkMetered() {
499         throw new RuntimeException("not implemented");
500     }
501
502     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
503         throw new RuntimeException("not implemented");
504     }
505
506     @Override
507     public int getRestoreDefaultNetworkDelay(int networkType) {
508         throw new RuntimeException("not implemented");
509     }
510
511     @Override
512     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
513         throw new RuntimeException("not implemented");
514     }
515
516     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
517         throw new RuntimeException("not implemented");
518     }
519
520     public void setAvoidUnvalidated(Network network) {
521         throw new RuntimeException("not implemented");
522     }
523
524     public void startCaptivePortalApp(Network network) {
525         throw new RuntimeException("not implemented");
526     }
527
528     public int getMultipathPreference(Network network) {
529         throw new RuntimeException("not implemented");
530     }
531
532     public int tether(String iface) {
533         throw new RuntimeException("not implemented");
534     }
535
536     public int untether(String iface) {
537         throw new RuntimeException("not implemented");
538     }
539
540     public int getLastTetherError(String iface) {
541         throw new RuntimeException("not implemented");
542     }
543
544     public String[] getTetherableUsbRegexs() {
545         throw new RuntimeException("not implemented");
546     }
547
548     public String[] getTetherableWifiRegexs() {
549         throw new RuntimeException("not implemented");
550     }
551
552     public String[] getTetherableBluetoothRegexs() {
553         throw new RuntimeException("not implemented");
554     }
555
556     public int setUsbTethering(boolean enable) {
557         throw new RuntimeException("not implemented");
558     }
559
560     public String[] getTetherableIfaces() {
561         throw new RuntimeException("not implemented");
562     }
563
564     public String[] getTetheredIfaces() {
565         throw new RuntimeException("not implemented");
566     }
567
568     public String[] getTetheringErroredIfaces() {
569         throw new RuntimeException("not implemented");
570     }
571
572     public String[] getTetheredDhcpRanges() {
573         throw new RuntimeException("not implemented");
574     }
575
576     @Override
577     public boolean isTetheringSupported() {
578         throw new RuntimeException("not implemented");
579     }
580
581     @Override
582     public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
583         throw new RuntimeException("not implemented");
584     }
585
586     @Override
587     public void stopTethering(int type) {
588         throw new RuntimeException("not implemented");
589     }
590
591
592     public void reportInetCondition(int networkType, int percentage) {
593         throw new RuntimeException("not implemented");
594     }
595
596     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
597         throw new RuntimeException("not implemented");
598     }
599
600     public ProxyInfo getProxyForNetwork(Network network) {
601         throw new RuntimeException("not implemented");
602     }
603
604     public void setGlobalProxy(ProxyInfo proxyProperties) {
605         throw new RuntimeException("not implemented");
606     }
607
608     public ProxyInfo getGlobalProxy() {
609         throw new RuntimeException("not implemented");
610     }
611
612     @Override
613     public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
614             int userId) {
615         throw new RuntimeException("not implemented");
616     }
617
618     public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) {
619         throw new RuntimeException("not implemented");
620     }
621
622     @Override
623     public ParcelFileDescriptor establishVpn(VpnConfig config) {
624         throw new RuntimeException("not implemented");
625     }
626
627     @Override
628     public void startLegacyVpn(VpnProfile profile) {
629         throw new RuntimeException("not implemented");
630     }
631
632     @Override
633     public LegacyVpnInfo getLegacyVpnInfo(int userId) {
634         throw new RuntimeException("not implemented");
635     }
636
637     @Override
638     public VpnInfo[] getAllVpnInfo() {
639         throw new RuntimeException("not implemented");
640     }
641
642     @Override
643     public VpnConfig getVpnConfig(int userId) {
644         throw new RuntimeException("not implemented");
645     }
646
647     @Override
648     public boolean updateLockdownVpn() {
649         throw new RuntimeException("not implemented");
650     }
651
652     @Override
653     public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdownEnabled) {
654         throw new RuntimeException("not implemented");
655     }
656
657     @Override
658     public String getAlwaysOnVpnPackage(int userId) {
659         throw new RuntimeException("not implemented");
660     }
661
662     @Override
663     public int checkMobileProvisioning(int suggestedTimeOutMs) {
664         throw new RuntimeException("not implemented");
665     }
666
667     @Override
668     public String getMobileProvisioningUrl() {
669         throw new RuntimeException("not implemented");
670     }
671
672     @Override
673     public void setProvisioningNotificationVisible(boolean visible, int networkType,
674             String action) {
675         throw new RuntimeException("not implemented");
676     }
677
678     @Override
679     public void setAirplaneMode(boolean enable) {
680         throw new RuntimeException("not implemented");
681     }
682
683     @Override
684     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
685             Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
686         networkCapabilities = new NetworkCapabilities(networkCapabilities);
687
688         if (timeoutMs < 0) {
689             throw new IllegalArgumentException("Bad timeout specified");
690         }
691
692         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
693                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
694         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder, true);
695         if (DBG) log("requestNetwork for " + nri);
696
697         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
698
699         return networkRequest;
700     }
701
702     @Override
703     public boolean requestBandwidthUpdate(Network network) {
704         throw new RuntimeException("not implemented");
705     }
706
707
708     @Override
709     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
710             PendingIntent operation) {
711         throw new RuntimeException("not implemented");
712     }
713
714     @Override
715     public void releasePendingNetworkRequest(PendingIntent operation) {
716         throw new RuntimeException("not implemented");
717     }
718
719     @Override
720     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
721             Messenger messenger, IBinder binder) {
722         throw new RuntimeException("not implemented");
723     }
724
725     @Override
726     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
727             PendingIntent operation) {
728         throw new RuntimeException("not implemented");
729     }
730
731     @Override
732     public void releaseNetworkRequest(NetworkRequest networkRequest) {
733         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(),
734                 0, networkRequest));
735     }
736
737     @Override
738     public void registerNetworkFactory(Messenger messenger, String name) {
739         NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
740         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
741     }
742
743     private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
744         if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
745         mNetworkFactoryInfos.put(nfi.messenger, nfi);
746         nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
747     }
748
749     @Override
750     public void unregisterNetworkFactory(Messenger messenger) {
751         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
752     }
753
754     private void handleUnregisterNetworkFactory(Messenger messenger) {
755         NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
756         if (nfi == null) {
757             loge("Failed to find Messenger in unregisterNetworkFactory");
758             return;
759         }
760         if (DBG) log("unregisterNetworkFactory for " + nfi.name);
761     }
762
763     public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
764             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
765             int currentScore, NetworkMisc networkMisc) {
766 //        final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
767 //                new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
768 //                linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
769 //                mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
770 //        synchronized (this) {
771 //            nai.networkMonitor.systemReady = mSystemReady;
772 //        }
773 //        mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
774 //        return nai.network.netId;
775         throw new RuntimeException("not implemented");
776     }
777
778     private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
779         if (VDBG) log("Got NetworkAgent Messenger");
780 //        mNetworkAgentInfos.put(na.messenger, na);
781 //        synchronized (mNetworkForNetId) {
782 //            mNetworkForNetId.put(na.network.netId, na);
783 //        }
784 //        na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
785 //        NetworkInfo networkInfo = na.networkInfo;
786 //        na.networkInfo = null;
787 //        updateNetworkInfo(na, networkInfo);
788     }
789
790
791     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
792         mNetworkRequests.put(nri.request, nri);
793         if (!nri.isRequest) {
794             for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
795                 if (nri.request.networkCapabilities.hasSignalStrength() &&
796                         network.satisfiesImmutableCapabilitiesOf(nri.request)) {
797                 }
798             }
799         }
800         rematchAllNetworksAndRequests(null, 0);
801         if (nri.isRequest) {
802             sendUpdatedScoreToFactories(nri.request, 0);
803         }
804     }
805
806     private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
807         NetworkRequestInfo nri = mNetworkRequests.get(request);
808         if (nri != null) {
809             if (DBG) log("releasing NetworkRequest " + request);
810             nri.unlinkDeathRecipient();
811             mNetworkRequests.remove(request);
812             if (nri.isRequest) {
813                 // Find all networks that are satisfying this request and remove the request
814                 // from their request lists.
815                 // TODO - it's my understanding that for a request there is only a single
816                 // network satisfying it, so this loop is wasteful
817                 //boolean wasKept = false;
818                 //for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
819                 //    if (nai.networkRequests.get(nri.request.requestId) != null) {
820                 //        nai.networkRequests.remove(nri.request.requestId);
821                 //        if (DBG) {
822                 //            log(" Removing from current network " + nai.name() +
823                 //                    ", leaving " + nai.networkRequests.size() +
824                 //                    " requests.");
825                 //        }
826                 //        if (unneeded(nai)) {
827                 //            if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
828                 //            teardownUnneededNetwork(nai);
829                 //        } else {
830                 //            // suspect there should only be one pass through here
831                 //            // but if any were kept do the check below
832                 //            wasKept |= true;
833                 //        }
834                 //    }
835                 //}
836
837                 //NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
838                 //if (nai != null) {
839                 //    mNetworkForRequestId.remove(nri.request.requestId);
840                 //}
841                 // Maintain the illusion.  When this request arrived, we might have pretended
842                 // that a network connected to serve it, even though the network was already
843                 // connected.  Now that this request has gone away, we might have to pretend
844                 // that the network disconnected.  LegacyTypeTracker will generate that
845                 // phantom disconnect for this type.
846                 //if (nri.request.legacyType != TYPE_NONE && nai != null) {
847                 //    boolean doRemove = true;
848                 //    if (wasKept) {
849                 //        // check if any of the remaining requests for this network are for the
850                 //        // same legacy type - if so, don't remove the nai
851                 //        for (int i = 0; i < nai.networkRequests.size(); i++) {
852                 //            NetworkRequest otherRequest = nai.networkRequests.valueAt(i);
853                 //            if (otherRequest.legacyType == nri.request.legacyType &&
854                 //                    isRequest(otherRequest)) {
855                 //                if (DBG) log(" still have other legacy request - leaving");
856                 //                doRemove = false;
857                 //            }
858                 //        }
859                 //    }
860                 //
861                 //    if (doRemove) {
862                 //        mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
863                 //    }
864                 //}
865
866                 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
867                     nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
868                             nri.request);
869                 }
870             } else {
871                 // listens don't have a singular affectedNetwork.  Check all networks to see
872                 // if this listen request applies and remove it.
873                 //for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
874                 //    nai.networkRequests.remove(nri.request.requestId);
875                 //    if (nri.request.networkCapabilities.hasSignalStrength() &&
876                 //            nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
877                 //        updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
878                 //    }
879                 //}
880             }
881             //callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
882         }
883     }
884
885     private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
886         for (int i = 0; i < nai.numNetworkRequests(); i++) {
887             NetworkRequest nr = nai.requestAt(i);
888             // Don't send listening requests to factories. b/17393458
889             if (!isRequest(nr)) continue;
890                 sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
891         }
892     }
893
894     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
895         if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
896         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
897             nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
898                     networkRequest);
899         }
900     }
901
902     private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
903     }
904
905     @Override
906     public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
907             String resultData, Bundle resultExtras) {
908         throw new RuntimeException("not implemented");
909     }
910
911     @Override
912     public boolean addVpnAddress(String address, int prefixLength) {
913         throw new RuntimeException("not implemented");
914     }
915
916     @Override
917     public boolean removeVpnAddress(String address, int prefixLength) {
918         throw new RuntimeException("not implemented");
919     }
920
921     @Override
922     public boolean setUnderlyingNetworksForVpn(Network[] networks) {
923         throw new RuntimeException("not implemented");
924     }
925
926     @Override
927     public String getCaptivePortalServerUrl() {
928         throw new RuntimeException("not implemented");
929     }
930
931     @Override
932     public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger,
933             IBinder binder, String srcAddr, int srcPort, String dstAddr) {
934         throw new RuntimeException("not implemented");
935     }
936
937     @Override
938     public void stopKeepalive(Network network, int slot) {
939         throw new RuntimeException("not implemented");
940     }
941
942     @Override
943     public void factoryReset() {
944         throw new RuntimeException("not implemented");
945     }
946
947     @VisibleForTesting
948     public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
949             NetworkAgentInfo nai, NetworkRequest defaultRequest) {
950         throw new RuntimeException("not implemented");
951     }
952
953     @VisibleForTesting
954     public NetworkRequest defaultRequest = null;
955     @VisibleForTesting
956     public synchronized void addDefaultRequest() {
957         if (defaultRequest != null) return;
958         NetworkCapabilities netCap = new NetworkCapabilities();
959         netCap.addCapability(NET_CAPABILITY_INTERNET);
960         netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
961         defaultRequest = requestNetwork(netCap, null, 0, new Binder(),
962                 ConnectivityManager.TYPE_NONE);
963     }
964
965     @VisibleForTesting
966     public synchronized void setCurrentScoreForRequest(NetworkRequest nr, int score) {
967         sendUpdatedScoreToFactories(nr, score);
968     }
969
970     @VisibleForTesting
971     public synchronized void removeDefaultRequest() {
972         if (defaultRequest == null) return;
973         releaseNetworkRequest(defaultRequest);
974         defaultRequest = null;
975     }
976
977
978 }