Merge "Add PairingException."
diff --git a/nearby/service/Android.bp b/nearby/service/Android.bp
index 13dd6a9..25beee6 100644
--- a/nearby/service/Android.bp
+++ b/nearby/service/Android.bp
@@ -36,6 +36,11 @@
         // pre-jarjar symbols are needed so that nearby-service can reference the original class
         // names at compile time
         "framework-nearby-pre-jarjar",
+        "error_prone_annotations",
+    ],
+    static_libs: [
+        "guava",
+        "androidx.annotation_annotation",
     ],
     sdk_version: "system_server_current",
 
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java
new file mode 100644
index 0000000..3a02b18
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothConsts.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth;
+
+import java.util.UUID;
+
+/**
+ * Bluetooth constants.
+ */
+public class BluetoothConsts {
+
+    /**
+     * Default MTU when value is unknown.
+     */
+    public static final int DEFAULT_MTU = 23;
+
+    // The following random uuids are used to indicate that the device has dynamic services.
+    /**
+     * UUID of dynamic service.
+     */
+    public static final UUID SERVICE_DYNAMIC_SERVICE =
+            UUID.fromString("00000100-0af3-11e5-a6c0-1697f925ec7b");
+
+    /**
+     * UUID of dynamic characteristic.
+     */
+    public static final UUID SERVICE_DYNAMIC_CHARACTERISTIC =
+            UUID.fromString("00002A05-0af3-11e5-a6c0-1697f925ec7b");
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java
new file mode 100644
index 0000000..83d4a23
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/BluetoothException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth;
+
+/**
+ * {@link Exception} thrown during a Bluetooth operation.
+ */
+public class BluetoothException extends Exception {
+    public BluetoothException(String message) {
+        super(message);
+    }
+
+    public BluetoothException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java
new file mode 100644
index 0000000..249011a
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/ReservedUuids.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth;
+
+import java.util.UUID;
+
+/**
+ * Reserved UUIDS by BT SIG.
+ * <p>
+ * See https://developer.bluetooth.org for more details.
+ */
+public class ReservedUuids {
+    /** UUIDs reserved for services. */
+    public static class Services {
+        /**
+         * The Device Information Service exposes manufacturer and/or vendor info about a device.
+         * <p>
+         * See reserved UUID org.bluetooth.service.device_information.
+         */
+        public static final UUID DEVICE_INFORMATION = fromShortUuid((short) 0x180A);
+
+        /**
+         * Generic attribute service.
+         * <p>
+         * See reserved UUID org.bluetooth.service.generic_attribute.
+         */
+        public static final UUID GENERIC_ATTRIBUTE = fromShortUuid((short) 0x1801);
+    }
+
+    /** UUIDs reserved for characteristics. */
+    public static class Characteristics {
+        /**
+         * The value of this characteristic is a UTF-8 string representing the firmware revision for
+         * the firmware within the device.
+         * <p>
+         * See reserved UUID org.bluetooth.characteristic.firmware_revision_string.
+         */
+        public static final UUID FIRMWARE_REVISION_STRING = fromShortUuid((short) 0x2A26);
+
+        /**
+         * Service change characteristic.
+         * <p>
+         * See reserved UUID org.bluetooth.characteristic.gatt.service_changed.
+         */
+        public static final UUID SERVICE_CHANGE = fromShortUuid((short) 0x2A05);
+    }
+
+    /** UUIDs reserved for descriptors. */
+    public static class Descriptors {
+        /**
+         * This descriptor shall be persistent across connections for bonded devices. The Client
+         * Characteristic Configuration descriptor is unique for each client. A client may read and
+         * write this descriptor to determine and set the configuration for that client.
+         * Authentication and authorization may be required by the server to write this descriptor.
+         * The default value for the Client Characteristic Configuration descriptor is 0x00. Upon
+         * connection of non-binded clients, this descriptor is set to the default value.
+         * <p>
+         * See reserved UUID org.bluetooth.descriptor.gatt.client_characteristic_configuration.
+         */
+        public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION =
+                fromShortUuid((short) 0x2902);
+    }
+
+    /** The base 128-bit UUID representation of a 16-bit UUID */
+    public static final UUID BASE_16_BIT_UUID =
+            UUID.fromString("00000000-0000-1000-8000-00805F9B34FB");
+
+    /** Converts from short UUId to UUID. */
+    public static UUID fromShortUuid(short shortUuid) {
+        return new UUID(((((long) shortUuid) << 32) & 0x0000FFFF00000000L)
+                | ReservedUuids.BASE_16_BIT_UUID.getMostSignificantBits(),
+                ReservedUuids.BASE_16_BIT_UUID.getLeastSignificantBits());
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java
new file mode 100644
index 0000000..88c9484
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/Ltv.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth.fastpair;
+
+import static com.google.common.io.BaseEncoding.base16;
+
+import com.google.common.primitives.Bytes;
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A length, type, value (LTV) data block.
+ */
+public class Ltv {
+
+    private static final int SIZE_OF_LEN_TYPE = 2;
+
+    final byte mType;
+    final byte[] mValue;
+
+    /**
+     * Thrown if there's an error during {@link #parse}.
+     */
+    public static class ParseException extends Exception {
+
+        @FormatMethod
+        private ParseException(@FormatString String format, Object... objects) {
+            super(String.format(format, objects));
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    public Ltv(byte type, byte... value) {
+        this.mType = type;
+        this.mValue = value;
+    }
+
+    /**
+     * Parses a list of LTV blocks out of the input byte block.
+     */
+    static List<Ltv> parse(byte[] bytes) throws ParseException {
+        List<Ltv> ltvs = new ArrayList<>();
+        // The "+ 2" is for the length and type bytes.
+        for (int valueLength, i = 0; i < bytes.length; i += SIZE_OF_LEN_TYPE + valueLength) {
+            // - 1 since the length in the packet includes the type byte.
+            valueLength = bytes[i] - 1;
+            if (valueLength < 0 || bytes.length < i + SIZE_OF_LEN_TYPE + valueLength) {
+                throw new ParseException(
+                        "Wrong length=%d at index=%d in LTVs=%s", bytes[i], i,
+                        base16().encode(bytes));
+            }
+            ltvs.add(new Ltv(bytes[i + 1], Arrays.copyOfRange(bytes, i + SIZE_OF_LEN_TYPE,
+                    i + SIZE_OF_LEN_TYPE + valueLength)));
+        }
+        return ltvs;
+    }
+
+    /**
+     * Returns an LTV block, where length is mValue.length + 1 (for the type byte).
+     */
+    public byte[] getBytes() {
+        return Bytes.concat(new byte[]{(byte) (mValue.length + 1), mType}, mValue);
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java
new file mode 100644
index 0000000..8f8e498
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PairingProgressListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth.fastpair;
+
+/** Callback interface for pairing progress. */
+public interface PairingProgressListener {
+    /** Enum for pairing events. */
+    enum PairingEvent {
+        START,
+        SUCCESS,
+        FAILED,
+        UNKNOWN;
+
+        public static PairingEvent fromOrdinal(int ordinal) {
+            PairingEvent[] values = PairingEvent.values();
+            if (ordinal < 0 || ordinal >= values.length) {
+                return UNKNOWN;
+            }
+            return values[ordinal];
+        }
+    }
+
+    /** Callback function upon pairing progress update. */
+    void onPairingProgressUpdating(PairingEvent event, String message);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java
new file mode 100644
index 0000000..f5807a3
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/PasskeyConfirmationHandler.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth.fastpair;
+
+import android.bluetooth.BluetoothDevice;
+
+/** Interface for getting the passkey confirmation request. */
+public interface PasskeyConfirmationHandler {
+    /** Called when getting the passkey confirmation request while pairing. */
+    void onPasskeyConfirmation(BluetoothDevice device, int passkey);
+}
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java
new file mode 100644
index 0000000..41ac9f5
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/ToggleBluetoothTask.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 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 com.android.server.nearby.common.bluetooth.fastpair;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/** Task for toggling Bluetooth on and back off again. */
+interface ToggleBluetoothTask {
+
+    /**
+     * Toggles the bluetooth adapter off and back on again to help improve connection reliability.
+     *
+     * @throws InterruptedException when waiting for the bluetooth adapter's state to be set has
+     *     been interrupted.
+     * @throws ExecutionException when waiting for the bluetooth adapter's state to be set has
+     *     failed.
+     * @throws TimeoutException when the bluetooth adapter's state fails to be set on or off.
+     */
+    void toggleBluetooth() throws InterruptedException, ExecutionException, TimeoutException;
+}