| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.libraries.tv.tvsystem.wifi; |
| |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.net.MacAddress; |
| import android.net.wifi.WifiConfiguration; |
| import android.net.wifi.WifiManager; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import com.android.internal.util.Preconditions; |
| |
| import java.nio.charset.StandardCharsets; |
| import java.util.Objects; |
| import java.util.concurrent.Executor; |
| |
| /** |
| * WiFi configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot). |
| * |
| * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the |
| * framework how it should open a hotspot. It is not meant to describe the network as it will be |
| * seen by clients; this role is currently served by {@link WifiConfiguration} (see |
| * {@link WifiManager.LocalOnlyHotspotReservation#getWifiConfiguration()}). |
| * |
| * Apps can use this to configure a local-only hotspot using |
| * {@link TvWifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor, |
| * WifiManager.LocalOnlyHotspotCallback)}. |
| * |
| * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to |
| * create a new instance. |
| * |
| * @hide |
| */ |
| @SystemApi |
| public final class SoftApConfiguration implements Parcelable { |
| /** |
| * SSID for the AP, or null for a framework-determined SSID. |
| */ |
| private final @Nullable |
| String mSsid; |
| /** |
| * BSSID for the AP, or null to use a framework-determined BSSID. |
| */ |
| private final @Nullable |
| MacAddress mBssid; |
| /** |
| * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). |
| */ |
| private final @Nullable |
| String mWpa2Passphrase; |
| |
| /** Private constructor for Builder and Parcelable implementation. */ |
| private SoftApConfiguration( |
| @Nullable String ssid, @Nullable MacAddress bssid, String wpa2Passphrase) { |
| mSsid = ssid; |
| mBssid = bssid; |
| mWpa2Passphrase = wpa2Passphrase; |
| } |
| |
| @Override |
| public boolean equals(Object otherObj) { |
| if (this == otherObj) { |
| return true; |
| } |
| if (!(otherObj instanceof SoftApConfiguration)) { |
| return false; |
| } |
| SoftApConfiguration other = (SoftApConfiguration) otherObj; |
| return Objects.equals(mSsid, other.mSsid) |
| && Objects.equals(mBssid, other.mBssid) |
| && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(mSsid, mBssid, mWpa2Passphrase); |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| dest.writeString(mSsid); |
| dest.writeParcelable(mBssid, flags); |
| dest.writeString(mWpa2Passphrase); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @NonNull |
| public static final Creator<SoftApConfiguration> CREATOR = new Creator<SoftApConfiguration>() { |
| @Override |
| public SoftApConfiguration createFromParcel(Parcel in) { |
| return new SoftApConfiguration( |
| in.readString(), |
| in.readParcelable(MacAddress.class.getClassLoader()), |
| in.readString()); |
| } |
| |
| @Override |
| public SoftApConfiguration[] newArray(int size) { |
| return new SoftApConfiguration[size]; |
| } |
| }; |
| |
| @Nullable |
| public String getSsid() { |
| return mSsid; |
| } |
| |
| @Nullable |
| public MacAddress getBssid() { |
| return mBssid; |
| } |
| |
| @Nullable |
| public String getWpa2Passphrase() { |
| return mWpa2Passphrase; |
| } |
| |
| /** |
| * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a |
| * Soft AP. |
| * |
| * All fields are optional. By default, SSID and BSSID are automatically chosen by the |
| * framework, and an open network is created. |
| */ |
| public static final class Builder { |
| private String mSsid; |
| private MacAddress mBssid; |
| private String mWpa2Passphrase; |
| |
| /** |
| * Constructs a Builder with default values (see {@link Builder}). |
| */ |
| public Builder() { |
| mSsid = null; |
| mBssid = null; |
| mWpa2Passphrase = null; |
| } |
| |
| /** |
| * Constructs a Builder initialized from an existing {@link SoftApConfiguration} instance. |
| */ |
| public Builder(@NonNull SoftApConfiguration other) { |
| Objects.requireNonNull(other); |
| |
| mSsid = other.mSsid; |
| mBssid = other.mBssid; |
| mWpa2Passphrase = other.mWpa2Passphrase; |
| } |
| |
| /** |
| * Builds the {@link SoftApConfiguration}. |
| * |
| * @return A new {@link SoftApConfiguration}, as configured by previous method calls. |
| */ |
| @NonNull |
| public SoftApConfiguration build() { |
| return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase); |
| } |
| |
| /** |
| * Specifies an SSID for the AP. |
| * |
| * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically |
| * chosen by the framework. |
| * @return Builder for chaining. |
| * @throws IllegalArgumentException when the SSID is empty or not valid Unicode. |
| */ |
| @NonNull |
| public Builder setSsid(@Nullable String ssid) { |
| if (ssid != null) { |
| Preconditions.checkStringNotEmpty(ssid); |
| Preconditions.checkArgument(StandardCharsets.UTF_8.newEncoder().canEncode(ssid)); |
| } |
| mSsid = ssid; |
| return this; |
| } |
| |
| /** |
| * Specifies a BSSID for the AP. |
| * |
| * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is |
| * responsible for avoiding collisions. |
| * @return Builder for chaining. |
| * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC |
| * address. |
| */ |
| @NonNull |
| public Builder setBssid(@Nullable MacAddress bssid) { |
| if (bssid != null) { |
| Preconditions.checkArgument(!bssid.equals(MacAddress.ALL_ZEROS_ADDRESS)); |
| Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS)); |
| } |
| mBssid = bssid; |
| return this; |
| } |
| |
| /** |
| * Specifies that this AP should use WPA2-PSK with the given passphrase. When set to null |
| * and no other encryption method is configured, an open network is created. |
| * |
| * @param passphrase The passphrase to use, or null to unset a previously-set WPA2-PSK |
| * configuration. |
| * @return Builder for chaining. |
| * @throws IllegalArgumentException when the passphrase is the empty string |
| */ |
| @NonNull |
| public Builder setWpa2Passphrase(@Nullable String passphrase) { |
| if (passphrase != null) { |
| Preconditions.checkStringNotEmpty(passphrase); |
| } |
| mWpa2Passphrase = passphrase; |
| return this; |
| } |
| } |
| } |