blob: 5cd4eb576aad952df187d4d820c82b8220fcc1b8 [file] [log] [blame]
Jeff Davidsondc960e22014-04-07 15:19:44 -07001/*
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
17package android.net;
18
Roshan Piusc278f802019-11-14 07:19:12 -080019import android.annotation.IntDef;
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -070020import android.annotation.NonNull;
Jeremy Joslinba242732017-01-24 17:16:42 -080021import android.annotation.Nullable;
Jeff Davidson7be8e972014-07-16 17:24:46 -070022import android.annotation.SystemApi;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080023import android.net.wifi.ScanResult;
Jeremy Joslinba242732017-01-24 17:16:42 -080024import android.net.wifi.WifiInfo;
David Su1cdbf622019-11-13 15:06:41 -080025import android.net.wifi.WifiManager;
Jeff Davidsondc960e22014-04-07 15:19:44 -070026import android.os.Parcel;
27import android.os.Parcelable;
Jeremy Joslinba242732017-01-24 17:16:42 -080028import android.text.TextUtils;
Stephen Chenfde900d2017-02-14 16:40:21 -080029import android.util.Log;
Jeff Davidsondc960e22014-04-07 15:19:44 -070030
Roshan Piusc278f802019-11-14 07:19:12 -080031import java.lang.annotation.Retention;
32import java.lang.annotation.RetentionPolicy;
Jeff Davidson6a4b2202014-04-16 17:29:40 -070033import java.util.Objects;
34
Jeff Davidsondc960e22014-04-07 15:19:44 -070035/**
36 * Information which identifies a specific network.
37 *
38 * @hide
39 */
Jeff Davidson7be8e972014-07-16 17:24:46 -070040@SystemApi
Jeff Davidson6a4b2202014-04-16 17:29:40 -070041// 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.
Jeff Davidsondc960e22014-04-07 15:19:44 -070047public class NetworkKey implements Parcelable {
48
Stephen Chenfde900d2017-02-14 16:40:21 -080049 private static final String TAG = "NetworkKey";
50
Jeff Davidsondc960e22014-04-07 15:19:44 -070051 /** A wifi network, for which {@link #wifiKey} will be populated. */
52 public static final int TYPE_WIFI = 1;
53
Roshan Piusc278f802019-11-14 07:19:12 -080054 /** @hide */
55 @Retention(RetentionPolicy.SOURCE)
56 @IntDef(prefix = {"TYPE_"}, value = {
57 TYPE_WIFI
58 })
59 public @interface NetworkType {}
60
Jeff Davidsondc960e22014-04-07 15:19:44 -070061 /**
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 /**
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080074 * Constructs a new NetworkKey for the given wifi {@link ScanResult}.
75 *
Roshan Pius5af52d32020-01-22 13:11:36 -080076 * @return A new {@link NetworkKey} instance or <code>null</code> if the given
77 * {@link ScanResult} instance is malformed.
Roshan Pius82442da2020-01-23 06:26:52 -080078 * @throws NullPointerException
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080079 */
Stephen Chenfde900d2017-02-14 16:40:21 -080080 @Nullable
Roshan Pius5af52d32020-01-22 13:11:36 -080081 public static NetworkKey createFromScanResult(@NonNull ScanResult result) {
Roshan Pius82442da2020-01-23 06:26:52 -080082 Objects.requireNonNull(result);
David Su1cdbf622019-11-13 15:06:41 -080083 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 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080099 }
100
101 /**
Jeremy Joslinba242732017-01-24 17:16:42 -0800102 * 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
110 public static NetworkKey createFromWifiInfo(@Nullable WifiInfo wifiInfo) {
111 if (wifiInfo != null) {
112 final String ssid = wifiInfo.getSSID();
113 final String bssid = wifiInfo.getBSSID();
David Su1cdbf622019-11-13 15:06:41 -0800114 if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiManager.UNKNOWN_SSID)
Jeremy Joslinba242732017-01-24 17:16:42 -0800115 && !TextUtils.isEmpty(bssid)) {
Stephen Chenfde900d2017-02-14 16:40:21 -0800116 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);
Jeremy Joslinba242732017-01-24 17:16:42 -0800124 }
125 }
126 return null;
127 }
128
129 /**
Jeff Davidsondc960e22014-04-07 15:19:44 -0700130 * Construct a new {@link NetworkKey} for a Wi-Fi network.
131 * @param wifiKey the {@link WifiKey} identifying this Wi-Fi network.
132 */
133 public NetworkKey(WifiKey wifiKey) {
134 this.type = TYPE_WIFI;
135 this.wifiKey = wifiKey;
136 }
137
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
150 public int describeContents() {
151 return 0;
152 }
153
154 @Override
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
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -0700167 public boolean equals(@Nullable Object o) {
Jeff Davidson6a4b2202014-04-16 17:29:40 -0700168 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
177 public int hashCode() {
178 return Objects.hash(type, wifiKey);
179 }
180
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -0700181 @NonNull
Jeff Davidson6a4b2202014-04-16 17:29:40 -0700182 @Override
Jeff Davidsondc960e22014-04-07 15:19:44 -0700183 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
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700194 public static final @android.annotation.NonNull Parcelable.Creator<NetworkKey> CREATOR =
Jeff Davidsondc960e22014-04-07 15:19:44 -0700195 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}