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 com.android.server.ranging; 18 19 import static java.lang.Math.min; 20 21 import android.content.Context; 22 import android.ranging.RangingManager; 23 24 import com.android.server.ranging.blerssi.BleRssiCapabilitiesAdapter; 25 import com.android.server.ranging.cs.CsCapabilitiesAdapter; 26 import com.android.server.ranging.rtt.RttCapabilitiesAdapter; 27 import com.android.server.ranging.uwb.UwbCapabilitiesAdapter; 28 29 import com.google.common.collect.ImmutableList; 30 31 import java.util.BitSet; 32 import java.util.List; 33 34 /** Enum representing an individual ranging technology. */ 35 public enum RangingTechnology { 36 UWB(0), // Ultra-Wide Band 37 CS(1), // Channel Sounding, formerly known as HADM 38 39 RTT(2), // Wifi RTT. 40 RSSI(3); // BLE RSSI. 41 42 public static final ImmutableList<RangingTechnology> TECHNOLOGIES = 43 ImmutableList.copyOf(RangingTechnology.values()); 44 45 private static final int BITMAP_SIZE_BYTES = 2; 46 47 private final int value; 48 RangingTechnology(int value)49 RangingTechnology(int value) { 50 this.value = value; 51 } 52 getValue()53 public @RangingManager.RangingTechnology int getValue() { 54 return value; 55 } 56 toByte()57 public byte toByte() { 58 return (byte) value; 59 } 60 61 /** 62 * Check whether this technology is available given the provided context. 63 * @return true if the technology is supported, false otherwise. 64 */ isSupported(Context context)65 public boolean isSupported(Context context) { 66 switch (this) { 67 case UWB: 68 return UwbCapabilitiesAdapter.isSupported(context); 69 case CS: 70 return CsCapabilitiesAdapter.isSupported(context); 71 case RTT: 72 return RttCapabilitiesAdapter.isSupported(context); 73 case RSSI: 74 return BleRssiCapabilitiesAdapter.isSupported(context); 75 default: 76 return false; 77 } 78 } 79 parseByte(byte technologiesByte)80 public static ImmutableList<RangingTechnology> parseByte(byte technologiesByte) { 81 BitSet bitset = BitSet.valueOf(new byte[]{technologiesByte}); 82 ImmutableList.Builder<RangingTechnology> technologies = ImmutableList.builder(); 83 for (RangingTechnology technology : RangingTechnology.values()) { 84 if (bitset.get(technology.value)) { 85 technologies.add(technology); 86 } 87 } 88 return technologies.build(); 89 } 90 toBitmap(List<RangingTechnology> technologies)91 public static byte[] toBitmap(List<RangingTechnology> technologies) { 92 if (technologies.isEmpty()) { 93 return new byte[BITMAP_SIZE_BYTES]; 94 } 95 BitSet bitset = new BitSet(BITMAP_SIZE_BYTES * 8); 96 for (RangingTechnology technology : technologies) { 97 bitset.set(technology.value); 98 } 99 byte[] bitmap = new byte[BITMAP_SIZE_BYTES]; 100 System.arraycopy( 101 bitset.toByteArray(), 0, bitmap, 0, 102 min(BITMAP_SIZE_BYTES, bitset.toByteArray().length)); 103 return bitmap; 104 } 105 fromBitmap(byte[] technologiesBitmap)106 public static ImmutableList<RangingTechnology> fromBitmap(byte[] technologiesBitmap) { 107 ImmutableList.Builder<RangingTechnology> techs = ImmutableList.builder(); 108 BitSet bitSet = BitSet.valueOf(technologiesBitmap); 109 for (int i = 0; i < BITMAP_SIZE_BYTES * 8; i++) { 110 if (bitSet.get(i)) { 111 if (i < RangingTechnology.values().length) { 112 techs.add(RangingTechnology.values()[i]); 113 } 114 } 115 } 116 return techs.build(); 117 } 118 }