1 /* 2 * Copyright (C) 2023 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.wifi; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.net.wifi.util.PersistableBundleUtils; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.os.PersistableBundle; 27 28 import com.android.wifi.flags.Flags; 29 30 import java.util.Objects; 31 32 /** 33 * Vendor-provided data for HAL configuration. 34 * 35 * @hide 36 */ 37 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 38 @SystemApi 39 public final class OuiKeyedData implements Parcelable { 40 private static final String TAG = "OuiKeyedData"; 41 42 /** 24-bit OUI identifier to identify the vendor/OEM. */ 43 private final int mOui; 44 /** PersistableBundle containing the vendor-defined data. */ 45 private final PersistableBundle mData; 46 OuiKeyedData(int oui, @NonNull PersistableBundle data)47 private OuiKeyedData(int oui, @NonNull PersistableBundle data) { 48 mOui = oui; 49 mData = (data != null) ? data.deepCopy() : null; 50 } 51 52 /** 53 * Get the OUI for this object. 54 * 55 * <p>See {@link Builder#Builder(int, PersistableBundle)}} 56 */ 57 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getOui()58 public int getOui() { 59 return mOui; 60 } 61 62 /** 63 * Get the data for this object. 64 * 65 * <p>See {@link Builder#Builder(int, PersistableBundle)}} 66 */ 67 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getData()68 public @NonNull PersistableBundle getData() { 69 return mData; 70 } 71 validateOui(int oui)72 private static boolean validateOui(int oui) { 73 // OUI must be a non-zero 24-bit value. 74 return oui != 0 && (oui & 0xFF000000) == 0; 75 } 76 77 /** 78 * Validate the parameters in this instance. 79 * 80 * @return true if all parameters are valid, false otherwise 81 * @hide 82 */ validate()83 public boolean validate() { 84 return validateOui(mOui) && (getData() != null); 85 } 86 87 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 88 @Override equals(@ullable Object o)89 public boolean equals(@Nullable Object o) { 90 if (this == o) return true; 91 if (o == null || getClass() != o.getClass()) return false; 92 OuiKeyedData that = (OuiKeyedData) o; 93 return mOui == that.mOui && PersistableBundleUtils.isEqual(mData, that.mData); 94 } 95 96 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 97 @Override hashCode()98 public int hashCode() { 99 return Objects.hash(mOui, PersistableBundleUtils.getHashCode(mData)); 100 } 101 102 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 103 @Override toString()104 public String toString() { 105 return "{oui=" + Integer.toHexString(mOui) + ", data=" + getData() + "}"; 106 } 107 108 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 109 @Override describeContents()110 public int describeContents() { 111 return 0; 112 } 113 114 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 115 @Override writeToParcel(@onNull Parcel dest, int flags)116 public void writeToParcel(@NonNull Parcel dest, int flags) { 117 dest.writeInt(mOui); 118 dest.writePersistableBundle(mData); 119 } 120 121 /** @hide */ OuiKeyedData(@onNull Parcel in)122 OuiKeyedData(@NonNull Parcel in) { 123 this.mOui = in.readInt(); 124 this.mData = in.readPersistableBundle(); 125 } 126 127 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 128 @NonNull 129 public static final Parcelable.Creator<OuiKeyedData> CREATOR = 130 new Parcelable.Creator<OuiKeyedData>() { 131 @Override 132 public OuiKeyedData createFromParcel(Parcel in) { 133 return new OuiKeyedData(in); 134 } 135 136 @Override 137 public OuiKeyedData[] newArray(int size) { 138 return new OuiKeyedData[size]; 139 } 140 }; 141 142 /** Builder for {@link OuiKeyedData}. */ 143 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 144 public static final class Builder { 145 private final int mOui; 146 private final @NonNull PersistableBundle mData; 147 148 /** 149 * Constructor for {@link Builder}. 150 * 151 * @param oui 24-bit OUI identifier to identify the vendor/OEM. See 152 * https://standards-oui.ieee.org/ for more information. 153 * @param data PersistableBundle containing additional configuration data. The definition 154 * should be provided by the vendor, and should be known to both the caller and to the 155 * vendor's implementation of the Wi-Fi HALs. 156 */ 157 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) Builder(int oui, @NonNull PersistableBundle data)158 public Builder(int oui, @NonNull PersistableBundle data) { 159 mOui = oui; 160 mData = data; 161 } 162 163 /** Construct an OuiKeyedData object with the specified parameters. */ 164 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 165 @NonNull build()166 public OuiKeyedData build() { 167 OuiKeyedData ouiKeyedData = new OuiKeyedData(mOui, mData); 168 if (!ouiKeyedData.validate()) { 169 throw new IllegalArgumentException("Provided parameters are invalid"); 170 } 171 return ouiKeyedData; 172 } 173 } 174 } 175