1 package com.xtremelabs.robolectric.shadows;
2 
3 import android.net.wifi.ScanResult;
4 import android.net.wifi.WifiConfiguration;
5 import android.net.wifi.WifiInfo;
6 import android.net.wifi.WifiManager;
7 import android.util.Pair;
8 import com.xtremelabs.robolectric.Robolectric;
9 import com.xtremelabs.robolectric.internal.Implementation;
10 import com.xtremelabs.robolectric.internal.Implements;
11 
12 import java.util.ArrayList;
13 import java.util.LinkedHashMap;
14 import java.util.List;
15 import java.util.Map;
16 
17 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
18 
19 @SuppressWarnings({"UnusedDeclaration"})
20 @Implements(WifiManager.class)
21 public class ShadowWifiManager {
22     private static float sSignalLevelInPercent=1f;
23     private boolean accessWifiStatePermission = true;
24     private boolean wifiEnabled = true;
25     private WifiInfo wifiInfo;
26     private List<ScanResult> scanResults;
27     private Map<Integer, WifiConfiguration> networkIdToConfiguredNetworks = new LinkedHashMap<Integer, WifiConfiguration>();
28     public boolean wasSaved;
29     private Pair<Integer, Boolean> lastEnabledNetwork;
30 
31     @Implementation
setWifiEnabled(boolean wifiEnabled)32     public boolean setWifiEnabled(boolean wifiEnabled) {
33         checkAccessWifiStatePermission();
34         this.wifiEnabled = wifiEnabled;
35         return true;
36     }
37 
38     @Implementation
isWifiEnabled()39     public boolean isWifiEnabled() {
40         checkAccessWifiStatePermission();
41         return wifiEnabled;
42     }
43 
44     @Implementation
getConnectionInfo()45     public WifiInfo getConnectionInfo() {
46         checkAccessWifiStatePermission();
47         if (wifiInfo == null) {
48             wifiInfo = Robolectric.newInstanceOf(WifiInfo.class);
49         }
50         return wifiInfo;
51     }
52 
53     @Implementation
getScanResults()54     public List<ScanResult> getScanResults() {
55         return scanResults;
56     }
57 
58     @Implementation
getConfiguredNetworks()59     public List<WifiConfiguration> getConfiguredNetworks() {
60         final ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<WifiConfiguration>();
61         for (WifiConfiguration wifiConfiguration : networkIdToConfiguredNetworks.values()) {
62             wifiConfigurations.add(wifiConfiguration);
63         }
64         return wifiConfigurations;
65     }
66 
67     @Implementation
addNetwork(WifiConfiguration config)68     public int addNetwork(WifiConfiguration config) {
69         int networkId = networkIdToConfiguredNetworks.size();
70         config.networkId = -1;
71         networkIdToConfiguredNetworks.put(networkId, makeCopy(config, networkId));
72         return networkId;
73     }
74 
makeCopy(WifiConfiguration config, int networkId)75     private WifiConfiguration makeCopy(WifiConfiguration config, int networkId) {
76         WifiConfiguration copy = shadowOf(config).copy();
77         copy.networkId = networkId;
78         return copy;
79     }
80 
81 
82     @Implementation
updateNetwork(WifiConfiguration config)83     public int updateNetwork(WifiConfiguration config) {
84         if (config == null || config.networkId < 0) {
85             return -1;
86         }
87         networkIdToConfiguredNetworks.put(config.networkId, makeCopy(config, config.networkId));
88         return config.networkId;
89     }
90 
91     @Implementation
saveConfiguration()92     public boolean saveConfiguration() {
93         wasSaved = true;
94         return true;
95     }
96 
97     @Implementation
enableNetwork(int netId, boolean disableOthers)98     public boolean enableNetwork(int netId, boolean disableOthers) {
99         lastEnabledNetwork = new Pair<Integer, Boolean>(netId, disableOthers);
100         return true;
101     }
102 
103     @Implementation
createWifiLock(int lockType, java.lang.String tag)104     public WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) {
105         return Robolectric.newInstanceOf(WifiManager.WifiLock.class);
106     }
107 
108     @Implementation
createWifiLock(java.lang.String tag)109     public WifiManager.WifiLock createWifiLock(java.lang.String tag) {
110         return createWifiLock(WifiManager.WIFI_MODE_FULL, tag);
111     }
112 
113     @Implementation
calculateSignalLevel(int rssi, int numLevels)114     public static int calculateSignalLevel (int rssi, int numLevels)
115     {
116         return (int)(sSignalLevelInPercent*(numLevels-1));
117     }
118 
setSignalLevelInPercent(float level)119     public static void setSignalLevelInPercent(float level) {
120         if (level < 0 || level > 1) {
121             throw new IllegalArgumentException(
122                     "level needs to be between 0 and 1");
123         }
124         sSignalLevelInPercent = level;
125     }
126 
setAccessWifiStatePermission(boolean accessWifiStatePermission)127     public void setAccessWifiStatePermission(boolean accessWifiStatePermission) {
128         this.accessWifiStatePermission = accessWifiStatePermission;
129     }
130 
checkAccessWifiStatePermission()131     private void checkAccessWifiStatePermission() {
132         if (!accessWifiStatePermission) {
133             throw new SecurityException();
134         }
135     }
136 
setScanResults(List<ScanResult> scanResults)137     public void setScanResults(List<ScanResult> scanResults) {
138         this.scanResults = scanResults;
139     }
140 
getLastEnabledNetwork()141     public Pair<Integer, Boolean> getLastEnabledNetwork() {
142         return lastEnabledNetwork;
143     }
144 
145 
146     @Implements(WifiManager.WifiLock.class)
147     public static class ShadowWifiLock {
148         private int refCount;
149         private boolean refCounted = true;
150         private boolean locked;
151         public static final int MAX_ACTIVE_LOCKS = 50;
152 
153         @Implementation
acquire()154         public synchronized void acquire() {
155             if (refCounted) {
156                 if (++refCount >= MAX_ACTIVE_LOCKS) throw new UnsupportedOperationException("Exceeded maximum number of wifi locks");
157             } else {
158                 locked = true;
159             }
160         }
161 
162         @Implementation
release()163         public synchronized void release() {
164             if (refCounted) {
165                 if (--refCount < 0) throw new RuntimeException("WifiLock under-locked");
166             } else {
167                 locked = false;
168             }
169         }
170 
171         @Implementation
isHeld()172         public synchronized boolean isHeld() {
173             return refCounted ? refCount > 0 : locked;
174         }
175 
176         @Implementation
setReferenceCounted(boolean refCounted)177         public void setReferenceCounted(boolean refCounted) {
178             this.refCounted = refCounted;
179         }
180     }
181 }
182