133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultzpackage com.xtremelabs.robolectric.shadows;
283628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin
31c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultzimport android.net.wifi.ScanResult;
4011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport android.net.wifi.WifiConfiguration;
570c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazurimport android.net.wifi.WifiInfo;
683628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwinimport android.net.wifi.WifiManager;
7011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport android.util.Pair;
870c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazurimport com.xtremelabs.robolectric.Robolectric;
922c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implementation;
1022c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implements;
1183628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin
12011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport java.util.ArrayList;
13011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport java.util.LinkedHashMap;
141c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultzimport java.util.List;
15011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport java.util.Map;
16011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
17011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultzimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
181c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz
1983628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin@SuppressWarnings({"UnusedDeclaration"})
2083628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin@Implements(WifiManager.class)
21afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williamspublic class ShadowWifiManager {
222d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer    private static float sSignalLevelInPercent=1f;
2374763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer    private boolean accessWifiStatePermission = true;
2483628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin    private boolean wifiEnabled = true;
25b4d20f1f3913e571cfc8d811b97a8e45920495a2Mike Mazur    private WifiInfo wifiInfo;
261c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    private List<ScanResult> scanResults;
27011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    private Map<Integer, WifiConfiguration> networkIdToConfiguredNetworks = new LinkedHashMap<Integer, WifiConfiguration>();
28011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public boolean wasSaved;
29011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    private Pair<Integer, Boolean> lastEnabledNetwork;
3083628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin
31de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
3283628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin    public boolean setWifiEnabled(boolean wifiEnabled) {
33b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur        checkAccessWifiStatePermission();
3483628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin        this.wifiEnabled = wifiEnabled;
3583628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin        return true;
3683628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin    }
3783628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin
38de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
3983628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin    public boolean isWifiEnabled() {
40b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur        checkAccessWifiStatePermission();
4183628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin        return wifiEnabled;
4283628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin    }
4383628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin
4470c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur    @Implementation
4570c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur    public WifiInfo getConnectionInfo() {
46b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur        checkAccessWifiStatePermission();
4770c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur        if (wifiInfo == null) {
4870c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur            wifiInfo = Robolectric.newInstanceOf(WifiInfo.class);
4970c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur        }
5070c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur        return wifiInfo;
5170c7d9dd5e7610ad85e4a1db654a8c8daaa15b0dMike Mazur    }
52b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur
531c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    @Implementation
541c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    public List<ScanResult> getScanResults() {
551c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz        return scanResults;
561c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    }
571c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz
58011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    @Implementation
59011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public List<WifiConfiguration> getConfiguredNetworks() {
60011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        final ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<WifiConfiguration>();
61011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        for (WifiConfiguration wifiConfiguration : networkIdToConfiguredNetworks.values()) {
62011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz            wifiConfigurations.add(wifiConfiguration);
63011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        }
64011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return wifiConfigurations;
65011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
66011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
67011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    @Implementation
68011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public int addNetwork(WifiConfiguration config) {
69011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        int networkId = networkIdToConfiguredNetworks.size();
70011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        config.networkId = -1;
71011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        networkIdToConfiguredNetworks.put(networkId, makeCopy(config, networkId));
72011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return networkId;
73011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
74011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
75011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    private WifiConfiguration makeCopy(WifiConfiguration config, int networkId) {
76011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        WifiConfiguration copy = shadowOf(config).copy();
77011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        copy.networkId = networkId;
78011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return copy;
79011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
80011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
81011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
82011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    @Implementation
83011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public int updateNetwork(WifiConfiguration config) {
84011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        if (config == null || config.networkId < 0) {
85011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz            return -1;
86011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        }
87011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        networkIdToConfiguredNetworks.put(config.networkId, makeCopy(config, config.networkId));
88011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return config.networkId;
89011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
90011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
91011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    @Implementation
92011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public boolean saveConfiguration() {
93011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        wasSaved = true;
94011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return true;
95011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
96011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
97011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    @Implementation
98011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public boolean enableNetwork(int netId, boolean disableOthers) {
99011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        lastEnabledNetwork = new Pair<Integer, Boolean>(netId, disableOthers);
100011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return true;
101011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
102011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
103759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    @Implementation
104759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    public WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) {
105759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        return Robolectric.newInstanceOf(WifiManager.WifiLock.class);
106759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    }
107759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
108759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    @Implementation
109759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    public WifiManager.WifiLock createWifiLock(java.lang.String tag) {
110759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        return createWifiLock(WifiManager.WIFI_MODE_FULL, tag);
111759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    }
1122d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer
1132d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer    @Implementation
1142d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer    public static int calculateSignalLevel (int rssi, int numLevels)
11574763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer    {
11674763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer        return (int)(sSignalLevelInPercent*(numLevels-1));
1172d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer    }
1182d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer
11974763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer    public static void setSignalLevelInPercent(float level) {
12074763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer        if (level < 0 || level > 1) {
12174763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer            throw new IllegalArgumentException(
12274763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer                    "level needs to be between 0 and 1");
12374763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer        }
12474763c0046940d5c91f68be9478015a905578ddaMatthias Kiefer        sSignalLevelInPercent = level;
1252d01c5fa22a0831c485d4f14992dc5aeb24a8c47Matthias Kiefer    }
126759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
127b4d20f1f3913e571cfc8d811b97a8e45920495a2Mike Mazur    public void setAccessWifiStatePermission(boolean accessWifiStatePermission) {
128b4d20f1f3913e571cfc8d811b97a8e45920495a2Mike Mazur        this.accessWifiStatePermission = accessWifiStatePermission;
129b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur    }
130b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur
131b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur    private void checkAccessWifiStatePermission() {
132b4d20f1f3913e571cfc8d811b97a8e45920495a2Mike Mazur        if (!accessWifiStatePermission) {
133b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur            throw new SecurityException();
134b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur        }
135b269a232e5f41e955a6c4bf3bdd84dd6cc08a6f3Mike Mazur    }
1361c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz
1371c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    public void setScanResults(List<ScanResult> scanResults) {
1381c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz        this.scanResults = scanResults;
1391c5a1843c60477a9a49148c46cb1b98d5ee5b26bTim Labeeuw & Tyler Schultz    }
140011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz
141011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    public Pair<Integer, Boolean> getLastEnabledNetwork() {
142011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz        return lastEnabledNetwork;
143011d50de8590a67a76d440ecfae2d8d2a114bcffTim Labeeuw & Tyler Schultz    }
144759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
145759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
146759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    @Implements(WifiManager.WifiLock.class)
147759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    public static class ShadowWifiLock {
148759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        private int refCount;
149759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        private boolean refCounted = true;
150759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        private boolean locked;
151759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        public static final int MAX_ACTIVE_LOCKS = 50;
152759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
153759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        @Implementation
154759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        public synchronized void acquire() {
155759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            if (refCounted) {
156759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel                if (++refCount >= MAX_ACTIVE_LOCKS) throw new UnsupportedOperationException("Exceeded maximum number of wifi locks");
157759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            } else {
158759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel                locked = true;
159759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            }
160759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        }
161759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
162759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        @Implementation
163759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        public synchronized void release() {
164759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            if (refCounted) {
165759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel                if (--refCount < 0) throw new RuntimeException("WifiLock under-locked");
166759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            } else {
167759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel                locked = false;
168759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            }
169759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        }
170759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
171759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        @Implementation
172759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        public synchronized boolean isHeld() {
173759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            return refCounted ? refCount > 0 : locked;
174759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        }
175759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel
176759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        @Implementation
177759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        public void setReferenceCounted(boolean refCounted) {
178759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel            this.refCounted = refCounted;
179759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel        }
180759be5980874ed70fa05573fc440f97c1e14bc0cJan Berkel    }
18183628c488feafc9655efb44de601004cf52ed0c7Christian Williams & Phil Goodwin}
182