1 /* 2 * Copyright (C) 2024 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.ranging; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.ranging.RangingManager.RangingTechnology; 26 import android.ranging.ble.cs.BleCsRangingCapabilities; 27 import android.ranging.ble.rssi.BleRssiRangingCapabilities; 28 import android.ranging.uwb.UwbRangingCapabilities; 29 import android.ranging.wifi.rtt.RttRangingCapabilities; 30 31 import com.android.ranging.flags.Flags; 32 33 import java.lang.annotation.ElementType; 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 import java.lang.annotation.Target; 37 import java.util.HashMap; 38 import java.util.Map; 39 40 /** 41 * Represents the capabilities and availability of various ranging technologies. 42 * 43 * <p>The {@code RangingCapabilities} class encapsulates the status of different ranging 44 * technologies. It also allows querying the availability of other ranging technologies through a 45 * mapping of technology identifiers to availability statuses.</p> 46 */ 47 @FlaggedApi(Flags.FLAG_RANGING_STACK_ENABLED) 48 public final class RangingCapabilities implements Parcelable { 49 50 /** 51 * Capabilities object for an individual ranging technology. 52 * 53 * @hide 54 */ 55 public interface TechnologyCapabilities { 56 /** @return the technology that these capabilities are associated with. */ 57 @RangingManager.RangingTechnology getTechnology()58 int getTechnology(); 59 } 60 61 @Nullable 62 private final UwbRangingCapabilities mUwbCapabilities; 63 64 @Nullable 65 private final RttRangingCapabilities mRttRangingCapabilities; 66 67 @Nullable 68 private final BleCsRangingCapabilities mCsCapabilities; 69 70 @Nullable 71 private final BleRssiRangingCapabilities mBleRssiCapabilities; 72 73 /** 74 * @hide 75 */ 76 @Retention(RetentionPolicy.SOURCE) 77 @Target({ElementType.TYPE_USE}) 78 @IntDef({ 79 /* Ranging technology is not supported on this device. */ 80 NOT_SUPPORTED, 81 /* Ranging technology is disabled. */ 82 DISABLED_USER, 83 /* Ranging technology disabled due to regulation. */ 84 DISABLED_REGULATORY, 85 /* Ranging technology is enabled. */ 86 ENABLED, 87 /* Ranging technology disabled due to admin restrictions. */ 88 DISABLED_USER_RESTRICTIONS 89 }) 90 public @interface RangingTechnologyAvailability { 91 } 92 93 /** 94 * Indicates that the ranging technology is not supported on the current device. 95 */ 96 public static final int NOT_SUPPORTED = 0; 97 98 /** 99 * Indicates that the ranging technology is disabled by the user. 100 */ 101 public static final int DISABLED_USER = 1; 102 103 /** 104 * Indicates that the ranging technology is disabled due to regulatory restrictions. 105 */ 106 public static final int DISABLED_REGULATORY = 2; 107 108 /** 109 * Indicates that the ranging technology is enabled and available for use. 110 */ 111 public static final int ENABLED = 3; 112 113 /** 114 * Indicates that the ranging technology is disabled due to device usage restrictions. 115 */ 116 public static final int DISABLED_USER_RESTRICTIONS = 4; 117 118 private final Map<@RangingManager.RangingTechnology Integer, 119 @RangingTechnologyAvailability Integer> mAvailabilities; 120 RangingCapabilities(Builder builder)121 private RangingCapabilities(Builder builder) { 122 mUwbCapabilities = 123 (UwbRangingCapabilities) builder.mCapabilities.get(RangingManager.UWB); 124 mRttRangingCapabilities = (RttRangingCapabilities) builder.mCapabilities.get( 125 RangingManager.WIFI_NAN_RTT); 126 mCsCapabilities = (BleCsRangingCapabilities) builder.mCapabilities.get( 127 RangingManager.BLE_CS); 128 mBleRssiCapabilities = (BleRssiRangingCapabilities) builder.mCapabilities.get( 129 RangingManager.BLE_RSSI); 130 mAvailabilities = builder.mAvailabilities; 131 } 132 RangingCapabilities(Parcel in)133 private RangingCapabilities(Parcel in) { 134 mUwbCapabilities = in.readParcelable( 135 UwbRangingCapabilities.class.getClassLoader(), 136 UwbRangingCapabilities.class); 137 mRttRangingCapabilities = in.readParcelable(RttRangingCapabilities.class.getClassLoader(), 138 RttRangingCapabilities.class); 139 mCsCapabilities = in.readParcelable( 140 BleCsRangingCapabilities.class.getClassLoader(), BleCsRangingCapabilities.class); 141 mBleRssiCapabilities = in.readParcelable( 142 BleRssiRangingCapabilities.class.getClassLoader(), 143 BleRssiRangingCapabilities.class); 144 int size = in.readInt(); 145 mAvailabilities = new HashMap<>(size); 146 for (int i = 0; i < size; i++) { 147 int key = in.readInt(); 148 int value = in.readInt(); 149 mAvailabilities.put(key, value); 150 } 151 } 152 153 @NonNull 154 public static final Creator<RangingCapabilities> CREATOR = 155 new Creator<RangingCapabilities>() { 156 @Override 157 public RangingCapabilities createFromParcel(Parcel in) { 158 return new RangingCapabilities(in); 159 } 160 161 @Override 162 public RangingCapabilities[] newArray(int size) { 163 return new RangingCapabilities[size]; 164 } 165 }; 166 167 /** 168 * Gets a map containing the availability of various ranging technologies. 169 * 170 * <p>The map uses technology identifiers as keys and their respective availability 171 * statuses as values.</p> 172 * 173 * @return a {@link Map} with key {@link RangingTechnology} and value 174 * {@link RangingTechnologyAvailability}. 175 */ 176 @NonNull 177 public Map<@RangingTechnology Integer, @RangingTechnologyAvailability Integer> getTechnologyAvailability()178 getTechnologyAvailability() { 179 return mAvailabilities; 180 } 181 182 /** 183 * Gets the UWB ranging capabilities. 184 * 185 * @return a {@link UwbRangingCapabilities} object or {@code null} if not available. 186 */ 187 @Nullable getUwbCapabilities()188 public UwbRangingCapabilities getUwbCapabilities() { 189 return mUwbCapabilities; 190 } 191 192 /** 193 * Gets the WiFi NAN-RTT ranging capabilities. 194 * 195 * @return a {@link RttRangingCapabilities} object or {@code null} if not available. 196 */ 197 @Nullable getRttRangingCapabilities()198 public RttRangingCapabilities getRttRangingCapabilities() { 199 return mRttRangingCapabilities; 200 } 201 202 /** 203 * Gets the BLE channel sounding ranging capabilities. 204 * 205 * @return a {@link BleCsRangingCapabilities} object or {@code null} if not available. 206 */ 207 @Nullable getCsCapabilities()208 public BleCsRangingCapabilities getCsCapabilities() { 209 return mCsCapabilities; 210 } 211 212 /** 213 * Gets the BLE RSSI ranging capabilities. 214 * This method is for internal use only-- BLE RSSI has no non-trivial capabilities. 215 * 216 * @hide 217 */ 218 @Nullable getBleRssiCapabilities()219 public BleRssiRangingCapabilities getBleRssiCapabilities() { 220 return mBleRssiCapabilities; 221 } 222 223 @Override describeContents()224 public int describeContents() { 225 return 0; 226 } 227 228 @Override writeToParcel(@ndroidx.annotation.NonNull Parcel dest, int flags)229 public void writeToParcel(@androidx.annotation.NonNull Parcel dest, int flags) { 230 dest.writeParcelable(mUwbCapabilities, flags); 231 dest.writeParcelable(mRttRangingCapabilities, flags); 232 dest.writeParcelable(mCsCapabilities, flags); 233 dest.writeParcelable(mBleRssiCapabilities, flags); 234 dest.writeInt(mAvailabilities.size()); // Write map size 235 for (Map.Entry<Integer, Integer> entry : mAvailabilities.entrySet()) { 236 dest.writeInt(entry.getKey()); // Write the key 237 dest.writeInt(entry.getValue()); // Write the value 238 } 239 } 240 241 /** 242 * Builder for {@link RangingCapabilities} 243 * 244 * @hide 245 */ 246 public static class Builder { 247 private final HashMap<Integer, TechnologyCapabilities> mCapabilities = new HashMap<>(); 248 private final HashMap<Integer, Integer> mAvailabilities = new HashMap<>(); 249 addCapabilities(@onNull TechnologyCapabilities capabilities)250 public Builder addCapabilities(@NonNull TechnologyCapabilities capabilities) { 251 mCapabilities.put(capabilities.getTechnology(), capabilities); 252 return this; 253 } 254 addAvailability( @angingTechnology int technology, @RangingTechnologyAvailability int availability )255 public Builder addAvailability( 256 @RangingTechnology int technology, @RangingTechnologyAvailability int availability 257 ) { 258 mAvailabilities.put(technology, availability); 259 return this; 260 } 261 build()262 public RangingCapabilities build() { 263 return new RangingCapabilities(this); 264 } 265 } 266 267 @Override toString()268 public String toString() { 269 return "RangingCapabilities{ " 270 + "mUwbCapabilities=" 271 + mUwbCapabilities 272 + ", mRttRangingCapabilities=" 273 + mRttRangingCapabilities 274 + ", mCsCapabilities=" 275 + mCsCapabilities 276 + ", mBleRssiCapabilities=" 277 + mBleRssiCapabilities 278 + ", mAvailabilities=" 279 + mAvailabilities 280 + " }"; 281 } 282 } 283