1 /* 2 * Copyright (C) 2018 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.telephony; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.List; 31 import java.util.Objects; 32 33 /** 34 * Phone capability which describes the data connection capability of modem. 35 * It's used to evaluate possible phone config change, for example from single 36 * SIM device to multi-SIM device. 37 * @hide 38 */ 39 @SystemApi 40 public final class PhoneCapability implements Parcelable { 41 // Hardcoded default DSDS capability. 42 /** @hide */ 43 public static final PhoneCapability DEFAULT_DSDS_CAPABILITY; 44 // Hardcoded default Single SIM single standby capability. 45 /** @hide */ 46 public static final PhoneCapability DEFAULT_SSSS_CAPABILITY; 47 48 /** @hide */ 49 @Retention(RetentionPolicy.SOURCE) 50 @IntDef(prefix = { "DEVICE_NR_CAPABILITY_" }, value = { 51 DEVICE_NR_CAPABILITY_NSA, 52 DEVICE_NR_CAPABILITY_SA, 53 }) 54 public @interface DeviceNrCapability {} 55 56 /** 57 * Indicates DEVICE_NR_CAPABILITY_NSA determine that the device enable the non-standalone 58 * (NSA) mode of 5G NR. 59 * @hide 60 */ 61 @SystemApi 62 public static final int DEVICE_NR_CAPABILITY_NSA = 1; 63 64 /** 65 * Indicates DEVICE_NR_CAPABILITY_SA determine that the device enable the standalone (SA) 66 * mode of 5G NR. 67 * @hide 68 */ 69 @SystemApi 70 public static final int DEVICE_NR_CAPABILITY_SA = 2; 71 72 static { 73 ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true); 74 ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true); 75 76 List<ModemInfo> logicalModemList = new ArrayList<>(); 77 logicalModemList.add(modemInfo1); 78 logicalModemList.add(modemInfo2); 79 int[] deviceNrCapabilities = new int[0]; 80 81 DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, logicalModemList, false, 82 deviceNrCapabilities); 83 84 logicalModemList = new ArrayList<>(); 85 logicalModemList.add(modemInfo1); 86 DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, logicalModemList, false, 87 deviceNrCapabilities); 88 } 89 90 /** 91 * mMaxActiveVoiceSubscriptions defines the maximum subscriptions that can support 92 * simultaneous voice calls. For a dual sim dual standby (DSDS) device it would be one, but 93 * for a dual sim dual active (DSDA) device, or a DSDS device that supports "virtual DSDA" ( 94 * using the data line of 1 SIM to temporarily provide IMS voice connectivity to the other SIM) 95 * it would be 2. 96 * 97 * @hide 98 */ 99 private final int mMaxActiveVoiceSubscriptions; 100 101 /** 102 * mMaxActiveDataSubscriptions defines the maximum subscriptions that can support 103 * simultaneous data connections. 104 * For example, for dual sim dual active L+L device it should be 2. 105 * 106 * @hide 107 */ 108 private final int mMaxActiveDataSubscriptions; 109 110 /** 111 * Whether modem supports both internet PDN up so 112 * that we can do ping test before tearing down the 113 * other one. 114 * 115 * @hide 116 */ 117 private final boolean mNetworkValidationBeforeSwitchSupported; 118 119 /** 120 * List of logical modem information. 121 * 122 * @hide 123 */ 124 @NonNull 125 private final List<ModemInfo> mLogicalModemList; 126 127 /** 128 * Device NR capabilities. 129 * 130 * @hide 131 */ 132 @NonNull 133 private final int[] mDeviceNrCapabilities; 134 135 /** @hide */ PhoneCapability(int maxActiveVoiceSubscriptions, int maxActiveDataSubscriptions, List<ModemInfo> logicalModemList, boolean networkValidationBeforeSwitchSupported, int[] deviceNrCapabilities)136 public PhoneCapability(int maxActiveVoiceSubscriptions, int maxActiveDataSubscriptions, 137 List<ModemInfo> logicalModemList, boolean networkValidationBeforeSwitchSupported, 138 int[] deviceNrCapabilities) { 139 this.mMaxActiveVoiceSubscriptions = maxActiveVoiceSubscriptions; 140 this.mMaxActiveDataSubscriptions = maxActiveDataSubscriptions; 141 // Make sure it's not null. 142 this.mLogicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList; 143 this.mNetworkValidationBeforeSwitchSupported = networkValidationBeforeSwitchSupported; 144 this.mDeviceNrCapabilities = deviceNrCapabilities; 145 } 146 PhoneCapability(@onNull Builder builder)147 private PhoneCapability(@NonNull Builder builder) { 148 this.mMaxActiveVoiceSubscriptions = builder.mMaxActiveVoiceSubscriptions; 149 this.mMaxActiveDataSubscriptions = builder.mMaxActiveDataSubscriptions; 150 // Make sure it's not null. 151 this.mLogicalModemList = builder.mLogicalModemList == null ? new ArrayList<>() 152 : builder.mLogicalModemList; 153 this.mNetworkValidationBeforeSwitchSupported = 154 builder.mNetworkValidationBeforeSwitchSupported; 155 this.mDeviceNrCapabilities = builder.mDeviceNrCapabilities; 156 157 } 158 159 @Override toString()160 public String toString() { 161 return "mMaxActiveVoiceSubscriptions=" + mMaxActiveVoiceSubscriptions 162 + " mMaxActiveDataSubscriptions=" + mMaxActiveDataSubscriptions 163 + " mNetworkValidationBeforeSwitchSupported=" 164 + mNetworkValidationBeforeSwitchSupported 165 + " mDeviceNrCapability " + Arrays.toString(mDeviceNrCapabilities); 166 } 167 PhoneCapability(Parcel in)168 private PhoneCapability(Parcel in) { 169 mMaxActiveVoiceSubscriptions = in.readInt(); 170 mMaxActiveDataSubscriptions = in.readInt(); 171 mNetworkValidationBeforeSwitchSupported = in.readBoolean(); 172 mLogicalModemList = new ArrayList<>(); 173 in.readList(mLogicalModemList, ModemInfo.class.getClassLoader(), android.telephony.ModemInfo.class); 174 mDeviceNrCapabilities = in.createIntArray(); 175 } 176 177 @Override hashCode()178 public int hashCode() { 179 return Objects.hash(mMaxActiveVoiceSubscriptions, 180 mMaxActiveDataSubscriptions, 181 mLogicalModemList, 182 mNetworkValidationBeforeSwitchSupported, 183 Arrays.hashCode(mDeviceNrCapabilities)); 184 } 185 186 @Override equals(Object o)187 public boolean equals(Object o) { 188 if (o == null || !(o instanceof PhoneCapability) || hashCode() != o.hashCode()) { 189 return false; 190 } 191 192 if (this == o) { 193 return true; 194 } 195 196 PhoneCapability s = (PhoneCapability) o; 197 198 return (mMaxActiveVoiceSubscriptions == s.mMaxActiveVoiceSubscriptions 199 && mMaxActiveDataSubscriptions == s.mMaxActiveDataSubscriptions 200 && mNetworkValidationBeforeSwitchSupported 201 == s.mNetworkValidationBeforeSwitchSupported 202 && mLogicalModemList.equals(s.mLogicalModemList) 203 && Arrays.equals(mDeviceNrCapabilities, s.mDeviceNrCapabilities)); 204 } 205 206 /** 207 * {@link Parcelable#describeContents} 208 */ describeContents()209 public int describeContents() { 210 return 0; 211 } 212 213 /** 214 * {@link Parcelable#writeToParcel} 215 */ writeToParcel(@onNull Parcel dest, @Parcelable.WriteFlags int flags)216 public void writeToParcel(@NonNull Parcel dest, @Parcelable.WriteFlags int flags) { 217 dest.writeInt(mMaxActiveVoiceSubscriptions); 218 dest.writeInt(mMaxActiveDataSubscriptions); 219 dest.writeBoolean(mNetworkValidationBeforeSwitchSupported); 220 dest.writeList(mLogicalModemList); 221 dest.writeIntArray(mDeviceNrCapabilities); 222 } 223 224 public static final @android.annotation.NonNull Parcelable.Creator<PhoneCapability> CREATOR = 225 new Parcelable.Creator() { 226 public PhoneCapability createFromParcel(Parcel in) { 227 return new PhoneCapability(in); 228 } 229 230 public PhoneCapability[] newArray(int size) { 231 return new PhoneCapability[size]; 232 } 233 }; 234 235 /** 236 * @return the maximum subscriptions that can support simultaneous voice calls. For a dual 237 * sim dual standby (DSDS) device it would be one, but for a dual sim dual active device it 238 * would be 2. 239 * @hide 240 */ 241 @SystemApi getMaxActiveVoiceSubscriptions()242 public @IntRange(from = 1) int getMaxActiveVoiceSubscriptions() { 243 return mMaxActiveVoiceSubscriptions; 244 } 245 246 /** 247 * @return the maximum subscriptions that can support simultaneous data connections. 248 * For example, for L+L device it should be 2. 249 * @hide 250 */ 251 @SystemApi getMaxActiveDataSubscriptions()252 public @IntRange(from = 1) int getMaxActiveDataSubscriptions() { 253 return mMaxActiveDataSubscriptions; 254 } 255 256 /** 257 * @return Check whether the Citizens Broadband Radio Service(CBRS) network validation before 258 * CBRS switch is supported or not. 259 * 260 * @hide 261 */ isNetworkValidationBeforeSwitchSupported()262 public boolean isNetworkValidationBeforeSwitchSupported() { 263 return mNetworkValidationBeforeSwitchSupported; 264 } 265 266 /** 267 * @return The list of logical modem information. 268 * @hide 269 */ getLogicalModemList()270 public List<ModemInfo> getLogicalModemList() { 271 return mLogicalModemList; 272 } 273 274 /** 275 * Return List of the device's NR capability. If the device doesn't support NR capability, 276 * then this api return empty array. 277 * @see DEVICE_NR_CAPABILITY_NSA 278 * @see DEVICE_NR_CAPABILITY_SA 279 * 280 * @return List of the device's NR capability. 281 * @hide 282 */ 283 @SystemApi getDeviceNrCapabilities()284 public @NonNull @DeviceNrCapability int[] getDeviceNrCapabilities() { 285 return mDeviceNrCapabilities == null ? (new int[0]) : mDeviceNrCapabilities; 286 } 287 288 289 /** 290 * Builder for {@link PhoneCapability}. 291 * 292 * @hide 293 */ 294 public static class Builder { 295 /** 296 * mMaxActiveVoiceSubscriptions defines the maximum subscriptions that can support 297 * simultaneous voice calls. For a dual sim dual standby (DSDS) device it would be one, but 298 * for a dual sim dual active (DSDA) device, or a DSDS device that supports "virtual DSDA" 299 * (using the data line of 1 SIM to temporarily provide IMS voice connectivity to the other 300 * SIM) it would be 2. 301 * 302 * @hide 303 */ 304 private int mMaxActiveVoiceSubscriptions = 0; 305 306 /** 307 * mMaxActiveDataSubscriptions defines the maximum subscriptions that can support 308 * simultaneous data connections. For example, for L+L device it should be 2. 309 * 310 * @hide 311 */ 312 private int mMaxActiveDataSubscriptions = 0; 313 314 /** 315 * Whether modem supports both internet PDN up so that we can do ping test before tearing 316 * down the other one. 317 * 318 * @hide 319 */ 320 private boolean mNetworkValidationBeforeSwitchSupported = false; 321 322 /** 323 * List of logical modem information. 324 * 325 * @hide 326 */ 327 @NonNull 328 private List<ModemInfo> mLogicalModemList = new ArrayList<>(); 329 330 /** 331 * Device NR capabilities. 332 * 333 * @hide 334 */ 335 @NonNull 336 private int[] mDeviceNrCapabilities = new int[0]; 337 338 /** 339 * Default constructor. 340 */ Builder()341 public Builder() { 342 } 343 Builder(@onNull PhoneCapability phoneCapability)344 public Builder(@NonNull PhoneCapability phoneCapability) { 345 mMaxActiveVoiceSubscriptions = phoneCapability.mMaxActiveVoiceSubscriptions; 346 mMaxActiveDataSubscriptions = phoneCapability.mMaxActiveDataSubscriptions; 347 mNetworkValidationBeforeSwitchSupported = 348 phoneCapability.mNetworkValidationBeforeSwitchSupported; 349 mLogicalModemList = phoneCapability.mLogicalModemList; 350 mDeviceNrCapabilities = phoneCapability.mDeviceNrCapabilities; 351 } 352 353 /** 354 * Sets the max active voice subscriptions supported by the device. 355 */ setMaxActiveVoiceSubscriptions(int maxActiveVoiceSubscriptions)356 public Builder setMaxActiveVoiceSubscriptions(int maxActiveVoiceSubscriptions) { 357 mMaxActiveVoiceSubscriptions = maxActiveVoiceSubscriptions; 358 return this; 359 } 360 361 /** 362 * Sets the max active voice subscriptions supported by the device. 363 */ setMaxActiveDataSubscriptions(int maxActiveDataSubscriptions)364 public Builder setMaxActiveDataSubscriptions(int maxActiveDataSubscriptions) { 365 mMaxActiveDataSubscriptions = maxActiveDataSubscriptions; 366 return this; 367 } 368 369 /** 370 * Sets the max active data subscriptions supported by the device. Can be fewer than the 371 * active voice subscriptions. 372 */ setNetworkValidationBeforeSwitchSupported( boolean networkValidationBeforeSwitchSupported)373 public Builder setNetworkValidationBeforeSwitchSupported( 374 boolean networkValidationBeforeSwitchSupported) { 375 mNetworkValidationBeforeSwitchSupported = networkValidationBeforeSwitchSupported; 376 return this; 377 } 378 379 /** 380 * Sets the logical modem list of the device. 381 */ setLogicalModemList(@onNull List<ModemInfo> logicalModemList)382 public Builder setLogicalModemList(@NonNull List<ModemInfo> logicalModemList) { 383 mLogicalModemList = logicalModemList; 384 return this; 385 } 386 387 /** 388 * Sets the NR capabilities supported by the device. 389 */ setDeviceNrCapabilities(@onNull int[] deviceNrCapabilities)390 public Builder setDeviceNrCapabilities(@NonNull int[] deviceNrCapabilities) { 391 mDeviceNrCapabilities = deviceNrCapabilities; 392 return this; 393 } 394 395 /** 396 * Build the {@link PhoneCapability}. 397 * 398 * @return The {@link PhoneCapability} instance. 399 */ build()400 public PhoneCapability build() { 401 return new PhoneCapability(this); 402 } 403 } 404 } 405