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