Loading core/java/android/bluetooth/BluetoothHeadset.java +67 −30 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.bluetooth; package android.bluetooth; import android.Manifest; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant; Loading Loading @@ -633,8 +634,9 @@ public final class BluetoothHeadset implements BluetoothProfile { * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @param device Bluetooth headset * @param device Bluetooth headset * @return false if there is no headset connected of if the connected headset doesn't support * @return false if there is no headset connected, or the connected headset doesn't support * voice recognition or on error, true otherwise * voice recognition, or voice recognition is already started, or audio channel is occupied, * or on error, true otherwise */ */ public boolean startVoiceRecognition(BluetoothDevice device) { public boolean startVoiceRecognition(BluetoothDevice device) { if (DBG) log("startVoiceRecognition()"); if (DBG) log("startVoiceRecognition()"); Loading @@ -654,10 +656,15 @@ public final class BluetoothHeadset implements BluetoothProfile { * Stop Bluetooth Voice Recognition mode, and shut down the * Stop Bluetooth Voice Recognition mode, and shut down the * Bluetooth audio path. * Bluetooth audio path. * * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @param device Bluetooth headset * @param device Bluetooth headset * @return false if there is no headset connected or on error, true otherwise * @return false if there is no headset connected, or voice recognition has not started, * or voice recognition has ended on this headset, or on error, true otherwise */ */ public boolean stopVoiceRecognition(BluetoothDevice device) { public boolean stopVoiceRecognition(BluetoothDevice device) { if (DBG) log("stopVoiceRecognition()"); if (DBG) log("stopVoiceRecognition()"); Loading Loading @@ -798,11 +805,12 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Check if Bluetooth SCO audio is connected. * Check if at least one headset's SCO audio is connected or connecting * * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @return true if SCO is connected, false otherwise or on error * @return true if at least one device's SCO audio is connected or connecting, false otherwise * or on error * @hide * @hide */ */ public boolean isAudioOn() { public boolean isAudioOn() { Loading @@ -821,11 +829,21 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a connection of headset audio. * Initiates a connection of headset audio to the current active device * It setup SCO channel with remote connected headset device. * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}. * * * @return true if successful false if there was some error such as there is no connected * <p> {@link #EXTRA_STATE} will transition from * headset * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED} * in case of failure to establish the audio connection. * * Note that this intent will not be sent if {@link BluetoothHeadset#isAudioOn()} is true * before calling this method * * @return false if there was some error such as there is no active headset * @hide * @hide */ */ public boolean connectAudio() { public boolean connectAudio() { Loading @@ -844,11 +862,14 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a disconnection of headset audio. * Initiates a disconnection of HFP SCO audio. * It tears down the SCO channel from remote headset device. * Tear down voice recognition or virtual voice call if any. * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * * @return true if successful false if there was some error such as there is no connected SCO * @return false if audio is not connected, or on error, true otherwise * channel * @hide * @hide */ */ public boolean disconnectAudio() { public boolean disconnectAudio() { Loading @@ -867,22 +888,33 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a SCO channel connection with the headset (if connected). * Initiates a SCO channel connection as a virtual voice call to the current active device * Also initiates a virtual voice call for Handsfree devices as many devices * Active handsfree device will be notified of incoming call and connected call. * do not accept SCO audio without a call. * This API allows the handsfree device to be used for routing non-cellular * call audio. * * * @param device Remote Bluetooth Device * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * @return true if successful, false if there was some error. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}. * * <p> {@link #EXTRA_STATE} will transition from * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED} * in case of failure to establish the audio connection. * * @return true if successful, false if one of the following case applies * - SCO audio is not idle (connecting or connected) * - virtual call has already started * - there is no active device * - a Telecom managed call is going on * - binder is dead or Bluetooth is disabled or other error * @hide * @hide */ */ public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) { @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean startScoUsingVirtualVoiceCall() { if (DBG) log("startScoUsingVirtualVoiceCall()"); if (DBG) log("startScoUsingVirtualVoiceCall()"); final IBluetoothHeadset service = mService; final IBluetoothHeadset service = mService; if (service != null && isEnabled() && isValidDevice(device)) { if (service != null && isEnabled()) { try { try { return service.startScoUsingVirtualVoiceCall(device); return service.startScoUsingVirtualVoiceCall(); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); } } Loading @@ -894,19 +926,24 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Terminates an ongoing SCO connection and the associated virtual * Terminates an ongoing SCO connection and the associated virtual call. * call. * * * @param device Remote Bluetooth Device * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * @return true if successful, false if there was some error. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * @return true if successful, false if one of the following case applies * - virtual voice call is not started or has ended * - binder is dead or Bluetooth is disabled or other error * @hide * @hide */ */ public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) { @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean stopScoUsingVirtualVoiceCall() { if (DBG) log("stopScoUsingVirtualVoiceCall()"); if (DBG) log("stopScoUsingVirtualVoiceCall()"); final IBluetoothHeadset service = mService; final IBluetoothHeadset service = mService; if (service != null && isEnabled() && isValidDevice(device)) { if (service != null && isEnabled()) { try { try { return service.stopScoUsingVirtualVoiceCall(device); return service.stopScoUsingVirtualVoiceCall(); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); } } Loading media/java/android/media/AudioManager.java +6 −8 Original line number Original line Diff line number Diff line Loading @@ -4276,8 +4276,7 @@ public class AudioManager { /** /** * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications. * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications. */ */ private ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> private final ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> mDeviceCallbacks = mDeviceCallbacks = new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>(); new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>(); /** /** Loading Loading @@ -4488,22 +4487,21 @@ public class AudioManager { calcListDeltas(mPreviousPorts, current_ports, GET_DEVICES_ALL); calcListDeltas(mPreviousPorts, current_ports, GET_DEVICES_ALL); AudioDeviceInfo[] removed_devices = AudioDeviceInfo[] removed_devices = calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL); calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL); if (added_devices.length != 0 || removed_devices.length != 0) { if (added_devices.length != 0 || removed_devices.length != 0) { synchronized (mDeviceCallbacks) { synchronized (mDeviceCallbacks) { for (int i = 0; i < mDeviceCallbacks.size(); i++) { for (int i = 0; i < mDeviceCallbacks.size(); i++) { handler = mDeviceCallbacks.valueAt(i).getHandler(); handler = mDeviceCallbacks.valueAt(i).getHandler(); if (handler != null) { if (handler != null) { if (added_devices.length != 0) { handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_ADDED, added_devices)); } if (removed_devices.length != 0) { if (removed_devices.length != 0) { handler.sendMessage(Message.obtain(handler, handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_REMOVED, MSG_DEVICES_DEVICES_REMOVED, removed_devices)); removed_devices)); } } if (added_devices.length != 0) { handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_ADDED, added_devices)); } } } } } } } Loading services/core/java/com/android/server/audio/AudioService.java +251 −174 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/bluetooth/BluetoothHeadset.java +67 −30 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.bluetooth; package android.bluetooth; import android.Manifest; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant; Loading Loading @@ -633,8 +634,9 @@ public final class BluetoothHeadset implements BluetoothProfile { * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @param device Bluetooth headset * @param device Bluetooth headset * @return false if there is no headset connected of if the connected headset doesn't support * @return false if there is no headset connected, or the connected headset doesn't support * voice recognition or on error, true otherwise * voice recognition, or voice recognition is already started, or audio channel is occupied, * or on error, true otherwise */ */ public boolean startVoiceRecognition(BluetoothDevice device) { public boolean startVoiceRecognition(BluetoothDevice device) { if (DBG) log("startVoiceRecognition()"); if (DBG) log("startVoiceRecognition()"); Loading @@ -654,10 +656,15 @@ public final class BluetoothHeadset implements BluetoothProfile { * Stop Bluetooth Voice Recognition mode, and shut down the * Stop Bluetooth Voice Recognition mode, and shut down the * Bluetooth audio path. * Bluetooth audio path. * * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @param device Bluetooth headset * @param device Bluetooth headset * @return false if there is no headset connected or on error, true otherwise * @return false if there is no headset connected, or voice recognition has not started, * or voice recognition has ended on this headset, or on error, true otherwise */ */ public boolean stopVoiceRecognition(BluetoothDevice device) { public boolean stopVoiceRecognition(BluetoothDevice device) { if (DBG) log("stopVoiceRecognition()"); if (DBG) log("stopVoiceRecognition()"); Loading Loading @@ -798,11 +805,12 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Check if Bluetooth SCO audio is connected. * Check if at least one headset's SCO audio is connected or connecting * * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * * @return true if SCO is connected, false otherwise or on error * @return true if at least one device's SCO audio is connected or connecting, false otherwise * or on error * @hide * @hide */ */ public boolean isAudioOn() { public boolean isAudioOn() { Loading @@ -821,11 +829,21 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a connection of headset audio. * Initiates a connection of headset audio to the current active device * It setup SCO channel with remote connected headset device. * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}. * * * @return true if successful false if there was some error such as there is no connected * <p> {@link #EXTRA_STATE} will transition from * headset * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED} * in case of failure to establish the audio connection. * * Note that this intent will not be sent if {@link BluetoothHeadset#isAudioOn()} is true * before calling this method * * @return false if there was some error such as there is no active headset * @hide * @hide */ */ public boolean connectAudio() { public boolean connectAudio() { Loading @@ -844,11 +862,14 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a disconnection of headset audio. * Initiates a disconnection of HFP SCO audio. * It tears down the SCO channel from remote headset device. * Tear down voice recognition or virtual voice call if any. * * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * * @return true if successful false if there was some error such as there is no connected SCO * @return false if audio is not connected, or on error, true otherwise * channel * @hide * @hide */ */ public boolean disconnectAudio() { public boolean disconnectAudio() { Loading @@ -867,22 +888,33 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Initiates a SCO channel connection with the headset (if connected). * Initiates a SCO channel connection as a virtual voice call to the current active device * Also initiates a virtual voice call for Handsfree devices as many devices * Active handsfree device will be notified of incoming call and connected call. * do not accept SCO audio without a call. * This API allows the handsfree device to be used for routing non-cellular * call audio. * * * @param device Remote Bluetooth Device * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * @return true if successful, false if there was some error. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}. * * <p> {@link #EXTRA_STATE} will transition from * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED} * in case of failure to establish the audio connection. * * @return true if successful, false if one of the following case applies * - SCO audio is not idle (connecting or connected) * - virtual call has already started * - there is no active device * - a Telecom managed call is going on * - binder is dead or Bluetooth is disabled or other error * @hide * @hide */ */ public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) { @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean startScoUsingVirtualVoiceCall() { if (DBG) log("startScoUsingVirtualVoiceCall()"); if (DBG) log("startScoUsingVirtualVoiceCall()"); final IBluetoothHeadset service = mService; final IBluetoothHeadset service = mService; if (service != null && isEnabled() && isValidDevice(device)) { if (service != null && isEnabled()) { try { try { return service.startScoUsingVirtualVoiceCall(device); return service.startScoUsingVirtualVoiceCall(); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); } } Loading @@ -894,19 +926,24 @@ public final class BluetoothHeadset implements BluetoothProfile { } } /** /** * Terminates an ongoing SCO connection and the associated virtual * Terminates an ongoing SCO connection and the associated virtual call. * call. * * * @param device Remote Bluetooth Device * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. * @return true if successful, false if there was some error. * If this function returns true, this intent will be broadcasted with * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}. * * @return true if successful, false if one of the following case applies * - virtual voice call is not started or has ended * - binder is dead or Bluetooth is disabled or other error * @hide * @hide */ */ public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) { @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean stopScoUsingVirtualVoiceCall() { if (DBG) log("stopScoUsingVirtualVoiceCall()"); if (DBG) log("stopScoUsingVirtualVoiceCall()"); final IBluetoothHeadset service = mService; final IBluetoothHeadset service = mService; if (service != null && isEnabled() && isValidDevice(device)) { if (service != null && isEnabled()) { try { try { return service.stopScoUsingVirtualVoiceCall(device); return service.stopScoUsingVirtualVoiceCall(); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); } } Loading
media/java/android/media/AudioManager.java +6 −8 Original line number Original line Diff line number Diff line Loading @@ -4276,8 +4276,7 @@ public class AudioManager { /** /** * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications. * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications. */ */ private ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> private final ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> mDeviceCallbacks = mDeviceCallbacks = new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>(); new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>(); /** /** Loading Loading @@ -4488,22 +4487,21 @@ public class AudioManager { calcListDeltas(mPreviousPorts, current_ports, GET_DEVICES_ALL); calcListDeltas(mPreviousPorts, current_ports, GET_DEVICES_ALL); AudioDeviceInfo[] removed_devices = AudioDeviceInfo[] removed_devices = calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL); calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL); if (added_devices.length != 0 || removed_devices.length != 0) { if (added_devices.length != 0 || removed_devices.length != 0) { synchronized (mDeviceCallbacks) { synchronized (mDeviceCallbacks) { for (int i = 0; i < mDeviceCallbacks.size(); i++) { for (int i = 0; i < mDeviceCallbacks.size(); i++) { handler = mDeviceCallbacks.valueAt(i).getHandler(); handler = mDeviceCallbacks.valueAt(i).getHandler(); if (handler != null) { if (handler != null) { if (added_devices.length != 0) { handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_ADDED, added_devices)); } if (removed_devices.length != 0) { if (removed_devices.length != 0) { handler.sendMessage(Message.obtain(handler, handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_REMOVED, MSG_DEVICES_DEVICES_REMOVED, removed_devices)); removed_devices)); } } if (added_devices.length != 0) { handler.sendMessage(Message.obtain(handler, MSG_DEVICES_DEVICES_ADDED, added_devices)); } } } } } } } Loading
services/core/java/com/android/server/audio/AudioService.java +251 −174 File changed.Preview size limit exceeded, changes collapsed. Show changes