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

Commit faaddc63 authored by Jaikumar Ganesh's avatar Jaikumar Ganesh Committed by Android (Google) Code Review
Browse files

Merge "Add direct calls to Bluez to add SDP records."

parents a60f00ff 84690c88
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.os.ParcelUuid;

import java.util.Arrays;
import java.util.HashSet;
import java.util.UUID;

/**
* Static helper methods and constants to decode the ParcelUuid of remote devices.
@@ -41,8 +42,12 @@ public final class BluetoothUuid {
            ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid HSP =
            ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid HSP_AG =
            ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid Handsfree =
            ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid Handsfree_AG =
            ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid AvrcpController =
            ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid AvrcpTarget =
@@ -57,6 +62,8 @@ public final class BluetoothUuid {
            ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid BNEP =
            ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
    public static final ParcelUuid PBAP_PSE =
            ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");

    public static final ParcelUuid[] RESERVED_UUIDS = {
        AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -173,4 +180,16 @@ public final class BluetoothUuid {
        return true;
    }

    /**
     * Extract the Service Identifier or the actual uuid from the Parcel Uuid.
     * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
     * this function will return 110B
     * @param parcelUuid
     * @return the service identifier.
     */
    public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
        UUID uuid = parcelUuid.getUuid();
        long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
        return (int)value;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -293,7 +293,7 @@ class BluetoothEventLoop {
                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            }
            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
        } else if (name.equals("Devices")) {
        } else if (name.equals("Devices") || name.equals("UUIDs")) {
            String value = null;
            int len = Integer.valueOf(propValues[1]);
            if (len > 0) {
+39 −53
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ public class BluetoothService extends IBluetooth.Stub {
    private boolean mRestart = false;  // need to call enable() after disable()
    private boolean mIsDiscovering;
    private boolean mTetheringOn;
    private int[] mAdapterSdpUuids;
    private int[] mAdapterSdpHandles;

    private BluetoothAdapter mAdapter;  // constant after init()
    private final BondState mBondState = new BondState();  // local cache of bondings
@@ -112,11 +114,10 @@ public class BluetoothService extends IBluetooth.Stub {
    private static final String SHARED_PREFERENCE_DOCK_ADDRESS = "dock_bluetooth_address";
    private static final String SHARED_PREFERENCES_NAME = "bluetooth_service_settings";

    private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
    private static final int MESSAGE_FINISH_DISABLE = 2;
    private static final int MESSAGE_UUID_INTENT = 3;
    private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 4;
    private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 5;
    private static final int MESSAGE_FINISH_DISABLE = 1;
    private static final int MESSAGE_UUID_INTENT = 2;
    private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 3;
    private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 4;

    // The time (in millisecs) to delay the pairing attempt after the first
    // auto pairing attempt fails. We use an exponential delay with
@@ -378,8 +379,10 @@ public class BluetoothService extends IBluetooth.Stub {
        if (mEnableThread != null && mEnableThread.isAlive()) {
            return false;
        }

        setBluetoothState(BluetoothAdapter.STATE_TURNING_OFF);
        mHandler.removeMessages(MESSAGE_REGISTER_SDP_RECORDS);

        if (mAdapterSdpHandles != null) removeReservedServiceRecordsNative(mAdapterSdpHandles);
        setBluetoothTetheringNative(false, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);

        // Allow 3 seconds for profiles to gracefully disconnect
@@ -516,43 +519,6 @@ public class BluetoothService extends IBluetooth.Stub {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_REGISTER_SDP_RECORDS:
                if (!isEnabledInternal()) {
                    return;
                }
                // SystemService.start() forks sdptool to register service
                // records. It can fail to register some records if it is
                // forked multiple times in a row, probably because there is
                // some race in sdptool or bluez when operated in parallel.
                // As a workaround, delay 500ms between each fork of sdptool.
                // TODO: Don't fork sdptool in order to register service
                // records, use a DBUS call instead.
                switch (msg.arg1) {
                case 1:
                    Log.d(TAG, "Registering hfag record");
                    SystemService.start("hfag");
                    mHandler.sendMessageDelayed(
                            mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 2, -1), 500);
                    break;
                case 2:
                    Log.d(TAG, "Registering hsag record");
                    SystemService.start("hsag");
                    mHandler.sendMessageDelayed(
                            mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 3, -1), 500);
                    break;
                case 3:
                    Log.d(TAG, "Registering pbap record");
                    SystemService.start("pbap");
                    mHandler.sendMessageDelayed(
                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 500);

                    break;
                case 4:
                    Log.d(TAG, "Registering opush record");
                    SystemService.start("opush");
                    break;
                }
                break;
            case MESSAGE_FINISH_DISABLE:
                finishDisable(msg.arg1 != 0);
                break;
@@ -625,23 +591,40 @@ public class BluetoothService extends IBluetooth.Stub {
                if (mSaveSetting) {
                    persistBluetoothOnSetting(true);
                }
                mIsDiscovering = false;
                mBondState.readAutoPairingData();
                mBondState.loadBondState();
                initProfileState();

                //Register SDP records.
                if (mContext.getResources().
                        getBoolean(com.android.internal.R.bool.config_voice_capable)) {
                    mHandler.sendMessageDelayed(
                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
                     int[] uuids = {
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                            BluetoothUuid.Handsfree_AG),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                            BluetoothUuid.HSP_AG),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.PBAP_PSE),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.ObexObjectPush),
                        };
                     mAdapterSdpUuids = uuids;

                } else {
                    // Register only OPP.
                    mHandler.sendMessageDelayed(
                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 3000);
                     int[] uuids = {
                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.HSP_AG),
                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.PBAP_PSE),
                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.ObexObjectPush),
                         };
                      mAdapterSdpUuids = uuids;
                }

                mAdapterSdpHandles = addReservedServiceRecordsNative(mAdapterSdpUuids);
                setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);

                mIsDiscovering = false;
                mBondState.readAutoPairingData();
                mBondState.loadBondState();
                initProfileState();

                // Log bluetooth on to battery stats.
                long ident = Binder.clearCallingIdentity();
@@ -2908,4 +2891,7 @@ public class BluetoothService extends IBluetooth.Stub {
    private native boolean setBluetoothTetheringNative(boolean value, String nap, String bridge);
    private native boolean connectPanDeviceNative(String path, String srcRole, String dstRole);
    private native boolean disconnectPanDeviceNative(String path);

    private native int[] addReservedServiceRecordsNative(int[] uuuids);
    private native boolean removeReservedServiceRecordsNative(int[] handles);
}
+75 −0
Original line number Diff line number Diff line
@@ -928,6 +928,79 @@ static jboolean discoverServicesNative(JNIEnv *env, jobject object,
    return JNI_FALSE;
}

static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
#ifdef HAVE_BLUETOOTH
    jint *handles;
    jintArray handleArray = NULL;
    int len;

    DBusError err;
    dbus_error_init(&err);

    if (dbus_message_get_args(reply, &err,
                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
                              DBUS_TYPE_INVALID)) {
        handleArray = env->NewIntArray(len);
        if (handleArray) {
            env->SetIntArrayRegion(handleArray, 0, len, handles);
        } else {
            LOGE("Null array in extract_handles");
        }
    } else {
        LOG_AND_FREE_DBUS_ERROR(&err);
    }
    return handleArray;
#endif
    return NULL;
}

static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
                                                jintArray uuids) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    DBusMessage *reply = NULL;

    native_data_t *nat = get_native_data(env, object);

    jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
    if (!svc_classes) return NULL;

    int len = env->GetArrayLength(uuids);
    reply = dbus_func_args(env, nat->conn,
                            get_adapter_path(env, object),
                            DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
                            &svc_classes, len, DBUS_TYPE_INVALID);
    env->ReleaseIntArrayElements(uuids, svc_classes, 0);
    return reply ? extract_handles(env, reply) : NULL;

#endif
    return NULL;
}

static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
                                                   jintArray handles) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = get_native_data(env, object);
    jint *values = env->GetIntArrayElements(handles, NULL);
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    if (values == NULL) return JNI_FALSE;

    jsize len = env->GetArrayLength(handles);

    reply = dbus_func_args(env, nat->conn,
                            get_adapter_path(env, object),
                            DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
                            &values, len, DBUS_TYPE_INVALID);
    env->ReleaseIntArrayElements(handles, values, NULL);
    return reply ? JNI_TRUE : JNI_FALSE;
#endif
    return JNI_FALSE;
}

static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
        jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
    LOGV(__FUNCTION__);
@@ -1193,6 +1266,8 @@ static JNINativeMethod sMethods[] = {
    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
    {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
    {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
    {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
    {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
    {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
    // HID functions
    {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},