Loading jni/com_android_bluetooth_hfpclient.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ static jmethodID method_onSubscriberInfo; static jmethodID method_onInBandRing; static jmethodID method_onLastVoiceTagNumber; static jmethodID method_onRingIndication; static jmethodID method_onUnknownEvent; static jbyteArray marshall_bda(const RawAddress* bd_addr) { CallbackEnv sCallbackEnv(__func__); Loading Loading @@ -368,6 +369,20 @@ static void ring_indication_cb(const RawAddress* bd_addr) { addr.get()); } static void unknown_event_cb(const RawAddress* bd_addr, const char* eventString) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; ScopedLocalRef<jstring> js_event(sCallbackEnv.get(), sCallbackEnv->NewStringUTF(eventString)); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownEvent, js_event.get(), addr.get()); } static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { sizeof(sBluetoothHfpClientCallbacks), connection_state_cb, Loading @@ -391,6 +406,7 @@ static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { in_band_ring_cb, last_voice_tag_number_cb, ring_indication_cb, unknown_event_cb, }; static void classInitNative(JNIEnv* env, jclass clazz) { Loading Loading @@ -423,6 +439,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_onLastVoiceTagNumber = env->GetMethodID(clazz, "onLastVoiceTagNumber", "(Ljava/lang/String;[B)V"); method_onRingIndication = env->GetMethodID(clazz, "onRingIndication", "([B)V"); method_onUnknownEvent = env->GetMethodID(clazz, "onUnknownEvent", "(Ljava/lang/String;[B)V"); ALOGI("%s succeeds", __func__); } Loading src/com/android/bluetooth/hfpclient/HeadsetClientHalConstants.java +1 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ public final class HeadsetClientHalConstants { // used for sending vendor specific AT cmds to AG. static final int HANDSFREECLIENT_AT_CMD_NREC = 15; static final int HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD = 16; // Flag to check for local NREC support static final boolean HANDSFREECLIENT_NREC_SUPPORTED = true; Loading src/com/android/bluetooth/hfpclient/HeadsetClientService.java +29 −0 Original line number Diff line number Diff line Loading @@ -430,6 +430,15 @@ public class HeadsetClientService extends ProfileService { return service.getCurrentAgEvents(device); } @Override public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) { HeadsetClientService service = getService(); if (service == null) { return false; } return service.sendVendorAtCommand(device, vendorId, atCommand); } @Override public Bundle getCurrentAgFeatures(BluetoothDevice device) { HeadsetClientService service = getService(); Loading Loading @@ -820,6 +829,26 @@ public class HeadsetClientService extends ProfileService { return true; } /** Send vendor AT command. */ public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); HeadsetClientStateMachine sm = getStateMachine(device); if (sm == null) { Log.e(TAG, "Cannot allocate SM for device " + device); return false; } int connectionState = sm.getConnectionState(device); if (connectionState != BluetoothProfile.STATE_CONNECTED) { return false; } Message msg = sm.obtainMessage(HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); sm.sendMessage(msg); return true; } public Bundle getCurrentAgEvents(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); HeadsetClientStateMachine sm = getStateMachine(device); Loading src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +17 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public class HeadsetClientStateMachine extends StateMachine { public static final int SEND_DTMF = 17; public static final int EXPLICIT_CALL_TRANSFER = 18; public static final int DISABLE_NREC = 20; public static final int SEND_VENDOR_AT_COMMAND = 21; // internal actions private static final int QUERY_CURRENT_CALLS = 50; Loading Loading @@ -176,6 +177,7 @@ public class HeadsetClientStateMachine extends StateMachine { private final AudioManager mAudioManager; private final NativeInterface mNativeInterface; private final VendorCommandResponseProcessor mVendorProcessor; // Accessor for the states, useful for reusing the state machines public IState getDisconnectedState() { Loading Loading @@ -667,6 +669,8 @@ public class HeadsetClientStateMachine extends StateMachine { mNativeInterface = nativeInterface; mAudioManager = mService.getAudioManager(); mVendorProcessor = new VendorCommandResponseProcessor(mService, mNativeInterface); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; Loading Loading @@ -1140,6 +1144,13 @@ public class HeadsetClientStateMachine extends StateMachine { } break; case SEND_VENDOR_AT_COMMAND: { int vendorId = message.arg1; String atCommand = (String) (message.obj); mVendorProcessor.sendCommand(vendorId, atCommand, mCurrentDevice); break; } // Called only for Mute/Un-mute - Mic volume change is not allowed. case SET_MIC_VOLUME: break; Loading Loading @@ -1390,6 +1401,12 @@ public class HeadsetClientStateMachine extends StateMachine { // implemented (by the client of this service). Use the // CALL_STATE_INCOMING (and similar) handle ringing. break; case StackEvent.EVENT_TYPE_UNKNOWN_EVENT: if (!mVendorProcessor.processEvent(event.valueString, event.device)) { Log.e(TAG, "Unknown event :" + event.valueString + " for device " + event.device); } break; default: Log.e(TAG, "Unknown stack event: " + event.type); break; Loading src/com/android/bluetooth/hfpclient/NativeInterface.java +17 −0 Original line number Diff line number Diff line Loading @@ -650,4 +650,21 @@ public class NativeInterface { "onRingIndication: Ignoring message because service not available: " + event); } } private void onUnknownEvent(String eventString, byte[] address) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_UNKNOWN_EVENT); event.device = getDevice(address); event.valueString = eventString; if (DBG) { Log.d(TAG, "onUnknownEvent: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); if (service != null) { service.messageFromNative(event); } else { Log.w(TAG, "onUnknowEvent: Ignoring message because service not available: " + event); } } } Loading
jni/com_android_bluetooth_hfpclient.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ static jmethodID method_onSubscriberInfo; static jmethodID method_onInBandRing; static jmethodID method_onLastVoiceTagNumber; static jmethodID method_onRingIndication; static jmethodID method_onUnknownEvent; static jbyteArray marshall_bda(const RawAddress* bd_addr) { CallbackEnv sCallbackEnv(__func__); Loading Loading @@ -368,6 +369,20 @@ static void ring_indication_cb(const RawAddress* bd_addr) { addr.get()); } static void unknown_event_cb(const RawAddress* bd_addr, const char* eventString) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; ScopedLocalRef<jstring> js_event(sCallbackEnv.get(), sCallbackEnv->NewStringUTF(eventString)); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownEvent, js_event.get(), addr.get()); } static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { sizeof(sBluetoothHfpClientCallbacks), connection_state_cb, Loading @@ -391,6 +406,7 @@ static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { in_band_ring_cb, last_voice_tag_number_cb, ring_indication_cb, unknown_event_cb, }; static void classInitNative(JNIEnv* env, jclass clazz) { Loading Loading @@ -423,6 +439,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_onLastVoiceTagNumber = env->GetMethodID(clazz, "onLastVoiceTagNumber", "(Ljava/lang/String;[B)V"); method_onRingIndication = env->GetMethodID(clazz, "onRingIndication", "([B)V"); method_onUnknownEvent = env->GetMethodID(clazz, "onUnknownEvent", "(Ljava/lang/String;[B)V"); ALOGI("%s succeeds", __func__); } Loading
src/com/android/bluetooth/hfpclient/HeadsetClientHalConstants.java +1 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ public final class HeadsetClientHalConstants { // used for sending vendor specific AT cmds to AG. static final int HANDSFREECLIENT_AT_CMD_NREC = 15; static final int HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD = 16; // Flag to check for local NREC support static final boolean HANDSFREECLIENT_NREC_SUPPORTED = true; Loading
src/com/android/bluetooth/hfpclient/HeadsetClientService.java +29 −0 Original line number Diff line number Diff line Loading @@ -430,6 +430,15 @@ public class HeadsetClientService extends ProfileService { return service.getCurrentAgEvents(device); } @Override public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) { HeadsetClientService service = getService(); if (service == null) { return false; } return service.sendVendorAtCommand(device, vendorId, atCommand); } @Override public Bundle getCurrentAgFeatures(BluetoothDevice device) { HeadsetClientService service = getService(); Loading Loading @@ -820,6 +829,26 @@ public class HeadsetClientService extends ProfileService { return true; } /** Send vendor AT command. */ public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); HeadsetClientStateMachine sm = getStateMachine(device); if (sm == null) { Log.e(TAG, "Cannot allocate SM for device " + device); return false; } int connectionState = sm.getConnectionState(device); if (connectionState != BluetoothProfile.STATE_CONNECTED) { return false; } Message msg = sm.obtainMessage(HeadsetClientStateMachine.SEND_VENDOR_AT_COMMAND, vendorId, 0, atCommand); sm.sendMessage(msg); return true; } public Bundle getCurrentAgEvents(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); HeadsetClientStateMachine sm = getStateMachine(device); Loading
src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +17 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public class HeadsetClientStateMachine extends StateMachine { public static final int SEND_DTMF = 17; public static final int EXPLICIT_CALL_TRANSFER = 18; public static final int DISABLE_NREC = 20; public static final int SEND_VENDOR_AT_COMMAND = 21; // internal actions private static final int QUERY_CURRENT_CALLS = 50; Loading Loading @@ -176,6 +177,7 @@ public class HeadsetClientStateMachine extends StateMachine { private final AudioManager mAudioManager; private final NativeInterface mNativeInterface; private final VendorCommandResponseProcessor mVendorProcessor; // Accessor for the states, useful for reusing the state machines public IState getDisconnectedState() { Loading Loading @@ -667,6 +669,8 @@ public class HeadsetClientStateMachine extends StateMachine { mNativeInterface = nativeInterface; mAudioManager = mService.getAudioManager(); mVendorProcessor = new VendorCommandResponseProcessor(mService, mNativeInterface); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; Loading Loading @@ -1140,6 +1144,13 @@ public class HeadsetClientStateMachine extends StateMachine { } break; case SEND_VENDOR_AT_COMMAND: { int vendorId = message.arg1; String atCommand = (String) (message.obj); mVendorProcessor.sendCommand(vendorId, atCommand, mCurrentDevice); break; } // Called only for Mute/Un-mute - Mic volume change is not allowed. case SET_MIC_VOLUME: break; Loading Loading @@ -1390,6 +1401,12 @@ public class HeadsetClientStateMachine extends StateMachine { // implemented (by the client of this service). Use the // CALL_STATE_INCOMING (and similar) handle ringing. break; case StackEvent.EVENT_TYPE_UNKNOWN_EVENT: if (!mVendorProcessor.processEvent(event.valueString, event.device)) { Log.e(TAG, "Unknown event :" + event.valueString + " for device " + event.device); } break; default: Log.e(TAG, "Unknown stack event: " + event.type); break; Loading
src/com/android/bluetooth/hfpclient/NativeInterface.java +17 −0 Original line number Diff line number Diff line Loading @@ -650,4 +650,21 @@ public class NativeInterface { "onRingIndication: Ignoring message because service not available: " + event); } } private void onUnknownEvent(String eventString, byte[] address) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_UNKNOWN_EVENT); event.device = getDevice(address); event.valueString = eventString; if (DBG) { Log.d(TAG, "onUnknownEvent: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); if (service != null) { service.messageFromNative(event); } else { Log.w(TAG, "onUnknowEvent: Ignoring message because service not available: " + event); } } }