168 lines
7.7 KiB
Java
168 lines
7.7 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2023 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;
|
||
|
|
||
|
import android.os.RemoteException;
|
||
|
import android.util.Log;
|
||
|
|
||
|
/** Utility class for socket metrics */
|
||
|
class SocketMetrics {
|
||
|
private static final String TAG = SocketMetrics.class.getSimpleName();
|
||
|
|
||
|
/*package*/ static final int SOCKET_NO_ERROR = -1;
|
||
|
|
||
|
// Defined in BluetoothProtoEnums.L2capCocConnectionResult of proto logging
|
||
|
private static final int RESULT_L2CAP_CONN_UNKNOWN = 0;
|
||
|
/*package*/ 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;
|
||
|
/*package*/ static final int RESULT_L2CAP_CONN_SERVER_FAILURE = 2000;
|
||
|
|
||
|
// Defined in BluetoothRfcommProtoEnums.RfcommConnectionResult of proto logging
|
||
|
private static final int RFCOMM_CONN_RESULT_FAILURE_UNKNOWN = 0;
|
||
|
private static final int RFCOMM_CONN_RESULT_SUCCESS = 1;
|
||
|
private static final int RFCOMM_CONN_RESULT_SOCKET_CONNECTION_FAILED = 2;
|
||
|
private static final int RFCOMM_CONN_RESULT_SOCKET_CONNECTION_CLOSED = 3;
|
||
|
private static final int RFCOMM_CONN_RESULT_UNABLE_TO_SEND_RPC = 4;
|
||
|
private static final int RFCOMM_CONN_RESULT_NULL_BLUETOOTH_DEVICE = 5;
|
||
|
private static final int RFCOMM_CONN_RESULT_GET_SOCKET_MANAGER_FAILED = 6;
|
||
|
private static final int RFCOMM_CONN_RESULT_NULL_FILE_DESCRIPTOR = 7;
|
||
|
|
||
|
static void logSocketConnect(
|
||
|
int socketExceptionCode,
|
||
|
long socketConnectionTimeNanos,
|
||
|
int connType,
|
||
|
BluetoothDevice device,
|
||
|
int port,
|
||
|
boolean auth,
|
||
|
long socketCreationTimeNanos,
|
||
|
long socketCreationLatencyNanos) {
|
||
|
IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
|
||
|
if (bluetoothProxy == null) {
|
||
|
Log.w(TAG, "logSocketConnect: bluetoothProxy is null");
|
||
|
return;
|
||
|
}
|
||
|
if (connType == BluetoothSocket.TYPE_L2CAP_LE) {
|
||
|
try {
|
||
|
bluetoothProxy.logL2capcocClientConnection(
|
||
|
device,
|
||
|
port,
|
||
|
auth,
|
||
|
getL2capLeConnectStatusCode(socketExceptionCode),
|
||
|
socketCreationTimeNanos, // to calculate end to end latency
|
||
|
socketCreationLatencyNanos, // latency of the constructor
|
||
|
socketConnectionTimeNanos); // to calculate the latency of connect()
|
||
|
} catch (RemoteException e) {
|
||
|
Log.w(TAG, "logL2capcocServerConnection failed", e);
|
||
|
}
|
||
|
} else if (connType == BluetoothSocket.TYPE_RFCOMM) {
|
||
|
boolean isSerialPort = true; // BluetoothSocket#connect API always uses serial port uuid
|
||
|
try {
|
||
|
bluetoothProxy.logRfcommConnectionAttempt(
|
||
|
device,
|
||
|
auth,
|
||
|
getRfcommConnectStatusCode(socketExceptionCode),
|
||
|
socketCreationTimeNanos, // to calculate end to end latency
|
||
|
isSerialPort);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.w(TAG, "logL2capcocServerConnection failed", e);
|
||
|
}
|
||
|
} else {
|
||
|
Log.d(TAG, "No metrics for connection type " + connType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void logSocketAccept(
|
||
|
BluetoothSocket acceptedSocket,
|
||
|
BluetoothSocket socket,
|
||
|
int connType,
|
||
|
int channel,
|
||
|
int timeout,
|
||
|
int result,
|
||
|
long socketCreationTimeMillis,
|
||
|
long socketCreationLatencyMillis,
|
||
|
long socketConnectionTimeMillis) {
|
||
|
if (connType != BluetoothSocket.TYPE_L2CAP_LE) {
|
||
|
return;
|
||
|
}
|
||
|
IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
|
||
|
if (bluetoothProxy == null) {
|
||
|
Log.w(TAG, "logSocketConnect: bluetoothProxy is null");
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
bluetoothProxy.logL2capcocServerConnection(
|
||
|
acceptedSocket == null ? null : acceptedSocket.getRemoteDevice(),
|
||
|
channel,
|
||
|
socket.isAuth(),
|
||
|
result,
|
||
|
socketCreationTimeMillis, // pass creation time to calculate end to end latency
|
||
|
socketCreationLatencyMillis, // socket creation latency
|
||
|
socketConnectionTimeMillis, // send connection start time for connection latency
|
||
|
timeout);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.w(TAG, "logL2capcocServerConnection failed", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static int getL2capLeConnectStatusCode(int socketExceptionCode) {
|
||
|
switch (socketExceptionCode) {
|
||
|
case (SOCKET_NO_ERROR):
|
||
|
return RESULT_L2CAP_CONN_SUCCESS;
|
||
|
case (BluetoothSocketException.NULL_DEVICE):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE;
|
||
|
case (BluetoothSocketException.SOCKET_MANAGER_FAILURE):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED;
|
||
|
case (BluetoothSocketException.SOCKET_CLOSED):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED;
|
||
|
case (BluetoothSocketException.SOCKET_CONNECTION_FAILURE):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED;
|
||
|
case (BluetoothSocketException.RPC_FAILURE):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC;
|
||
|
case (BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE):
|
||
|
return RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR;
|
||
|
default:
|
||
|
return RESULT_L2CAP_CONN_UNKNOWN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static int getRfcommConnectStatusCode(int socketExceptionCode) {
|
||
|
switch (socketExceptionCode) {
|
||
|
case (SOCKET_NO_ERROR):
|
||
|
return RFCOMM_CONN_RESULT_SUCCESS;
|
||
|
case (BluetoothSocketException.NULL_DEVICE):
|
||
|
return RFCOMM_CONN_RESULT_NULL_BLUETOOTH_DEVICE;
|
||
|
case (BluetoothSocketException.SOCKET_MANAGER_FAILURE):
|
||
|
return RFCOMM_CONN_RESULT_GET_SOCKET_MANAGER_FAILED;
|
||
|
case (BluetoothSocketException.SOCKET_CLOSED):
|
||
|
return RFCOMM_CONN_RESULT_SOCKET_CONNECTION_CLOSED;
|
||
|
case (BluetoothSocketException.SOCKET_CONNECTION_FAILURE):
|
||
|
return RFCOMM_CONN_RESULT_SOCKET_CONNECTION_FAILED;
|
||
|
case (BluetoothSocketException.RPC_FAILURE):
|
||
|
return RFCOMM_CONN_RESULT_UNABLE_TO_SEND_RPC;
|
||
|
case (BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE):
|
||
|
return RFCOMM_CONN_RESULT_NULL_FILE_DESCRIPTOR;
|
||
|
default:
|
||
|
return RFCOMM_CONN_RESULT_FAILURE_UNKNOWN;
|
||
|
}
|
||
|
}
|
||
|
}
|