16bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang/*
26bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * Copyright (C) 2014 The Android Open Source Project
36bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang *
46bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * Licensed under the Apache License, Version 2.0 (the "License");
56bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * you may not use this file except in compliance with the License.
66bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * You may obtain a copy of the License at
76bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang *
86bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang *      http://www.apache.org/licenses/LICENSE-2.0
96bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang *
106bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * Unless required by applicable law or agreed to in writing, software
116bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * distributed under the License is distributed on an "AS IS" BASIS,
126bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * See the License for the specific language governing permissions and
146bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * limitations under the License.
156bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang */
166bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
176bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangpackage android.bluetooth.le;
186bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
19833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wangimport android.bluetooth.BluetoothAdapter;
206bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport android.util.SparseArray;
216bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
226bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport java.util.Arrays;
236bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport java.util.Iterator;
246bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport java.util.Map;
256bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport java.util.Objects;
266bf513d32db7fbc157681bd642e12a201cf20a89Wei Wangimport java.util.Set;
276bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
286bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang/**
296bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * Helper class for Bluetooth LE utils.
306bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang *
316bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang * @hide
326bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang */
33833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wangpublic class BluetoothLeUtils {
346bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
356bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    /**
366bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     * Returns a string composed from a {@link SparseArray}.
376bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     */
386bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    static String toString(SparseArray<byte[]> array) {
396bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (array == null) {
406bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return "null";
416bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
426bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (array.size() == 0) {
436bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return "{}";
446bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
456bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        StringBuilder buffer = new StringBuilder();
466bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        buffer.append('{');
476bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        for (int i = 0; i < array.size(); ++i) {
48ee80922c6a1228886589dcd4598a1cadf0bd1ff8Wei Wang            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
496bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
506bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        buffer.append('}');
516bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        return buffer.toString();
526bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    }
536bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
546bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    /**
556bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     * Returns a string composed from a {@link Map}.
566bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     */
576bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    static <T> String toString(Map<T, byte[]> map) {
586bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (map == null) {
596bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return "null";
606bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
616bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (map.isEmpty()) {
626bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return "{}";
636bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
646bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        StringBuilder buffer = new StringBuilder();
656bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        buffer.append('{');
666bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
676bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        while (it.hasNext()) {
686bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            Map.Entry<T, byte[]> entry = it.next();
696bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            Object key = entry.getKey();
706bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
716bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            if (it.hasNext()) {
726bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang                buffer.append(", ");
736bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            }
746bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
756bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        buffer.append('}');
766bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        return buffer.toString();
776bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    }
786bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
796bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    /**
806bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     * Check whether two {@link SparseArray} equal.
816bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     */
826bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
836bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (array == otherArray) {
846bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return true;
856bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
866bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (array == null || otherArray == null) {
876bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return false;
886bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
896bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (array.size() != otherArray.size()) {
906bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return false;
916bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
926bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
936bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        // Keys are guaranteed in ascending order when indices are in ascending order.
946bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        for (int i = 0; i < array.size(); ++i) {
956bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            if (array.keyAt(i) != otherArray.keyAt(i) ||
966bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang                    !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
976bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang                return false;
986bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            }
996bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1006bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        return true;
1016bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    }
1026bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang
1036bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    /**
1046bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     * Check whether two {@link Map} equal.
1056bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang     */
1066bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
1076bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (map == otherMap) {
1086bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return true;
1096bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1106bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (map == null || otherMap == null) {
1116bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return false;
1126bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1136bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (map.size() != otherMap.size()) {
1146bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return false;
1156bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1166bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        Set<T> keys = map.keySet();
1176bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        if (!keys.equals(otherMap.keySet())) {
1186bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            return false;
1196bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1206bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        for (T key : keys) {
1216bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
1226bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang                return false;
1236bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang            }
1246bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        }
1256bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang        return true;
1266bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang    }
127833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang
128833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang    /**
129833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang     * Ensure Bluetooth is turned on.
130833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang     *
131833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not
132833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang     *             {@link BluetoothAdapter#STATE_ON}.
133833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang     */
134833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang    static void checkAdapterStateOn(BluetoothAdapter adapter) {
135d055adbe2c1c65d9346e65209fa8790190bc239eNitin Arora        if (adapter == null || !adapter.isLeEnabled()) {//adapter.getState() != BluetoothAdapter.STATE_ON) {
136833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang            throw new IllegalStateException("BT Adapter is not turned ON");
137833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang        }
138833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang    }
139833559d9f3f0bd6ddb1cf9c1571975751830e045Wei Wang
1406bf513d32db7fbc157681bd642e12a201cf20a89Wei Wang}
141