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.android.settingslib.wifi;
18 
19 import android.content.Context;
20 import android.net.ConnectivityManager;
21 import android.net.NetworkInfo;
22 import android.net.wifi.ScanResult;
23 import android.net.wifi.WifiConfiguration;
24 import android.net.wifi.WifiInfo;
25 import android.net.wifi.WifiManager;
26 import android.os.Bundle;
27 import android.os.Parcelable;
28 
29 import androidx.annotation.Keep;
30 
31 import com.android.settingslib.wifi.AccessPoint.Speed;
32 
33 import java.util.ArrayList;
34 
35 /**
36 * Build and return a valid AccessPoint.
37 *
38 * Only intended for testing the AccessPoint class or creating Access points to be used in testing
39 * applications. AccessPoints were designed to only be populated by the mechanisms of scan results
40 * and wifi configurations.
41 */
42 @Keep
43 public class TestAccessPointBuilder {
44     // match the private values in WifiManager
45     private static final int MIN_RSSI = -100;
46     private static final int MAX_RSSI = -55;
47 
48     // set some sensible defaults
49     private String mBssid = null;
50     private int mSpeed = Speed.NONE;
51     private int mRssi = AccessPoint.UNREACHABLE_RSSI;
52     private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
53     private String ssid = "TestSsid";
54     private NetworkInfo mNetworkInfo = null;
55     private String mFqdn = null;
56     private String mProviderFriendlyName = null;
57     private int mSecurity = AccessPoint.SECURITY_NONE;
58     private WifiConfiguration mWifiConfig;
59     private WifiInfo mWifiInfo;
60 
61     Context mContext;
62     private ArrayList<ScanResult> mScanResults;
63     private ArrayList<TimestampedScoredNetwork> mScoredNetworkCache;
64 
65     @Keep
TestAccessPointBuilder(Context context)66     public TestAccessPointBuilder(Context context) {
67         mContext = context;
68     }
69 
70     @Keep
build()71     public AccessPoint build() {
72         Bundle bundle = new Bundle();
73 
74         WifiConfiguration wifiConfig = null;
75         // ephemeral networks don't have a WifiConfiguration object in AccessPoint representation.
76         if (mNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
77             wifiConfig = new WifiConfiguration();
78             wifiConfig.networkId = mNetworkId;
79             wifiConfig.BSSID = mBssid;
80         }
81 
82         bundle.putString(AccessPoint.KEY_SSID, ssid);
83         bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
84         bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
85         bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
86         if (mFqdn != null) {
87             bundle.putString(AccessPoint.KEY_PASSPOINT_UNIQUE_ID, mFqdn);
88         }
89         if (mProviderFriendlyName != null) {
90             bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
91         }
92         if (mScanResults != null) {
93             bundle.putParcelableArray(AccessPoint.KEY_SCANRESULTS,
94                     mScanResults.toArray(new Parcelable[mScanResults.size()]));
95         }
96         if (mScoredNetworkCache != null) {
97             bundle.putParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE, mScoredNetworkCache);
98         }
99         bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity);
100         bundle.putInt(AccessPoint.KEY_SPEED, mSpeed);
101 
102         AccessPoint ap = new AccessPoint(mContext, bundle);
103         ap.setRssi(mRssi);
104         return ap;
105     }
106 
107     @Keep
setActive(boolean active)108     public TestAccessPointBuilder setActive(boolean active) {
109         if (active) {
110             mNetworkInfo = new NetworkInfo(
111                 ConnectivityManager.TYPE_DUMMY,
112                 ConnectivityManager.TYPE_DUMMY,
113                 "TestNetwork",
114                 "TestNetwork");
115         } else {
116             mNetworkInfo = null;
117         }
118         return this;
119     }
120 
121     /**
122      * Set the rssi based upon the desired signal level.
123      *
124      * <p>Side effect: if this AccessPoint was previously unreachable,
125      * setting the level will also make it reachable.
126      */
127     @Keep
setLevel(int level)128     public TestAccessPointBuilder setLevel(int level) {
129         // Reversal of WifiManager.calculateSignalLevels
130         WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
131         int maxSignalLevel = wifiManager.getMaxSignalLevel();
132         if (level == 0) {
133             mRssi = MIN_RSSI;
134         } else if (level > maxSignalLevel) {
135             mRssi = MAX_RSSI;
136         } else {
137             float inputRange = MAX_RSSI - MIN_RSSI;
138             float outputRange = maxSignalLevel;
139             mRssi = (int) (level * inputRange / outputRange + MIN_RSSI);
140         }
141         return this;
142     }
143 
144     @Keep
setNetworkInfo(NetworkInfo info)145     public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
146         mNetworkInfo = info;
147         return this;
148     }
149 
150     @Keep
setRssi(int rssi)151     public TestAccessPointBuilder setRssi(int rssi) {
152         mRssi = rssi;
153         return this;
154     }
155 
setSpeed(int speed)156     public TestAccessPointBuilder setSpeed(int speed) {
157         mSpeed = speed;
158         return this;
159     }
160 
161     /**
162     * Set whether the AccessPoint is reachable.
163     * Side effect: if the signal level was not previously set,
164     * making an AccessPoint reachable will set the signal to the minimum level.
165     */
166     @Keep
setReachable(boolean reachable)167     public TestAccessPointBuilder setReachable(boolean reachable) {
168         if (reachable) {
169             // only override the mRssi if it hasn't been set yet
170             if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
171                 mRssi = MIN_RSSI;
172             }
173         } else {
174             mRssi = AccessPoint.UNREACHABLE_RSSI;
175         }
176         return this;
177     }
178 
179     @Keep
setSaved(boolean saved)180     public TestAccessPointBuilder setSaved(boolean saved){
181         if (saved) {
182              mNetworkId = 1;
183         } else {
184              mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
185         }
186         return this;
187     }
188 
189     @Keep
setSecurity(int security)190     public TestAccessPointBuilder setSecurity(int security) {
191         mSecurity = security;
192         return this;
193     }
194 
195     @Keep
setSsid(String newSsid)196     public TestAccessPointBuilder setSsid(String newSsid) {
197         ssid = newSsid;
198         return this;
199     }
200 
201     @Keep
setFqdn(String fqdn)202     public TestAccessPointBuilder setFqdn(String fqdn) {
203         mFqdn = fqdn;
204         return this;
205     }
206 
207     @Keep
setProviderFriendlyName(String friendlyName)208     public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
209         mProviderFriendlyName = friendlyName;
210         return this;
211     }
212 
213     @Keep
setWifiInfo(WifiInfo info)214     public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
215         mWifiInfo = info;
216         return this;
217     }
218 
219     /**
220      * Set the networkId in the WifiConfig.
221      *
222      * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
223      * AccessPoint a saved network.
224      */
225     @Keep
setNetworkId(int networkId)226     public TestAccessPointBuilder setNetworkId(int networkId) {
227         mNetworkId = networkId;
228         return this;
229     }
230 
setBssid(String bssid)231     public TestAccessPointBuilder setBssid(String bssid) {
232         mBssid = bssid;
233         return this;
234     }
235 
setScanResults(ArrayList<ScanResult> scanResults)236     public TestAccessPointBuilder setScanResults(ArrayList<ScanResult> scanResults) {
237         mScanResults = scanResults;
238         return this;
239     }
240 
setScoredNetworkCache( ArrayList<TimestampedScoredNetwork> scoredNetworkCache)241     public TestAccessPointBuilder setScoredNetworkCache(
242             ArrayList<TimestampedScoredNetwork> scoredNetworkCache) {
243         mScoredNetworkCache = scoredNetworkCache;
244         return this;
245     }
246 }
247