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