Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +76 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothProfile; Loading Loading @@ -1694,6 +1696,52 @@ public class LeAudioService extends ProfileService { } } /** * Gets the current codec status (configuration and capability). * * @param device the remote Bluetooth device. * @return the current codec status * @hide */ public BluetoothLeAudioCodecStatus getCodecStatus(BluetoothDevice device) { if (DBG) { Log.d(TAG, "getCodecStatus(" + device + ")"); } return null; } /** * Sets the codec configuration preference. * * @param device the remote Bluetooth device. * @param codecConfig the codec configuration preference * @hide */ public void setCodecConfigPreference(BluetoothDevice device, BluetoothLeAudioCodecConfig codecConfig) { if (DBG) { Log.d(TAG, "setCodecConfigPreference(" + device + "): " + Objects.toString(codecConfig)); } if (device == null) { Log.e(TAG, "setCodecConfigPreference: Invalid device"); return; } if (codecConfig == null) { Log.e(TAG, "setCodecConfigPreference: Codec config can't be null"); return; } BluetoothLeAudioCodecStatus codecStatus = getCodecStatus(device); if (codecStatus == null) { Log.e(TAG, "setCodecConfigPreference: Codec status is null"); return; } // TODO: pass the information to bt stack } /** * Binder object: must be a static class or memory leak may occur */ Loading Loading @@ -2057,6 +2105,34 @@ public class LeAudioService extends ProfileService { receiver.propagateException(e); } } @Override public void getCodecStatus(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { LeAudioService service = getService(source); BluetoothLeAudioCodecStatus codecStatus = null; if (service != null) { enforceBluetoothPrivilegedPermission(service); codecStatus = service.getCodecStatus(device); } receiver.send(codecStatus); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void setCodecConfigPreference(BluetoothDevice device, BluetoothLeAudioCodecConfig codecConfig, AttributionSource source) { LeAudioService service = getService(source); if (service == null) { return; } enforceBluetoothPrivilegedPermission(service); service.setCodecConfigPreference(device, codecConfig); } } @Override Loading framework/java/android/bluetooth/BluetoothLeAudio.java +26 −3 Original line number Diff line number Diff line Loading @@ -966,9 +966,22 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { Log.d(TAG, "getCodecStatus(" + device + ")"); } final IBluetoothLeAudio service = getService(); final BluetoothLeAudioCodecStatus defaultValue = null; // TODO: Add the implementation to get codec status if (service == null) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (mAdapter.isEnabled() && isValidDevice(device)) { try { final SynchronousResultReceiver<BluetoothLeAudioCodecStatus> recv = new SynchronousResultReceiver(); service.getCodecStatus(device, mAttributionSource, recv); return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException | TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } return defaultValue; } Loading @@ -994,8 +1007,18 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { throw new IllegalArgumentException("codecConfig cannot be null"); } // TODO: Add the implementation to set config preference return; final IBluetoothLeAudio service = getService(); if (service == null) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (mAdapter.isEnabled() && isValidDevice(device)) { try { service.setCodecConfigPreference(device, codecConfig, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } } } framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java +16 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,16 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { * @return {@code true} if the codec config matches, {@code false} otherwise */ public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) { // TODO: Add the implementation to check the config is selectable if (codecConfig == null) { return false; } for (BluetoothLeAudioCodecConfig selectableConfig : mCodecsSelectableCapabilities) { if (codecConfig.equals(selectableConfig)) { return true; } } return false; } /** * Returns a hash based on the codec config and local capabilities. Loading Loading @@ -171,6 +178,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the current codec configuration. * * @return The current codec config. */ public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() { return mCodecConfig; Loading @@ -178,6 +187,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the codecs local capabilities. * * @return The list of codec config that supported by the local system. */ public @NonNull List<BluetoothLeAudioCodecConfig> getCodecLocalCapabilities() { return (mCodecsLocalCapabilities == null) Loading @@ -186,6 +197,9 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the codecs selectable capabilities. * * @return The list of codec config that supported by both of the local system and * remote devices. */ public @NonNull List<BluetoothLeAudioCodecConfig> getCodecSelectableCapabilities() { return (mCodecsSelectableCapabilities == null) Loading system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.bluetooth; parcelable BluetoothLeAudioCodecConfig; system/binder/android/bluetooth/IBluetoothLeAudio.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.bluetooth; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.IBluetoothLeBroadcastCallback; import android.content.AttributionSource; Loading Loading @@ -51,6 +52,10 @@ oneway interface IBluetoothLeAudio { void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getConnectedGroupLeadDevice(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getCodecStatus(in BluetoothDevice device, in AttributionSource source, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setCodecConfigPreference(in BluetoothDevice device, in BluetoothLeAudioCodecConfig codecConfig, in AttributionSource source); /* Same value as bluetooth::groups::kGroupUnknown */ const int LE_AUDIO_GROUP_ID_INVALID = -1; Loading Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +76 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothProfile; Loading Loading @@ -1694,6 +1696,52 @@ public class LeAudioService extends ProfileService { } } /** * Gets the current codec status (configuration and capability). * * @param device the remote Bluetooth device. * @return the current codec status * @hide */ public BluetoothLeAudioCodecStatus getCodecStatus(BluetoothDevice device) { if (DBG) { Log.d(TAG, "getCodecStatus(" + device + ")"); } return null; } /** * Sets the codec configuration preference. * * @param device the remote Bluetooth device. * @param codecConfig the codec configuration preference * @hide */ public void setCodecConfigPreference(BluetoothDevice device, BluetoothLeAudioCodecConfig codecConfig) { if (DBG) { Log.d(TAG, "setCodecConfigPreference(" + device + "): " + Objects.toString(codecConfig)); } if (device == null) { Log.e(TAG, "setCodecConfigPreference: Invalid device"); return; } if (codecConfig == null) { Log.e(TAG, "setCodecConfigPreference: Codec config can't be null"); return; } BluetoothLeAudioCodecStatus codecStatus = getCodecStatus(device); if (codecStatus == null) { Log.e(TAG, "setCodecConfigPreference: Codec status is null"); return; } // TODO: pass the information to bt stack } /** * Binder object: must be a static class or memory leak may occur */ Loading Loading @@ -2057,6 +2105,34 @@ public class LeAudioService extends ProfileService { receiver.propagateException(e); } } @Override public void getCodecStatus(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { LeAudioService service = getService(source); BluetoothLeAudioCodecStatus codecStatus = null; if (service != null) { enforceBluetoothPrivilegedPermission(service); codecStatus = service.getCodecStatus(device); } receiver.send(codecStatus); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void setCodecConfigPreference(BluetoothDevice device, BluetoothLeAudioCodecConfig codecConfig, AttributionSource source) { LeAudioService service = getService(source); if (service == null) { return; } enforceBluetoothPrivilegedPermission(service); service.setCodecConfigPreference(device, codecConfig); } } @Override Loading
framework/java/android/bluetooth/BluetoothLeAudio.java +26 −3 Original line number Diff line number Diff line Loading @@ -966,9 +966,22 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { Log.d(TAG, "getCodecStatus(" + device + ")"); } final IBluetoothLeAudio service = getService(); final BluetoothLeAudioCodecStatus defaultValue = null; // TODO: Add the implementation to get codec status if (service == null) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (mAdapter.isEnabled() && isValidDevice(device)) { try { final SynchronousResultReceiver<BluetoothLeAudioCodecStatus> recv = new SynchronousResultReceiver(); service.getCodecStatus(device, mAttributionSource, recv); return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException | TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } return defaultValue; } Loading @@ -994,8 +1007,18 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { throw new IllegalArgumentException("codecConfig cannot be null"); } // TODO: Add the implementation to set config preference return; final IBluetoothLeAudio service = getService(); if (service == null) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (mAdapter.isEnabled() && isValidDevice(device)) { try { service.setCodecConfigPreference(device, codecConfig, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } } }
framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java +16 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,16 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { * @return {@code true} if the codec config matches, {@code false} otherwise */ public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) { // TODO: Add the implementation to check the config is selectable if (codecConfig == null) { return false; } for (BluetoothLeAudioCodecConfig selectableConfig : mCodecsSelectableCapabilities) { if (codecConfig.equals(selectableConfig)) { return true; } } return false; } /** * Returns a hash based on the codec config and local capabilities. Loading Loading @@ -171,6 +178,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the current codec configuration. * * @return The current codec config. */ public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() { return mCodecConfig; Loading @@ -178,6 +187,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the codecs local capabilities. * * @return The list of codec config that supported by the local system. */ public @NonNull List<BluetoothLeAudioCodecConfig> getCodecLocalCapabilities() { return (mCodecsLocalCapabilities == null) Loading @@ -186,6 +197,9 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable { /** * Returns the codecs selectable capabilities. * * @return The list of codec config that supported by both of the local system and * remote devices. */ public @NonNull List<BluetoothLeAudioCodecConfig> getCodecSelectableCapabilities() { return (mCodecsSelectableCapabilities == null) Loading
system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.bluetooth; parcelable BluetoothLeAudioCodecConfig;
system/binder/android/bluetooth/IBluetoothLeAudio.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.bluetooth; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.IBluetoothLeBroadcastCallback; import android.content.AttributionSource; Loading Loading @@ -51,6 +52,10 @@ oneway interface IBluetoothLeAudio { void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getConnectedGroupLeadDevice(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getCodecStatus(in BluetoothDevice device, in AttributionSource source, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setCodecConfigPreference(in BluetoothDevice device, in BluetoothLeAudioCodecConfig codecConfig, in AttributionSource source); /* Same value as bluetooth::groups::kGroupUnknown */ const int LE_AUDIO_GROUP_ID_INVALID = -1; Loading