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

Commit 3f9e8073 authored by Jayden Kim's avatar Jayden Kim Committed by Automerger Merge Worker
Browse files

Merge "Update Socket API to get L2CAP channel ID through native stack" into main am: 1256b3fa

parents 9e96fe67 1256b3fa
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -34,5 +34,7 @@ interface IBluetoothSocketManager
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
    void requestMaximumTxDataLength(in BluetoothDevice device);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    boolean checkPermissionForL2capChannelInfo(in AttributionSource attributionSource);
    int getL2capLocalChannelId(in ParcelUuid connectionUuid, in AttributionSource attributionSource);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    int getL2capRemoteChannelId(in ParcelUuid connectionUuid, in AttributionSource attributionSource);
}
+50 −0
Original line number Diff line number Diff line
@@ -47,6 +47,15 @@ struct formatter<bt_discovery_state_t> : enum_formatter<bt_discovery_state_t> {
};
}  // namespace fmt

static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
  std::array<uint8_t, Uuid::kNumBytes128> uu;
  for (int i = 0; i < 8; i++) {
    uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
    uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
  }
  return Uuid::From128BitBE(uu);
}

namespace android {
// Both

@@ -58,6 +67,7 @@ namespace android {
#define BLE_ADDR_RANDOM 0x01

const jint INVALID_FD = -1;
const jint INVALID_CID = -1;

static jmethodID method_oobDataReceivedCallback;
static jmethodID method_stateChangeCallback;
@@ -2138,6 +2148,42 @@ static jboolean pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv* /* env */,
             : JNI_FALSE;
}

static jint getSocketL2capLocalChannelIdNative(JNIEnv* /* env */,
                                               jobject /* obj */,
                                               jlong conn_uuid_lsb,
                                               jlong conn_uuid_msb) {
  log::verbose("");

  if (!sBluetoothSocketInterface) {
    return INVALID_CID;
  }
  uint16_t cid;
  Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
  if (sBluetoothSocketInterface->get_l2cap_local_cid(uuid, &cid) !=
      BT_STATUS_SUCCESS) {
    return INVALID_CID;
  }
  return (jint)cid;
}

static jint getSocketL2capRemoteChannelIdNative(JNIEnv* /* env */,
                                                jobject /* obj */,
                                                jlong conn_uuid_lsb,
                                                jlong conn_uuid_msb) {
  log::verbose("");

  if (!sBluetoothSocketInterface) {
    return INVALID_CID;
  }
  uint16_t cid;
  Uuid uuid = from_java_uuid(conn_uuid_msb, conn_uuid_lsb);
  if (sBluetoothSocketInterface->get_l2cap_remote_cid(uuid, &cid) !=
      BT_STATUS_SUCCESS) {
    return INVALID_CID;
  }
  return (jint)cid;
}

int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
  const JNINativeMethod methods[] = {
      {"initNative", "(ZZI[Ljava/lang/String;ZLjava/lang/String;)Z",
@@ -2200,6 +2246,10 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
       (void*)getRemotePbapPceVersionNative},
      {"pbapPseDynamicVersionUpgradeIsEnabledNative", "()Z",
       (void*)pbapPseDynamicVersionUpgradeIsEnabledNative},
      {"getSocketL2capLocalChannelIdNative", "(JJ)I",
       (void*)getSocketL2capLocalChannelIdNative},
      {"getSocketL2capRemoteChannelIdNative", "(JJ)I",
       (void*)getSocketL2capRemoteChannelIdNative},
  };
  const int result = REGISTER_NATIVE_METHODS(
      env, "com/android/bluetooth/btservice/AdapterNativeInterface", methods);
+19 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.bluetooth.btservice;

import android.bluetooth.OobData;
import android.os.ParcelUuid;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -246,6 +247,18 @@ public class AdapterNativeInterface {
        return isLogRedactionEnabledNative();
    }

    int getSocketL2capLocalChannelId(ParcelUuid connectionUuid) {
        return getSocketL2capLocalChannelIdNative(
                connectionUuid.getUuid().getLeastSignificantBits(),
                connectionUuid.getUuid().getMostSignificantBits());
    }

    int getSocketL2capRemoteChannelId(ParcelUuid connectionUuid) {
        return getSocketL2capRemoteChannelIdNative(
                connectionUuid.getUuid().getLeastSignificantBits(),
                connectionUuid.getUuid().getMostSignificantBits());
    }

    /**********************************************************************************************/
    /*********************************** callbacks from native ************************************/
    /**********************************************************************************************/
@@ -352,4 +365,10 @@ public class AdapterNativeInterface {
    private native boolean pbapPseDynamicVersionUpgradeIsEnabledNative();

    private native boolean isLogRedactionEnabledNative();

    private native int getSocketL2capLocalChannelIdNative(
            long connectionUuidLsb, long connectionUuidMsb);

    private native int getSocketL2capRemoteChannelIdNative(
            long connectionUuidLsb, long connectionUuidMsb);
}
+21 −6
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ class BluetoothSocketManagerBinder extends IBluetoothSocketManager.Stub {

    private static final int INVALID_FD = -1;

    private static final int INVALID_CID = -1;

    private AdapterService mService;

    BluetoothSocketManagerBinder(AdapterService service) {
@@ -105,18 +107,31 @@ class BluetoothSocketManagerBinder extends IBluetoothSocketManager.Stub {
    }

    @Override
    public boolean checkPermissionForL2capChannelInfo(AttributionSource source) {
    public int getL2capLocalChannelId(ParcelUuid connectionUuid, AttributionSource source) {
        AdapterService service = mService;
        if (service == null
                || !Utils.callerIsSystemOrActiveOrManagedUser(
                        service, TAG, "getL2capLocalChannelId")
                || !Utils.checkConnectPermissionForDataDelivery(
                        service, source, "BluetoothSocketManagerBinder getL2capLocalChannelId")) {
            return INVALID_CID;
        }
        Utils.enforceBluetoothPrivilegedPermission(service);
        return service.getNative().getSocketL2capLocalChannelId(connectionUuid);
    }

    @Override
    public int getL2capRemoteChannelId(ParcelUuid connectionUuid, AttributionSource source) {
        AdapterService service = mService;
        if (service == null
                || !Utils.callerIsSystemOrActiveOrManagedUser(
                service, TAG, "checkPermissionForL2capChannelInfo")
                        service, TAG, "getL2capRemoteChannelId")
                || !Utils.checkConnectPermissionForDataDelivery(
                service, source,
                "BluetoothSocketManagerBinder checkPermissionForL2capChannelInfo")) {
            return false;
                        service, source, "BluetoothSocketManagerBinder getL2capRemoteChannelId")) {
            return INVALID_CID;
        }
        Utils.enforceBluetoothPrivilegedPermission(service);
        return true;
        return service.getNative().getSocketL2capRemoteChannelId(connectionUuid);
    }

    private void enforceActiveUser() {
+33 −31
Original line number Diff line number Diff line
@@ -156,13 +156,12 @@ public final class BluetoothSocket implements Closeable {
    @UnsupportedAppUsage private int mPort; /* RFCOMM channel or L2CAP psm */
    private String mServiceName;

    private static final int SOCK_SIGNAL_SIZE = 24;
    private static final int SOCK_SIGNAL_SIZE = 36;

    private ByteBuffer mL2capBuffer = null;
    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 mL2capLocalCid = 0;
    private int mL2capRemoteCid = 0;
    private ParcelUuid mConnectionUuid;

    private long mSocketCreationTimeNanos = 0;
    private long mSocketCreationLatencyNanos = 0;
@@ -299,8 +298,7 @@ public final class BluetoothSocket implements Closeable {
        mOutputStream = new BluetoothOutputStream(this);
        mMaxRxPacketSize = s.mMaxRxPacketSize;
        mMaxTxPacketSize = s.mMaxTxPacketSize;
        mL2capLocalCid = s.mL2capLocalCid;
        mL2capRemoteCid = s.mL2capRemoteCid;
        mConnectionUuid = s.mConnectionUuid;

        mServiceName = s.mServiceName;
        mExcludeSdp = s.mExcludeSdp;
@@ -743,6 +741,7 @@ public final class BluetoothSocket implements Closeable {
                    mPfd.close();
                    mPfd = null;
                }
                mConnectionUuid = null;
            }
        }
    }
@@ -856,6 +855,13 @@ public final class BluetoothSocket implements Closeable {
                android.Manifest.permission.BLUETOOTH_PRIVILEGED,
            })
    public int getL2capLocalChannelId() throws IOException {
        if (mType != TYPE_L2CAP_LE) {
            throw new BluetoothSocketException(BluetoothSocketException.L2CAP_UNKNOWN);
        }
        if (mSocketState != SocketState.CONNECTED || mConnectionUuid == null) {
            throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED);
        }
        int cid;
        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
        if (bluetoothProxy == null) {
            throw new BluetoothSocketException(BluetoothSocketException.BLUETOOTH_OFF_FAILURE);
@@ -865,22 +871,17 @@ public final class BluetoothSocket implements Closeable {
            if (socketManager == null) {
                throw new BluetoothSocketException(BluetoothSocketException.SOCKET_MANAGER_FAILURE);
            }
            if (!socketManager.checkPermissionForL2capChannelInfo(
                    AttributionSource.myAttributionSource())) {
                throw new SecurityException(
                    "Need BLUETOOTH_CONNECT and BLUETOOTH_PRIVILEGED Permission");
            }
            cid =
                    socketManager.getL2capLocalChannelId(
                            mConnectionUuid, AttributionSource.myAttributionSource());
        } catch (RemoteException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            throw new IOException("unable to send RPC: " + e.getMessage());
        }
        if (mType != TYPE_L2CAP_LE) {
            throw new BluetoothSocketException(BluetoothSocketException.L2CAP_UNKNOWN);
        }
        if (mSocketState != SocketState.CONNECTED) {
        if (cid == -1) {
            throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED);
        }
        return mL2capLocalCid;
        return cid;
    }

    /**
@@ -898,6 +899,13 @@ public final class BluetoothSocket implements Closeable {
                android.Manifest.permission.BLUETOOTH_PRIVILEGED,
            })
    public int getL2capRemoteChannelId() throws IOException {
        if (mType != TYPE_L2CAP_LE) {
            throw new BluetoothSocketException(BluetoothSocketException.L2CAP_UNKNOWN);
        }
        if (mSocketState != SocketState.CONNECTED || mConnectionUuid == null) {
            throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED);
        }
        int cid;
        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
        if (bluetoothProxy == null) {
            throw new BluetoothSocketException(BluetoothSocketException.BLUETOOTH_OFF_FAILURE);
@@ -907,22 +915,17 @@ public final class BluetoothSocket implements Closeable {
            if (socketManager == null) {
                throw new BluetoothSocketException(BluetoothSocketException.SOCKET_MANAGER_FAILURE);
            }
            if (!socketManager.checkPermissionForL2capChannelInfo(
                    AttributionSource.myAttributionSource())) {
                throw new SecurityException(
                    "Need BLUETOOTH_CONNECT and BLUETOOTH_PRIVILEGED Permission");
            }
            cid =
                    socketManager.getL2capRemoteChannelId(
                            mConnectionUuid, AttributionSource.myAttributionSource());
        } catch (RemoteException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            throw new IOException("unable to send RPC: " + e.getMessage());
        }
        if (mType != TYPE_L2CAP_LE) {
            throw new BluetoothSocketException(BluetoothSocketException.L2CAP_UNKNOWN);
        }
        if (mSocketState != SocketState.CONNECTED) {
        if (cid == -1) {
            throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED);
        }
        return mL2capRemoteCid;
        return cid;
    }

    /** @hide */
@@ -961,8 +964,9 @@ public final class BluetoothSocket implements Closeable {
        int status = bb.getInt();
        mMaxTxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
        mMaxRxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
        mL2capLocalCid = (bb.getShort() & 0xffff); // Convert to unsigned value
        mL2capRemoteCid = (bb.getShort() & 0xffff); // Convert to unsigned value
        long uuidLsb = bb.getLong();
        long uuidMsb = bb.getLong();
        mConnectionUuid = new ParcelUuid(new UUID(uuidMsb, uuidLsb));
        String RemoteAddr = convertAddr(addr);
        if (VDBG) {
            Log.d(
@@ -979,10 +983,8 @@ public final class BluetoothSocket implements Closeable {
                            + mMaxRxPacketSize
                            + " MaxTxPktSize: "
                            + mMaxTxPacketSize
                            + " mL2capLocalCid: "
                            + String.format("0x%04x", mL2capLocalCid)
                            + " mL2capRemoteCid: "
                            + String.format("0x%04x", mL2capRemoteCid));
                            + " mConnectionUuid: "
                            + mConnectionUuid.toString());
        }
        if (status != 0) {
            throw new IOException("Connection failure, status: " + status);
Loading