Home | History | Annotate | Download | only in shadows
      1 package org.robolectric.shadows;
      2 
      3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
      4 import static android.os.Build.VERSION_CODES.LOLLIPOP;
      5 
      6 import android.net.DhcpInfo;
      7 import android.net.wifi.ScanResult;
      8 import android.net.wifi.WifiConfiguration;
      9 import android.net.wifi.WifiInfo;
     10 import android.net.wifi.WifiManager;
     11 import android.util.Pair;
     12 import java.util.ArrayList;
     13 import java.util.LinkedHashMap;
     14 import java.util.List;
     15 import java.util.Map;
     16 import org.robolectric.Shadows;
     17 import org.robolectric.annotation.Implementation;
     18 import org.robolectric.annotation.Implements;
     19 import org.robolectric.util.ReflectionHelpers;
     20 
     21 /**
     22  * Shadow for {@link android.net.wifi.WifiManager}.
     23  */
     24 @Implements(WifiManager.class)
     25 public class ShadowWifiManager {
     26   private static float sSignalLevelInPercent = 1f;
     27   private boolean accessWifiStatePermission = true;
     28   private boolean wifiEnabled = true;
     29   private boolean wasSaved = false;
     30   private WifiInfo wifiInfo;
     31   private List<ScanResult> scanResults;
     32   private final Map<Integer, WifiConfiguration> networkIdToConfiguredNetworks = new LinkedHashMap<>();
     33   private Pair<Integer, Boolean> lastEnabledNetwork;
     34   private DhcpInfo dhcpInfo;
     35   private boolean isScanAlwaysAvailable = true;
     36 
     37   @Implementation
     38   public boolean setWifiEnabled(boolean wifiEnabled) {
     39     checkAccessWifiStatePermission();
     40     this.wifiEnabled = wifiEnabled;
     41     return true;
     42   }
     43 
     44   @Implementation
     45   public boolean isWifiEnabled() {
     46     checkAccessWifiStatePermission();
     47     return wifiEnabled;
     48   }
     49 
     50   @Implementation
     51   public int getWifiState() {
     52     if (isWifiEnabled()) {
     53       return WifiManager.WIFI_STATE_ENABLED;
     54     } else {
     55       return WifiManager.WIFI_STATE_DISABLED;
     56     }
     57   }
     58 
     59   @Implementation
     60   public WifiInfo getConnectionInfo() {
     61     checkAccessWifiStatePermission();
     62     if (wifiInfo == null) {
     63       wifiInfo = ReflectionHelpers.callConstructor(WifiInfo.class);
     64     }
     65     return wifiInfo;
     66   }
     67 
     68   /**
     69    * Sets the connection info as the provided {@link WifiInfo}.
     70    */
     71   public void setConnectionInfo(WifiInfo wifiInfo) {
     72     this.wifiInfo = wifiInfo;
     73   }
     74 
     75   @Implementation
     76   public List<ScanResult> getScanResults() {
     77     return scanResults;
     78   }
     79 
     80   @Implementation
     81   public List<WifiConfiguration> getConfiguredNetworks() {
     82     final ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<>();
     83     for (WifiConfiguration wifiConfiguration : networkIdToConfiguredNetworks.values()) {
     84       wifiConfigurations.add(wifiConfiguration);
     85     }
     86     return wifiConfigurations;
     87   }
     88 
     89   @Implementation(minSdk = LOLLIPOP)
     90   public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
     91     return getConfiguredNetworks();
     92   }
     93 
     94   @Implementation
     95   public int addNetwork(WifiConfiguration config) {
     96     int networkId = networkIdToConfiguredNetworks.size();
     97     config.networkId = -1;
     98     networkIdToConfiguredNetworks.put(networkId, makeCopy(config, networkId));
     99     return networkId;
    100   }
    101 
    102   @Implementation
    103   public boolean removeNetwork(int netId) {
    104     networkIdToConfiguredNetworks.remove(netId);
    105     return true;
    106   }
    107 
    108   @Implementation
    109   public int updateNetwork(WifiConfiguration config) {
    110     if (config == null || config.networkId < 0) {
    111       return -1;
    112     }
    113     networkIdToConfiguredNetworks.put(config.networkId, makeCopy(config, config.networkId));
    114     return config.networkId;
    115   }
    116 
    117   @Implementation
    118   public boolean saveConfiguration() {
    119     wasSaved = true;
    120     return true;
    121   }
    122 
    123   @Implementation
    124   public boolean enableNetwork(int netId, boolean disableOthers) {
    125     lastEnabledNetwork = new Pair<>(netId, disableOthers);
    126     return true;
    127   }
    128 
    129   @Implementation
    130   public WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) {
    131     return ReflectionHelpers.callConstructor(WifiManager.WifiLock.class);
    132   }
    133 
    134   @Implementation
    135   public WifiManager.WifiLock createWifiLock(java.lang.String tag) {
    136     return createWifiLock(WifiManager.WIFI_MODE_FULL, tag);
    137   }
    138 
    139   @Implementation
    140   public static int calculateSignalLevel(int rssi, int numLevels) {
    141     return (int) (sSignalLevelInPercent * (numLevels - 1));
    142   }
    143 
    144   @Implementation
    145   public boolean startScan() {
    146     return true;
    147   }
    148 
    149   @Implementation
    150   public DhcpInfo getDhcpInfo() {
    151     return dhcpInfo;
    152   }
    153 
    154   @Implementation(minSdk = JELLY_BEAN_MR2)
    155   public boolean isScanAlwaysAvailable() {
    156     return isScanAlwaysAvailable;
    157   }
    158 
    159   public static void setSignalLevelInPercent(float level) {
    160     if (level < 0 || level > 1) {
    161       throw new IllegalArgumentException("level needs to be between 0 and 1");
    162     }
    163     sSignalLevelInPercent = level;
    164   }
    165 
    166   public void setAccessWifiStatePermission(boolean accessWifiStatePermission) {
    167     this.accessWifiStatePermission = accessWifiStatePermission;
    168   }
    169 
    170   public void setScanResults(List<ScanResult> scanResults) {
    171     this.scanResults = scanResults;
    172   }
    173 
    174   public void setDhcpInfo(DhcpInfo dhcpInfo) {
    175     this.dhcpInfo = dhcpInfo;
    176   }
    177 
    178   public Pair<Integer, Boolean> getLastEnabledNetwork() {
    179     return lastEnabledNetwork;
    180   }
    181 
    182   public boolean wasConfigurationSaved() {
    183     return wasSaved;
    184   }
    185 
    186   public void setIsScanAlwaysAvailable(boolean isScanAlwaysAvailable) {
    187     this.isScanAlwaysAvailable = isScanAlwaysAvailable;
    188   }
    189 
    190   private void checkAccessWifiStatePermission() {
    191     if (!accessWifiStatePermission) {
    192       throw new SecurityException();
    193     }
    194   }
    195 
    196   private WifiConfiguration makeCopy(WifiConfiguration config, int networkId) {
    197     WifiConfiguration copy = Shadows.shadowOf(config).copy();
    198     copy.networkId = networkId;
    199     return copy;
    200   }
    201 
    202   @Implements(WifiManager.WifiLock.class)
    203   public static class ShadowWifiLock {
    204     private int refCount;
    205     private boolean refCounted = true;
    206     private boolean locked;
    207     public static final int MAX_ACTIVE_LOCKS = 50;
    208 
    209     @Implementation
    210     public synchronized void acquire() {
    211       if (refCounted) {
    212         if (++refCount >= MAX_ACTIVE_LOCKS) throw new UnsupportedOperationException("Exceeded maximum number of wifi locks");
    213       } else {
    214         locked = true;
    215       }
    216     }
    217 
    218     @Implementation
    219     public synchronized void release() {
    220       if (refCounted) {
    221         if (--refCount < 0) throw new RuntimeException("WifiLock under-locked");
    222       } else {
    223         locked = false;
    224       }
    225     }
    226 
    227     @Implementation
    228     public synchronized boolean isHeld() {
    229       return refCounted ? refCount > 0 : locked;
    230     }
    231 
    232     @Implementation
    233     public void setReferenceCounted(boolean refCounted) {
    234       this.refCounted = refCounted;
    235     }
    236   }
    237 }
    238