• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.googlecode.android_scripting.facade;
18 
19 import android.app.Service;
20 import android.app.usage.NetworkStats;
21 import android.app.usage.NetworkStats.Bucket;
22 import android.app.usage.NetworkStatsManager;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.net.ConnectivityManager;
28 import android.net.ConnectivityManager.PacketKeepalive;
29 import android.net.ConnectivityManager.PacketKeepaliveCallback;
30 import android.net.LinkProperties;
31 import android.net.Network;
32 import android.net.NetworkCapabilities;
33 import android.net.NetworkInfo;
34 import android.net.NetworkPolicy;
35 import android.net.NetworkPolicyManager;
36 import android.net.NetworkRequest;
37 import android.net.ProxyInfo;
38 import android.net.StringNetworkSpecifier;
39 import android.os.Bundle;
40 import android.os.RemoteException;
41 import android.provider.Settings;
42 
43 import com.google.common.io.ByteStreams;
44 import com.googlecode.android_scripting.FileUtils;
45 import com.googlecode.android_scripting.Log;
46 import com.googlecode.android_scripting.facade.wifi.WifiAwareManagerFacade;
47 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
48 import com.googlecode.android_scripting.rpc.Rpc;
49 import com.googlecode.android_scripting.rpc.RpcOptional;
50 import com.googlecode.android_scripting.rpc.RpcParameter;
51 
52 import org.json.JSONArray;
53 import org.json.JSONException;
54 import org.json.JSONObject;
55 
56 import java.io.BufferedInputStream;
57 import java.io.File;
58 import java.io.FileOutputStream;
59 import java.io.IOException;
60 import java.io.InputStream;
61 import java.io.OutputStream;
62 import java.net.Inet4Address;
63 import java.net.Inet6Address;
64 import java.net.InetAddress;
65 import java.net.NetworkInterface;
66 import java.net.SocketException;
67 import java.net.URL;
68 import java.net.URLConnection;
69 import java.net.UnknownHostException;
70 import java.util.ArrayList;
71 import java.util.Collections;
72 import java.util.Enumeration;
73 import java.util.HashMap;
74 import java.util.List;
75 
76 /**
77  * Access ConnectivityManager functions.
78  */
79 public class ConnectivityManagerFacade extends RpcReceiver {
80 
81     public static int AIRPLANE_MODE_OFF = 0;
82     public static int AIRPLANE_MODE_ON = 1;
83     public static int DATA_ROAMING_ON = 1;
84 
85     private static HashMap<Long, Network> sNetworkHashMap = new HashMap<Long, Network>();
86 
87     class ConnectivityReceiver extends BroadcastReceiver {
88 
89         @Override
onReceive(Context context, Intent intent)90         public void onReceive(Context context, Intent intent) {
91             String action = intent.getAction();
92 
93             if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
94                 Log.e("ConnectivityReceiver received non-connectivity action!");
95                 return;
96             }
97 
98             Bundle b = intent.getExtras();
99 
100             if (b == null) {
101                 Log.e("ConnectivityReceiver failed to receive extras!");
102                 return;
103             }
104 
105             int netType =
106                     b.getInt(ConnectivityManager.EXTRA_NETWORK_TYPE,
107                             ConnectivityManager.TYPE_NONE);
108 
109             if (netType == ConnectivityManager.TYPE_NONE) {
110                 Log.i("ConnectivityReceiver received change to TYPE_NONE.");
111                 return;
112             }
113 
114             /*
115              * Technically there is a race condition here, but retrieving the NetworkInfo from the
116              * bundle is deprecated. See ConnectivityManager.EXTRA_NETWORK_INFO
117              */
118             for (NetworkInfo info : mManager.getAllNetworkInfo()) {
119                 if (info.getType() == netType) {
120                     mEventFacade.postEvent(ConnectivityConstants.EventConnectivityChanged, info);
121                 }
122             }
123         }
124     }
125 
126     class PacketKeepaliveReceiver extends PacketKeepaliveCallback {
127         public static final int EVENT_INVALID = -1;
128         public static final int EVENT_NONE = 0;
129         public static final int EVENT_STARTED = 1 << 0;
130         public static final int EVENT_STOPPED = 1 << 1;
131         public static final int EVENT_ERROR = 1 << 2;
132         public static final int EVENT_ALL = EVENT_STARTED |
133                 EVENT_STOPPED |
134                 EVENT_ERROR;
135         private int mEvents;
136         public String mId;
137         public PacketKeepalive mPacketKeepalive;
138 
PacketKeepaliveReceiver(int events)139         public PacketKeepaliveReceiver(int events) {
140             super();
141             mEvents = events;
142             mId = this.toString();
143         }
144 
startListeningForEvents(int events)145         public void startListeningForEvents(int events) {
146             mEvents |= events & EVENT_ALL;
147         }
148 
stopListeningForEvents(int events)149         public void stopListeningForEvents(int events) {
150             mEvents &= ~(events & EVENT_ALL);
151         }
152 
153         @Override
onStarted()154         public void onStarted() {
155             Log.d("PacketKeepaliveCallback on start!");
156             if ((mEvents & EVENT_STARTED) == EVENT_STARTED) {
157                 mEventFacade.postEvent(
158                     ConnectivityConstants.EventPacketKeepaliveCallback,
159                     new ConnectivityEvents.PacketKeepaliveEvent(
160                         mId,
161                         getPacketKeepaliveReceiverEventString(EVENT_STARTED)));
162             }
163         }
164 
165         @Override
onStopped()166         public void onStopped() {
167             Log.d("PacketKeepaliveCallback on stop!");
168             if ((mEvents & EVENT_STOPPED) == EVENT_STOPPED) {
169                 mEventFacade.postEvent(
170                         ConnectivityConstants.EventPacketKeepaliveCallback,
171                     new ConnectivityEvents.PacketKeepaliveEvent(
172                         mId,
173                         getPacketKeepaliveReceiverEventString(EVENT_STOPPED)));
174             }
175         }
176 
177         @Override
onError(int error)178         public void onError(int error) {
179             Log.d("PacketKeepaliveCallback on error! - code:" + error);
180             if ((mEvents & EVENT_ERROR) == EVENT_ERROR) {
181                 mEventFacade.postEvent(
182                         ConnectivityConstants.EventPacketKeepaliveCallback,
183                     new ConnectivityEvents.PacketKeepaliveEvent(
184                         mId,
185                         getPacketKeepaliveReceiverEventString(EVENT_ERROR)));
186             }
187         }
188     }
189 
190     class NetworkCallback extends ConnectivityManager.NetworkCallback {
191         public static final int EVENT_INVALID = -1;
192         public static final int EVENT_NONE = 0;
193         public static final int EVENT_PRECHECK = 1 << 0;
194         public static final int EVENT_AVAILABLE = 1 << 1;
195         public static final int EVENT_LOSING = 1 << 2;
196         public static final int EVENT_LOST = 1 << 3;
197         public static final int EVENT_UNAVAILABLE = 1 << 4;
198         public static final int EVENT_CAPABILITIES_CHANGED = 1 << 5;
199         public static final int EVENT_SUSPENDED = 1 << 6;
200         public static final int EVENT_RESUMED = 1 << 7;
201         public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8;
202         public static final int EVENT_ALL = EVENT_PRECHECK |
203                 EVENT_AVAILABLE |
204                 EVENT_LOSING |
205                 EVENT_LOST |
206                 EVENT_UNAVAILABLE |
207                 EVENT_CAPABILITIES_CHANGED |
208                 EVENT_SUSPENDED |
209                 EVENT_RESUMED |
210                 EVENT_LINK_PROPERTIES_CHANGED;
211 
212         private int mEvents;
213         public String mId;
214         private long mCreateTimestamp;
215 
NetworkCallback(int events)216         public NetworkCallback(int events) {
217             super();
218             mEvents = events;
219             mId = this.toString();
220             mCreateTimestamp = System.currentTimeMillis();
221         }
222 
startListeningForEvents(int events)223         public void startListeningForEvents(int events) {
224             mEvents |= events & EVENT_ALL;
225         }
226 
stopListeningForEvents(int events)227         public void stopListeningForEvents(int events) {
228             mEvents &= ~(events & EVENT_ALL);
229         }
230 
231         @Override
onPreCheck(Network network)232         public void onPreCheck(Network network) {
233             Log.d("NetworkCallback onPreCheck");
234             if ((mEvents & EVENT_PRECHECK) == EVENT_PRECHECK) {
235                 mEventFacade.postEvent(
236                         ConnectivityConstants.EventNetworkCallback,
237                     new ConnectivityEvents.NetworkCallbackEventBase(
238                         mId,
239                         getNetworkCallbackEventString(EVENT_PRECHECK), mCreateTimestamp));
240             }
241         }
242 
243         @Override
onAvailable(Network network)244         public void onAvailable(Network network) {
245             Log.d("NetworkCallback onAvailable");
246             if ((mEvents & EVENT_AVAILABLE) == EVENT_AVAILABLE) {
247                 mEventFacade.postEvent(
248                         ConnectivityConstants.EventNetworkCallback,
249                     new ConnectivityEvents.NetworkCallbackEventBase(
250                         mId,
251                         getNetworkCallbackEventString(EVENT_AVAILABLE), mCreateTimestamp));
252             }
253         }
254 
255         @Override
onLosing(Network network, int maxMsToLive)256         public void onLosing(Network network, int maxMsToLive) {
257             Log.d("NetworkCallback onLosing");
258             if ((mEvents & EVENT_LOSING) == EVENT_LOSING) {
259                 mEventFacade.postEvent(
260                         ConnectivityConstants.EventNetworkCallback,
261                     new ConnectivityEvents.NetworkCallbackEventOnLosing(
262                         mId,
263                         getNetworkCallbackEventString(EVENT_LOSING), mCreateTimestamp,
264                         maxMsToLive));
265             }
266         }
267 
268         @Override
onLost(Network network)269         public void onLost(Network network) {
270             Log.d("NetworkCallback onLost");
271             if ((mEvents & EVENT_LOST) == EVENT_LOST) {
272                 mEventFacade.postEvent(
273                         ConnectivityConstants.EventNetworkCallback,
274                     new ConnectivityEvents.NetworkCallbackEventBase(
275                         mId,
276                         getNetworkCallbackEventString(EVENT_LOST), mCreateTimestamp));
277             }
278         }
279 
280         @Override
onUnavailable()281         public void onUnavailable() {
282             Log.d("NetworkCallback onUnavailable");
283             if ((mEvents & EVENT_UNAVAILABLE) == EVENT_UNAVAILABLE) {
284                 mEventFacade.postEvent(
285                         ConnectivityConstants.EventNetworkCallback,
286                     new ConnectivityEvents.NetworkCallbackEventBase(
287                         mId,
288                         getNetworkCallbackEventString(EVENT_UNAVAILABLE), mCreateTimestamp));
289             }
290         }
291 
292         @Override
onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities)293         public void onCapabilitiesChanged(Network network,
294                 NetworkCapabilities networkCapabilities) {
295             Log.d("NetworkCallback onCapabilitiesChanged. RSSI:" +
296                     networkCapabilities.getSignalStrength());
297             if ((mEvents & EVENT_CAPABILITIES_CHANGED) == EVENT_CAPABILITIES_CHANGED) {
298                 mEventFacade.postEvent(
299                         ConnectivityConstants.EventNetworkCallback,
300                     new ConnectivityEvents.NetworkCallbackEventOnCapabilitiesChanged(
301                         mId,
302                         getNetworkCallbackEventString(EVENT_CAPABILITIES_CHANGED), mCreateTimestamp,
303                         networkCapabilities));
304             }
305         }
306 
307         @Override
onNetworkSuspended(Network network)308         public void onNetworkSuspended(Network network) {
309             Log.d("NetworkCallback onNetworkSuspended");
310             if ((mEvents & EVENT_SUSPENDED) == EVENT_SUSPENDED) {
311                 mEventFacade.postEvent(
312                         ConnectivityConstants.EventNetworkCallback,
313                     new ConnectivityEvents.NetworkCallbackEventBase(
314                         mId,
315                         getNetworkCallbackEventString(EVENT_SUSPENDED), mCreateTimestamp));
316             }
317         }
318 
319         @Override
onLinkPropertiesChanged(Network network, LinkProperties linkProperties)320         public void onLinkPropertiesChanged(Network network,
321                 LinkProperties linkProperties) {
322             Log.d("NetworkCallback onLinkPropertiesChanged");
323             if ((mEvents & EVENT_LINK_PROPERTIES_CHANGED) == EVENT_LINK_PROPERTIES_CHANGED) {
324                 mEventFacade.postEvent(
325                         ConnectivityConstants.EventNetworkCallback,
326                         new ConnectivityEvents.NetworkCallbackEventOnLinkPropertiesChanged(mId,
327                                 getNetworkCallbackEventString(EVENT_LINK_PROPERTIES_CHANGED),
328                                 mCreateTimestamp,
329                                 linkProperties.getInterfaceName()));
330             }
331         }
332 
333         @Override
onNetworkResumed(Network network)334         public void onNetworkResumed(Network network) {
335             Log.d("NetworkCallback onNetworkResumed");
336             if ((mEvents & EVENT_RESUMED) == EVENT_RESUMED) {
337                 mEventFacade.postEvent(
338                         ConnectivityConstants.EventNetworkCallback,
339                     new ConnectivityEvents.NetworkCallbackEventBase(
340                         mId,
341                         getNetworkCallbackEventString(EVENT_RESUMED), mCreateTimestamp));
342             }
343         }
344     }
345 
getNetworkCallbackEvent(String event)346     private static int getNetworkCallbackEvent(String event) {
347         switch (event) {
348             case ConnectivityConstants.NetworkCallbackPreCheck:
349                 return NetworkCallback.EVENT_PRECHECK;
350             case ConnectivityConstants.NetworkCallbackAvailable:
351                 return NetworkCallback.EVENT_AVAILABLE;
352             case ConnectivityConstants.NetworkCallbackLosing:
353                 return NetworkCallback.EVENT_LOSING;
354             case ConnectivityConstants.NetworkCallbackLost:
355                 return NetworkCallback.EVENT_LOST;
356             case ConnectivityConstants.NetworkCallbackUnavailable:
357                 return NetworkCallback.EVENT_UNAVAILABLE;
358             case ConnectivityConstants.NetworkCallbackCapabilitiesChanged:
359                 return NetworkCallback.EVENT_CAPABILITIES_CHANGED;
360             case ConnectivityConstants.NetworkCallbackSuspended:
361                 return NetworkCallback.EVENT_SUSPENDED;
362             case ConnectivityConstants.NetworkCallbackResumed:
363                 return NetworkCallback.EVENT_RESUMED;
364             case ConnectivityConstants.NetworkCallbackLinkPropertiesChanged:
365                 return NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED;
366         }
367         return NetworkCallback.EVENT_INVALID;
368     }
369 
getNetworkCallbackEventString(int event)370     private static String getNetworkCallbackEventString(int event) {
371         switch (event) {
372             case NetworkCallback.EVENT_PRECHECK:
373                 return ConnectivityConstants.NetworkCallbackPreCheck;
374             case NetworkCallback.EVENT_AVAILABLE:
375                 return ConnectivityConstants.NetworkCallbackAvailable;
376             case NetworkCallback.EVENT_LOSING:
377                 return ConnectivityConstants.NetworkCallbackLosing;
378             case NetworkCallback.EVENT_LOST:
379                 return ConnectivityConstants.NetworkCallbackLost;
380             case NetworkCallback.EVENT_UNAVAILABLE:
381                 return ConnectivityConstants.NetworkCallbackUnavailable;
382             case NetworkCallback.EVENT_CAPABILITIES_CHANGED:
383                 return ConnectivityConstants.NetworkCallbackCapabilitiesChanged;
384             case NetworkCallback.EVENT_SUSPENDED:
385                 return ConnectivityConstants.NetworkCallbackSuspended;
386             case NetworkCallback.EVENT_RESUMED:
387                 return ConnectivityConstants.NetworkCallbackResumed;
388             case NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED:
389                 return ConnectivityConstants.NetworkCallbackLinkPropertiesChanged;
390         }
391         return ConnectivityConstants.NetworkCallbackInvalid;
392     }
393 
getPacketKeepaliveReceiverEvent(String event)394     private static int getPacketKeepaliveReceiverEvent(String event) {
395         switch (event) {
396             case ConnectivityConstants.PacketKeepaliveCallbackStarted:
397                 return PacketKeepaliveReceiver.EVENT_STARTED;
398             case ConnectivityConstants.PacketKeepaliveCallbackStopped:
399                 return PacketKeepaliveReceiver.EVENT_STOPPED;
400             case ConnectivityConstants.PacketKeepaliveCallbackError:
401                 return PacketKeepaliveReceiver.EVENT_ERROR;
402         }
403         return PacketKeepaliveReceiver.EVENT_INVALID;
404     }
405 
getPacketKeepaliveReceiverEventString(int event)406     private static String getPacketKeepaliveReceiverEventString(int event) {
407         switch (event) {
408             case PacketKeepaliveReceiver.EVENT_STARTED:
409                 return ConnectivityConstants.PacketKeepaliveCallbackStarted;
410             case PacketKeepaliveReceiver.EVENT_STOPPED:
411                 return ConnectivityConstants.PacketKeepaliveCallbackStopped;
412             case PacketKeepaliveReceiver.EVENT_ERROR:
413                 return ConnectivityConstants.PacketKeepaliveCallbackError;
414         }
415         return ConnectivityConstants.PacketKeepaliveCallbackInvalid;
416     }
417 
418     /**
419      * Callbacks used in ConnectivityManager to confirm tethering has started/failed.
420      */
421     class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback {
422         @Override
onTetheringStarted()423         public void onTetheringStarted() {
424             mEventFacade.postEvent(ConnectivityConstants.TetheringStartedCallback, null);
425         }
426 
427         @Override
onTetheringFailed()428         public void onTetheringFailed() {
429             mEventFacade.postEvent(ConnectivityConstants.TetheringFailedCallback, null);
430         }
431     }
432 
433     private final ConnectivityManager mManager;
434     private NetworkPolicyManager mNetPolicyManager;
435     private NetworkStatsManager mNetStatsManager;
436     private final Service mService;
437     private final Context mContext;
438     private final ConnectivityReceiver mConnectivityReceiver;
439     private final EventFacade mEventFacade;
440     private PacketKeepalive mPacketKeepalive;
441     private NetworkCallback mNetworkCallback;
442     private static HashMap<String, PacketKeepaliveReceiver> mPacketKeepaliveReceiverMap =
443             new HashMap<String, PacketKeepaliveReceiver>();
444     private static HashMap<String, NetworkCallback> mNetworkCallbackMap =
445             new HashMap<String, NetworkCallback>();
446     private boolean mTrackingConnectivityStateChange;
447 
ConnectivityManagerFacade(FacadeManager manager)448     public ConnectivityManagerFacade(FacadeManager manager) {
449         super(manager);
450         mService = manager.getService();
451         mContext = mService.getBaseContext();
452         mManager = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
453         mNetPolicyManager = NetworkPolicyManager.from(mContext);
454         mNetStatsManager = (NetworkStatsManager)
455               mService.getSystemService(Context.NETWORK_STATS_SERVICE);
456         mEventFacade = manager.getReceiver(EventFacade.class);
457         mConnectivityReceiver = new ConnectivityReceiver();
458         mTrackingConnectivityStateChange = false;
459     }
460 
461     @Rpc(description = "Listen for connectivity changes")
connectivityStartTrackingConnectivityStateChange()462     public void connectivityStartTrackingConnectivityStateChange() {
463         if (!mTrackingConnectivityStateChange) {
464             mTrackingConnectivityStateChange = true;
465             mContext.registerReceiver(mConnectivityReceiver,
466                     new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
467         }
468     }
469 
470     @Rpc(description = "start natt keep alive")
connectivityStartNattKeepalive(Integer intervalSeconds, String srcAddrString, Integer srcPort, String dstAddrString)471     public String connectivityStartNattKeepalive(Integer intervalSeconds, String srcAddrString,
472             Integer srcPort, String dstAddrString) throws UnknownHostException {
473         try {
474             Network mNetwork = mManager.getActiveNetwork();
475             InetAddress srcAddr = InetAddress.getByName(srcAddrString);
476             InetAddress dstAddr = InetAddress.getByName(dstAddrString);
477             Log.d("startNattKeepalive srcAddr:" + srcAddr.getHostAddress());
478             Log.d("startNattKeepalive dstAddr:" + dstAddr.getHostAddress());
479             Log.d("startNattKeepalive srcPort:" + srcPort);
480             Log.d("startNattKeepalive intervalSeconds:" + intervalSeconds);
481             PacketKeepaliveReceiver mPacketKeepaliveReceiver = new PacketKeepaliveReceiver(
482                     PacketKeepaliveReceiver.EVENT_ALL);
483             mPacketKeepalive = mManager.startNattKeepalive(mNetwork, (int) intervalSeconds,
484                     mPacketKeepaliveReceiver, srcAddr, (int) srcPort, dstAddr);
485             if (mPacketKeepalive != null) {
486                 mPacketKeepaliveReceiver.mPacketKeepalive = mPacketKeepalive;
487                 String key = mPacketKeepaliveReceiver.mId;
488                 mPacketKeepaliveReceiverMap.put(key, mPacketKeepaliveReceiver);
489                 return key;
490             } else {
491                 Log.e("startNattKeepalive fail, startNattKeepalive return null");
492                 return null;
493             }
494         } catch (UnknownHostException e) {
495             Log.e("startNattKeepalive UnknownHostException");
496             return null;
497         }
498     }
499 
500     @Rpc(description = "stop natt keep alive")
connectivityStopNattKeepalive(String key)501     public Boolean connectivityStopNattKeepalive(String key) {
502         PacketKeepaliveReceiver mPacketKeepaliveReceiver =
503                 mPacketKeepaliveReceiverMap.get(key);
504         if (mPacketKeepaliveReceiver != null) {
505             mPacketKeepaliveReceiver.mPacketKeepalive.stop();
506             return true;
507         } else {
508             return false;
509         }
510     }
511 
512     /**
513      * Remove key from the PacketKeepaliveReceiver map
514      */
515     @Rpc(description = "remove PacketKeepaliveReceiver key")
connectivityRemovePacketKeepaliveReceiverKey(String key)516     public void connectivityRemovePacketKeepaliveReceiverKey(String key) {
517         mPacketKeepaliveReceiverMap.remove(key);
518     }
519 
520     @Rpc(description = "start listening for NattKeepalive Event")
connectivityNattKeepaliveStartListeningForEvent(String key, String eventString)521     public Boolean connectivityNattKeepaliveStartListeningForEvent(String key, String eventString) {
522         PacketKeepaliveReceiver mPacketKeepaliveReceiver =
523                 mPacketKeepaliveReceiverMap.get(key);
524         if (mPacketKeepaliveReceiver != null) {
525             int event = getPacketKeepaliveReceiverEvent(eventString);
526             if (event == PacketKeepaliveReceiver.EVENT_INVALID) {
527                 return false;
528             }
529             mPacketKeepaliveReceiver.startListeningForEvents(event);
530             return true;
531         } else {
532             return false;
533         }
534     }
535 
536     @Rpc(description = "stop listening for NattKeepalive Event")
connectivityNattKeepaliveStopListeningForEvent(String key, String eventString)537     public Boolean connectivityNattKeepaliveStopListeningForEvent(String key, String eventString) {
538         PacketKeepaliveReceiver mPacketKeepaliveReceiver =
539                 mPacketKeepaliveReceiverMap.get(key);
540         if (mPacketKeepaliveReceiver != null) {
541             int event = getPacketKeepaliveReceiverEvent(eventString);
542             if (event == PacketKeepaliveReceiver.EVENT_INVALID) {
543                 return false;
544             }
545             mPacketKeepaliveReceiver.stopListeningForEvents(event);
546             return true;
547         } else {
548             return false;
549         }
550     }
551 
552     @Rpc(description = "start listening for NetworkCallback Event")
connectivityNetworkCallbackStartListeningForEvent(String key, String eventString)553     public Boolean connectivityNetworkCallbackStartListeningForEvent(String key, String eventString) {
554         NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key);
555         if (mNetworkCallback != null) {
556             int event = getNetworkCallbackEvent(eventString);
557             if (event == NetworkCallback.EVENT_INVALID) {
558                 return false;
559             }
560             mNetworkCallback.startListeningForEvents(event);
561             return true;
562         } else {
563             return false;
564         }
565     }
566 
567     @Rpc(description = "stop listening for NetworkCallback Event")
connectivityNetworkCallbackStopListeningForEvent(String key, String eventString)568     public Boolean connectivityNetworkCallbackStopListeningForEvent(String key, String eventString) {
569         NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key);
570         if (mNetworkCallback != null) {
571             int event = getNetworkCallbackEvent(eventString);
572             if (event == NetworkCallback.EVENT_INVALID) {
573                 return false;
574             }
575             mNetworkCallback.stopListeningForEvents(event);
576             return true;
577         } else {
578             return false;
579         }
580     }
581 
582     @Rpc(description = "Set Rssi Threshold Monitor")
connectivitySetRssiThresholdMonitor(Integer rssi)583     public String connectivitySetRssiThresholdMonitor(Integer rssi) {
584         Log.d("SL4A:setRssiThresholdMonitor rssi = " + rssi);
585         NetworkRequest.Builder builder = new NetworkRequest.Builder();
586         builder.setSignalStrength((int) rssi);
587         builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
588         NetworkRequest networkRequest = builder.build();
589         mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
590         mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
591         String key = mNetworkCallback.mId;
592         mNetworkCallbackMap.put(key, mNetworkCallback);
593         return key;
594     }
595 
596     @Rpc(description = "Stop Rssi Threshold Monitor")
connectivityStopRssiThresholdMonitor(String key)597     public Boolean connectivityStopRssiThresholdMonitor(String key) {
598         Log.d("SL4A:stopRssiThresholdMonitor key = " + key);
599         return connectivityUnregisterNetworkCallback(key);
600     }
601 
buildNetworkRequestFromJson(JSONObject configJson)602     private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson)
603             throws JSONException {
604         NetworkRequest.Builder builder = new NetworkRequest.Builder();
605 
606         if (configJson.has("ClearCapabilities")) {
607             /* the 'ClearCapabilities' property does not have a value (that we use). Its presence
608              is used to clear the capabilities of the constructed network request (which is
609              constructed with some default capabilities already present). */
610             Log.d("build ClearCapabilities");
611             builder.clearCapabilities();
612         }
613         if (configJson.has("TransportType")) {
614             Log.d("build TransportType" + configJson.getInt("TransportType"));
615             builder.addTransportType(configJson.getInt("TransportType"));
616         }
617         if (configJson.has("SignalStrength")) {
618             Log.d("build SignalStrength" + configJson.getInt("SignalStrength"));
619             builder.setSignalStrength(configJson.getInt("SignalStrength"));
620         }
621         if (configJson.has("Capability")) {
622             JSONArray capabilities = configJson.getJSONArray("Capability");
623             for (int i = 0; i < capabilities.length(); i++) {
624                 Log.d("build Capability" + capabilities.getInt(i));
625                 builder.addCapability(capabilities.getInt(i));
626             }
627         }
628         if (configJson.has("LinkUpstreamBandwidthKbps")) {
629             Log.d("build LinkUpstreamBandwidthKbps" + configJson.getInt(
630                     "LinkUpstreamBandwidthKbps"));
631             builder.setLinkUpstreamBandwidthKbps(configJson.getInt(
632                     "LinkUpstreamBandwidthKbps"));
633         }
634         if (configJson.has("LinkDownstreamBandwidthKbps")) {
635             Log.d("build LinkDownstreamBandwidthKbps" + configJson.getInt(
636                     "LinkDownstreamBandwidthKbps"));
637             builder.setLinkDownstreamBandwidthKbps(configJson.getInt(
638                     "LinkDownstreamBandwidthKbps"));
639         }
640         if (configJson.has("NetworkSpecifier")) {
641             Log.d("build NetworkSpecifier" + configJson.getString("NetworkSpecifier"));
642             builder.setNetworkSpecifier(configJson.getString(
643                     "NetworkSpecifier"));
644         }
645         NetworkRequest networkRequest = builder.build();
646         return networkRequest;
647     }
648 
649     @Rpc(description = "register a network callback")
connectivityRegisterNetworkCallback(@pcParametername = "configJson") JSONObject configJson)650     public String connectivityRegisterNetworkCallback(@RpcParameter(name = "configJson")
651     JSONObject configJson) throws JSONException {
652         NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
653         mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
654         mManager.registerNetworkCallback(networkRequest, mNetworkCallback);
655         String key = mNetworkCallback.mId;
656         mNetworkCallbackMap.put(key, mNetworkCallback);
657         return key;
658     }
659 
660     @Rpc(description = "unregister a network callback")
connectivityUnregisterNetworkCallback(@pcParametername = "key") String key)661     public Boolean connectivityUnregisterNetworkCallback(@RpcParameter(name = "key")
662     String key) {
663         mNetworkCallback = mNetworkCallbackMap.get(key);
664         if (mNetworkCallback != null) {
665             mNetworkCallbackMap.remove(key);
666             mManager.unregisterNetworkCallback(mNetworkCallback);
667             return true;
668         } else {
669             return false;
670         }
671     }
672 
673     @Rpc(description = "request a network")
connectivityRequestNetwork(@pcParametername = "configJson") JSONObject configJson)674     public String connectivityRequestNetwork(@RpcParameter(name = "configJson")
675     JSONObject configJson) throws JSONException {
676         NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
677         mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
678         mManager.requestNetwork(networkRequest, mNetworkCallback);
679         String key = mNetworkCallback.mId;
680         mNetworkCallbackMap.put(key, mNetworkCallback);
681         return key;
682     }
683 
684     @Rpc(description = "Request a Wi-Fi Aware network")
connectivityRequestWifiAwareNetwork(@pcParametername = "configJson") JSONObject configJson)685     public String connectivityRequestWifiAwareNetwork(@RpcParameter(name = "configJson")
686             JSONObject configJson) throws JSONException {
687         NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson);
688         if (networkRequest.networkCapabilities.getNetworkSpecifier() instanceof
689                 StringNetworkSpecifier) {
690             String ns =
691                     ((StringNetworkSpecifier) networkRequest.networkCapabilities
692                             .getNetworkSpecifier()).specifier;
693             JSONObject j = new JSONObject(ns);
694             networkRequest.networkCapabilities.setNetworkSpecifier(
695                     WifiAwareManagerFacade.getNetworkSpecifier(j));
696         }
697         mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL);
698         mManager.requestNetwork(networkRequest, mNetworkCallback);
699         String key = mNetworkCallback.mId;
700         mNetworkCallbackMap.put(key, mNetworkCallback);
701         return key;
702     }
703 
704     @Rpc(description = "Stop listening for connectivity changes")
connectivityStopTrackingConnectivityStateChange()705     public void connectivityStopTrackingConnectivityStateChange() {
706         if (mTrackingConnectivityStateChange) {
707             mTrackingConnectivityStateChange = false;
708             mContext.unregisterReceiver(mConnectivityReceiver);
709         }
710     }
711 
712     @Rpc(description = "Get the extra information about the network state provided by lower network layers.")
connectivityNetworkGetActiveConnectionExtraInfo()713     public String connectivityNetworkGetActiveConnectionExtraInfo() {
714         NetworkInfo current = mManager.getActiveNetworkInfo();
715         if (current == null) {
716             Log.d("No network is active at the moment.");
717             return null;
718         }
719         return current.getExtraInfo();
720     }
721 
722     @Rpc(description = "Return the subtype name of the current network, null if not connected")
connectivityNetworkGetActiveConnectionSubtypeName()723     public String connectivityNetworkGetActiveConnectionSubtypeName() {
724         NetworkInfo current = mManager.getActiveNetworkInfo();
725         if (current == null) {
726             Log.d("No network is active at the moment.");
727             return null;
728         }
729         return current.getSubtypeName();
730     }
731 
732     @Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI")
connectivityNetworkGetActiveConnectionTypeName()733     public String connectivityNetworkGetActiveConnectionTypeName() {
734         NetworkInfo current = mManager.getActiveNetworkInfo();
735         if (current == null) {
736             Log.d("No network is active at the moment.");
737             return null;
738         }
739         return current.getTypeName();
740     }
741 
742     @Rpc(description = "Get connection status information about all network types supported by the device.")
connectivityNetworkGetAllInfo()743     public NetworkInfo[] connectivityNetworkGetAllInfo() {
744         return mManager.getAllNetworkInfo();
745     }
746 
747     @Rpc(description = "Check whether the active network is connected to the Internet.")
connectivityNetworkIsConnected()748     public Boolean connectivityNetworkIsConnected() {
749         NetworkInfo current = mManager.getActiveNetworkInfo();
750         if (current == null) {
751             Log.d("No network is active at the moment.");
752             return false;
753         }
754         return current.isConnected();
755     }
756 
757     @Rpc(description = "Checks the airplane mode setting.",
758             returns = "True if airplane mode is enabled.")
connectivityCheckAirplaneMode()759     public Boolean connectivityCheckAirplaneMode() {
760         try {
761             return Settings.Global.getInt(mService.getContentResolver(),
762                     Settings.Global.AIRPLANE_MODE_ON) == AIRPLANE_MODE_ON;
763         } catch (Settings.SettingNotFoundException e) {
764             Log.e("Settings.Global.AIRPLANE_MODE_ON not found!");
765             return false;
766         }
767     }
768 
769     @Rpc(description = "Toggles airplane mode on and off.",
770             returns = "True if airplane mode is enabled.")
connectivityToggleAirplaneMode(@pcParametername = "enabled") @pcOptional Boolean enabled)771     public void connectivityToggleAirplaneMode(@RpcParameter(name = "enabled")
772     @RpcOptional
773     Boolean enabled) {
774         if (enabled == null) {
775             enabled = !connectivityCheckAirplaneMode();
776         }
777         mManager.setAirplaneMode(enabled);
778     }
779 
780     /**
781     * Check global data roaming setting.
782     * @return True if roaming is enabled; false otherwise.
783     */
784     @Rpc(description = "Checks data roaming mode setting.",
785             returns = "True if data roaming mode is enabled.")
connectivityCheckDataRoamingMode()786     public Boolean connectivityCheckDataRoamingMode() {
787         try {
788             return Settings.Global.getInt(mService.getContentResolver(),
789                     Settings.Global.DATA_ROAMING) == DATA_ROAMING_ON;
790         } catch (Settings.SettingNotFoundException e) {
791             Log.e("Settings.Global.DATA_ROAMING not found!");
792             return false;
793         }
794     }
795 
796     /**
797     * Enable or disable data roaming.
798     * @param roaming 1: Enable data roaming; 0: Disable data roaming.
799     * @return True for setting roaming mode successfully; false otherwise.
800     */
801     @Rpc(description = "Set Data Roaming Enabled or Disabled")
connectivitySetDataRoaming( @pcParametername = "roaming") Integer roaming)802     public boolean connectivitySetDataRoaming(
803             @RpcParameter(name = "roaming") Integer roaming) {
804         Log.d("connectivitySetDataRoaming by SubscriptionManager");
805         return Settings.Global.putInt(mService.getContentResolver(),
806                     Settings.Global.DATA_ROAMING, roaming);
807     }
808 
809     @Rpc(description = "Check if tethering supported or not.",
810             returns = "True if tethering is supported.")
connectivityIsTetheringSupported()811     public boolean connectivityIsTetheringSupported() {
812         return mManager.isTetheringSupported();
813     }
814 
815     @Rpc(description = "Call to start tethering with a provisioning check if needed")
connectivityStartTethering(@pcParametername = "type") Integer type, @RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi)816     public void connectivityStartTethering(@RpcParameter(name = "type") Integer type,
817             @RpcParameter(name = "showProvisioningUi") Boolean showProvisioningUi) {
818         Log.d("startTethering for type: " + type + " showProvUi: " + showProvisioningUi);
819         OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback();
820         mManager.startTethering(type, showProvisioningUi, tetherCallback);
821     }
822 
823     @Rpc(description = "Call to stop tethering")
connectivityStopTethering(@pcParametername = "type") Integer type)824     public void connectivityStopTethering(@RpcParameter(name = "type") Integer type) {
825         Log.d("stopTethering for type: " + type);
826         mManager.stopTethering(type);
827     }
828 
getInetAddrsForInterface(String ifaceName)829     private Enumeration<InetAddress> getInetAddrsForInterface(String ifaceName) {
830         NetworkInterface iface = null;
831         try {
832             iface = NetworkInterface.getByName(ifaceName);
833         } catch (SocketException e) {
834             return null;
835         }
836 
837         if (iface == null)
838             return null;
839         return iface.getInetAddresses();
840     }
841 
842     @Rpc(description = "Returns the link local IPv6 address of the interface.")
connectivityGetLinkLocalIpv6Address(@pcParametername = "ifaceName") String ifaceName)843     public String connectivityGetLinkLocalIpv6Address(@RpcParameter(name = "ifaceName")
844             String ifaceName) {
845         Inet6Address inet6Address = null;
846         Enumeration<InetAddress> inetAddresses = getInetAddrsForInterface(ifaceName);
847         if (inetAddresses == null) {
848             return null;
849         }
850 
851         while (inetAddresses.hasMoreElements()) {
852             InetAddress addr = inetAddresses.nextElement();
853             if (addr instanceof Inet6Address) {
854                 if (((Inet6Address) addr).isLinkLocalAddress()) {
855                     inet6Address = (Inet6Address) addr;
856                     break;
857                 }
858             }
859         }
860 
861         if (inet6Address == null) {
862             return null;
863         }
864 
865         return inet6Address.getHostAddress();
866     }
867 
868     @Rpc(description = "Return IPv4 address of an interface")
connectivityGetIPv4Addresses( @pcParametername = "ifaceName") String ifaceName)869     public List<String> connectivityGetIPv4Addresses(
870             @RpcParameter(name = "ifaceName") String ifaceName) {
871         Enumeration<InetAddress> inetAddresses
872                 = getInetAddrsForInterface(ifaceName);
873         if (inetAddresses == null)
874             return null;
875 
876         List<String> inetAddrs = new ArrayList<String>();
877         while (inetAddresses.hasMoreElements()) {
878             InetAddress addr = inetAddresses.nextElement();
879             if (addr instanceof Inet4Address) {
880                 Inet4Address inet4Address =  (Inet4Address) addr;
881                 inetAddrs.add(inet4Address.getHostAddress());
882             }
883         }
884 
885         return inetAddrs;
886     }
887 
888     @Rpc(description = "Return IPv6 addrs of an interface except link local")
connectivityGetIPv6Addresses( @pcParametername = "ifaceName") String ifaceName)889     public List<String> connectivityGetIPv6Addresses(
890             @RpcParameter(name = "ifaceName") String ifaceName) {
891         Enumeration<InetAddress> inetAddresses
892                 = getInetAddrsForInterface(ifaceName);
893         if (inetAddresses == null)
894             return null;
895 
896         List<String> inetAddrs = new ArrayList<String>();
897         while (inetAddresses.hasMoreElements()) {
898             InetAddress addr = inetAddresses.nextElement();
899             if (addr instanceof Inet6Address) {
900                 if (((Inet6Address) addr).isLinkLocalAddress())
901                     continue;
902                 Inet6Address inet6Address =  (Inet6Address) addr;
903                 inetAddrs.add(inet6Address.getHostAddress());
904             }
905         }
906 
907         return inetAddrs;
908     }
909 
910     @Rpc(description = "Returns active link properties")
connectivityGetActiveLinkProperties()911     public LinkProperties connectivityGetActiveLinkProperties() {
912         return mManager.getActiveLinkProperties();
913     }
914 
915     @Rpc(description = "Returns all IP addresses of the active link")
connectivityGetAllAddressesOfActiveLink()916     public List<InetAddress> connectivityGetAllAddressesOfActiveLink() {
917         LinkProperties linkProp = mManager.getActiveLinkProperties();
918         return linkProp.getAllAddresses();
919     }
920 
921     @Rpc(description = "Check if active link has default IPv6 route")
connectivityHasIPv6DefaultRoute()922     public boolean connectivityHasIPv6DefaultRoute() {
923         LinkProperties linkProp = mManager.getActiveLinkProperties();
924         return linkProp.hasIPv6DefaultRoute();
925     }
926 
927     @Rpc(description = "Factory reset of network policies")
connectivityFactoryResetNetworkPolicies(String subscriberId)928     public void connectivityFactoryResetNetworkPolicies(String subscriberId) {
929         mNetPolicyManager.factoryReset(subscriberId);
930     }
931 
932     /**
933      * Method to set data warning limit on the device.
934      */
935     @Rpc(description = "Set data warning limit for subscriber ID")
connectivitySetDataWarningLimit(String subscriberId, Long dataLimit)936     public void connectivitySetDataWarningLimit(String subscriberId, Long dataLimit) {
937         NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies();
938         for (int i = 0; i < allPolicies.length; i++) {
939             String subId = allPolicies[i].template.getSubscriberId();
940             if (subId != null && subId.equals(subscriberId)) {
941                 allPolicies[i].warningBytes = dataLimit.longValue();
942                 break;
943             }
944         }
945         mNetPolicyManager.setNetworkPolicies(allPolicies);
946     }
947 
948     /**
949      * Method to set data usage limit on the device.
950      */
951     @Rpc(description = "Set data usage limit for subscriber ID")
connectivitySetDataUsageLimit(String subscriberId, Long dataLimit)952     public void connectivitySetDataUsageLimit(String subscriberId, Long dataLimit) {
953         NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies();
954         for (int i = 0; i < allPolicies.length; i++) {
955             String subId = allPolicies[i].template.getSubscriberId();
956             if (subId != null && subId.equals(subscriberId)) {
957                 allPolicies[i].limitBytes = dataLimit.longValue();
958                 break;
959             }
960         }
961         mNetPolicyManager.setNetworkPolicies(allPolicies);
962     }
963 
964     /**
965      * Method to get data usage limit on the device.
966      */
967     @Rpc(description = "Get data usage limit for subscriber ID")
connectivityGetDataUsageLimit(String subscriberId)968     public long connectivityGetDataUsageLimit(String subscriberId) {
969         NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies();
970         for (int i = 0; i < allPolicies.length; i++) {
971             String subId = allPolicies[i].template.getSubscriberId();
972             if (subId != null && subId.equals(subscriberId)) return allPolicies[i].limitBytes;
973         }
974         return -1;
975     }
976 
977     /**
978      * Method to get data warning limit on the device
979      */
980     @Rpc(description = "Get data warning limit for subscriber ID")
connectivityGetDataWarningLimit(String subscriberId)981     public long connectivityGetDataWarningLimit(String subscriberId) {
982         NetworkPolicy[] allPolicies = mNetPolicyManager.getNetworkPolicies();
983         for (int i = 0; i < allPolicies.length; i++) {
984             String subId = allPolicies[i].template.getSubscriberId();
985             if (subId != null && subId.equals(subscriberId)) return allPolicies[i].warningBytes;
986         }
987         return -1;
988     }
989 
990     @Rpc(description = "Get network stats for device")
connectivityQuerySummaryForDevice(Integer connType, String subscriberId, Long startTime, Long endTime)991     public long connectivityQuerySummaryForDevice(Integer connType,
992             String subscriberId, Long startTime, Long endTime)
993             throws SecurityException, RemoteException {
994         Bucket bucket = mNetStatsManager.querySummaryForDevice(
995               connType, subscriberId, startTime, endTime);
996         return bucket.getTxBytes() + bucket.getRxBytes();
997     }
998 
999     @Rpc(description = "Get network stats for device - Rx bytes")
connectivityQuerySummaryForDeviceRxBytes(Integer connType, String subscriberId, Long startTime, Long endTime)1000     public long connectivityQuerySummaryForDeviceRxBytes(Integer connType,
1001             String subscriberId, Long startTime, Long endTime)
1002             throws SecurityException, RemoteException {
1003         Bucket bucket = mNetStatsManager.querySummaryForDevice(
1004               connType, subscriberId, startTime, endTime);
1005         return bucket.getRxBytes();
1006     }
1007 
1008     @Rpc(description = "Get network stats for UID")
connectivityQueryDetailsForUid(Integer connType, String subscriberId, Long startTime, Long endTime, Integer uid)1009     public long connectivityQueryDetailsForUid(Integer connType,
1010             String subscriberId, Long startTime, Long endTime, Integer uid)
1011             throws SecurityException, RemoteException {
1012         long totalData = 0;
1013         NetworkStats netStats = mNetStatsManager.queryDetailsForUid(
1014                 connType, subscriberId, startTime, endTime, uid);
1015         Bucket bucket = new Bucket();
1016         while(netStats.hasNextBucket() && netStats.getNextBucket(bucket)) {
1017             totalData += bucket.getTxBytes() + bucket.getRxBytes();
1018         }
1019         netStats.close();
1020         return totalData;
1021     }
1022 
1023     @Rpc(description = "Get network stats for UID - Rx bytes")
connectivityQueryDetailsForUidRxBytes(Integer connType, String subscriberId, Long startTime, Long endTime, Integer uid)1024     public long connectivityQueryDetailsForUidRxBytes(Integer connType,
1025             String subscriberId, Long startTime, Long endTime, Integer uid)
1026             throws SecurityException, RemoteException {
1027         long rxBytes = 0;
1028         NetworkStats netStats = mNetStatsManager.queryDetailsForUid(
1029                 connType, subscriberId, startTime, endTime, uid);
1030         Bucket bucket = new Bucket();
1031         while(netStats.hasNextBucket() && netStats.getNextBucket(bucket)) {
1032             rxBytes += bucket.getRxBytes();
1033         }
1034         netStats.close();
1035         return rxBytes;
1036     }
1037 
1038     @Rpc(description = "Returns all interfaces on the android deivce")
connectivityGetNetworkInterfaces()1039     public List<NetworkInterface> connectivityGetNetworkInterfaces() {
1040         List<NetworkInterface> interfaces = null;
1041         try {
1042             interfaces = Collections.list(
1043                   NetworkInterface.getNetworkInterfaces());
1044         } catch (SocketException e) {
1045             return null;
1046         };
1047 
1048         return interfaces;
1049     }
1050 
1051     /**
1052     * Get multipath preference for a given network.
1053     * @param networkId : network id of wifi or cell network
1054     * @return Integer value of multipath preference
1055     */
1056     @Rpc(description = "Return Multipath preference for a given network")
connectivityGetMultipathPreferenceForNetwork(Long networkId)1057     public Integer connectivityGetMultipathPreferenceForNetwork(Long networkId) {
1058         Network network = sNetworkHashMap.get(networkId.longValue());
1059         return mManager.getMultipathPreference(network);
1060     }
1061 
1062     /**
1063     * Return HashMap key for Network object.
1064     * @return long value of Network object key
1065     */
1066     @Rpc(description = "Return key to active network stored in a hash map")
connectivityGetActiveNetwork()1067     public long connectivityGetActiveNetwork() {
1068         Network network = mManager.getActiveNetwork();
1069         long id = network.getNetworkHandle();
1070         sNetworkHashMap.put(id, network);
1071         return id;
1072     }
1073 
1074     /**
1075     * Get mutlipath preference for active network.
1076     * @return Integer value of multipath preference
1077     */
1078     @Rpc(description = "Return Multipath preference for active network")
connectivityGetMultipathPreference()1079     public Integer connectivityGetMultipathPreference() {
1080         Network network = mManager.getActiveNetwork();
1081         return mManager.getMultipathPreference(network);
1082     }
1083 
1084     /**
1085     * Download file of a given url using Network#openConnection call.
1086     * @param networkId : network id of wifi or cell network
1087     * @param urlString : url in String format
1088     */
1089     @Rpc(description = "Download file on a given network with Network#openConnection")
connectivityNetworkOpenConnection(Long networkId, String urlString)1090     public void connectivityNetworkOpenConnection(Long networkId, String urlString) {
1091         Network network = sNetworkHashMap.get(networkId.longValue());
1092         try {
1093             URL url = new URL(urlString);
1094             URLConnection urlConnection = network.openConnection(url);
1095             File outFile = FileUtils.getExternalDownload();
1096             int lastIdx = urlString.lastIndexOf('/');
1097             String filename = urlString.substring(lastIdx + 1);
1098             Log.d("Using name from url: " + filename);
1099             outFile = new File(outFile, filename);
1100             InputStream in = new BufferedInputStream(urlConnection.getInputStream());
1101             OutputStream output = new FileOutputStream(outFile);
1102             ByteStreams.copy(in, output);
1103         } catch (IOException e) {
1104             Log.e("Failed to download file: " + e.toString());
1105         }
1106     }
1107 
1108     /**
1109      * Sets the global proxy using the given information.
1110      *
1111      * @param hostname hostname of the proxy
1112      * @param port     port set on the proxy server
1113      * @param exclList List of hostnames excluded
1114      */
1115     @Rpc(description = "Set global proxy")
connectivitySetGlobalProxy(String hostname, Integer port, String exclList)1116     public void connectivitySetGlobalProxy(String hostname, Integer port, String exclList) {
1117         ProxyInfo proxyInfo = new ProxyInfo(hostname, port.intValue(), exclList);
1118         mManager.setGlobalProxy(proxyInfo);
1119     }
1120 
1121     /**
1122      * Sets the global proxy using a PAC URI.
1123      *
1124      * @param pac PAC URI in string
1125      */
1126     @Rpc(description = "Set global proxy with proxy autoconfig")
connectivitySetGlobalPacProxy(String pac)1127     public void connectivitySetGlobalPacProxy(String pac) {
1128         ProxyInfo proxyInfo = new ProxyInfo(pac);
1129         mManager.setGlobalProxy(proxyInfo);
1130     }
1131 
1132     /**
1133      * Gets the global proxy settings.
1134      *
1135      * @return ProxyInfo object in dictionary
1136      */
1137     @Rpc(description = "Get global proxy")
connectivityGetGlobalProxy()1138     public ProxyInfo connectivityGetGlobalProxy() {
1139         ProxyInfo proxyInfo = mManager.getGlobalProxy();
1140         if (proxyInfo == null) return null;
1141         return proxyInfo;
1142     }
1143 
1144     /**
1145      * Resets the global proxy settings.
1146      */
1147     @Rpc(description = "Reset global proxy")
connectivityResetGlobalProxy()1148     public void connectivityResetGlobalProxy() {
1149         mManager.setGlobalProxy(null);
1150     }
1151 
1152     /**
1153      * Check if active network is metered.
1154      */
1155     @Rpc(description = "Is active network metered")
connectivityIsActiveNetworkMetered()1156     public boolean connectivityIsActiveNetworkMetered() {
1157         return mManager.isActiveNetworkMetered();
1158     }
1159 
1160     @Override
shutdown()1161     public void shutdown() {
1162         connectivityStopTrackingConnectivityStateChange();
1163     }
1164 }
1165