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 32 public boolean setWifiEnabled(boolean wifiEnabled) { 33 checkAccessWifiStatePermission(); 34 this.wifiEnabled = wifiEnabled; 35 return true; 36 } 37 38 @Implementation 39 public boolean isWifiEnabled() { 40 checkAccessWifiStatePermission(); 41 return wifiEnabled; 42 } 43 44 @Implementation 45 public WifiInfo getConnectionInfo() { 46 checkAccessWifiStatePermission(); 47 if (wifiInfo == null) { 48 wifiInfo = Robolectric.newInstanceOf(WifiInfo.class); 49 } 50 return wifiInfo; 51 } 52 53 @Implementation 54 public List<ScanResult> getScanResults() { 55 return scanResults; 56 } 57 58 @Implementation 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 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 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 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 92 public boolean saveConfiguration() { 93 wasSaved = true; 94 return true; 95 } 96 97 @Implementation 98 public boolean enableNetwork(int netId, boolean disableOthers) { 99 lastEnabledNetwork = new Pair<Integer, Boolean>(netId, disableOthers); 100 return true; 101 } 102 103 @Implementation 104 public WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) { 105 return Robolectric.newInstanceOf(WifiManager.WifiLock.class); 106 } 107 108 @Implementation 109 public WifiManager.WifiLock createWifiLock(java.lang.String tag) { 110 return createWifiLock(WifiManager.WIFI_MODE_FULL, tag); 111 } 112 113 @Implementation 114 public static int calculateSignalLevel (int rssi, int numLevels) 115 { 116 return (int)(sSignalLevelInPercent*(numLevels-1)); 117 } 118 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 127 public void setAccessWifiStatePermission(boolean accessWifiStatePermission) { 128 this.accessWifiStatePermission = accessWifiStatePermission; 129 } 130 131 private void checkAccessWifiStatePermission() { 132 if (!accessWifiStatePermission) { 133 throw new SecurityException(); 134 } 135 } 136 137 public void setScanResults(List<ScanResult> scanResults) { 138 this.scanResults = scanResults; 139 } 140 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 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 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 172 public synchronized boolean isHeld() { 173 return refCounted ? refCount > 0 : locked; 174 } 175 176 @Implementation 177 public void setReferenceCounted(boolean refCounted) { 178 this.refCounted = refCounted; 179 } 180 } 181 } 182