/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_bluetooth_bluedroid_bluetoothhalhelpers_h__ #define mozilla_dom_bluetooth_bluedroid_bluetoothhalhelpers_h__ #include #include #include #include #if ANDROID_VERSION >= 18 #include #endif #if ANDROID_VERSION >= 19 #include #endif #include "BluetoothCommon.h" #include "mozilla/ArrayUtils.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/dom/TypedArray.h" #include "nsThreadUtils.h" BEGIN_BLUETOOTH_NAMESPACE // // Conversion // inline nsresult Convert(bt_status_t aIn, BluetoothStatus& aOut) { static const BluetoothStatus sStatus[] = { CONVERT(BT_STATUS_SUCCESS, STATUS_SUCCESS), CONVERT(BT_STATUS_FAIL, STATUS_FAIL), CONVERT(BT_STATUS_NOT_READY, STATUS_NOT_READY), CONVERT(BT_STATUS_NOMEM, STATUS_NOMEM), CONVERT(BT_STATUS_BUSY, STATUS_BUSY), CONVERT(BT_STATUS_DONE, STATUS_DONE), CONVERT(BT_STATUS_UNSUPPORTED, STATUS_UNSUPPORTED), CONVERT(BT_STATUS_PARM_INVALID, STATUS_PARM_INVALID), CONVERT(BT_STATUS_UNHANDLED, STATUS_UNHANDLED), CONVERT(BT_STATUS_AUTH_FAILURE, STATUS_AUTH_FAILURE), CONVERT(BT_STATUS_RMT_DEV_DOWN, STATUS_RMT_DEV_DOWN) }; if (aIn >= MOZ_ARRAY_LENGTH(sStatus)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sStatus[aIn]; return NS_OK; } inline nsresult Convert(int aIn, BluetoothStatus& aOut) { return Convert(static_cast(aIn), aOut); } nsresult Convert(const nsAString& aIn, bt_property_type_t& aOut); inline nsresult Convert(bool aIn, bt_scan_mode_t& aOut) { static const bt_scan_mode_t sScanMode[] = { CONVERT(false, BT_SCAN_MODE_CONNECTABLE), CONVERT(true, BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sScanMode)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sScanMode[aIn]; return NS_OK; } inline nsresult Convert(bt_scan_mode_t aIn, BluetoothScanMode& aOut) { static const BluetoothScanMode sScanMode[] = { CONVERT(BT_SCAN_MODE_NONE, SCAN_MODE_NONE), CONVERT(BT_SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE), CONVERT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sScanMode)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sScanMode[aIn]; return NS_OK; } struct ConvertNamedValue { ConvertNamedValue(const BluetoothNamedValue& aNamedValue) : mNamedValue(aNamedValue) { } const BluetoothNamedValue& mNamedValue; // temporary fields nsCString mStringValue; bt_scan_mode_t mScanMode; }; nsresult Convert(ConvertNamedValue& aIn, bt_property_t& aOut); nsresult Convert(const nsAString& aIn, bt_bdaddr_t& aOut); nsresult Convert(BluetoothSspVariant aIn, bt_ssp_variant_t& aOut); inline nsresult Convert(const bt_ssp_variant_t& aIn, BluetoothSspVariant& aOut) { static const BluetoothSspVariant sSspVariant[] = { CONVERT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, SSP_VARIANT_PASSKEY_CONFIRMATION), CONVERT(BT_SSP_VARIANT_PASSKEY_ENTRY, SSP_VARIANT_PASSKEY_ENTRY), CONVERT(BT_SSP_VARIANT_CONSENT, SSP_VARIANT_CONSENT), CONVERT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION, SSP_VARIANT_PASSKEY_NOTIFICATION) }; if (aIn >= MOZ_ARRAY_LENGTH(sSspVariant)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sSspVariant[aIn]; return NS_OK; } inline nsresult Convert(const bool& aIn, uint8_t& aOut) { // casting converts true/false to either 1 or 0 aOut = static_cast(aIn); return NS_OK; } nsresult Convert(const uint8_t aIn[16], bt_uuid_t& aOut); nsresult Convert(const bt_uuid_t& aIn, BluetoothUuid& aOut); nsresult Convert(const BluetoothUuid& aIn, bt_uuid_t& aOut); nsresult Convert(const nsAString& aIn, bt_pin_code_t& aOut); nsresult Convert(const bt_bdaddr_t& aIn, nsAString& aOut); inline nsresult Convert(const bt_bdaddr_t* aIn, nsAString& aOut) { if (!aIn) { aOut.AssignLiteral(BLUETOOTH_ADDRESS_NONE); return NS_OK; } return Convert(*aIn, aOut); } inline nsresult Convert(bt_state_t aIn, bool& aOut) { static const bool sState[] = { CONVERT(BT_STATE_OFF, false), CONVERT(BT_STATE_ON, true) }; if (aIn >= MOZ_ARRAY_LENGTH(sState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sState[aIn]; return NS_OK; } inline nsresult Convert(bt_property_type_t aIn, BluetoothPropertyType& aOut) { static const BluetoothPropertyType sPropertyType[] = { CONVERT(0, static_cast(0)), // invalid, required by gcc CONVERT(BT_PROPERTY_BDNAME, PROPERTY_BDNAME), CONVERT(BT_PROPERTY_BDADDR, PROPERTY_BDADDR), CONVERT(BT_PROPERTY_UUIDS, PROPERTY_UUIDS), CONVERT(BT_PROPERTY_CLASS_OF_DEVICE, PROPERTY_CLASS_OF_DEVICE), CONVERT(BT_PROPERTY_TYPE_OF_DEVICE, PROPERTY_TYPE_OF_DEVICE), CONVERT(BT_PROPERTY_SERVICE_RECORD, PROPERTY_SERVICE_RECORD), CONVERT(BT_PROPERTY_ADAPTER_SCAN_MODE, PROPERTY_ADAPTER_SCAN_MODE), CONVERT(BT_PROPERTY_ADAPTER_BONDED_DEVICES, PROPERTY_ADAPTER_BONDED_DEVICES), CONVERT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, PROPERTY_ADAPTER_DISCOVERY_TIMEOUT), CONVERT(BT_PROPERTY_REMOTE_FRIENDLY_NAME, PROPERTY_REMOTE_FRIENDLY_NAME), CONVERT(BT_PROPERTY_REMOTE_RSSI, PROPERTY_REMOTE_RSSI) #if ANDROID_VERSION >= 18 , CONVERT(BT_PROPERTY_REMOTE_VERSION_INFO,PROPERTY_REMOTE_VERSION_INFO) #endif }; if (aIn == BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP) { /* This case is handled separately to not populate * |sPropertyType| with empty entries. */ aOut = PROPERTY_REMOTE_DEVICE_TIMESTAMP; return NS_OK; } if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sPropertyType)) { /* Bug 1065999: working around unknown properties */ aOut = PROPERTY_UNKNOWN; return NS_OK; } aOut = sPropertyType[aIn]; return NS_OK; } inline nsresult Convert(bt_discovery_state_t aIn, bool& aOut) { static const bool sDiscoveryState[] = { CONVERT(BT_DISCOVERY_STOPPED, false), CONVERT(BT_DISCOVERY_STARTED, true) }; if (aIn >= MOZ_ARRAY_LENGTH(sDiscoveryState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sDiscoveryState[aIn]; return NS_OK; } inline nsresult Convert(const char* aIn, nsACString& aOut) { aOut.Assign(aIn); return NS_OK; } inline nsresult Convert(const char* aIn, nsAString& aOut) { aOut = NS_ConvertUTF8toUTF16(aIn); return NS_OK; } inline nsresult Convert(const bt_bdname_t& aIn, nsAString& aOut) { return Convert(reinterpret_cast(aIn.name), aOut); } inline nsresult Convert(const bt_bdname_t* aIn, nsAString& aOut) { if (!aIn) { aOut.Truncate(); return NS_OK; } return Convert(*aIn, aOut); } inline nsresult Convert(bt_bond_state_t aIn, BluetoothBondState& aOut) { static const BluetoothBondState sBondState[] = { CONVERT(BT_BOND_STATE_NONE, BOND_STATE_NONE), CONVERT(BT_BOND_STATE_BONDING, BOND_STATE_BONDING), CONVERT(BT_BOND_STATE_BONDED, BOND_STATE_BONDED) }; if (aIn >= MOZ_ARRAY_LENGTH(sBondState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sBondState[aIn]; return NS_OK; } inline nsresult Convert(bt_acl_state_t aIn, bool& aOut) { static const bool sAclState[] = { CONVERT(BT_ACL_STATE_CONNECTED, true), CONVERT(BT_ACL_STATE_DISCONNECTED, false) }; if (aIn >= MOZ_ARRAY_LENGTH(sAclState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sAclState[aIn]; return NS_OK; } inline nsresult Convert(bt_device_type_t aIn, BluetoothTypeOfDevice& aOut) { static const BluetoothTypeOfDevice sTypeOfDevice[] = { CONVERT(0, static_cast(0)), // invalid, required by gcc CONVERT(BT_DEVICE_DEVTYPE_BREDR, TYPE_OF_DEVICE_BREDR), CONVERT(BT_DEVICE_DEVTYPE_BLE, TYPE_OF_DEVICE_BLE), CONVERT(BT_DEVICE_DEVTYPE_DUAL, TYPE_OF_DEVICE_DUAL) }; if (aIn >= MOZ_ARRAY_LENGTH(sTypeOfDevice)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sTypeOfDevice[aIn]; return NS_OK; } nsresult Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut); inline nsresult Convert(BluetoothSocketType aIn, btsock_type_t& aOut) { // FIXME: Array member [0] is currently invalid, but required // by gcc. Start values in |BluetoothSocketType| at index // 0 to fix this problem. static const btsock_type_t sSocketType[] = { CONVERT(0, static_cast(0)), // invalid, [0] required by gcc CONVERT(BluetoothSocketType::RFCOMM, BTSOCK_RFCOMM), CONVERT(BluetoothSocketType::SCO, BTSOCK_SCO), CONVERT(BluetoothSocketType::L2CAP, BTSOCK_L2CAP), // EL2CAP is not supported by Bluedroid }; if (aIn == BluetoothSocketType::EL2CAP || aIn >= MOZ_ARRAY_LENGTH(sSocketType) || !sSocketType[aIn]) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sSocketType[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeAtResponse aIn, bthf_at_response_t& aOut) { static const bthf_at_response_t sAtResponse[] = { CONVERT(HFP_AT_RESPONSE_ERROR, BTHF_AT_RESPONSE_ERROR), CONVERT(HFP_AT_RESPONSE_OK, BTHF_AT_RESPONSE_OK) }; if (aIn >= MOZ_ARRAY_LENGTH(sAtResponse)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sAtResponse[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeCallAddressType aIn, bthf_call_addrtype_t& aOut) { static const bthf_call_addrtype_t sCallAddressType[] = { CONVERT(HFP_CALL_ADDRESS_TYPE_UNKNOWN, BTHF_CALL_ADDRTYPE_UNKNOWN), CONVERT(HFP_CALL_ADDRESS_TYPE_INTERNATIONAL, BTHF_CALL_ADDRTYPE_INTERNATIONAL) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallAddressType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallAddressType[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeCallDirection aIn, bthf_call_direction_t& aOut) { static const bthf_call_direction_t sCallDirection[] = { CONVERT(HFP_CALL_DIRECTION_OUTGOING, BTHF_CALL_DIRECTION_OUTGOING), CONVERT(HFP_CALL_DIRECTION_INCOMING, BTHF_CALL_DIRECTION_INCOMING) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallDirection)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallDirection[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeCallMode aIn, bthf_call_mode_t& aOut) { static const bthf_call_mode_t sCallMode[] = { CONVERT(HFP_CALL_MODE_VOICE, BTHF_CALL_TYPE_VOICE), CONVERT(HFP_CALL_MODE_DATA, BTHF_CALL_TYPE_DATA), CONVERT(HFP_CALL_MODE_FAX, BTHF_CALL_TYPE_FAX) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallMode)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallMode[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeCallMptyType aIn, bthf_call_mpty_type_t& aOut) { static const bthf_call_mpty_type_t sCallMptyType[] = { CONVERT(HFP_CALL_MPTY_TYPE_SINGLE, BTHF_CALL_MPTY_TYPE_SINGLE), CONVERT(HFP_CALL_MPTY_TYPE_MULTI, BTHF_CALL_MPTY_TYPE_MULTI) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallMptyType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallMptyType[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeCallState aIn, bthf_call_state_t& aOut) { static const bthf_call_state_t sCallState[] = { CONVERT(HFP_CALL_STATE_ACTIVE, BTHF_CALL_STATE_ACTIVE), CONVERT(HFP_CALL_STATE_HELD, BTHF_CALL_STATE_HELD), CONVERT(HFP_CALL_STATE_DIALING, BTHF_CALL_STATE_DIALING), CONVERT(HFP_CALL_STATE_ALERTING, BTHF_CALL_STATE_ALERTING), CONVERT(HFP_CALL_STATE_INCOMING, BTHF_CALL_STATE_INCOMING), CONVERT(HFP_CALL_STATE_WAITING, BTHF_CALL_STATE_WAITING), CONVERT(HFP_CALL_STATE_IDLE, BTHF_CALL_STATE_IDLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallState[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeNetworkState aIn, bthf_network_state_t& aOut) { static const bthf_network_state_t sNetworkState[] = { CONVERT(HFP_NETWORK_STATE_NOT_AVAILABLE, BTHF_NETWORK_STATE_NOT_AVAILABLE), CONVERT(HFP_NETWORK_STATE_AVAILABLE, BTHF_NETWORK_STATE_AVAILABLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sNetworkState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sNetworkState[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeServiceType aIn, bthf_service_type_t& aOut) { static const bthf_service_type_t sServiceType[] = { CONVERT(HFP_SERVICE_TYPE_HOME, BTHF_SERVICE_TYPE_HOME), CONVERT(HFP_SERVICE_TYPE_ROAMING, BTHF_SERVICE_TYPE_ROAMING) }; if (aIn >= MOZ_ARRAY_LENGTH(sServiceType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sServiceType[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeVolumeType aIn, bthf_volume_type_t& aOut) { static const bthf_volume_type_t sVolumeType[] = { CONVERT(HFP_VOLUME_TYPE_SPEAKER, BTHF_VOLUME_TYPE_SPK), CONVERT(HFP_VOLUME_TYPE_MICROPHONE, BTHF_VOLUME_TYPE_MIC) }; if (aIn >= MOZ_ARRAY_LENGTH(sVolumeType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sVolumeType[aIn]; return NS_OK; } inline nsresult Convert(bthf_audio_state_t aIn, BluetoothHandsfreeAudioState& aOut) { static const BluetoothHandsfreeAudioState sAudioState[] = { CONVERT(BTHF_AUDIO_STATE_DISCONNECTED, HFP_AUDIO_STATE_DISCONNECTED), CONVERT(BTHF_AUDIO_STATE_CONNECTING, HFP_AUDIO_STATE_CONNECTING), CONVERT(BTHF_AUDIO_STATE_CONNECTED, HFP_AUDIO_STATE_CONNECTED), CONVERT(BTHF_AUDIO_STATE_DISCONNECTING, HFP_AUDIO_STATE_DISCONNECTING) }; if (aIn >= MOZ_ARRAY_LENGTH(sAudioState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sAudioState[aIn]; return NS_OK; } inline nsresult Convert(bthf_chld_type_t aIn, BluetoothHandsfreeCallHoldType& aOut) { static const BluetoothHandsfreeCallHoldType sCallHoldType[] = { CONVERT(BTHF_CHLD_TYPE_RELEASEHELD, HFP_CALL_HOLD_RELEASEHELD), CONVERT(BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD, HFP_CALL_HOLD_RELEASEACTIVE_ACCEPTHELD), CONVERT(BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD, HFP_CALL_HOLD_HOLDACTIVE_ACCEPTHELD), CONVERT(BTHF_CHLD_TYPE_ADDHELDTOCONF, HFP_CALL_HOLD_ADDHELDTOCONF) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallHoldType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sCallHoldType[aIn]; return NS_OK; } inline nsresult Convert(bthf_connection_state_t aIn, BluetoothHandsfreeConnectionState& aOut) { static const BluetoothHandsfreeConnectionState sConnectionState[] = { CONVERT(BTHF_CONNECTION_STATE_DISCONNECTED, HFP_CONNECTION_STATE_DISCONNECTED), CONVERT(BTHF_CONNECTION_STATE_CONNECTING, HFP_CONNECTION_STATE_CONNECTING), CONVERT(BTHF_CONNECTION_STATE_CONNECTED, HFP_CONNECTION_STATE_CONNECTED), CONVERT(BTHF_CONNECTION_STATE_SLC_CONNECTED, HFP_CONNECTION_STATE_SLC_CONNECTED), CONVERT(BTHF_CONNECTION_STATE_DISCONNECTING, HFP_CONNECTION_STATE_DISCONNECTING) }; if (aIn >= MOZ_ARRAY_LENGTH(sConnectionState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sConnectionState[aIn]; return NS_OK; } inline nsresult Convert(bthf_nrec_t aIn, BluetoothHandsfreeNRECState& aOut) { static const BluetoothHandsfreeNRECState sNRECState[] = { CONVERT(BTHF_NREC_STOP, HFP_NREC_STOPPED), CONVERT(BTHF_NREC_START, HFP_NREC_STARTED) }; if (aIn >= MOZ_ARRAY_LENGTH(sNRECState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sNRECState[aIn]; return NS_OK; } inline nsresult Convert(bthf_vr_state_t aIn, BluetoothHandsfreeVoiceRecognitionState& aOut) { static const BluetoothHandsfreeVoiceRecognitionState sVoiceRecognitionState[] = { CONVERT(BTHF_VR_STATE_STOPPED, HFP_VOICE_RECOGNITION_STOPPED), CONVERT(BTHF_VR_STATE_STARTED, HFP_VOICE_RECOGNITION_STARTED) }; if (aIn >= MOZ_ARRAY_LENGTH(sVoiceRecognitionState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sVoiceRecognitionState[aIn]; return NS_OK; } inline nsresult Convert(bthf_volume_type_t aIn, BluetoothHandsfreeVolumeType& aOut) { static const BluetoothHandsfreeVolumeType sVolumeType[] = { CONVERT(BTHF_VOLUME_TYPE_SPK, HFP_VOLUME_TYPE_SPEAKER), CONVERT(BTHF_VOLUME_TYPE_MIC, HFP_VOLUME_TYPE_MICROPHONE) }; if (aIn >= MOZ_ARRAY_LENGTH(sVolumeType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sVolumeType[aIn]; return NS_OK; } inline nsresult Convert(btav_connection_state_t aIn, BluetoothA2dpConnectionState& aOut) { static const BluetoothA2dpConnectionState sConnectionState[] = { CONVERT(BTAV_CONNECTION_STATE_DISCONNECTED, A2DP_CONNECTION_STATE_DISCONNECTED), CONVERT(BTAV_CONNECTION_STATE_CONNECTING, A2DP_CONNECTION_STATE_CONNECTING), CONVERT(BTAV_CONNECTION_STATE_CONNECTED, A2DP_CONNECTION_STATE_CONNECTED), CONVERT(BTAV_CONNECTION_STATE_DISCONNECTING, A2DP_CONNECTION_STATE_DISCONNECTING), }; if (aIn >= MOZ_ARRAY_LENGTH(sConnectionState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sConnectionState[aIn]; return NS_OK; } inline nsresult Convert(btav_audio_state_t aIn, BluetoothA2dpAudioState& aOut) { static const BluetoothA2dpAudioState sAudioState[] = { CONVERT(BTAV_AUDIO_STATE_REMOTE_SUSPEND, A2DP_AUDIO_STATE_REMOTE_SUSPEND), CONVERT(BTAV_AUDIO_STATE_STOPPED, A2DP_AUDIO_STATE_STOPPED), CONVERT(BTAV_AUDIO_STATE_STARTED, A2DP_AUDIO_STATE_STARTED), }; if (aIn >= MOZ_ARRAY_LENGTH(sAudioState)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sAudioState[aIn]; return NS_OK; } #if ANDROID_VERSION >= 18 inline nsresult Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut) { aOut.mVerMajor = aIn.version; aOut.mVerMinor = aIn.sub_ver; aOut.mManufacturer = aIn.manufacturer; return NS_OK; } inline nsresult Convert(ControlPlayStatus aIn, btrc_play_status_t& aOut) { static const btrc_play_status_t sPlayStatus[] = { CONVERT(PLAYSTATUS_STOPPED, BTRC_PLAYSTATE_STOPPED), CONVERT(PLAYSTATUS_PLAYING, BTRC_PLAYSTATE_PLAYING), CONVERT(PLAYSTATUS_PAUSED, BTRC_PLAYSTATE_PAUSED), CONVERT(PLAYSTATUS_FWD_SEEK, BTRC_PLAYSTATE_FWD_SEEK), CONVERT(PLAYSTATUS_REV_SEEK, BTRC_PLAYSTATE_REV_SEEK) }; if (aIn >= MOZ_ARRAY_LENGTH(sPlayStatus)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sPlayStatus[aIn]; return NS_OK; } inline nsresult Convert(enum BluetoothAvrcpPlayerAttribute aIn, btrc_player_attr_t& aOut) { static const btrc_player_attr_t sPlayerAttr[] = { CONVERT(AVRCP_PLAYER_ATTRIBUTE_EQUALIZER, BTRC_PLAYER_ATTR_EQUALIZER), CONVERT(AVRCP_PLAYER_ATTRIBUTE_REPEAT, BTRC_PLAYER_ATTR_REPEAT), CONVERT(AVRCP_PLAYER_ATTRIBUTE_SHUFFLE, BTRC_PLAYER_ATTR_SHUFFLE), CONVERT(AVRCP_PLAYER_ATTRIBUTE_SCAN, BTRC_PLAYER_ATTR_SCAN) }; if (aIn >= MOZ_ARRAY_LENGTH(sPlayerAttr)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sPlayerAttr[aIn]; return NS_OK; } inline nsresult Convert(btrc_player_attr_t aIn, enum BluetoothAvrcpPlayerAttribute& aOut) { static const BluetoothAvrcpPlayerAttribute sPlayerAttr[] = { CONVERT(0, static_cast(0)), // invalid, [0] required by gcc CONVERT(BTRC_PLAYER_ATTR_EQUALIZER, AVRCP_PLAYER_ATTRIBUTE_EQUALIZER), CONVERT(BTRC_PLAYER_ATTR_REPEAT, AVRCP_PLAYER_ATTRIBUTE_REPEAT), CONVERT(BTRC_PLAYER_ATTR_SHUFFLE, AVRCP_PLAYER_ATTRIBUTE_SHUFFLE), CONVERT(BTRC_PLAYER_ATTR_SCAN, AVRCP_PLAYER_ATTRIBUTE_SCAN) }; if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sPlayerAttr)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sPlayerAttr[aIn]; return NS_OK; } inline nsresult Convert(enum BluetoothAvrcpStatus aIn, btrc_status_t& aOut) { static const btrc_status_t sStatus[] = { CONVERT(AVRCP_STATUS_BAD_COMMAND, BTRC_STS_BAD_CMD), CONVERT(AVRCP_STATUS_BAD_PARAMETER, BTRC_STS_BAD_PARAM), CONVERT(AVRCP_STATUS_NOT_FOUND, BTRC_STS_NOT_FOUND), CONVERT(AVRCP_STATUS_INTERNAL_ERROR, BTRC_STS_INTERNAL_ERR), CONVERT(AVRCP_STATUS_SUCCESS, BTRC_STS_NO_ERROR) }; if (aIn >= MOZ_ARRAY_LENGTH(sStatus)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sStatus[aIn]; return NS_OK; } inline nsresult Convert(enum BluetoothAvrcpEvent aIn, btrc_event_id_t& aOut) { static const btrc_event_id_t sEventId[] = { CONVERT(AVRCP_EVENT_PLAY_STATUS_CHANGED, BTRC_EVT_PLAY_STATUS_CHANGED), CONVERT(AVRCP_EVENT_TRACK_CHANGE, BTRC_EVT_TRACK_CHANGE), CONVERT(AVRCP_EVENT_TRACK_REACHED_END, BTRC_EVT_TRACK_REACHED_END), CONVERT(AVRCP_EVENT_TRACK_REACHED_START, BTRC_EVT_TRACK_REACHED_START), CONVERT(AVRCP_EVENT_PLAY_POS_CHANGED, BTRC_EVT_PLAY_POS_CHANGED), CONVERT(AVRCP_EVENT_APP_SETTINGS_CHANGED, BTRC_EVT_APP_SETTINGS_CHANGED) }; if (aIn >= MOZ_ARRAY_LENGTH(sEventId)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sEventId[aIn]; return NS_OK; } inline nsresult Convert(btrc_event_id_t aIn, enum BluetoothAvrcpEvent& aOut) { static const BluetoothAvrcpEvent sEventId[] = { CONVERT(0, static_cast(0)), // invalid, [0] required by gcc CONVERT(BTRC_EVT_PLAY_STATUS_CHANGED, AVRCP_EVENT_PLAY_STATUS_CHANGED), CONVERT(BTRC_EVT_TRACK_CHANGE, AVRCP_EVENT_TRACK_CHANGE), CONVERT(BTRC_EVT_TRACK_REACHED_END, AVRCP_EVENT_TRACK_REACHED_END), CONVERT(BTRC_EVT_TRACK_REACHED_START, AVRCP_EVENT_TRACK_REACHED_START), CONVERT(BTRC_EVT_PLAY_POS_CHANGED, AVRCP_EVENT_PLAY_POS_CHANGED), CONVERT(6, static_cast(0)), // invalid, [6] required by gcc CONVERT(7, static_cast(0)), // invalid, [7] required by gcc CONVERT(BTRC_EVT_APP_SETTINGS_CHANGED, AVRCP_EVENT_APP_SETTINGS_CHANGED) }; if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sEventId[aIn]; return NS_OK; } inline nsresult Convert(btrc_media_attr_t aIn, enum BluetoothAvrcpMediaAttribute& aOut) { static const BluetoothAvrcpMediaAttribute sEventId[] = { CONVERT(0, static_cast(0)), // invalid, [0] required by gcc CONVERT(BTRC_MEDIA_ATTR_TITLE, AVRCP_MEDIA_ATTRIBUTE_TITLE), CONVERT(BTRC_MEDIA_ATTR_ARTIST, AVRCP_MEDIA_ATTRIBUTE_ARTIST), CONVERT(BTRC_MEDIA_ATTR_ALBUM, AVRCP_MEDIA_ATTRIBUTE_ALBUM), CONVERT(BTRC_MEDIA_ATTR_TRACK_NUM, AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM), CONVERT(BTRC_MEDIA_ATTR_NUM_TRACKS, AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS), CONVERT(BTRC_MEDIA_ATTR_GENRE, AVRCP_MEDIA_ATTRIBUTE_GENRE), CONVERT(BTRC_MEDIA_ATTR_PLAYING_TIME, AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME) }; if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sEventId[aIn]; return NS_OK; } inline nsresult Convert(enum BluetoothAvrcpNotification aIn, btrc_notification_type_t& aOut) { static const btrc_notification_type_t sNotificationType[] = { CONVERT(AVRCP_NTF_INTERIM, BTRC_NOTIFICATION_TYPE_INTERIM), CONVERT(AVRCP_NTF_CHANGED, BTRC_NOTIFICATION_TYPE_CHANGED) }; if (aIn >= MOZ_ARRAY_LENGTH(sNotificationType)) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sNotificationType[aIn]; return NS_OK; } nsresult Convert(const BluetoothAvrcpElementAttribute& aIn, btrc_element_attr_val_t& aOut); nsresult Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut); #endif // ANDROID_VERSION >= 18 #if ANDROID_VERSION >= 19 inline nsresult Convert(btrc_remote_features_t aIn, unsigned long& aOut) { /* The input type's name is misleading. The converted value is * actually a bitmask. */ aOut = static_cast(aIn); return NS_OK; } #endif // ANDROID_VERSION >= 19 inline nsresult Convert(int aIn, BluetoothGattStatus& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const BluetoothGattStatus sGattStatus[] = { CONVERT(0x0000, GATT_STATUS_SUCCESS), CONVERT(0x0001, GATT_STATUS_INVALID_HANDLE), CONVERT(0x0002, GATT_STATUS_READ_NOT_PERMITTED), CONVERT(0x0003, GATT_STATUS_WRITE_NOT_PERMITTED), CONVERT(0x0004, GATT_STATUS_INVALID_PDU), CONVERT(0x0005, GATT_STATUS_INSUFFICIENT_AUTHENTICATION), CONVERT(0x0006, GATT_STATUS_REQUEST_NOT_SUPPORTED), CONVERT(0x0007, GATT_STATUS_INVALID_OFFSET), CONVERT(0x0008, GATT_STATUS_INSUFFICIENT_AUTHORIZATION), CONVERT(0x0009, GATT_STATUS_PREPARE_QUEUE_FULL), CONVERT(0x000a, GATT_STATUS_ATTRIBUTE_NOT_FOUND), CONVERT(0x000b, GATT_STATUS_ATTRIBUTE_NOT_LONG), CONVERT(0x000c, GATT_STATUS_INSUFFICIENT_ENCRYPTION_KEY_SIZE), CONVERT(0x000d, GATT_STATUS_INVALID_ATTRIBUTE_LENGTH), CONVERT(0x000e, GATT_STATUS_UNLIKELY_ERROR), CONVERT(0x000f, GATT_STATUS_INSUFFICIENT_ENCRYPTION), CONVERT(0x0010, GATT_STATUS_UNSUPPORTED_GROUP_TYPE), CONVERT(0x0011, GATT_STATUS_INSUFFICIENT_RESOURCES) }; if (static_cast(aIn) >= MOZ_ARRAY_LENGTH(sGattStatus)) { aOut = GATT_STATUS_UNKNOWN_ERROR; return NS_ERROR_ILLEGAL_VALUE; } else { aOut = sGattStatus[aIn]; } return NS_OK; } inline nsresult Convert(BluetoothGattStatus aIn, int& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const int sGattStatus[] = { CONVERT(GATT_STATUS_SUCCESS, 0x0000), CONVERT(GATT_STATUS_INVALID_HANDLE, 0x0001), CONVERT(GATT_STATUS_READ_NOT_PERMITTED, 0x0002), CONVERT(GATT_STATUS_WRITE_NOT_PERMITTED, 0x0003), CONVERT(GATT_STATUS_INVALID_PDU, 0x0004), CONVERT(GATT_STATUS_INSUFFICIENT_AUTHENTICATION, 0x0005), CONVERT(GATT_STATUS_REQUEST_NOT_SUPPORTED, 0x0006), CONVERT(GATT_STATUS_INVALID_OFFSET, 0x0007), CONVERT(GATT_STATUS_INSUFFICIENT_AUTHORIZATION, 0x0008), CONVERT(GATT_STATUS_PREPARE_QUEUE_FULL, 0x0009), CONVERT(GATT_STATUS_ATTRIBUTE_NOT_FOUND, 0x000a), CONVERT(GATT_STATUS_ATTRIBUTE_NOT_LONG, 0x000b), CONVERT(GATT_STATUS_INSUFFICIENT_ENCRYPTION_KEY_SIZE, 0x000c), CONVERT(GATT_STATUS_INVALID_ATTRIBUTE_LENGTH, 0x000d), CONVERT(GATT_STATUS_UNLIKELY_ERROR, 0x000e), CONVERT(GATT_STATUS_INSUFFICIENT_ENCRYPTION, 0x000f), CONVERT(GATT_STATUS_UNSUPPORTED_GROUP_TYPE, 0x0010), CONVERT(GATT_STATUS_INSUFFICIENT_RESOURCES, 0x0011) }; if (static_cast(aIn) >= MOZ_ARRAY_LENGTH(sGattStatus)) { aOut = -1; return NS_ERROR_ILLEGAL_VALUE; } else { aOut = sGattStatus[aIn]; } return NS_OK; } nsresult Convert(const uint8_t* aIn, BluetoothGattAdvData& aOut); inline nsresult Convert(BluetoothGattAttrPerm aIn, int& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const uint16_t sGattAttrPermBit[] = { CONVERT(0, GATT_ATTR_PERM_BIT_READ), CONVERT(1, GATT_ATTR_PERM_BIT_READ_ENCRYPTED), CONVERT(2, GATT_ATTR_PERM_BIT_READ_ENCRYPTED_MITM), CONVERT(3, 0), CONVERT(4, GATT_ATTR_PERM_BIT_WRITE), CONVERT(5, GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED), CONVERT(6, GATT_ATTR_PERM_BIT_WRITE_ENCRYPTED_MITM), CONVERT(7, GATT_ATTR_PERM_BIT_WRITE_SIGNED), CONVERT(8, GATT_ATTR_PERM_BIT_WRITE_SIGNED_MITM) }; aOut = 0; for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sGattAttrPermBit); i++) { if (aIn & sGattAttrPermBit[i]) { aOut |= (1 << i); } } return NS_OK; } inline nsresult Convert(int aIn, BluetoothGattCharProp& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const uint8_t sGattCharPropBit[] = { CONVERT(0, GATT_CHAR_PROP_BIT_BROADCAST), CONVERT(1, GATT_CHAR_PROP_BIT_READ), CONVERT(2, GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE), CONVERT(3, GATT_CHAR_PROP_BIT_WRITE), CONVERT(4, GATT_CHAR_PROP_BIT_NOTIFY), CONVERT(5, GATT_CHAR_PROP_BIT_INDICATE), CONVERT(6, GATT_CHAR_PROP_BIT_SIGNED_WRITE), CONVERT(7, GATT_CHAR_PROP_BIT_EXTENDED_PROPERTIES) }; aOut = BLUETOOTH_EMPTY_GATT_CHAR_PROP; for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sGattCharPropBit); i++) { if (aIn & (1 << i)) { aOut |= sGattCharPropBit[i]; } } return NS_OK; } inline nsresult Convert(BluetoothGattCharProp aIn, int& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const uint8_t sGattCharPropBit[] = { CONVERT(0, GATT_CHAR_PROP_BIT_BROADCAST), CONVERT(1, GATT_CHAR_PROP_BIT_READ), CONVERT(2, GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE), CONVERT(3, GATT_CHAR_PROP_BIT_WRITE), CONVERT(4, GATT_CHAR_PROP_BIT_NOTIFY), CONVERT(5, GATT_CHAR_PROP_BIT_INDICATE), CONVERT(6, GATT_CHAR_PROP_BIT_SIGNED_WRITE), CONVERT(7, GATT_CHAR_PROP_BIT_EXTENDED_PROPERTIES) }; aOut = 0; for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sGattCharPropBit); i++) { if (aIn & sGattCharPropBit[i]) { aOut |= (1 << i); } } return NS_OK; } inline nsresult Convert(BluetoothGattAuthReq aIn, int& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const int sGattAuthReq[] = { CONVERT(GATT_AUTH_REQ_NONE, 0), CONVERT(GATT_AUTH_REQ_NO_MITM, 1), CONVERT(GATT_AUTH_REQ_MITM, 2), CONVERT(GATT_AUTH_REQ_SIGNED_NO_MITM, 3), CONVERT(GATT_AUTH_REQ_SIGNED_MITM, 4) }; if (aIn >= MOZ_ARRAY_LENGTH(sGattAuthReq)) { aOut = GATT_AUTH_REQ_NONE; // silences compiler warning return NS_ERROR_ILLEGAL_VALUE; } aOut = sGattAuthReq[aIn]; return NS_OK; } inline nsresult Convert(BluetoothGattWriteType aIn, int& aOut) { /* Reference: $B2G/external/bluetooth/bluedroid/stack/include/gatt_api.h */ static const int sGattWriteType[] = { CONVERT(GATT_WRITE_TYPE_NO_RESPONSE, 1), CONVERT(GATT_WRITE_TYPE_NORMAL, 2), CONVERT(GATT_WRITE_TYPE_PREPARE, 3), CONVERT(GATT_WRITE_TYPE_SIGNED, 4) }; if (aIn >= MOZ_ARRAY_LENGTH(sGattWriteType)) { aOut = GATT_WRITE_TYPE_NORMAL; // silences compiler warning return NS_ERROR_ILLEGAL_VALUE; } aOut = sGattWriteType[aIn]; return NS_OK; } inline nsresult Convert(const ArrayBuffer& aIn, char* aOut) { aIn.ComputeLengthAndData(); memcpy(aOut, aIn.Data(), aIn.Length()); return NS_OK; } #if ANDROID_VERSION >= 19 nsresult Convert(const BluetoothGattId& aIn, btgatt_gatt_id_t& aOut); nsresult Convert(const btgatt_gatt_id_t& aIn, BluetoothGattId& aOut); nsresult Convert(const BluetoothGattServiceId& aIn, btgatt_srvc_id_t& aOut); nsresult Convert(const btgatt_srvc_id_t& aIn, BluetoothGattServiceId& aOut); nsresult Convert(const btgatt_read_params_t& aIn, BluetoothGattReadParam& aOut); nsresult Convert(const btgatt_write_params_t& aIn, BluetoothGattWriteParam& aOut); nsresult Convert(const btgatt_notify_params_t& aIn, BluetoothGattNotifyParam& aOut); nsresult Convert(const BluetoothGattTestParam& aIn, btgatt_test_params_t& aOut); inline nsresult Convert(BluetoothTransport aIn, int& aOut) { static const int sTransport[] = { CONVERT(TRANSPORT_AUTO, 0), CONVERT(TRANSPORT_BREDR, 1), CONVERT(TRANSPORT_LE, 2) }; if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sTransport))) { aOut = -1; return NS_ERROR_ILLEGAL_VALUE; } aOut = sTransport[aIn]; return NS_OK; } nsresult Convert(const BluetoothGattResponse& aIn, btgatt_response_t& aOut); #endif // ANDROID_VERSION >= 19 #if ANDROID_VERSION >= 21 nsresult Convert(const BluetoothTransport& aIn, btgatt_transport_t& aOut); nsresult Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut); inline nsresult Convert(bthf_wbs_config_t aIn, BluetoothHandsfreeWbsConfig& aOut) { static const BluetoothHandsfreeWbsConfig sWbsConfig[] = { CONVERT(BTHF_WBS_NONE, HFP_WBS_NONE), CONVERT(BTHF_WBS_NO, HFP_WBS_NO), CONVERT(BTHF_WBS_YES, HFP_WBS_YES) }; if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sWbsConfig[aIn]; return NS_OK; } inline nsresult Convert(BluetoothHandsfreeWbsConfig aIn, bthf_wbs_config_t& aOut) { static const bthf_wbs_config_t sWbsConfig[] = { CONVERT(HFP_WBS_NONE, BTHF_WBS_NONE), CONVERT(HFP_WBS_NO, BTHF_WBS_NO), CONVERT(HFP_WBS_YES, BTHF_WBS_YES) }; if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { return NS_ERROR_ILLEGAL_VALUE; } aOut = sWbsConfig[aIn]; return NS_OK; } #endif // ANDROID_VERSION >= 21 /* |ConvertArray| is a helper for converting arrays. Pass an * instance of this structure as the first argument to |Convert| * to convert an array. The output type has to support the array * subscript operator. */ template struct ConvertArray { ConvertArray(const T* aData, unsigned long aLength) : mData(aData) , mLength(aLength) { } const T* mData; unsigned long mLength; }; /* This implementation of |Convert| converts the elements of an * array one-by-one. The result data structures must have enough * memory allocated. */ template inline nsresult Convert(const ConvertArray& aIn, Tout& aOut) { for (unsigned long i = 0; i < aIn.mLength; ++i) { nsresult rv = Convert(aIn.mData[i], aOut[i]); if (NS_FAILED(rv)) { return rv; } } return NS_OK; } /* This implementation of |Convert| is a helper that automatically * allocates enough memory to hold the conversion results. The * actual conversion is performed by the array-conversion helper * above. */ template inline nsresult Convert(const ConvertArray& aIn, nsAutoArrayPtr& aOut) { aOut = new Tout[aIn.mLength]; Tout* out = aOut.get(); return Convert(aIn, out); } /* |ConvertDefault| is a helper function to return the result of a * conversion or a default value if the conversion fails. */ template inline Tout ConvertDefault(const Tin& aIn, const Tout& aDefault) { Tout out = aDefault; // assignment silences compiler warning if (NS_FAILED(Convert(aIn, out))) { return aDefault; } return out; } /* This implementation of |Convert| is a helper for copying the * input value into the output value. It handles all cases that * need no conversion. */ template inline nsresult Convert(const T& aIn, T& aOut) { aOut = aIn; return NS_OK; } nsresult Convert(const bt_property_t& aIn, BluetoothProperty& aOut); // // Result handling // template class BluetoothHALInterfaceRunnable0 : public nsRunnable { public: BluetoothHALInterfaceRunnable0(Obj* aObj, Res (Obj::*aMethod)()) : mObj(aObj) , mMethod(aMethod) { MOZ_ASSERT(mObj); MOZ_ASSERT(mMethod); } NS_METHOD Run() override { ((*mObj).*mMethod)(); return NS_OK; } private: nsRefPtr mObj; void (Obj::*mMethod)(); }; template class BluetoothHALInterfaceRunnable1 : public nsRunnable { public: BluetoothHALInterfaceRunnable1(Obj* aObj, Res (Obj::*aMethod)(Arg1), const Arg1& aArg1) : mObj(aObj) , mMethod(aMethod) , mArg1(aArg1) { MOZ_ASSERT(mObj); MOZ_ASSERT(mMethod); } NS_METHOD Run() override { ((*mObj).*mMethod)(mArg1); return NS_OK; } private: nsRefPtr mObj; Res (Obj::*mMethod)(Arg1); Tin1 mArg1; }; template class BluetoothHALInterfaceRunnable3 : public nsRunnable { public: BluetoothHALInterfaceRunnable3(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3), const Arg1& aArg1, const Arg2& aArg2, const Arg3& aArg3) : mObj(aObj) , mMethod(aMethod) , mArg1(aArg1) , mArg2(aArg2) , mArg3(aArg3) { MOZ_ASSERT(mObj); MOZ_ASSERT(mMethod); } NS_METHOD Run() override { ((*mObj).*mMethod)(mArg1, mArg2, mArg3); return NS_OK; } private: nsRefPtr mObj; Res (Obj::*mMethod)(Arg1, Arg2, Arg3); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; }; // // Notification handling // template class BluetoothNotificationHALRunnable0 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable0 SelfType; static already_AddRefed Create(Res (ObjectType::*aMethod)()) { nsRefPtr runnable(new SelfType(aMethod)); return runnable.forget(); } static void Dispatch(Res (ObjectType::*aMethod)()) { nsRefPtr runnable = Create(aMethod); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable0::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(); } return NS_OK; } private: BluetoothNotificationHALRunnable0(Res (ObjectType::*aMethod)()) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } Res (ObjectType::*mMethod)(); }; template class BluetoothNotificationHALRunnable1 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable1 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1), const T1& aIn1) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1), const T1& aIn1) { nsRefPtr runnable = Create(aMethod, aIn1); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable1::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1); } return NS_OK; } private: BluetoothNotificationHALRunnable1(Res (ObjectType::*aMethod)(Arg1)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1); Tin1 mArg1; }; template class BluetoothNotificationHALRunnable2 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable2 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2), const T1& aIn1, const T2& aIn2) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2), const T1& aIn1, const T2& aIn2) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable2::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2); } return NS_OK; } private: BluetoothNotificationHALRunnable2( Res (ObjectType::*aMethod)(Arg1, Arg2)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2); Tin1 mArg1; Tin2 mArg2; }; template class BluetoothNotificationHALRunnable3 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable3 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), const T1& aIn1, const T2& aIn2, const T3& aIn3) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), const T1& aIn1, const T2& aIn2, const T3& aIn3) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable3::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2, mArg3); } return NS_OK; } private: BluetoothNotificationHALRunnable3( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; }; template class BluetoothNotificationHALRunnable4 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable4 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable4::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4); } return NS_OK; } private: BluetoothNotificationHALRunnable4( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn4, mArg4); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; Tin4 mArg4; }; template class BluetoothNotificationHALRunnable5 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable5 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4, aIn5); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable5::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5); } return NS_OK; } private: BluetoothNotificationHALRunnable5( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn4, mArg4); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn5, mArg5); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; Tin4 mArg4; Tin5 mArg5; }; template class BluetoothNotificationHALRunnable6 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable6 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5, aIn6))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4, aIn5, aIn6); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable6::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6); } return NS_OK; } private: BluetoothNotificationHALRunnable6( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn4, mArg4); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn5, mArg5); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn6, mArg6); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; Tin4 mArg4; Tin5 mArg5; Tin6 mArg6; }; template class BluetoothNotificationHALRunnable7 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable7 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5, aIn6, aIn7))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4, aIn5, aIn6, aIn7); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable7::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6, mArg7); } return NS_OK; } private: BluetoothNotificationHALRunnable7( Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn4, mArg4); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn5, mArg5); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn6, mArg6); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn7, mArg7); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; Tin4 mArg4; Tin5 mArg5; Tin6 mArg6; Tin7 mArg7; }; template class BluetoothNotificationHALRunnable9 : public nsRunnable { public: typedef typename ObjectWrapper::ObjectType ObjectType; typedef BluetoothNotificationHALRunnable9 SelfType; template static already_AddRefed Create( Res (ObjectType::*aMethod)( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7, const T8& aIn8, const T9& aIn9) { nsRefPtr runnable(new SelfType(aMethod)); if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5, aIn6, aIn7, aIn8, aIn9))) { return nullptr; } return runnable.forget(); } template static void Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7, const T8& aIn8, const T9& aIn9) { nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4, aIn5, aIn6, aIn7, aIn8, aIn9); if (!runnable) { BT_WARNING("BluetoothNotificationHALRunnable8::Create failed"); return; } nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { BT_WARNING("NS_DispatchToMainThread failed: %X", rv); } } NS_METHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); ObjectType* obj = ObjectWrapper::GetInstance(); if (!obj) { BT_WARNING("Notification handler not initialized"); } else { ((*obj).*mMethod)( mArg1, mArg2, mArg3, mArg4, mArg5, mArg6, mArg7, mArg8, mArg9); } return NS_OK; } private: BluetoothNotificationHALRunnable9( Res (ObjectType::*aMethod)( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) : mMethod(aMethod) { MOZ_ASSERT(mMethod); } template nsresult ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, const T5& aIn5, const T6& aIn6, const T7& aIn7, const T8& aIn8, const T9& aIn9) { nsresult rv = Convert(aIn1, mArg1); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn2, mArg2); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn3, mArg3); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn4, mArg4); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn5, mArg5); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn6, mArg6); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn7, mArg7); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn8, mArg8); if (NS_FAILED(rv)) { return rv; } rv = Convert(aIn9, mArg9); if (NS_FAILED(rv)) { return rv; } return NS_OK; } Res (ObjectType::*mMethod)( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); Tin1 mArg1; Tin2 mArg2; Tin3 mArg3; Tin4 mArg4; Tin5 mArg5; Tin6 mArg6; Tin7 mArg7; Tin8 mArg8; Tin9 mArg9; }; END_BLUETOOTH_NAMESPACE #endif