Convert CarBleManager to Java

Bug: 143651521
Test: Unit tests pass and association succeeds
Change-Id: I171ab0cf9131378c0c4f054354192f752e02cb01
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java
new file mode 100644
index 0000000..d649d10
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2019 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.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ThreadSafeCallbacks;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+
+/**
+ * Generic BLE manager for a car that keeps track of connected devices and their associated
+ * callbacks.
+ */
+public abstract class CarBleManager {
+
+    private static final String TAG = "CarBleManager";
+
+    final ConnectedDeviceStorage mStorage;
+
+    final CopyOnWriteArraySet<BleDevice> mConnectedDevices = new CopyOnWriteArraySet<>();
+
+    final ThreadSafeCallbacks<Callback> mCallbacks = new ThreadSafeCallbacks<>();
+
+    protected CarBleManager(@NonNull ConnectedDeviceStorage connectedDeviceStorage) {
+        mStorage = connectedDeviceStorage;
+    }
+
+    /**
+     * Initialize and start the manager.
+     */
+    public void start() {
+    }
+
+    /**
+     * Stop the manager and clean up.
+     */
+    public void stop() {
+        for (BleDevice device : mConnectedDevices) {
+            if (device.mGatt != null) {
+                device.mGatt.close();
+            }
+        }
+        mConnectedDevices.clear();
+        mCallbacks.clear();
+    }
+
+    /**
+     * Register a {@link Callback} to be notified on the {@link Executor}.
+     */
+    public void registerCallback(@NonNull Callback callback, @NonNull Executor executor) {
+        mCallbacks.add(callback, executor);
+    }
+
+    /**
+     * Unregister a callback.
+     *
+     * @param callback The {@link Callback} to unregister.
+     */
+    public void unregisterCallback(@NonNull Callback callback) {
+        mCallbacks.remove(callback);
+    }
+
+    /**
+     * Send a message to a connected device.
+     *
+     * @param deviceId Id of connected device.
+     * @param message  {@link DeviceMessage} to send.
+     */
+    public void sendMessage(@NonNull String deviceId, @NonNull DeviceMessage message) {
+        BleDevice device = getConnectedDevice(deviceId);
+        if (device == null) {
+            logw(TAG, "Attempted to send message to unknown device $deviceId. Ignored.");
+            return;
+        }
+
+        sendMessage(device, message);
+    }
+
+    /**
+     * Send a message to a connected device.
+     *
+     * @param device  The connected {@link BleDevice}.
+     * @param message {@link DeviceMessage} to send.
+     */
+    public void sendMessage(@NonNull BleDevice device, @NonNull DeviceMessage message) {
+        String deviceId = device.mDeviceId;
+        if (deviceId == null) {
+            deviceId = "Unidentified device";
+        }
+
+        logd(TAG, "Writing " + message.getMessage().length + " bytes to " + deviceId + ".");
+
+
+        if (message.isMessageEncrypted()) {
+            device.mSecureChannel.sendEncryptedMessage(message);
+        } else {
+            device.mSecureChannel.getStream().writeMessage(message);
+        }
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching {@link BluetoothGatt} if available. Returns
+     * {@code null} if no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull BluetoothGatt gatt) {
+        for (BleDevice device : mConnectedDevices) {
+            if (device.mGatt == gatt) {
+                return device;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching {@link BluetoothDevice} if available. Returns
+     * {@code null} if no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull BluetoothDevice device) {
+        for (BleDevice connectedDevice : mConnectedDevices) {
+            if (device.equals(connectedDevice.mDevice)) {
+                return connectedDevice;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching device id if available. Returns {@code null} if
+     * no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull String deviceId) {
+        for (BleDevice device : mConnectedDevices) {
+            if (deviceId.equals(device.mDeviceId)) {
+                return device;
+            }
+        }
+
+        return null;
+    }
+
+    /** Add the {@link BleDevice} that has connected. */
+    void addConnectedDevice(@NonNull BleDevice device) {
+        mConnectedDevices.add(device);
+    }
+
+    /** Return the number of devices currently connected. */
+    int getConnectedDevicesCount() {
+        return mConnectedDevices.size();
+    }
+
+    /** Remove [@link BleDevice} that has been disconnected. */
+    void removeConnectedDevice(@NonNull BleDevice device) {
+        mConnectedDevices.remove(device);
+    }
+
+    /** State for a connected device. */
+    enum BleDeviceState {
+        CONNECTING,
+        PENDING_VERIFICATION,
+        CONNECTED,
+        UNKNOWN
+    }
+
+    /**
+     * Container class to hold information about a connected device.
+     */
+    static class BleDevice {
+
+        BluetoothDevice mDevice;
+        BluetoothGatt mGatt;
+        BleDeviceState mState;
+        String mDeviceId;
+        SecureBleChannel mSecureChannel;
+
+        BleDevice(@NonNull BluetoothDevice device, @Nullable BluetoothGatt gatt) {
+            mDevice = device;
+            mGatt = gatt;
+            mState = BleDeviceState.UNKNOWN;
+        }
+    }
+
+    /**
+     * Callback for triggered events from {@link CarBleManager}.
+     */
+    public interface Callback {
+        /**
+         * Triggered when device is connected and device id retrieved. Device is now ready to
+         * receive messages.
+         *
+         * @param deviceId Id of device that has connected.
+         */
+        void onDeviceConnected(@NonNull String deviceId);
+
+        /**
+         * Triggered when device is disconnected.
+         *
+         * @param deviceId Id of device that has disconnected.
+         */
+        void onDeviceDisconnected(@NonNull String deviceId);
+
+        /**
+         * Triggered when device has established encryption for secure communication.
+         *
+         * @param deviceId Id of device that has established encryption.
+         */
+        void onSecureChannelEstablished(@NonNull String deviceId);
+
+        /**
+         * Triggered when a new message is received.
+         *
+         * @param deviceId Id of the device that sent the message.
+         * @param message  {@link DeviceMessage} received.
+         */
+        void onMessageReceived(@NonNull String deviceId, @NonNull DeviceMessage message);
+
+        /**
+         * Triggered when an error when establishing the secure channel.
+         *
+         * @param deviceId Id of the device that experienced the error.
+         */
+        void onSecureChannelError(@NonNull String deviceId);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.kt b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.kt
deleted file mode 100644
index 6dbc208..0000000
--- a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.kt
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2019 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.car.connecteddevice.ble
-
-import android.bluetooth.BluetoothDevice
-import android.bluetooth.BluetoothGatt
-import com.android.car.connecteddevice.storage.ConnectedDeviceStorage
-import com.android.car.connecteddevice.util.ThreadSafeCallbacksKt
-import com.android.car.connecteddevice.util.logd
-import com.android.car.connecteddevice.util.logw
-import java.util.concurrent.CopyOnWriteArraySet
-import java.util.concurrent.Executor
-
-private const val TAG = "CarBleManager"
-
-/**
- * Generic BLE manager for a car that keeps track of connected devices and their associated
- * callbacks.
- *
- * @param connectedDeviceStorage Shared [ConnectedDeviceStorage] for companion features.
- */
-internal abstract class CarBleManager(
-    private val connectedDeviceStorage: ConnectedDeviceStorage
-) {
-
-    protected val connectedDevices = CopyOnWriteArraySet<BleDevice>()
-
-    protected val callbacks = ThreadSafeCallbacksKt<Callback>()
-
-    open fun start() {
-    }
-
-    open fun stop() {
-        connectedDevices.forEach { it.gatt?.close() }
-        connectedDevices.clear()
-        callbacks.clear()
-    }
-
-    /**
-     * Register a [callback] to be notified on the [executor].
-     */
-    fun registerCallback(callback: Callback, executor: Executor) {
-        callbacks.add(callback, executor)
-    }
-
-    /**
-     * Unregister a callback
-     *
-     * @param callback The [Callback] to unregister.
-     */
-    fun unregisterCallback(callback: Callback) {
-        callbacks.remove(callback)
-    }
-
-    /**
-     * Send a message to a connected device.
-     *
-     * @param deviceId Id of connected device.
-     * @param message [DeviceMessage] to send.
-     */
-    fun sendMessage(deviceId: String, message: DeviceMessage) {
-        getConnectedDevice(deviceId)?.run {
-            sendMessage(this, message)
-        } ?: logw(TAG, "Attempted to send message to unknown device $deviceId. Ignored")
-    }
-
-    /**
-     * Send a message to a connected device.
-     *
-     * @param bleDevice The connected [BleDevice].
-     * @param message [DeviceMessage] to send.
-     */
-    protected fun sendMessage(bleDevice: BleDevice, message: DeviceMessage) {
-        logd(
-            TAG,
-            "Writing ${message.message.size} bytes to " +
-                "${bleDevice.deviceId ?: "Unidentified device"}."
-        )
-
-        if (message.isMessageEncrypted) {
-            bleDevice.secureChannel?.sendEncryptedMessage(message)
-        } else {
-            bleDevice.secureChannel?.stream?.writeMessage(message)
-        }
-    }
-
-    /**
-     * Get the [BleDevice] with matching [gatt] if available. Returns `null` if no matches
-     * found.
-     */
-    protected fun getConnectedDevice(gatt: BluetoothGatt): BleDevice? {
-        return connectedDevices.firstOrNull { it.gatt == gatt }
-    }
-
-    /**
-     * Get the [BleDevice] with matching [device] if available. Returns `null` if no
-     * matches found.
-     */
-    protected fun getConnectedDevice(device: BluetoothDevice): BleDevice? {
-        return connectedDevices.firstOrNull { it.device == device }
-    }
-
-    /**
-     * Get the [BleDevice] with matching [deviceId] if available. Returns `null` if no matches
-     * found.
-     */
-    protected fun getConnectedDevice(deviceId: String): BleDevice? {
-        return connectedDevices.firstOrNull { it.deviceId == deviceId }
-    }
-
-    /** Add the [bleDevice] that has connected. */
-    protected fun addConnectedDevice(bleDevice: BleDevice) {
-        connectedDevices.add(bleDevice)
-    }
-
-    /** Return the number of devices currently connected. */
-    protected fun connectedDevicesCount(): Int {
-        return connectedDevices.count()
-    }
-
-    /** Remove [bleDevice] that has been disconnected. */
-    protected fun removeConnectedDevice(bleDevice: BleDevice) {
-        connectedDevices.remove(bleDevice)
-    }
-
-    /**
-     * Container class to hold information about a connected device.
-     *
-     * @param device The [BluetoothDevice] from the connection.
-     * @param gatt The [BluetoothGatt] from the connection. Only applicable for central connections.
-     */
-    protected data class BleDevice(
-        val device: BluetoothDevice,
-        val gatt: BluetoothGatt?
-    ) {
-        var state: BleDeviceState = BleDeviceState.UNKNOWN
-        var deviceId: String? = null
-        var secureChannel: SecureBleChannel? = null
-    }
-
-    /** State for a connected device. */
-    protected enum class BleDeviceState {
-        CONNECTING,
-        PENDING_VERIFICATION,
-        CONNECTED,
-        UNKNOWN
-    }
-
-    /**
-     * Callback for triggered events from [CarBleManager].
-     */
-    interface Callback {
-
-        /**
-         * Triggered when device is connected and device id retrieved. Device is now ready to
-         * receive messages.
-         *
-         * @param deviceId Id of device that has connected.
-         */
-        fun onDeviceConnected(deviceId: String)
-
-        /**
-         * Triggered when device is disconnected.
-         *
-         * @param deviceId Id of device that has disconnected.
-         */
-        fun onDeviceDisconnected(deviceId: String)
-
-        /**
-         * Triggered when device has established encryption for secure communication.
-         *
-         * @param deviceId Id of device that has established encryption.
-         */
-        fun onSecureChannelEstablished(deviceId: String)
-
-        /**
-         * Triggered when a new message is received.
-         *
-         * @param deviceId Id of the device that sent the message.
-         * @param message [DeviceMessage] received.
-         */
-        fun onMessageReceived(deviceId: String, message: DeviceMessage)
-
-        /**
-         * Triggered when an error when establishing the secure channel.
-         *
-         * @param deviceId Id of the device that experienced the error.
-         */
-        fun onSecureChannelError(deviceId: String)
-    }
-}