1 /* 2 * Copyright (C) 2020 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 static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ; 20 import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ; 21 import static android.net.wifi.WifiScanner.WIFI_BAND_6_GHZ; 22 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.SystemApi; 26 import android.os.Build; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 30 import androidx.annotation.RequiresApi; 31 32 import com.android.modules.utils.build.SdkLevel; 33 34 import java.util.Objects; 35 36 /** 37 * Data structure class representing a Wi-Fi channel that would cause interference to/receive 38 * interference from the active cellular channels and should be avoided. 39 * 40 * @hide 41 */ 42 @SystemApi 43 @RequiresApi(Build.VERSION_CODES.S) 44 public final class CoexUnsafeChannel implements Parcelable { 45 public static final int POWER_CAP_NONE = Integer.MAX_VALUE; 46 47 private @WifiAnnotations.WifiBandBasic int mBand; 48 private int mChannel; 49 private int mPowerCapDbm; 50 51 /** 52 * Constructor for a CoexUnsafeChannel with no power cap specified. 53 * @param band One of {@link WifiAnnotations.WifiBandBasic} 54 * @param channel Channel number 55 */ CoexUnsafeChannel(@ifiAnnotations.WifiBandBasic int band, int channel)56 public CoexUnsafeChannel(@WifiAnnotations.WifiBandBasic int band, int channel) { 57 if (!SdkLevel.isAtLeastS()) { 58 throw new UnsupportedOperationException(); 59 } 60 mBand = band; 61 mChannel = channel; 62 mPowerCapDbm = POWER_CAP_NONE; 63 } 64 65 /** 66 * Constructor for a CoexUnsafeChannel with power cap specified. 67 * @param band One of {@link WifiAnnotations.WifiBandBasic} 68 * @param channel Channel number 69 * @param powerCapDbm Power cap in dBm 70 */ CoexUnsafeChannel(@ifiAnnotations.WifiBandBasic int band, int channel, int powerCapDbm)71 public CoexUnsafeChannel(@WifiAnnotations.WifiBandBasic int band, int channel, 72 int powerCapDbm) { 73 if (!SdkLevel.isAtLeastS()) { 74 throw new UnsupportedOperationException(); 75 } 76 mBand = band; 77 mChannel = channel; 78 mPowerCapDbm = powerCapDbm; 79 } 80 81 /** Returns the Wi-Fi band of this channel as one of {@link WifiAnnotations.WifiBandBasic} */ getBand()82 public @WifiAnnotations.WifiBandBasic int getBand() { 83 return mBand; 84 } 85 86 /** Returns the channel number of this channel. */ getChannel()87 public int getChannel() { 88 return mChannel; 89 } 90 91 /** 92 * Returns the power cap of this channel in dBm or {@link CoexUnsafeChannel#POWER_CAP_NONE} 93 * if the power cap is not specified. 94 */ getPowerCapDbm()95 public int getPowerCapDbm() { 96 return mPowerCapDbm; 97 } 98 99 @Override equals(@ullable Object o)100 public boolean equals(@Nullable Object o) { 101 if (this == o) return true; 102 if (o == null || getClass() != o.getClass()) return false; 103 CoexUnsafeChannel that = (CoexUnsafeChannel) o; 104 return mBand == that.mBand 105 && mChannel == that.mChannel 106 && mPowerCapDbm == that.mPowerCapDbm; 107 } 108 109 @Override hashCode()110 public int hashCode() { 111 return Objects.hash(mBand, mChannel, mPowerCapDbm); 112 } 113 114 @Override toString()115 public String toString() { 116 StringBuilder sj = new StringBuilder("CoexUnsafeChannel{"); 117 if (mBand == WIFI_BAND_24_GHZ) { 118 sj.append("2.4GHz"); 119 } else if (mBand == WIFI_BAND_5_GHZ) { 120 sj.append("5GHz"); 121 } else if (mBand == WIFI_BAND_6_GHZ) { 122 sj.append("6GHz"); 123 } else { 124 sj.append("UNKNOWN BAND"); 125 } 126 sj.append(", ").append(mChannel); 127 if (mPowerCapDbm != POWER_CAP_NONE) { 128 sj.append(", ").append(mPowerCapDbm).append("dBm"); 129 } 130 sj.append('}'); 131 return sj.toString(); 132 } 133 134 /** Implement the Parcelable interface {@hide} */ 135 @Override describeContents()136 public int describeContents() { 137 return 0; 138 } 139 140 /** Implement the Parcelable interface {@hide} */ 141 @Override writeToParcel(Parcel dest, int flags)142 public void writeToParcel(Parcel dest, int flags) { 143 dest.writeInt(mBand); 144 dest.writeInt(mChannel); 145 dest.writeInt(mPowerCapDbm); 146 } 147 148 /** Implement the Parcelable interface */ 149 public static final @NonNull Creator<CoexUnsafeChannel> CREATOR = 150 new Creator<CoexUnsafeChannel>() { 151 public CoexUnsafeChannel createFromParcel(Parcel in) { 152 final int band = in.readInt(); 153 final int channel = in.readInt(); 154 final int powerCapDbm = in.readInt(); 155 return new CoexUnsafeChannel(band, channel, powerCapDbm); 156 } 157 158 public CoexUnsafeChannel[] newArray(int size) { 159 return new CoexUnsafeChannel[size]; 160 } 161 }; 162 } 163