• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.bluetooth.le;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.util.SparseArray;
21 
22 import java.time.Duration;
23 import java.util.Arrays;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.Objects;
27 import java.util.Set;
28 import java.util.UUID;
29 
30 /**
31  * Helper class for Bluetooth LE utils.
32  *
33  * @hide
34  */
35 public class BluetoothLeUtils {
36 
37     /**
38      * Timeout value for synchronous binder call
39      */
40     private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(5);
41 
42     /**
43      * @return timeout value for synchronous binder call
44      */
getSyncTimeout()45     static Duration getSyncTimeout() {
46         return SYNC_CALLS_TIMEOUT;
47     }
48 
49     /**
50      * Returns a string composed from a {@link SparseArray}.
51      */
toString(SparseArray<byte[]> array)52     static String toString(SparseArray<byte[]> array) {
53         if (array == null) {
54             return "null";
55         }
56         if (array.size() == 0) {
57             return "{}";
58         }
59         StringBuilder buffer = new StringBuilder();
60         buffer.append('{');
61         for (int i = 0; i < array.size(); ++i) {
62             buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
63         }
64         buffer.append('}');
65         return buffer.toString();
66     }
67 
68     /**
69      * Returns a string composed from a {@link Map}.
70      */
toString(Map<T, byte[]> map)71     static <T> String toString(Map<T, byte[]> map) {
72         if (map == null) {
73             return "null";
74         }
75         if (map.isEmpty()) {
76             return "{}";
77         }
78         StringBuilder buffer = new StringBuilder();
79         buffer.append('{');
80         Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
81         while (it.hasNext()) {
82             Map.Entry<T, byte[]> entry = it.next();
83             Object key = entry.getKey();
84             buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
85             if (it.hasNext()) {
86                 buffer.append(", ");
87             }
88         }
89         buffer.append('}');
90         return buffer.toString();
91     }
92 
93     /**
94      * Check whether two {@link SparseArray} equal.
95      */
equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray)96     static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
97         if (array == otherArray) {
98             return true;
99         }
100         if (array == null || otherArray == null) {
101             return false;
102         }
103         if (array.size() != otherArray.size()) {
104             return false;
105         }
106 
107         // Keys are guaranteed in ascending order when indices are in ascending order.
108         for (int i = 0; i < array.size(); ++i) {
109             if (array.keyAt(i) != otherArray.keyAt(i)
110                     || !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
111                 return false;
112             }
113         }
114         return true;
115     }
116 
117     /**
118      * Check whether two {@link Map} equal.
119      */
equals(Map<T, byte[]> map, Map<T, byte[]> otherMap)120     static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
121         if (map == otherMap) {
122             return true;
123         }
124         if (map == null || otherMap == null) {
125             return false;
126         }
127         if (map.size() != otherMap.size()) {
128             return false;
129         }
130         Set<T> keys = map.keySet();
131         if (!keys.equals(otherMap.keySet())) {
132             return false;
133         }
134         for (T key : keys) {
135             if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
136                 return false;
137             }
138         }
139         return true;
140     }
141 
142     /**
143      * Ensure Bluetooth is turned on.
144      *
145      * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
146      * BluetoothAdapter#STATE_ON}.
147      */
checkAdapterStateOn(BluetoothAdapter adapter)148     static void checkAdapterStateOn(BluetoothAdapter adapter) {
149         if (adapter == null || !adapter.isLeEnabled()) {
150             throw new IllegalStateException("BT Adapter is not turned ON");
151         }
152     }
153 
154     /**
155      * Compares two UUIDs with a UUID mask.
156      *
157      * @param data first {@link #UUID} to compare.
158      * @param uuid second {@link #UUID} to compare.
159      * @param mask mask {@link #UUID}.
160      * @return true if both UUIDs are equals when masked, false otherwise.
161      */
maskedEquals(UUID data, UUID uuid, UUID mask)162     static boolean maskedEquals(UUID data, UUID uuid, UUID mask) {
163         if (mask == null) {
164             return Objects.equals(data, uuid);
165         }
166         return (data.getLeastSignificantBits() & mask.getLeastSignificantBits())
167                 == (uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
168                 && (data.getMostSignificantBits() & mask.getMostSignificantBits())
169                 == (uuid.getMostSignificantBits() & mask.getMostSignificantBits());
170     }
171 }
172