diff options
Diffstat (limited to 'framework/java')
5 files changed, 151 insertions, 253 deletions
diff --git a/framework/java/android/bluetooth/le/AdvertiseData.java b/framework/java/android/bluetooth/le/AdvertiseData.java index 843cd846f0..b137eeb0ce 100644 --- a/framework/java/android/bluetooth/le/AdvertiseData.java +++ b/framework/java/android/bluetooth/le/AdvertiseData.java @@ -17,15 +17,14 @@ package android.bluetooth.le; import android.annotation.Nullable; +import android.bluetooth.BluetoothUuid; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; -import android.util.ArrayMap; -import android.util.SparseArray; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Objects; /** @@ -43,18 +42,27 @@ public final class AdvertiseData implements Parcelable { @Nullable private final List<ParcelUuid> mServiceUuids; - private final SparseArray<byte[]> mManufacturerSpecificData; - private final Map<ParcelUuid, byte[]> mServiceData; + private final int mManufacturerId; + @Nullable + private final byte[] mManufacturerSpecificData; + + @Nullable + private final ParcelUuid mServiceDataUuid; + @Nullable + private final byte[] mServiceData; + private final boolean mIncludeTxPowerLevel; private final boolean mIncludeDeviceName; private AdvertiseData(List<ParcelUuid> serviceUuids, - SparseArray<byte[]> manufacturerData, - Map<ParcelUuid, byte[]> serviceData, - boolean includeTxPowerLevel, + ParcelUuid serviceDataUuid, byte[] serviceData, + int manufacturerId, + byte[] manufacturerSpecificData, boolean includeTxPowerLevel, boolean includeDeviceName) { mServiceUuids = serviceUuids; - mManufacturerSpecificData = manufacturerData; + mManufacturerId = manufacturerId; + mManufacturerSpecificData = manufacturerSpecificData; + mServiceDataUuid = serviceDataUuid; mServiceData = serviceData; mIncludeTxPowerLevel = includeTxPowerLevel; mIncludeDeviceName = includeDeviceName; @@ -69,17 +77,32 @@ public final class AdvertiseData implements Parcelable { } /** - * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The - * manufacturer id is a non-negative number assigned by Bluetooth SIG. + * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth + * SIG. */ - public SparseArray<byte[]> getManufacturerSpecificData() { + public int getManufacturerId() { + return mManufacturerId; + } + + /** + * Returns the manufacturer specific data which is the content of manufacturer specific data + * field. The first 2 bytes of the data contain the company id. + */ + public byte[] getManufacturerSpecificData() { return mManufacturerSpecificData; } /** - * Returns a map of 16-bit UUID and its corresponding service data. + * Returns a 16-bit UUID of the service that the service data is associated with. + */ + public ParcelUuid getServiceDataUuid() { + return mServiceDataUuid; + } + + /** + * Returns service data. */ - public Map<ParcelUuid, byte[]> getServiceData() { + public byte[] getServiceData() { return mServiceData; } @@ -102,8 +125,8 @@ public final class AdvertiseData implements Parcelable { */ @Override public int hashCode() { - return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData, - mIncludeDeviceName, mIncludeTxPowerLevel); + return Objects.hash(mServiceUuids, mManufacturerId, mManufacturerSpecificData, + mServiceDataUuid, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel); } /** @@ -119,17 +142,20 @@ public final class AdvertiseData implements Parcelable { } AdvertiseData other = (AdvertiseData) obj; return Objects.equals(mServiceUuids, other.mServiceUuids) && - Utils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) && - Utils.equals(mServiceData, other.mServiceData) && + mManufacturerId == other.mManufacturerId && + Objects.deepEquals(mManufacturerSpecificData, other.mManufacturerSpecificData) && + Objects.equals(mServiceDataUuid, other.mServiceDataUuid) && + Objects.deepEquals(mServiceData, other.mServiceData) && mIncludeDeviceName == other.mIncludeDeviceName && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel; } @Override public String toString() { - return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData=" - + Utils.toString(mManufacturerSpecificData) + ", mServiceData=" - + Utils.toString(mServiceData) + return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerId=" + + mManufacturerId + ", mManufacturerSpecificData=" + + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid=" + + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData) + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName=" + mIncludeDeviceName + "]"; } @@ -143,30 +169,21 @@ public final class AdvertiseData implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeList(mServiceUuids); - // mManufacturerSpecificData could not be null. - dest.writeInt(mManufacturerSpecificData.size()); - for (int i = 0; i < mManufacturerSpecificData.size(); ++i) { - dest.writeInt(mManufacturerSpecificData.keyAt(i)); - byte[] data = mManufacturerSpecificData.valueAt(i); - if (data == null) { - dest.writeInt(0); - } else { - dest.writeInt(1); - dest.writeInt(data.length); - dest.writeByteArray(data); - } + dest.writeInt(mManufacturerId); + if (mManufacturerSpecificData == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + dest.writeInt(mManufacturerSpecificData.length); + dest.writeByteArray(mManufacturerSpecificData); } - dest.writeInt(mServiceData.size()); - for (ParcelUuid uuid : mServiceData.keySet()) { - dest.writeParcelable(uuid, flags); - byte[] data = mServiceData.get(uuid); - if (data == null) { - dest.writeInt(0); - } else { - dest.writeInt(1); - dest.writeInt(data.length); - dest.writeByteArray(data); - } + dest.writeParcelable(mServiceDataUuid, flags); + if (mServiceData == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + dest.writeInt(mServiceData.length); + dest.writeByteArray(mServiceData); } dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0)); dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0)); @@ -192,26 +209,20 @@ public final class AdvertiseData implements Parcelable { builder.addServiceUuid(uuid); } } - int manufacturerSize = in.readInt(); - for (int i = 0; i < manufacturerSize; ++i) { - int manufacturerId = in.readInt(); - if (in.readInt() == 1) { - int manufacturerDataLength = in.readInt(); - byte[] manufacturerData = new byte[manufacturerDataLength]; - in.readByteArray(manufacturerData); - builder.addManufacturerData(manufacturerId, manufacturerData); - } + int manufacturerId = in.readInt(); + if (in.readInt() == 1) { + int manufacturerDataLength = in.readInt(); + byte[] manufacturerData = new byte[manufacturerDataLength]; + in.readByteArray(manufacturerData); + builder.setManufacturerData(manufacturerId, manufacturerData); } - int serviceDataSize = in.readInt(); - for (int i = 0; i < serviceDataSize; ++i) { - ParcelUuid serviceDataUuid = in.readParcelable( - ParcelUuid.class.getClassLoader()); - if (in.readInt() == 1) { - int serviceDataLength = in.readInt(); - byte[] serviceData = new byte[serviceDataLength]; - in.readByteArray(serviceData); - builder.addServiceData(serviceDataUuid, serviceData); - } + ParcelUuid serviceDataUuid = in.readParcelable( + ParcelUuid.class.getClassLoader()); + if (in.readInt() == 1) { + int serviceDataLength = in.readInt(); + byte[] serviceData = new byte[serviceDataLength]; + in.readByteArray(serviceData); + builder.setServiceData(serviceDataUuid, serviceData); } builder.setIncludeTxPowerLevel(in.readByte() == 1); builder.setIncludeDeviceName(in.readByte() == 1); @@ -225,8 +236,13 @@ public final class AdvertiseData implements Parcelable { public static final class Builder { @Nullable private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>(); - private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>(); - private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>(); + private int mManufacturerId = -1; + @Nullable + private byte[] mManufacturerSpecificData; + @Nullable + private ParcelUuid mServiceDataUuid; + @Nullable + private byte[] mServiceData; private boolean mIncludeTxPowerLevel; private boolean mIncludeDeviceName; @@ -252,17 +268,18 @@ public final class AdvertiseData implements Parcelable { * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is * empty. */ - public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) { + public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) { if (serviceDataUuid == null || serviceData == null) { throw new IllegalArgumentException( "serviceDataUuid or serviceDataUuid is null"); } - mServiceData.put(serviceDataUuid, serviceData); + mServiceDataUuid = serviceDataUuid; + mServiceData = serviceData; return this; } /** - * Add manufacturer specific data. + * Set manufacturer specific data. * <p> * Please refer to the Bluetooth Assigned Numbers document provided by the <a * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company @@ -273,7 +290,7 @@ public final class AdvertiseData implements Parcelable { * @throws IllegalArgumentException If the {@code manufacturerId} is negative or * {@code manufacturerSpecificData} is null. */ - public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) { + public Builder setManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) { if (manufacturerId < 0) { throw new IllegalArgumentException( "invalid manufacturerId - " + manufacturerId); @@ -281,7 +298,8 @@ public final class AdvertiseData implements Parcelable { if (manufacturerSpecificData == null) { throw new IllegalArgumentException("manufacturerSpecificData is null"); } - mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData); + mManufacturerId = manufacturerId; + mManufacturerSpecificData = manufacturerSpecificData; return this; } @@ -306,7 +324,9 @@ public final class AdvertiseData implements Parcelable { * Build the {@link AdvertiseData}. */ public AdvertiseData build() { - return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData, + return new AdvertiseData(mServiceUuids, + mServiceDataUuid, + mServiceData, mManufacturerId, mManufacturerSpecificData, mIncludeTxPowerLevel, mIncludeDeviceName); } } diff --git a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java index 8879da7328..4d128e7439 100644 --- a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java +++ b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java @@ -209,13 +209,13 @@ public final class BluetoothLeAdvertiser { num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT; } } - for (ParcelUuid uuid : data.getServiceData().keySet()) { + if (data.getServiceDataUuid() != null) { size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH - + byteLength(data.getServiceData().get(uuid)); + + byteLength(data.getServiceData()); } - for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) { + if (data.getManufacturerId() > 0) { size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH + - byteLength(data.getManufacturerSpecificData().valueAt(i)); + byteLength(data.getManufacturerSpecificData()); } if (data.getIncludeTxPowerLevel()) { size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte. diff --git a/framework/java/android/bluetooth/le/ScanFilter.java b/framework/java/android/bluetooth/le/ScanFilter.java index d1b93d234b..30aaf2e4cc 100644 --- a/framework/java/android/bluetooth/le/ScanFilter.java +++ b/framework/java/android/bluetooth/le/ScanFilter.java @@ -181,7 +181,7 @@ public final class ScanFilter implements Parcelable { byte[] serviceDataMask = new byte[serviceDataMaskLength]; in.readByteArray(serviceDataMask); builder.setServiceData( - servcieDataUuid, serviceData, serviceDataMask); + servcieDataUuid, serviceData, serviceDataMask); } } } @@ -242,6 +242,9 @@ public final class ScanFilter implements Parcelable { return mServiceDataMask; } + /** + * @hide + */ @Nullable public ParcelUuid getServiceDataUuid() { return mServiceDataUuid; @@ -300,17 +303,19 @@ public final class ScanFilter implements Parcelable { } // Service data match - if (mServiceDataUuid != null) { - if (!matchesPartialData(mServiceData, mServiceDataMask, - scanRecord.getServiceData(mServiceDataUuid))) { + if (mServiceData != null) { + if (!Objects.equals(mServiceDataUuid, scanRecord.getServiceDataUuid()) || + !matchesPartialData(mServiceData, mServiceDataMask, + scanRecord.getServiceData())) { return false; } } // Manufacturer data match. - if (mManufacturerId >= 0) { - if (!matchesPartialData(mManufacturerData, mManufacturerDataMask, - scanRecord.getManufacturerSpecificData(mManufacturerId))) { + if (mManufacturerData != null) { + if (mManufacturerId != scanRecord.getManufacturerId() || + !matchesPartialData(mManufacturerData, + mManufacturerDataMask, scanRecord.getManufacturerSpecificData())) { return false; } } diff --git a/framework/java/android/bluetooth/le/ScanRecord.java b/framework/java/android/bluetooth/le/ScanRecord.java index e7f33ff116..e564c7d66d 100644 --- a/framework/java/android/bluetooth/le/ScanRecord.java +++ b/framework/java/android/bluetooth/le/ScanRecord.java @@ -19,14 +19,11 @@ package android.bluetooth.le; import android.annotation.Nullable; import android.bluetooth.BluetoothUuid; import android.os.ParcelUuid; -import android.util.ArrayMap; import android.util.Log; -import android.util.SparseArray; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; /** * Represents a scan record from Bluetooth LE scan. @@ -56,9 +53,14 @@ public final class ScanRecord { @Nullable private final List<ParcelUuid> mServiceUuids; - private final SparseArray<byte[]> mManufacturerSpecificData; + private final int mManufacturerId; + @Nullable + private final byte[] mManufacturerSpecificData; - private final Map<ParcelUuid, byte[]> mServiceData; + @Nullable + private final ParcelUuid mServiceDataUuid; + @Nullable + private final byte[] mServiceData; // Transmission power level(in dB). private final int mTxPowerLevel; @@ -79,46 +81,40 @@ public final class ScanRecord { /** * Returns a list of service UUIDs within the advertisement that are used to identify the - * bluetooth GATT services. + * bluetooth gatt services. */ public List<ParcelUuid> getServiceUuids() { return mServiceUuids; } /** - * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific - * data. + * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth + * SIG. */ - public SparseArray<byte[]> getManufacturerSpecificData() { - return mManufacturerSpecificData; + public int getManufacturerId() { + return mManufacturerId; } /** - * Returns the manufacturer specific data associated with the manufacturer id. Returns - * {@code null} if the {@code manufacturerId} is not found. + * Returns the manufacturer specific data which is the content of manufacturer specific data + * field. */ - @Nullable - public byte[] getManufacturerSpecificData(int manufacturerId) { - return mManufacturerSpecificData.get(manufacturerId); + public byte[] getManufacturerSpecificData() { + return mManufacturerSpecificData; } /** - * Returns a map of service UUID and its corresponding service data. + * Returns a 16-bit UUID of the service that the service data is associated with. */ - public Map<ParcelUuid, byte[]> getServiceData() { - return mServiceData; + public ParcelUuid getServiceDataUuid() { + return mServiceDataUuid; } /** - * Returns the service data byte array associated with the {@code serviceUuid}. Returns - * {@code null} if the {@code serviceDataUuid} is not found. + * Returns service data. */ - @Nullable - public byte[] getServiceData(ParcelUuid serviceDataUuid) { - if (serviceDataUuid == null) { - return null; - } - return mServiceData.get(serviceDataUuid); + public byte[] getServiceData() { + return mServiceData; } /** @@ -148,12 +144,14 @@ public final class ScanRecord { } private ScanRecord(List<ParcelUuid> serviceUuids, - SparseArray<byte[]> manufacturerData, - Map<ParcelUuid, byte[]> serviceData, - int advertiseFlags, int txPowerLevel, + ParcelUuid serviceDataUuid, byte[] serviceData, + int manufacturerId, + byte[] manufacturerSpecificData, int advertiseFlags, int txPowerLevel, String localName, byte[] bytes) { mServiceUuids = serviceUuids; - mManufacturerSpecificData = manufacturerData; + mManufacturerId = manufacturerId; + mManufacturerSpecificData = manufacturerSpecificData; + mServiceDataUuid = serviceDataUuid; mServiceData = serviceData; mDeviceName = localName; mAdvertiseFlags = advertiseFlags; @@ -170,6 +168,7 @@ public final class ScanRecord { * order. * * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response. + * * @hide */ public static ScanRecord parseFromBytes(byte[] scanRecord) { @@ -182,9 +181,10 @@ public final class ScanRecord { List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>(); String localName = null; int txPowerLevel = Integer.MIN_VALUE; - - SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>(); - Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>(); + ParcelUuid serviceDataUuid = null; + byte[] serviceData = null; + int manufacturerId = -1; + byte[] manufacturerSpecificData = null; try { while (currentPos < scanRecord.length) { @@ -230,20 +230,16 @@ public final class ScanRecord { int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT; byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos, serviceUuidLength); - ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom( - serviceDataUuidBytes); - byte[] serviceDataArray = extractBytes(scanRecord, - currentPos + serviceUuidLength, dataLength - serviceUuidLength); - serviceData.put(serviceDataUuid, serviceDataArray); + serviceDataUuid = BluetoothUuid.parseUuidFrom(serviceDataUuidBytes); + serviceData = extractBytes(scanRecord, currentPos + 2, dataLength - 2); break; case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA: // The first two bytes of the manufacturer specific data are // manufacturer ids in little endian. - int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) + + manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) + (scanRecord[currentPos] & 0xFF); - byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2, + manufacturerSpecificData = extractBytes(scanRecord, currentPos + 2, dataLength - 2); - manufacturerData.put(manufacturerId, manufacturerDataBytes); break; default: // Just ignore, we don't handle such data type. @@ -255,8 +251,9 @@ public final class ScanRecord { if (serviceUuids.isEmpty()) { serviceUuids = null; } - return new ScanRecord(serviceUuids, manufacturerData, serviceData, - advertiseFlag, txPowerLevel, localName, scanRecord); + return new ScanRecord(serviceUuids, serviceDataUuid, serviceData, + manufacturerId, manufacturerSpecificData, advertiseFlag, txPowerLevel, + localName, scanRecord); } catch (IndexOutOfBoundsException e) { Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord)); return null; @@ -266,11 +263,13 @@ public final class ScanRecord { @Override public String toString() { return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids - + ", mManufacturerSpecificData=" + Utils.toString(mManufacturerSpecificData) - + ", mServiceData=" + Utils.toString(mServiceData) + + ", mManufacturerId=" + mManufacturerId + ", mManufacturerSpecificData=" + + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid=" + + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData) + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]"; } + // Parse service UUIDs. private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength, int uuidLength, List<ParcelUuid> serviceUuids) { diff --git a/framework/java/android/bluetooth/le/Utils.java b/framework/java/android/bluetooth/le/Utils.java deleted file mode 100644 index 8598dd7772..0000000000 --- a/framework/java/android/bluetooth/le/Utils.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth.le; - -import android.util.SparseArray; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Helper class for Bluetooth LE utils. - * - * @hide - */ -public class Utils { - - /** - * Returns a string composed from a {@link SparseArray}. - */ - static String toString(SparseArray<byte[]> array) { - if (array == null) { - return "null"; - } - if (array.size() == 0) { - return "{}"; - } - StringBuilder buffer = new StringBuilder(); - buffer.append('{'); - for (int i = 0; i < array.size(); ++i) { - buffer.append(array.keyAt(i)).append("=").append(array.valueAt(i)); - } - buffer.append('}'); - return buffer.toString(); - } - - /** - * Returns a string composed from a {@link Map}. - */ - static <T> String toString(Map<T, byte[]> map) { - if (map == null) { - return "null"; - } - if (map.isEmpty()) { - return "{}"; - } - StringBuilder buffer = new StringBuilder(); - buffer.append('{'); - Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<T, byte[]> entry = it.next(); - Object key = entry.getKey(); - buffer.append(key).append("=").append(Arrays.toString(map.get(key))); - if (it.hasNext()) { - buffer.append(", "); - } - } - buffer.append('}'); - return buffer.toString(); - } - - /** - * Check whether two {@link SparseArray} equal. - */ - static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) { - if (array == otherArray) { - return true; - } - if (array == null || otherArray == null) { - return false; - } - if (array.size() != otherArray.size()) { - return false; - } - - // Keys are guaranteed in ascending order when indices are in ascending order. - for (int i = 0; i < array.size(); ++i) { - if (array.keyAt(i) != otherArray.keyAt(i) || - !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) { - return false; - } - } - return true; - } - - /** - * Check whether two {@link Map} equal. - */ - static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) { - if (map == otherMap) { - return true; - } - if (map == null || otherMap == null) { - return false; - } - if (map.size() != otherMap.size()) { - return false; - } - Set<T> keys = map.keySet(); - if (!keys.equals(otherMap.keySet())) { - return false; - } - for (T key : keys) { - if (!Objects.deepEquals(map.get(key), otherMap.get(key))) { - return false; - } - } - return true; - } -} |