• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 android.net;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.net.wifi.ScanResult;
24 import android.net.wifi.WifiInfo;
25 import android.net.wifi.WifiManager;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.text.TextUtils;
29 import android.util.Log;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 import java.util.Objects;
34 
35 /**
36  * Information which identifies a specific network.
37  *
38  * @hide
39  */
40 @SystemApi
41 // NOTE: Ideally, we would abstract away the details of what identifies a network of a specific
42 // type, so that all networks appear the same and can be scored without concern to the network type
43 // itself. However, because no such cross-type identifier currently exists in the Android framework,
44 // and because systems might obtain information about networks from sources other than Android
45 // devices, we need to provide identifying details about each specific network type (wifi, cell,
46 // etc.) so that clients can pull out these details depending on the type of network.
47 public class NetworkKey implements Parcelable {
48 
49     private static final String TAG = "NetworkKey";
50 
51     /** A wifi network, for which {@link #wifiKey} will be populated. */
52     public static final int TYPE_WIFI = 1;
53 
54     /** @hide */
55     @Retention(RetentionPolicy.SOURCE)
56     @IntDef(prefix = {"TYPE_"}, value = {
57             TYPE_WIFI
58     })
59     public @interface NetworkType {}
60 
61     /**
62      * The type of this network.
63      * @see #TYPE_WIFI
64      */
65     public final int type;
66 
67     /**
68      * Information identifying a Wi-Fi network. Only set when {@link #type} equals
69      * {@link #TYPE_WIFI}.
70      */
71     public final WifiKey wifiKey;
72 
73     /**
74      * Constructs a new NetworkKey for the given wifi {@link ScanResult}.
75      *
76      * @return A new {@link NetworkKey} instance or <code>null</code> if the given
77      *         {@link ScanResult} instance is malformed.
78      * @throws NullPointerException
79      */
80     @Nullable
createFromScanResult(@onNull ScanResult result)81     public static NetworkKey createFromScanResult(@NonNull ScanResult result) {
82         Objects.requireNonNull(result);
83         final String ssid = result.SSID;
84         if (TextUtils.isEmpty(ssid) || ssid.equals(WifiManager.UNKNOWN_SSID)) {
85             return null;
86         }
87         final String bssid = result.BSSID;
88         if (TextUtils.isEmpty(bssid)) {
89             return null;
90         }
91 
92         try {
93             WifiKey wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid);
94             return new NetworkKey(wifiKey);
95         } catch (IllegalArgumentException e) {
96             Log.e(TAG, "Unable to create WifiKey.", e);
97             return null;
98         }
99     }
100 
101     /**
102      * Constructs a new NetworkKey for the given {@link WifiInfo}.
103      *
104      * @param wifiInfo the {@link WifiInfo} to create a {@link NetworkKey} for.
105      * @return A new {@link NetworkKey} instance or <code>null</code> if the given {@link WifiInfo}
106      *         instance doesn't represent a connected WiFi network.
107      * @hide
108      */
109     @Nullable
createFromWifiInfo(@ullable WifiInfo wifiInfo)110     public static NetworkKey createFromWifiInfo(@Nullable WifiInfo wifiInfo) {
111         if (wifiInfo != null) {
112             final String ssid = wifiInfo.getSSID();
113             final String bssid = wifiInfo.getBSSID();
114             if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiManager.UNKNOWN_SSID)
115                     && !TextUtils.isEmpty(bssid)) {
116                 WifiKey wifiKey;
117                 try {
118                     wifiKey = new WifiKey(ssid, bssid);
119                 } catch (IllegalArgumentException e) {
120                     Log.e(TAG, "Unable to create WifiKey.", e);
121                     return null;
122                 }
123                 return new NetworkKey(wifiKey);
124             }
125         }
126         return null;
127     }
128 
129     /**
130      * Construct a new {@link NetworkKey} for a Wi-Fi network.
131      * @param wifiKey the {@link WifiKey} identifying this Wi-Fi network.
132      */
NetworkKey(WifiKey wifiKey)133     public NetworkKey(WifiKey wifiKey) {
134         this.type = TYPE_WIFI;
135         this.wifiKey = wifiKey;
136     }
137 
NetworkKey(Parcel in)138     private NetworkKey(Parcel in) {
139         type = in.readInt();
140         switch (type) {
141             case TYPE_WIFI:
142                 wifiKey = WifiKey.CREATOR.createFromParcel(in);
143                 break;
144             default:
145                 throw new IllegalArgumentException("Parcel has unknown type: " + type);
146         }
147     }
148 
149     @Override
describeContents()150     public int describeContents() {
151         return 0;
152     }
153 
154     @Override
writeToParcel(Parcel out, int flags)155     public void writeToParcel(Parcel out, int flags) {
156         out.writeInt(type);
157         switch (type) {
158             case TYPE_WIFI:
159                 wifiKey.writeToParcel(out, flags);
160                 break;
161             default:
162                 throw new IllegalStateException("NetworkKey has unknown type " + type);
163         }
164     }
165 
166     @Override
equals(@ullable Object o)167     public boolean equals(@Nullable Object o) {
168         if (this == o) return true;
169         if (o == null || getClass() != o.getClass()) return false;
170 
171         NetworkKey that = (NetworkKey) o;
172 
173         return type == that.type && Objects.equals(wifiKey, that.wifiKey);
174     }
175 
176     @Override
hashCode()177     public int hashCode() {
178         return Objects.hash(type, wifiKey);
179     }
180 
181     @NonNull
182     @Override
toString()183     public String toString() {
184         switch (type) {
185             case TYPE_WIFI:
186                 return wifiKey.toString();
187             default:
188                 // Don't throw an exception here in case someone is logging this object in a catch
189                 // block for debugging purposes.
190                 return "InvalidKey";
191         }
192     }
193 
194     public static final @android.annotation.NonNull Parcelable.Creator<NetworkKey> CREATOR =
195             new Parcelable.Creator<NetworkKey>() {
196                 @Override
197                 public NetworkKey createFromParcel(Parcel in) {
198                     return new NetworkKey(in);
199                 }
200 
201                 @Override
202                 public NetworkKey[] newArray(int size) {
203                     return new NetworkKey[size];
204                 }
205             };
206 }
207