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