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
17package android.bluetooth.le;
18
19import android.bluetooth.BluetoothAdapter;
20import android.util.SparseArray;
21
22import java.util.Arrays;
23import java.util.Iterator;
24import java.util.Map;
25import java.util.Objects;
26import java.util.Set;
27
28/**
29 * Helper class for Bluetooth LE utils.
30 *
31 * @hide
32 */
33public class BluetoothLeUtils {
34
35    /**
36     * Returns a string composed from a {@link SparseArray}.
37     */
38    static String toString(SparseArray<byte[]> array) {
39        if (array == null) {
40            return "null";
41        }
42        if (array.size() == 0) {
43            return "{}";
44        }
45        StringBuilder buffer = new StringBuilder();
46        buffer.append('{');
47        for (int i = 0; i < array.size(); ++i) {
48            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
49        }
50        buffer.append('}');
51        return buffer.toString();
52    }
53
54    /**
55     * Returns a string composed from a {@link Map}.
56     */
57    static <T> String toString(Map<T, byte[]> map) {
58        if (map == null) {
59            return "null";
60        }
61        if (map.isEmpty()) {
62            return "{}";
63        }
64        StringBuilder buffer = new StringBuilder();
65        buffer.append('{');
66        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
67        while (it.hasNext()) {
68            Map.Entry<T, byte[]> entry = it.next();
69            Object key = entry.getKey();
70            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
71            if (it.hasNext()) {
72                buffer.append(", ");
73            }
74        }
75        buffer.append('}');
76        return buffer.toString();
77    }
78
79    /**
80     * Check whether two {@link SparseArray} equal.
81     */
82    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
83        if (array == otherArray) {
84            return true;
85        }
86        if (array == null || otherArray == null) {
87            return false;
88        }
89        if (array.size() != otherArray.size()) {
90            return false;
91        }
92
93        // Keys are guaranteed in ascending order when indices are in ascending order.
94        for (int i = 0; i < array.size(); ++i) {
95            if (array.keyAt(i) != otherArray.keyAt(i) ||
96                    !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
97                return false;
98            }
99        }
100        return true;
101    }
102
103    /**
104     * Check whether two {@link Map} equal.
105     */
106    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
107        if (map == otherMap) {
108            return true;
109        }
110        if (map == null || otherMap == null) {
111            return false;
112        }
113        if (map.size() != otherMap.size()) {
114            return false;
115        }
116        Set<T> keys = map.keySet();
117        if (!keys.equals(otherMap.keySet())) {
118            return false;
119        }
120        for (T key : keys) {
121            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
122                return false;
123            }
124        }
125        return true;
126    }
127
128    /**
129     * Ensure Bluetooth is turned on.
130     *
131     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not
132     *             {@link BluetoothAdapter#STATE_ON}.
133     */
134    static void checkAdapterStateOn(BluetoothAdapter adapter) {
135        if (adapter == null || adapter.getState() != BluetoothAdapter.STATE_ON) {
136            throw new IllegalStateException("BT Adapter is not turned ON");
137        }
138    }
139
140}
141