blob: ad3b07ef3672aa118230e1b25a37b40bcae01aeb [file] [log] [blame]
Pomai Ahloe28d3cb2023-11-02 17:19:30 -07001/*
2 * Copyright (C) 2023 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
17package android.bluetooth;
18
19import static android.bluetooth.BluetoothUtils.getSyncTimeout;
20
21import android.os.RemoteException;
22import android.util.Log;
23
24import com.android.modules.utils.SynchronousResultReceiver;
25
26import java.util.concurrent.TimeoutException;
27
28/** Utility class for socket metrics */
29class SocketMetrics {
30 private static final String TAG = SocketMetrics.class.getSimpleName();
31
32 /*package*/ static final int SOCKET_NO_ERROR = -1;
33
34 // Defined in BluetoothProtoEnums.L2capCocConnectionResult of proto logging
35 private static final int RESULT_L2CAP_CONN_UNKNOWN = 0;
36 /*package*/ static final int RESULT_L2CAP_CONN_SUCCESS = 1;
37 private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED = 1000;
38 private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED = 1001;
39 private static final int RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC = 1002;
40 private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE = 1003;
41 private static final int RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED = 1004;
42 private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR = 1005;
43 /*package*/ static final int RESULT_L2CAP_CONN_SERVER_FAILURE = 2000;
44
45 static void logSocketConnect(
46 int socketExceptionCode,
Pomai Ahlobc19c022023-11-13 16:37:06 -080047 long socketConnectionTimeNanos,
Pomai Ahloe28d3cb2023-11-02 17:19:30 -070048 int connType,
49 BluetoothDevice device,
50 int port,
51 boolean auth,
Pomai Ahlobc19c022023-11-13 16:37:06 -080052 long socketCreationTimeNanos,
53 long socketCreationLatencyNanos) {
Pomai Ahloe28d3cb2023-11-02 17:19:30 -070054 if (connType != BluetoothSocket.TYPE_L2CAP_LE) {
55 return;
56 }
57 IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
58 if (bluetoothProxy == null) {
59 Log.w(TAG, "logSocketConnect: bluetoothProxy is null");
60 return;
61 }
62 int errCode = getL2capLeConnectStatusCode(socketExceptionCode);
63 try {
64 final SynchronousResultReceiver recv = SynchronousResultReceiver.get();
65 bluetoothProxy.logL2capcocClientConnection(
66 device,
67 port,
68 auth,
69 errCode,
Pomai Ahlobc19c022023-11-13 16:37:06 -080070 socketCreationTimeNanos, // to calculate end to end latency
71 socketCreationLatencyNanos, // latency of the constructor
72 socketConnectionTimeNanos, // to calculate the latency of connect()
Pomai Ahloe28d3cb2023-11-02 17:19:30 -070073 recv);
74 recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
75 } catch (RemoteException | TimeoutException e) {
76 Log.w(TAG, "logL2capcocClientConnection failed", e);
77 }
78 }
79
80 static void logSocketAccept(
81 BluetoothSocket acceptedSocket,
82 BluetoothSocket socket,
83 int connType,
84 int channel,
85 int timeout,
86 int result,
87 long socketCreationTimeMillis,
88 long socketCreationLatencyMillis,
89 long socketConnectionTimeMillis) {
90 if (connType != BluetoothSocket.TYPE_L2CAP_LE) {
91 return;
92 }
93 IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
94 if (bluetoothProxy == null) {
95 Log.w(TAG, "logSocketConnect: bluetoothProxy is null");
96 return;
97 }
98 try {
99 final SynchronousResultReceiver recv = SynchronousResultReceiver.get();
100 bluetoothProxy.logL2capcocServerConnection(
101 acceptedSocket == null ? null : acceptedSocket.getRemoteDevice(),
102 channel,
103 socket.isAuth(),
104 result,
105 socketCreationTimeMillis, // pass creation time to calculate end to end latency
106 socketCreationLatencyMillis, // socket creation latency
107 socketConnectionTimeMillis, // send connection start time for connection latency
108 timeout,
109 recv);
110 recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
111
112 } catch (RemoteException | TimeoutException e) {
113 Log.w(TAG, "logL2capcocServerConnection failed", e);
114 }
115 }
116
117 private static int getL2capLeConnectStatusCode(int socketExceptionCode) {
118 switch (socketExceptionCode) {
119 case (SOCKET_NO_ERROR):
120 return RESULT_L2CAP_CONN_SUCCESS;
121 case (BluetoothSocketException.NULL_DEVICE):
122 return RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE;
123 case (BluetoothSocketException.SOCKET_MANAGER_FAILURE):
124 return RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED;
125 case (BluetoothSocketException.SOCKET_CLOSED):
126 return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED;
127 case (BluetoothSocketException.SOCKET_CONNECTION_FAILURE):
128 return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED;
129 case (BluetoothSocketException.RPC_FAILURE):
130 return RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC;
131 case (BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE):
132 return RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR;
133 default:
134 return RESULT_L2CAP_CONN_UNKNOWN;
135 }
136 }
137}