Loading android/app/jni/com_android_bluetooth_hfpclient.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,12 @@ static void audio_state_cb(const RawAddress* bd_addr, static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint)state); (jint)state, addr.get()); } static void network_state_cb(const RawAddress* bd_addr, Loading Loading @@ -348,7 +352,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) { env->GetMethodID(clazz, "onConnectionStateChanged", "(III[B)V"); method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I)V"); method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V"); method_onNetworkState = env->GetMethodID(clazz, "onNetworkState", "(I[B)V"); method_onNetworkRoaming = env->GetMethodID(clazz, "onNetworkRoaming", "(I[B)V"); method_onNetworkSignal = env->GetMethodID(clazz, "onNetworkSignal", "(I[B)V"); Loading android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java +24 −4 Original line number Diff line number Diff line Loading @@ -582,14 +582,34 @@ public class HeadsetClientService extends ProfileService { } boolean startVoiceRecognition(BluetoothDevice device) { Log.e(TAG, "startVoiceRecognition API not available"); 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; } sm.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_START); return true; } boolean stopVoiceRecognition(BluetoothDevice device) { Log.e(TAG, "stopVoiceRecognition API not available"); 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; } sm.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_STOP); return true; } int getAudioState(BluetoothDevice device) { HeadsetClientStateMachine sm = getStateMachine(device); Loading android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +50 −0 Original line number Diff line number Diff line Loading @@ -75,10 +75,13 @@ public class HeadsetClientStateMachine extends StateMachine { static final int NO_ACTION = 0; // external actions public static final int AT_OK = 0; public static final int CONNECT = 1; public static final int DISCONNECT = 2; public static final int CONNECT_AUDIO = 3; public static final int DISCONNECT_AUDIO = 4; public static final int VOICE_RECOGNITION_START = 5; public static final int VOICE_RECOGNITION_STOP = 6; public static final int SET_MIC_VOLUME = 7; public static final int SET_SPEAKER_VOLUME = 8; public static final int DIAL_NUMBER = 10; Loading Loading @@ -151,6 +154,7 @@ public class HeadsetClientStateMachine extends StateMachine { private static AudioManager sAudioManager; private int mAudioState; private boolean mAudioWbs; private int mVoiceRecognitionActive; private final BluetoothAdapter mAdapter; private TelecomManager mTelecomManager; Loading Loading @@ -674,6 +678,7 @@ public class HeadsetClientStateMachine extends StateMachine { } mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; mTelecomManager = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE); Loading Loading @@ -1111,6 +1116,28 @@ public class HeadsetClientStateMachine extends StateMachine { } break; case VOICE_RECOGNITION_START: if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STOPPED) { if (NativeInterface.startVoiceRecognitionNative( getByteAddress(mCurrentDevice))) { addQueuedAction(VOICE_RECOGNITION_START); } else { Log.e(TAG, "ERROR: Couldn't start voice recognition"); } } break; case VOICE_RECOGNITION_STOP: if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STARTED) { if (NativeInterface.stopVoiceRecognitionNative( getByteAddress(mCurrentDevice))) { addQueuedAction(VOICE_RECOGNITION_STOP); } else { Log.e(TAG, "ERROR: Couldn't stop voice recognition"); } } break; // Called only for Mute/Un-mute - Mic volume change is not allowed. case SET_MIC_VOLUME: break; Loading Loading @@ -1283,6 +1310,17 @@ public class HeadsetClientStateMachine extends StateMachine { intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); break; case StackEvent.EVENT_TYPE_VR_STATE_CHANGED: if (mVoiceRecognitionActive != event.valueInt) { mVoiceRecognitionActive = event.valueInt; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, mVoiceRecognitionActive); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); } break; case StackEvent.EVENT_TYPE_CALL: case StackEvent.EVENT_TYPE_CALLSETUP: case StackEvent.EVENT_TYPE_CALLHELD: Loading Loading @@ -1327,6 +1365,18 @@ public class HeadsetClientStateMachine extends StateMachine { case QUERY_CURRENT_CALLS: queryCallsDone(); break; case VOICE_RECOGNITION_START: if (event.valueInt == AT_OK) { mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STARTED; } break; case VOICE_RECOGNITION_STOP: if (event.valueInt == AT_OK) { mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; } break; default: Log.w(TAG, "Unhandled AT OK " + event); break; Loading android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java +18 −4 Original line number Diff line number Diff line Loading @@ -111,8 +111,21 @@ class NativeInterface { } } private void onVrStateChanged(int state) { Log.w(TAG, "onVrStateChanged not supported"); private void onVrStateChanged(int state, byte[] address) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_VR_STATE_CHANGED); event.valueInt = state; event.device = getDevice(address); if (DBG) { Log.d(TAG, "onVrStateChanged: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); if (service != null) { service.messageFromNative(event); } else { Log.w(TAG, "onVrStateChanged: Ignoring message because service not available: " + event); } } private void onNetworkState(int state, byte[] address) { Loading @@ -120,7 +133,7 @@ class NativeInterface { event.valueInt = state; event.device = getDevice(address); if (DBG) { Log.d(TAG, "onVrStateChanged: address " + address + " event " + event); Log.d(TAG, "onNetworkStateChanged: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); Loading @@ -128,7 +141,8 @@ class NativeInterface { service.messageFromNative(event); } else { Log.w(TAG, "onVrStateChanged: Ignoring message because service not available: " + event); "onNetworkStateChanged: Ignoring message because service not available: " + event); } } Loading android/app/src/com/android/bluetooth/hfpclient/StackEvent.java +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ public class StackEvent { public static final int EVENT_TYPE_NONE = 0; public static final int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1; public static final int EVENT_TYPE_AUDIO_STATE_CHANGED = 2; public static final int EVENT_TYPE_VR_STATE_CHANGED = 3; public static final int EVENT_TYPE_NETWORK_STATE = 4; public static final int EVENT_TYPE_ROAMING_STATE = 5; public static final int EVENT_TYPE_NETWORK_SIGNAL = 6; Loading Loading
android/app/jni/com_android_bluetooth_hfpclient.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,12 @@ static void audio_state_cb(const RawAddress* bd_addr, static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint)state); (jint)state, addr.get()); } static void network_state_cb(const RawAddress* bd_addr, Loading Loading @@ -348,7 +352,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) { env->GetMethodID(clazz, "onConnectionStateChanged", "(III[B)V"); method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V"); method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I)V"); method_onVrStateChanged = env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V"); method_onNetworkState = env->GetMethodID(clazz, "onNetworkState", "(I[B)V"); method_onNetworkRoaming = env->GetMethodID(clazz, "onNetworkRoaming", "(I[B)V"); method_onNetworkSignal = env->GetMethodID(clazz, "onNetworkSignal", "(I[B)V"); Loading
android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java +24 −4 Original line number Diff line number Diff line Loading @@ -582,14 +582,34 @@ public class HeadsetClientService extends ProfileService { } boolean startVoiceRecognition(BluetoothDevice device) { Log.e(TAG, "startVoiceRecognition API not available"); 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; } sm.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_START); return true; } boolean stopVoiceRecognition(BluetoothDevice device) { Log.e(TAG, "stopVoiceRecognition API not available"); 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; } sm.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_STOP); return true; } int getAudioState(BluetoothDevice device) { HeadsetClientStateMachine sm = getStateMachine(device); Loading
android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +50 −0 Original line number Diff line number Diff line Loading @@ -75,10 +75,13 @@ public class HeadsetClientStateMachine extends StateMachine { static final int NO_ACTION = 0; // external actions public static final int AT_OK = 0; public static final int CONNECT = 1; public static final int DISCONNECT = 2; public static final int CONNECT_AUDIO = 3; public static final int DISCONNECT_AUDIO = 4; public static final int VOICE_RECOGNITION_START = 5; public static final int VOICE_RECOGNITION_STOP = 6; public static final int SET_MIC_VOLUME = 7; public static final int SET_SPEAKER_VOLUME = 8; public static final int DIAL_NUMBER = 10; Loading Loading @@ -151,6 +154,7 @@ public class HeadsetClientStateMachine extends StateMachine { private static AudioManager sAudioManager; private int mAudioState; private boolean mAudioWbs; private int mVoiceRecognitionActive; private final BluetoothAdapter mAdapter; private TelecomManager mTelecomManager; Loading Loading @@ -674,6 +678,7 @@ public class HeadsetClientStateMachine extends StateMachine { } mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; mTelecomManager = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE); Loading Loading @@ -1111,6 +1116,28 @@ public class HeadsetClientStateMachine extends StateMachine { } break; case VOICE_RECOGNITION_START: if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STOPPED) { if (NativeInterface.startVoiceRecognitionNative( getByteAddress(mCurrentDevice))) { addQueuedAction(VOICE_RECOGNITION_START); } else { Log.e(TAG, "ERROR: Couldn't start voice recognition"); } } break; case VOICE_RECOGNITION_STOP: if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STARTED) { if (NativeInterface.stopVoiceRecognitionNative( getByteAddress(mCurrentDevice))) { addQueuedAction(VOICE_RECOGNITION_STOP); } else { Log.e(TAG, "ERROR: Couldn't stop voice recognition"); } } break; // Called only for Mute/Un-mute - Mic volume change is not allowed. case SET_MIC_VOLUME: break; Loading Loading @@ -1283,6 +1310,17 @@ public class HeadsetClientStateMachine extends StateMachine { intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); break; case StackEvent.EVENT_TYPE_VR_STATE_CHANGED: if (mVoiceRecognitionActive != event.valueInt) { mVoiceRecognitionActive = event.valueInt; intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, mVoiceRecognitionActive); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); } break; case StackEvent.EVENT_TYPE_CALL: case StackEvent.EVENT_TYPE_CALLSETUP: case StackEvent.EVENT_TYPE_CALLHELD: Loading Loading @@ -1327,6 +1365,18 @@ public class HeadsetClientStateMachine extends StateMachine { case QUERY_CURRENT_CALLS: queryCallsDone(); break; case VOICE_RECOGNITION_START: if (event.valueInt == AT_OK) { mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STARTED; } break; case VOICE_RECOGNITION_STOP: if (event.valueInt == AT_OK) { mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; } break; default: Log.w(TAG, "Unhandled AT OK " + event); break; Loading
android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java +18 −4 Original line number Diff line number Diff line Loading @@ -111,8 +111,21 @@ class NativeInterface { } } private void onVrStateChanged(int state) { Log.w(TAG, "onVrStateChanged not supported"); private void onVrStateChanged(int state, byte[] address) { StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_VR_STATE_CHANGED); event.valueInt = state; event.device = getDevice(address); if (DBG) { Log.d(TAG, "onVrStateChanged: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); if (service != null) { service.messageFromNative(event); } else { Log.w(TAG, "onVrStateChanged: Ignoring message because service not available: " + event); } } private void onNetworkState(int state, byte[] address) { Loading @@ -120,7 +133,7 @@ class NativeInterface { event.valueInt = state; event.device = getDevice(address); if (DBG) { Log.d(TAG, "onVrStateChanged: address " + address + " event " + event); Log.d(TAG, "onNetworkStateChanged: address " + address + " event " + event); } HeadsetClientService service = HeadsetClientService.getHeadsetClientService(); Loading @@ -128,7 +141,8 @@ class NativeInterface { service.messageFromNative(event); } else { Log.w(TAG, "onVrStateChanged: Ignoring message because service not available: " + event); "onNetworkStateChanged: Ignoring message because service not available: " + event); } } Loading
android/app/src/com/android/bluetooth/hfpclient/StackEvent.java +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ public class StackEvent { public static final int EVENT_TYPE_NONE = 0; public static final int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1; public static final int EVENT_TYPE_AUDIO_STATE_CHANGED = 2; public static final int EVENT_TYPE_VR_STATE_CHANGED = 3; public static final int EVENT_TYPE_NETWORK_STATE = 4; public static final int EVENT_TYPE_ROAMING_STATE = 5; public static final int EVENT_TYPE_NETWORK_SIGNAL = 6; Loading