Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9cebf50 authored by Chen Chen's avatar Chen Chen Committed by Automerger Merge Worker
Browse files

Merge "BluetoothMetrics: Upload Bluetooth L2CAP CoC Client Connection Metrics"...

Merge "BluetoothMetrics: Upload Bluetooth L2CAP CoC Client Connection Metrics" am: c175743a am: b21bac64 am: a3931bec

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2454845



Change-Id: I132b388ef38901ecf888d73707cea5b09ff7c8b2
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b6a90327 a3931bec
Loading
Loading
Loading
Loading
+48 −0
Original line number Original line Diff line number Diff line
@@ -680,6 +680,34 @@ public class AdapterService extends Service {
        mMetricsLogger = metricsLogger;
        mMetricsLogger = metricsLogger;
    }
    }



    /**
     *  Log L2CAP CoC Client Connection Metrics
     *
     *  @param device Bluetooth device
     *  @param port port of socket
     *  @param isSecured if secured API is called
     *  @param result transaction result of the connection
     *  @param connectionLatencyMillis latency of the connection
     */
    public void logL2capcocClientConnection(
            BluetoothDevice device,
            int port,
            boolean isSecured,
            int result,
            long connectionLatencyMillis,
            int appUid) {

        int metricId = getMetricId(device);
        Log.i(TAG, "Statslog L2capcoc client connection. metricId "
                + metricId + " port " + port + " isSecured " + isSecured
                + " result " + result + " connectionLatencyMillis " + connectionLatencyMillis
                + " appUid " + appUid);
        BluetoothStatsLog.write(
                BluetoothStatsLog.BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION,
                metricId, port, isSecured, result, connectionLatencyMillis, appUid);
    }

    @RequiresPermission(allOf = {
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.UPDATE_DEVICE_STATS,
            android.Manifest.permission.UPDATE_DEVICE_STATS,
@@ -3436,6 +3464,26 @@ public class AdapterService extends Service {
            return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder);
            return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder);
        }
        }


        @Override
        public void logL2capcocClientConnection(
                BluetoothDevice device,
                int port,
                boolean isSecured,
                int result,
                long connectionLatencyMillis) {
            AdapterService service = getService();
            if (service == null) {
                return;
            }
            service.logL2capcocClientConnection(
                    device,
                    port,
                    isSecured,
                    result,
                    connectionLatencyMillis,
                    Binder.getCallingUid());
        }

        @Override
        @Override
        public void sdpSearch(BluetoothDevice device, ParcelUuid uuid, AttributionSource source,
        public void sdpSearch(BluetoothDevice device, ParcelUuid uuid, AttributionSource source,
                SynchronousResultReceiver receiver) {
                SynchronousResultReceiver receiver) {
+100 −23
Original line number Original line Diff line number Diff line
@@ -121,6 +121,16 @@ public final class BluetoothSocket implements Closeable {
    /*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
    /*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
    /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;
    /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;


    // Defined in BluetoothProtoEnums.L2capCocConnectionResult of proto logging
    private static final int RESULT_L2CAP_CONN_UNKNOWN = 0;
    private static final int RESULT_L2CAP_CONN_SUCCESS = 1;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_FAILED = 1000;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_CLOSED = 1001;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_UNABLE_TO_SEND_RPC = 1002;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_NULL_BLUETOOTH_DEVICE = 1003;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_GET_SOCKET_MANAGER_FAILED = 1004;
    private static final int RESULT_L2CAP_CONN_BlUETOOTH_NULL_FILE_DESCRIPTOR = 1005;

    private final int mType;  /* one of TYPE_RFCOMM etc */
    private final int mType;  /* one of TYPE_RFCOMM etc */
    private BluetoothDevice mDevice;    /* remote device */
    private BluetoothDevice mDevice;    /* remote device */
    private String mAddress;    /* remote address */
    private String mAddress;    /* remote address */
@@ -153,6 +163,8 @@ public final class BluetoothSocket implements Closeable {
    private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer.
    private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer.
    private int mMaxRxPacketSize = 0; // The l2cap maximum packet size that can be received.
    private int mMaxRxPacketSize = 0; // The l2cap maximum packet size that can be received.


    private long mSocketCreationTime = 0;

    private enum SocketState {
    private enum SocketState {
        INIT,
        INIT,
        CONNECTED,
        CONNECTED,
@@ -327,6 +339,7 @@ public final class BluetoothSocket implements Closeable {
            BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
            BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
            throws IOException {
            throws IOException {
        if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
        if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
        mSocketCreationTime = System.currentTimeMillis();
        if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
        if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
                && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
                && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
            if (port < 1 || port > MAX_RFCOMM_CHANNEL) {
            if (port < 1 || port > MAX_RFCOMM_CHANNEL) {
@@ -403,6 +416,7 @@ public final class BluetoothSocket implements Closeable {
        mExcludeSdp = s.mExcludeSdp;
        mExcludeSdp = s.mExcludeSdp;
        mAuthMitm = s.mAuthMitm;
        mAuthMitm = s.mAuthMitm;
        mMin16DigitPin = s.mMin16DigitPin;
        mMin16DigitPin = s.mMin16DigitPin;
        mSocketCreationTime = s.mSocketCreationTime;
    }
    }


    private BluetoothSocket acceptSocket(String remoteAddr) throws IOException {
    private BluetoothSocket acceptSocket(String remoteAddr) throws IOException {
@@ -568,20 +582,42 @@ public final class BluetoothSocket implements Closeable {
    @RequiresBluetoothConnectPermission
    @RequiresBluetoothConnectPermission
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    public void connect() throws IOException {
    public void connect() throws IOException {
        if (mDevice == null) throw new IOException(NULL_DEVICE_ERR_MSG);

        try {
            if (mSocketState == SocketState.CLOSED) throw new IOException(SOCKET_CLOSED_MSG);
        IBluetooth bluetoothProxy =
        IBluetooth bluetoothProxy =
                BluetoothAdapter.getDefaultAdapter().getBluetoothService();
                BluetoothAdapter.getDefaultAdapter().getBluetoothService();
            if (bluetoothProxy == null) throw new IOException(BLUETOOTH_OFF_FAILURE_MSG);
        if (bluetoothProxy == null) {
            throw new IOException(BLUETOOTH_OFF_FAILURE_MSG);
        }
        if (mDevice == null) {
            logL2capcocClientConnection(
                    bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_NULL_BLUETOOTH_DEVICE);
            throw new IOException(NULL_DEVICE_ERR_MSG);
        }
        try {
            if (mSocketState == SocketState.CLOSED) {
                logL2capcocClientConnection(
                        bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_CLOSED);
                throw new IOException(SOCKET_CLOSED_MSG);
            }

            IBluetoothSocketManager socketManager = bluetoothProxy.getSocketManager();
            IBluetoothSocketManager socketManager = bluetoothProxy.getSocketManager();
            if (socketManager == null) throw new IOException(SOCKET_MANAGER_FAILURE_MSG);
            if (socketManager == null) {
                logL2capcocClientConnection(
                        bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_GET_SOCKET_MANAGER_FAILED);
                throw new IOException(SOCKET_MANAGER_FAILURE_MSG);
            }
            mPfd = socketManager.connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags());
            mPfd = socketManager.connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags());
            synchronized (this) {
            synchronized (this) {
                if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
                if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
                if (mSocketState == SocketState.CLOSED) throw new IOException(SOCKET_CLOSED_MSG);
                if (mSocketState == SocketState.CLOSED) {
                if (mPfd == null) throw new IOException(SOCKET_CONNECTION_FAILURE_MSG);
                    logL2capcocClientConnection(
                            bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_CLOSED);
                    throw new IOException(SOCKET_CLOSED_MSG);
                }
                if (mPfd == null) {
                    logL2capcocClientConnection(
                            bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_NULL_FILE_DESCRIPTOR);
                    throw new IOException(SOCKET_CONNECTION_FAILURE_MSG);
                }
                FileDescriptor fd = mPfd.getFileDescriptor();
                FileDescriptor fd = mPfd.getFileDescriptor();
                mSocket = new LocalSocket(fd);
                mSocket = new LocalSocket(fd);
                mSocketIS = mSocket.getInputStream();
                mSocketIS = mSocket.getInputStream();
@@ -590,51 +626,75 @@ public final class BluetoothSocket implements Closeable {
            int channel = readInt(mSocketIS);
            int channel = readInt(mSocketIS);
            if (channel == 0) {
            if (channel == 0) {
                int errCode = (int) mSocketIS.read();
                int errCode = (int) mSocketIS.read();
                String exceptionMsg = "";
                switch(errCode) {
                switch(errCode) {
                    case L2CAP_ACL_FAILURE:
                    case L2CAP_ACL_FAILURE:
                        throw new IOException(L2CAP_ACL_FAILURE_MSG);
                        exceptionMsg = L2CAP_ACL_FAILURE_MSG;
                        break;
                    case L2CAP_CLIENT_SECURITY_FAILURE:
                    case L2CAP_CLIENT_SECURITY_FAILURE:
                        throw new IOException(L2CAP_CLIENT_SECURITY_FAILURE_MSG);
                        exceptionMsg = L2CAP_CLIENT_SECURITY_FAILURE_MSG;
                        break;
                    case L2CAP_INSUFFICIENT_AUTHENTICATION:
                    case L2CAP_INSUFFICIENT_AUTHENTICATION:
                        throw new IOException(L2CAP_INSUFFICIENT_AUTHORIZATION_MSG);
                        exceptionMsg = L2CAP_INSUFFICIENT_AUTHORIZATION_MSG;
                        break;
                    case L2CAP_INSUFFICIENT_AUTHORIZATION:
                    case L2CAP_INSUFFICIENT_AUTHORIZATION:
                        throw new IOException(L2CAP_INSUFFICIENT_AUTHORIZATION_MSG);
                        exceptionMsg = L2CAP_INSUFFICIENT_AUTHORIZATION_MSG;
                        break;
                    case L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE:
                    case L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE:
                        throw new IOException(L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE_MSG);
                        exceptionMsg = L2CAP_INSUFFICIENT_ENCRYPT_KEY_SIZE_MSG;
                        break;
                    case L2CAP_INSUFFICIENT_ENCRYPTION:
                    case L2CAP_INSUFFICIENT_ENCRYPTION:
                        throw new IOException(L2CAP_INSUFFICIENT_ENCRYPTION_MSG);
                        exceptionMsg = L2CAP_INSUFFICIENT_ENCRYPTION_MSG;
                        break;
                    case L2CAP_INVALID_SOURCE_CID:
                    case L2CAP_INVALID_SOURCE_CID:
                        throw new IOException(L2CAP_INVALID_SOURCE_CID_MSG);
                        exceptionMsg = L2CAP_INVALID_SOURCE_CID_MSG;
                        break;
                    case L2CAP_SOURCE_CID_ALREADY_ALLOCATED:
                    case L2CAP_SOURCE_CID_ALREADY_ALLOCATED:
                        throw new IOException(L2CAP_SOURCE_CID_ALREADY_ALLOCATED_MSG);
                        exceptionMsg = L2CAP_SOURCE_CID_ALREADY_ALLOCATED_MSG;
                        break;
                    case L2CAP_UNACCEPTABLE_PARAMETERS:
                    case L2CAP_UNACCEPTABLE_PARAMETERS:
                        throw new IOException(L2CAP_UNACCEPTABLE_PARAMETERS_MSG);
                        exceptionMsg = L2CAP_UNACCEPTABLE_PARAMETERS_MSG;
                        break;
                    case L2CAP_INVALID_PARAMETERS:
                    case L2CAP_INVALID_PARAMETERS:
                        throw new IOException(L2CAP_INVALID_PARAMETERS_MSG);
                        exceptionMsg = L2CAP_INVALID_PARAMETERS_MSG;
                        break;
                    case L2CAP_NO_RESOURCES:
                    case L2CAP_NO_RESOURCES:
                        throw new IOException(L2CAP_NO_RESOURCES_MSG);
                        exceptionMsg = L2CAP_NO_RESOURCES_MSG;
                        break;
                    case L2CAP_NO_PSM_AVAILABLE:
                    case L2CAP_NO_PSM_AVAILABLE:
                        throw new IOException(L2CAP_NO_PSM_AVAILABLE_MSG);
                        exceptionMsg = L2CAP_NO_PSM_AVAILABLE_MSG;
                        break;
                    case L2CAP_TIMEOUT:
                    case L2CAP_TIMEOUT:
                        throw new IOException(L2CAP_TIMEOUT_MSG);
                        exceptionMsg = L2CAP_TIMEOUT_MSG;
                        break;
                    default:
                    default:
                        throw new IOException(L2CAP_UNKNOWN_ERR_MSG);
                        exceptionMsg = L2CAP_UNKNOWN_ERR_MSG;
                        errCode = RESULT_L2CAP_CONN_UNKNOWN;
                }
                }
                logL2capcocClientConnection(bluetoothProxy, errCode);
                throw new IOException(exceptionMsg);
            }
            }
            if (channel < 0) {
            if (channel < 0) {
                logL2capcocClientConnection(
                        bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_FAILED);
                throw new IOException(SOCKET_CONNECTION_FAILURE_MSG);
                throw new IOException(SOCKET_CONNECTION_FAILURE_MSG);
            }
            }
            mPort = channel;
            mPort = channel;
            waitSocketSignal(mSocketIS);
            waitSocketSignal(mSocketIS);
            synchronized (this) {
            synchronized (this) {
                if (mSocketState == SocketState.CLOSED) {
                if (mSocketState == SocketState.CLOSED) {
                    logL2capcocClientConnection(
                            bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_SOCKET_CONNECTION_CLOSED);
                    throw new IOException(SOCKET_CLOSED_MSG);
                    throw new IOException(SOCKET_CLOSED_MSG);
                }
                }
                mSocketState = SocketState.CONNECTED;
                mSocketState = SocketState.CONNECTED;
                if (DBG) Log.d(TAG, "connect(), socket connected");
                if (DBG) Log.d(TAG, "connect(), socket connected");
            }
            }
            logL2capcocClientConnection(bluetoothProxy, RESULT_L2CAP_CONN_SUCCESS);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            logL2capcocClientConnection(
                    bluetoothProxy, RESULT_L2CAP_CONN_BlUETOOTH_UNABLE_TO_SEND_RPC);
            throw new IOException("unable to send RPC: " + e.getMessage());
            throw new IOException("unable to send RPC: " + e.getMessage());
        }
        }
    }
    }
@@ -843,6 +903,19 @@ public final class BluetoothSocket implements Closeable {
        }
        }
    }
    }


    private void logL2capcocClientConnection(IBluetooth bluetoothProxy, int errCode) {
        if (mType != TYPE_L2CAP_LE) {
            return;
        }
        try {
            bluetoothProxy.logL2capcocClientConnection(
                    mDevice, mPort, mAuth, errCode,
                    System.currentTimeMillis() - mSocketCreationTime);
        } catch (RemoteException e) {
            Log.w(TAG, "logL2capcocClientConnection failed due to remote exception");
        }
    }

    /*package */ void removeChannel() {
    /*package */ void removeChannel() {
    }
    }


@@ -850,6 +923,10 @@ public final class BluetoothSocket implements Closeable {
        return mPort;
        return mPort;
    }
    }


    /*package */ long getSocketCreationTime() {
        return mSocketCreationTime;
    }

    /**
    /**
     * Get the maximum supported Transmit packet size for the underlying transport.
     * Get the maximum supported Transmit packet size for the underlying transport.
     * Use this to optimize the writes done to the output socket, to avoid sending
     * Use this to optimize the writes done to the output socket, to avoid sending
+3 −0
Original line number Original line Diff line number Diff line
@@ -180,6 +180,9 @@ interface IBluetooth
    @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
    @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
    IBluetoothSocketManager getSocketManager();
    IBluetoothSocketManager getSocketManager();


    @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
    oneway void logL2capcocClientConnection(in BluetoothDevice device, int port, boolean isSecured, int result, long connectionLatencyMillis);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    oneway void factoryReset(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
    oneway void factoryReset(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);