• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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.nearby.common.bluetooth.fastpair;
18 
19 import androidx.annotation.Nullable;
20 import androidx.annotation.VisibleForTesting;
21 
22 import java.nio.ByteBuffer;
23 import java.nio.ByteOrder;
24 import java.nio.ShortBuffer;
25 import java.util.Arrays;
26 
27 /** Represents a block of bytes, with hashCode and equals. */
28 public abstract class Bytes {
29     private static final char[] sHexDigits = "0123456789abcdef".toCharArray();
30     private final byte[] mBytes;
31 
32     /**
33      * A logical value consisting of one or more bytes in the given order (little-endian, i.e.
34      * LSO...MSO, or big-endian, i.e. MSO...LSO). E.g. the Fast Pair Model ID is a 3-byte value,
35      * and a Bluetooth device address is a 6-byte value.
36      */
37     public static class Value extends Bytes {
38         private final ByteOrder mByteOrder;
39 
40         /**
41          * Constructor.
42          */
Value(byte[] bytes, ByteOrder byteOrder)43         public Value(byte[] bytes, ByteOrder byteOrder) {
44             super(bytes);
45             this.mByteOrder = byteOrder;
46         }
47 
48         /**
49          * Gets bytes.
50          */
getBytes(ByteOrder byteOrder)51         public byte[] getBytes(ByteOrder byteOrder) {
52             return this.mByteOrder.equals(byteOrder) ? getBytes() : reverse(getBytes());
53         }
54 
55         @VisibleForTesting
reverse(byte[] bytes)56         static byte[] reverse(byte[] bytes) {
57             byte[] reversedBytes = new byte[bytes.length];
58             for (int i = 0; i < bytes.length; i++) {
59                 reversedBytes[i] = bytes[bytes.length - i - 1];
60             }
61             return reversedBytes;
62         }
63     }
64 
Bytes(byte[] bytes)65     Bytes(byte[] bytes) {
66         mBytes = bytes;
67     }
68 
toHexString(byte[] bytes)69     private static String toHexString(byte[] bytes) {
70         StringBuilder sb = new StringBuilder(2 * bytes.length);
71         for (byte b : bytes) {
72             sb.append(sHexDigits[(b >> 4) & 0xf]).append(sHexDigits[b & 0xf]);
73         }
74         return sb.toString();
75     }
76 
77     /** Returns 2-byte values in the same order, each using the given byte order. */
toBytes(ByteOrder byteOrder, short... shorts)78     public static byte[] toBytes(ByteOrder byteOrder, short... shorts) {
79         ByteBuffer byteBuffer = ByteBuffer.allocate(shorts.length * 2).order(byteOrder);
80         for (short s : shorts) {
81             byteBuffer.putShort(s);
82         }
83         return byteBuffer.array();
84     }
85 
86     /** Returns the shorts in the same order, each converted using the given byte order. */
toShorts(ByteOrder byteOrder, byte[] bytes)87     static short[] toShorts(ByteOrder byteOrder, byte[] bytes) {
88         ShortBuffer shortBuffer = ByteBuffer.wrap(bytes).order(byteOrder).asShortBuffer();
89         short[] shorts = new short[shortBuffer.remaining()];
90         shortBuffer.get(shorts);
91         return shorts;
92     }
93 
94     /** @return The bytes. */
getBytes()95     public byte[] getBytes() {
96         return mBytes;
97     }
98 
99     @Override
equals(@ullable Object o)100     public boolean equals(@Nullable Object o) {
101         if (this == o) {
102             return true;
103         }
104         if (!(o instanceof Bytes)) {
105             return false;
106         }
107         Bytes that = (Bytes) o;
108         return Arrays.equals(mBytes, that.mBytes);
109     }
110 
111     @Override
hashCode()112     public int hashCode() {
113         return Arrays.hashCode(mBytes);
114     }
115 
116     @Override
toString()117     public String toString() {
118         return toHexString(mBytes);
119     }
120 }
121