Loading android/app/src/com/android/bluetooth/a2dp/A2dpService.java +104 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,17 @@ package com.android.bluetooth.a2dp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothA2dp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.ParcelUuid; import android.provider.Settings; import android.util.Log; Loading @@ -42,6 +47,46 @@ public class A2dpService extends ProfileService { private A2dpStateMachine mStateMachine; private Avrcp mAvrcp; private BroadcastReceiver mConnectionStateChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { return; } int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (state != BluetoothProfile.STATE_CONNECTED || device == null) { return; } // Each time a device connects, we want to re-check if it supports optional // codecs (perhaps it's had a firmware update, etc.) and save that state if // it differs from what we had saved before. int previousSupport = getSupportsOptionalCodecs(device); boolean supportsOptional = false; for (BluetoothCodecConfig config : mStateMachine.getCodecStatus().getCodecsSelectableCapabilities()) { if (!config.isMandatoryCodec()) { supportsOptional = true; break; } } if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN || supportsOptional != (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) { setSupportsOptionalCodecs(device, supportsOptional); } if (supportsOptional) { int enabled = getOptionalCodecsEnabled(device); if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { enableOptionalCodecs(); } else if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED) { disableOptionalCodecs(); } } } }; private static A2dpService sAd2dpService; static final ParcelUuid[] A2DP_SOURCE_UUID = { BluetoothUuid.AudioSource Loading @@ -63,6 +108,9 @@ public class A2dpService extends ProfileService { mAvrcp = Avrcp.make(this); mStateMachine = A2dpStateMachine.make(this, this); setA2dpService(this); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); registerReceiver(mConnectionStateChangedReceiver, filter); return true; } Loading @@ -77,6 +125,7 @@ public class A2dpService extends ProfileService { } protected boolean cleanup() { unregisterReceiver(mConnectionStateChangedReceiver); if (mStateMachine!= null) { mStateMachine.cleanup(); } Loading Loading @@ -249,6 +298,43 @@ public class A2dpService extends ProfileService { mStateMachine.disableOptionalCodecs(); } public int getSupportsOptionalCodecs(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int support = Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); return support; } public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; Settings.Global.putInt(getContentResolver(), Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), value); } public int getOptionalCodecsEnabled(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); return Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); } public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { Log.w(TAG, "Unexpected value passed to setOptionalCodecsEnabled:" + value); return; } Settings.Global.putInt(getContentResolver(), Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), value); } //Binder object: Must be static class or memory leak may occur private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder { Loading Loading @@ -364,6 +450,24 @@ public class A2dpService extends ProfileService { if (service == null) return; service.disableOptionalCodecs(); } public int supportsOptionalCodecs(BluetoothDevice device) { A2dpService service = getService(); if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN; return service.getSupportsOptionalCodecs(device); } public int getOptionalCodecsEnabled(BluetoothDevice device) { A2dpService service = getService(); if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; return service.getOptionalCodecsEnabled(device); } public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { A2dpService service = getService(); if (service == null) return; service.setOptionalCodecsEnabled(device, value); } }; @Override Loading Loading
android/app/src/com/android/bluetooth/a2dp/A2dpService.java +104 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,17 @@ package com.android.bluetooth.a2dp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothA2dp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.ParcelUuid; import android.provider.Settings; import android.util.Log; Loading @@ -42,6 +47,46 @@ public class A2dpService extends ProfileService { private A2dpStateMachine mStateMachine; private Avrcp mAvrcp; private BroadcastReceiver mConnectionStateChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { return; } int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (state != BluetoothProfile.STATE_CONNECTED || device == null) { return; } // Each time a device connects, we want to re-check if it supports optional // codecs (perhaps it's had a firmware update, etc.) and save that state if // it differs from what we had saved before. int previousSupport = getSupportsOptionalCodecs(device); boolean supportsOptional = false; for (BluetoothCodecConfig config : mStateMachine.getCodecStatus().getCodecsSelectableCapabilities()) { if (!config.isMandatoryCodec()) { supportsOptional = true; break; } } if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN || supportsOptional != (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) { setSupportsOptionalCodecs(device, supportsOptional); } if (supportsOptional) { int enabled = getOptionalCodecsEnabled(device); if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { enableOptionalCodecs(); } else if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED) { disableOptionalCodecs(); } } } }; private static A2dpService sAd2dpService; static final ParcelUuid[] A2DP_SOURCE_UUID = { BluetoothUuid.AudioSource Loading @@ -63,6 +108,9 @@ public class A2dpService extends ProfileService { mAvrcp = Avrcp.make(this); mStateMachine = A2dpStateMachine.make(this, this); setA2dpService(this); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); registerReceiver(mConnectionStateChangedReceiver, filter); return true; } Loading @@ -77,6 +125,7 @@ public class A2dpService extends ProfileService { } protected boolean cleanup() { unregisterReceiver(mConnectionStateChangedReceiver); if (mStateMachine!= null) { mStateMachine.cleanup(); } Loading Loading @@ -249,6 +298,43 @@ public class A2dpService extends ProfileService { mStateMachine.disableOptionalCodecs(); } public int getSupportsOptionalCodecs(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int support = Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); return support; } public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; Settings.Global.putInt(getContentResolver(), Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), value); } public int getOptionalCodecsEnabled(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); return Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); } public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { Log.w(TAG, "Unexpected value passed to setOptionalCodecsEnabled:" + value); return; } Settings.Global.putInt(getContentResolver(), Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), value); } //Binder object: Must be static class or memory leak may occur private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder { Loading Loading @@ -364,6 +450,24 @@ public class A2dpService extends ProfileService { if (service == null) return; service.disableOptionalCodecs(); } public int supportsOptionalCodecs(BluetoothDevice device) { A2dpService service = getService(); if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN; return service.getSupportsOptionalCodecs(device); } public int getOptionalCodecsEnabled(BluetoothDevice device) { A2dpService service = getService(); if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; return service.getOptionalCodecsEnabled(device); } public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { A2dpService service = getService(); if (service == null) return; service.setOptionalCodecsEnabled(device, value); } }; @Override Loading