Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +239 −149 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile.ServiceListener; import android.bluetooth.BluetoothStatusCodes; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; Loading @@ -42,7 +41,6 @@ import android.os.Looper; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import androidx.annotation.RequiresApi; Loading @@ -53,15 +51,17 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; /** * LocalBluetoothLeBroadcast provides an interface between the Settings app * and the functionality of the local {@link BluetoothLeBroadcast}. * Use the {@link BluetoothLeBroadcast.Callback} to get the result callback. * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of * the local {@link BluetoothLeBroadcast}. Use the {@link BluetoothLeBroadcast.Callback} to get the * result callback. */ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { private static final String TAG = "LocalBluetoothLeBroadcast"; Loading @@ -74,7 +74,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { // Order of this profile in device profiles list private static final int ORDINAL = 1; private static final int UNKNOWN_VALUE_PLACEHOLDER = -1; private static final Uri[] SETTINGS_URIS = new Uri[]{ private static final Uri[] SETTINGS_URIS = new Uri[] { Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO), Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE), Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME), Loading @@ -95,14 +96,19 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { private Executor mExecutor; private ContentResolver mContentResolver; private ContentObserver mSettingsObserver; // Cached broadcast callbacks being register before service is connected. private Map<BluetoothLeBroadcast.Callback, Executor> mCachedBroadcastCallbackExecutorMap = new ConcurrentHashMap<>(); private final ServiceListener mServiceListener = new ServiceListener() { private final ServiceListener mServiceListener = new ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if (DEBUG) { Log.d(TAG, "Bluetooth service connected: " + profile); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && !mIsBroadcastProfileReady) { if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && !mIsBroadcastProfileReady) { mServiceBroadcast = (BluetoothLeBroadcast) proxy; mIsBroadcastProfileReady = true; registerServiceCallBack(mExecutor, mBroadcastCallback); Loading @@ -111,6 +117,16 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { updateBroadcastInfoFromBroadcastMetadata(metadata.get(0)); } registerContentObserver(); if (DEBUG) { Log.d( TAG, "onServiceConnected: register " + "mCachedBroadcastCallbackExecutorMap = " + mCachedBroadcastCallbackExecutorMap); } mCachedBroadcastCallbackExecutorMap.forEach( (callback, executor) -> registerServiceCallBack(executor, callback)); } else if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) && !mIsBroadcastAssistantProfileReady) { mIsBroadcastAssistantProfileReady = true; Loading @@ -122,11 +138,13 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onServiceDisconnected(int profile) { if (DEBUG) { Log.d(TAG, "Bluetooth service disconnected"); Log.d(TAG, "Bluetooth service disconnected: " + profile); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && mIsBroadcastProfileReady) { if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && mIsBroadcastProfileReady) { mIsBroadcastProfileReady = false; unregisterServiceCallBack(mBroadcastCallback); mCachedBroadcastCallbackExecutorMap.clear(); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) && mIsBroadcastAssistantProfileReady) { Loading @@ -145,8 +163,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastStarted(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastStarted(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastStarted(), reason = " + reason + ", broadcastId = " + broadcastId); } setLatestBroadcastId(broadcastId); Loading @@ -161,8 +182,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } @Override public void onBroadcastMetadataChanged(int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) { public void onBroadcastMetadataChanged( int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) { if (DEBUG) { Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId); } Loading @@ -172,8 +193,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastStopped(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastStopped(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastStopped(), reason = " + reason + ", broadcastId = " + broadcastId); } Loading @@ -191,8 +215,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastUpdated(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " + broadcastId); } setLatestBroadcastId(broadcastId); Loading @@ -202,26 +229,28 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastUpdateFailed(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = " + broadcastId); } } @Override public void onPlaybackStarted(int reason, int broadcastId) { } public void onPlaybackStarted(int reason, int broadcastId) {} @Override public void onPlaybackStopped(int reason, int broadcastId) { } public void onPlaybackStopped(int reason, int broadcastId) {} }; private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new BluetoothLeBroadcastAssistant.Callback() { @Override public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceAdded( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSearchStarted(int reason) {} Loading @@ -238,38 +267,65 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {} @Override public void onSourceAddFailed(@NonNull BluetoothDevice sink, @NonNull BluetoothLeBroadcastMetadata source, int reason) {} public void onSourceAddFailed( @NonNull BluetoothDevice sink, @NonNull BluetoothLeBroadcastMetadata source, int reason) {} @Override public void onSourceModified(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceModified( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSourceModifyFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceModifyFailed( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSourceRemoved(@NonNull BluetoothDevice sink, int sourceId, int reason) { public void onSourceRemoved( @NonNull BluetoothDevice sink, int sourceId, int reason) { if (DEBUG) { Log.d(TAG, "onSourceRemoved(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); Log.d( TAG, "onSourceRemoved(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); } } @Override public void onSourceRemoveFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) { public void onSourceRemoveFailed( @NonNull BluetoothDevice sink, int sourceId, int reason) { if (DEBUG) { Log.d(TAG, "onSourceRemoveFailed(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); Log.d( TAG, "onSourceRemoveFailed(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); } } @Override public void onReceiveStateChanged(@NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) {} public void onReceiveStateChanged( @NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) { if (DEBUG) { Log.d( TAG, "onReceiveStateChanged(), sink = " + sink + ", sourceId = " + sourceId + ", state = " + state); } } }; private class BroadcastSettingsObserver extends ContentObserver { Loading @@ -296,8 +352,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { BluetoothAdapter.getDefaultAdapter() .getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); .getProfileProxy( context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); } /** Loading @@ -312,11 +368,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } String programInfo = getProgramInfo(); if (DEBUG) { Log.d(TAG, "startBroadcast: language = " + language + " ,programInfo = " + programInfo); Log.d(TAG, "startBroadcast: language = " + language + " ,programInfo = " + programInfo); } buildContentMetadata(language, programInfo); mServiceBroadcast.startBroadcast(mBluetoothLeAudioContentMetadata, mServiceBroadcast.startBroadcast( mBluetoothLeAudioContentMetadata, (mBroadcastCode != null && mBroadcastCode.length > 0) ? mBroadcastCode : null); } Loading Loading @@ -344,8 +400,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, programInfo); Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, programInfo); } } Loading @@ -372,7 +430,9 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE, Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE, new String(broadcastCode, StandardCharsets.UTF_8)); } } Loading Loading @@ -401,8 +461,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, mAppSourceName); Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, mAppSourceName); } } Loading @@ -427,7 +489,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { if (mBluetoothLeBroadcastMetadata == null) { final List<BluetoothLeBroadcastMetadata> metadataList = mServiceBroadcast.getAllBroadcastMetadata(); mBluetoothLeBroadcastMetadata = metadataList.stream() mBluetoothLeBroadcastMetadata = metadataList.stream() .filter(i -> i.getBroadcastId() == mBroadcastId) .findFirst() .orElse(null); Loading @@ -440,21 +503,26 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "updateBroadcastInfoFromContentProvider: mContentResolver is null"); return; } String programInfo = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO); String programInfo = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO); if (programInfo == null) { programInfo = getDefaultValueOfProgramInfo(); } setProgramInfo(programInfo, /* updateContentResolver= */ false); String prefBroadcastCode = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE); byte[] broadcastCode = (prefBroadcastCode == null) ? getDefaultValueOfBroadcastCode() String prefBroadcastCode = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE); byte[] broadcastCode = (prefBroadcastCode == null) ? getDefaultValueOfBroadcastCode() : prefBroadcastCode.getBytes(StandardCharsets.UTF_8); setBroadcastCode(broadcastCode, /* updateContentResolver= */ false); String appSourceName = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME); String appSourceName = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME); setAppSourceName(appSourceName, /* updateContentResolver= */ false); } Loading @@ -478,8 +546,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } /** * Stop the latest LE Broadcast. If the system stopped the LE Broadcast, then the system * calls the corresponding callback {@link BluetoothLeBroadcast.Callback}. * Stop the latest LE Broadcast. If the system stopped the LE Broadcast, then the system calls * the corresponding callback {@link BluetoothLeBroadcast.Callback}. */ public void stopLatestBroadcast() { stopBroadcast(mBroadcastId); Loading Loading @@ -511,7 +579,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } String programInfo = getProgramInfo(); if (DEBUG) { Log.d(TAG, Log.d( TAG, "updateBroadcast: language = " + language + " ,programInfo = " + programInfo); } mNewAppSourceName = appSourceName; Loading @@ -519,50 +588,79 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { mServiceBroadcast.updateBroadcast(mBroadcastId, mBluetoothLeAudioContentMetadata); } public void registerServiceCallBack(@NonNull @CallbackExecutor Executor executor, /** * Register Broadcast Callbacks to track its state and receivers * * @param executor Executor object for callback * @param callback Callback object to be registered */ public void registerServiceCallBack( @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothLeBroadcast.Callback callback) { if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); Log.d(TAG, "registerServiceCallBack failed, the BluetoothLeBroadcast is null."); mCachedBroadcastCallbackExecutorMap.putIfAbsent(callback, executor); return; } try { mServiceBroadcast.registerCallback(executor, callback); } catch (IllegalArgumentException e) { Log.w(TAG, "registerServiceCallBack failed. " + e.getMessage()); } } /** * Register Broadcast Assistant Callbacks to track it's state and receivers * Register Broadcast Assistant Callbacks to track its state and receivers * * @param executor Executor object for callback * @param callback Callback object to be registered */ public void registerBroadcastAssistantCallback(@NonNull @CallbackExecutor Executor executor, private void registerBroadcastAssistantCallback( @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothLeBroadcastAssistant.Callback callback) { if (mServiceBroadcastAssistant == null) { Log.d(TAG, "The BluetoothLeBroadcastAssisntant is null."); Log.d( TAG, "registerBroadcastAssistantCallback failed, " + "the BluetoothLeBroadcastAssistant is null."); return; } mServiceBroadcastAssistant.registerCallback(executor, callback); } /** * Unregister previously registered Broadcast Callbacks * * @param callback Callback object to be unregistered */ public void unregisterServiceCallBack(@NonNull BluetoothLeBroadcast.Callback callback) { mCachedBroadcastCallbackExecutorMap.remove(callback); if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); Log.d(TAG, "unregisterServiceCallBack failed, the BluetoothLeBroadcast is null."); return; } try { mServiceBroadcast.unregisterCallback(callback); } catch (IllegalArgumentException e) { Log.w(TAG, "unregisterServiceCallBack failed. " + e.getMessage()); } } /** * Unregister previousely registered Broadcast Assistant Callbacks * Unregister previously registered Broadcast Assistant Callbacks * * @param callback Callback object to be unregistered */ public void unregisterBroadcastAssistantCallback( private void unregisterBroadcastAssistantCallback( @NonNull BluetoothLeBroadcastAssistant.Callback callback) { if (mServiceBroadcastAssistant == null) { Log.d(TAG, "The BluetoothLeBroadcastAssisntant is null."); Log.d( TAG, "unregisterBroadcastAssistantCallback, " + "the BluetoothLeBroadcastAssistant is null."); return; } Loading @@ -570,8 +668,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } private void buildContentMetadata(String language, String programInfo) { mBluetoothLeAudioContentMetadata = mBuilder.setLanguage(language).setProgramInfo( programInfo).build(); mBluetoothLeAudioContentMetadata = mBuilder.setLanguage(language).setProgramInfo(programInfo).build(); } public LocalBluetoothLeBroadcastMetadata getLocalBluetoothLeBroadcastMetaData() { Loading Loading @@ -600,9 +698,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return true; } /** * Not supported since LE Audio Broadcasts do not establish a connection. */ /** Not supported since LE Audio Broadcasts do not establish a connection. */ public int getConnectionStatus(BluetoothDevice device) { if (mServiceBroadcast == null) { return BluetoothProfile.STATE_DISCONNECTED; Loading @@ -611,9 +707,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return mServiceBroadcast.getConnectionState(device); } /** * Not supported since LE Audio Broadcasts do not establish a connection. */ /** Not supported since LE Audio Broadcasts do not establish a connection. */ public List<BluetoothDevice> getConnectedDevices() { if (mServiceBroadcast == null) { return new ArrayList<BluetoothDevice>(0); Loading @@ -622,8 +716,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return mServiceBroadcast.getConnectedDevices(); } public @NonNull List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata() { /** Get all broadcast metadata. */ public @NonNull List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata() { if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); return Collections.emptyList(); Loading @@ -640,16 +734,14 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return !mServiceBroadcast.getAllBroadcastMetadata().isEmpty(); } /** * Service does not provide method to get/set policy. */ /** Service does not provide method to get/set policy. */ public int getConnectionPolicy(BluetoothDevice device) { return CONNECTION_POLICY_FORBIDDEN; } /** * Service does not provide "setEnabled" method. Please use {@link #startBroadcast}, * {@link #stopBroadcast()} or {@link #updateBroadcast(String, String)} * Service does not provide "setEnabled" method. Please use {@link #startBroadcast}, {@link * #stopBroadcast()} or {@link #updateBroadcast(String, String)} */ public boolean setEnabled(BluetoothDevice device, boolean enabled) { return false; Loading Loading @@ -683,9 +775,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } if (mServiceBroadcast != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy( BluetoothProfile.LE_AUDIO_BROADCAST, mServiceBroadcast); BluetoothAdapter.getDefaultAdapter() .closeProfileProxy(BluetoothProfile.LE_AUDIO_BROADCAST, mServiceBroadcast); mServiceBroadcast = null; } catch (Throwable t) { Log.w(TAG, "Error cleaning up LeAudio proxy", t); Loading Loading @@ -752,5 +843,4 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } } } } packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java +148 −83 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +239 −149 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile.ServiceListener; import android.bluetooth.BluetoothStatusCodes; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; Loading @@ -42,7 +41,6 @@ import android.os.Looper; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import androidx.annotation.RequiresApi; Loading @@ -53,15 +51,17 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; /** * LocalBluetoothLeBroadcast provides an interface between the Settings app * and the functionality of the local {@link BluetoothLeBroadcast}. * Use the {@link BluetoothLeBroadcast.Callback} to get the result callback. * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of * the local {@link BluetoothLeBroadcast}. Use the {@link BluetoothLeBroadcast.Callback} to get the * result callback. */ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { private static final String TAG = "LocalBluetoothLeBroadcast"; Loading @@ -74,7 +74,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { // Order of this profile in device profiles list private static final int ORDINAL = 1; private static final int UNKNOWN_VALUE_PLACEHOLDER = -1; private static final Uri[] SETTINGS_URIS = new Uri[]{ private static final Uri[] SETTINGS_URIS = new Uri[] { Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO), Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE), Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME), Loading @@ -95,14 +96,19 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { private Executor mExecutor; private ContentResolver mContentResolver; private ContentObserver mSettingsObserver; // Cached broadcast callbacks being register before service is connected. private Map<BluetoothLeBroadcast.Callback, Executor> mCachedBroadcastCallbackExecutorMap = new ConcurrentHashMap<>(); private final ServiceListener mServiceListener = new ServiceListener() { private final ServiceListener mServiceListener = new ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if (DEBUG) { Log.d(TAG, "Bluetooth service connected: " + profile); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && !mIsBroadcastProfileReady) { if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && !mIsBroadcastProfileReady) { mServiceBroadcast = (BluetoothLeBroadcast) proxy; mIsBroadcastProfileReady = true; registerServiceCallBack(mExecutor, mBroadcastCallback); Loading @@ -111,6 +117,16 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { updateBroadcastInfoFromBroadcastMetadata(metadata.get(0)); } registerContentObserver(); if (DEBUG) { Log.d( TAG, "onServiceConnected: register " + "mCachedBroadcastCallbackExecutorMap = " + mCachedBroadcastCallbackExecutorMap); } mCachedBroadcastCallbackExecutorMap.forEach( (callback, executor) -> registerServiceCallBack(executor, callback)); } else if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) && !mIsBroadcastAssistantProfileReady) { mIsBroadcastAssistantProfileReady = true; Loading @@ -122,11 +138,13 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onServiceDisconnected(int profile) { if (DEBUG) { Log.d(TAG, "Bluetooth service disconnected"); Log.d(TAG, "Bluetooth service disconnected: " + profile); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && mIsBroadcastProfileReady) { if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST) && mIsBroadcastProfileReady) { mIsBroadcastProfileReady = false; unregisterServiceCallBack(mBroadcastCallback); mCachedBroadcastCallbackExecutorMap.clear(); } if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) && mIsBroadcastAssistantProfileReady) { Loading @@ -145,8 +163,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastStarted(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastStarted(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastStarted(), reason = " + reason + ", broadcastId = " + broadcastId); } setLatestBroadcastId(broadcastId); Loading @@ -161,8 +182,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } @Override public void onBroadcastMetadataChanged(int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) { public void onBroadcastMetadataChanged( int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) { if (DEBUG) { Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId); } Loading @@ -172,8 +193,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastStopped(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastStopped(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastStopped(), reason = " + reason + ", broadcastId = " + broadcastId); } Loading @@ -191,8 +215,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastUpdated(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " + broadcastId); } setLatestBroadcastId(broadcastId); Loading @@ -202,26 +229,28 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @Override public void onBroadcastUpdateFailed(int reason, int broadcastId) { if (DEBUG) { Log.d(TAG, "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = " Log.d( TAG, "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = " + broadcastId); } } @Override public void onPlaybackStarted(int reason, int broadcastId) { } public void onPlaybackStarted(int reason, int broadcastId) {} @Override public void onPlaybackStopped(int reason, int broadcastId) { } public void onPlaybackStopped(int reason, int broadcastId) {} }; private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new BluetoothLeBroadcastAssistant.Callback() { @Override public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceAdded( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSearchStarted(int reason) {} Loading @@ -238,38 +267,65 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {} @Override public void onSourceAddFailed(@NonNull BluetoothDevice sink, @NonNull BluetoothLeBroadcastMetadata source, int reason) {} public void onSourceAddFailed( @NonNull BluetoothDevice sink, @NonNull BluetoothLeBroadcastMetadata source, int reason) {} @Override public void onSourceModified(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceModified( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSourceModifyFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) {} public void onSourceModifyFailed( @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSourceRemoved(@NonNull BluetoothDevice sink, int sourceId, int reason) { public void onSourceRemoved( @NonNull BluetoothDevice sink, int sourceId, int reason) { if (DEBUG) { Log.d(TAG, "onSourceRemoved(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); Log.d( TAG, "onSourceRemoved(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); } } @Override public void onSourceRemoveFailed(@NonNull BluetoothDevice sink, int sourceId, int reason) { public void onSourceRemoveFailed( @NonNull BluetoothDevice sink, int sourceId, int reason) { if (DEBUG) { Log.d(TAG, "onSourceRemoveFailed(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); Log.d( TAG, "onSourceRemoveFailed(), sink = " + sink + ", reason = " + reason + ", sourceId = " + sourceId); } } @Override public void onReceiveStateChanged(@NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) {} public void onReceiveStateChanged( @NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) { if (DEBUG) { Log.d( TAG, "onReceiveStateChanged(), sink = " + sink + ", sourceId = " + sourceId + ", state = " + state); } } }; private class BroadcastSettingsObserver extends ContentObserver { Loading @@ -296,8 +352,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { BluetoothAdapter.getDefaultAdapter() .getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); .getProfileProxy( context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); } /** Loading @@ -312,11 +368,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } String programInfo = getProgramInfo(); if (DEBUG) { Log.d(TAG, "startBroadcast: language = " + language + " ,programInfo = " + programInfo); Log.d(TAG, "startBroadcast: language = " + language + " ,programInfo = " + programInfo); } buildContentMetadata(language, programInfo); mServiceBroadcast.startBroadcast(mBluetoothLeAudioContentMetadata, mServiceBroadcast.startBroadcast( mBluetoothLeAudioContentMetadata, (mBroadcastCode != null && mBroadcastCode.length > 0) ? mBroadcastCode : null); } Loading Loading @@ -344,8 +400,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, programInfo); Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, programInfo); } } Loading @@ -372,7 +430,9 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE, Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE, new String(broadcastCode, StandardCharsets.UTF_8)); } } Loading Loading @@ -401,8 +461,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "mContentResolver is null"); return; } Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, mAppSourceName); Settings.Secure.putString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, mAppSourceName); } } Loading @@ -427,7 +489,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { if (mBluetoothLeBroadcastMetadata == null) { final List<BluetoothLeBroadcastMetadata> metadataList = mServiceBroadcast.getAllBroadcastMetadata(); mBluetoothLeBroadcastMetadata = metadataList.stream() mBluetoothLeBroadcastMetadata = metadataList.stream() .filter(i -> i.getBroadcastId() == mBroadcastId) .findFirst() .orElse(null); Loading @@ -440,21 +503,26 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "updateBroadcastInfoFromContentProvider: mContentResolver is null"); return; } String programInfo = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO); String programInfo = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO); if (programInfo == null) { programInfo = getDefaultValueOfProgramInfo(); } setProgramInfo(programInfo, /* updateContentResolver= */ false); String prefBroadcastCode = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE); byte[] broadcastCode = (prefBroadcastCode == null) ? getDefaultValueOfBroadcastCode() String prefBroadcastCode = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE); byte[] broadcastCode = (prefBroadcastCode == null) ? getDefaultValueOfBroadcastCode() : prefBroadcastCode.getBytes(StandardCharsets.UTF_8); setBroadcastCode(broadcastCode, /* updateContentResolver= */ false); String appSourceName = Settings.Secure.getString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME); String appSourceName = Settings.Secure.getString( mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME); setAppSourceName(appSourceName, /* updateContentResolver= */ false); } Loading @@ -478,8 +546,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } /** * Stop the latest LE Broadcast. If the system stopped the LE Broadcast, then the system * calls the corresponding callback {@link BluetoothLeBroadcast.Callback}. * Stop the latest LE Broadcast. If the system stopped the LE Broadcast, then the system calls * the corresponding callback {@link BluetoothLeBroadcast.Callback}. */ public void stopLatestBroadcast() { stopBroadcast(mBroadcastId); Loading Loading @@ -511,7 +579,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } String programInfo = getProgramInfo(); if (DEBUG) { Log.d(TAG, Log.d( TAG, "updateBroadcast: language = " + language + " ,programInfo = " + programInfo); } mNewAppSourceName = appSourceName; Loading @@ -519,50 +588,79 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { mServiceBroadcast.updateBroadcast(mBroadcastId, mBluetoothLeAudioContentMetadata); } public void registerServiceCallBack(@NonNull @CallbackExecutor Executor executor, /** * Register Broadcast Callbacks to track its state and receivers * * @param executor Executor object for callback * @param callback Callback object to be registered */ public void registerServiceCallBack( @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothLeBroadcast.Callback callback) { if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); Log.d(TAG, "registerServiceCallBack failed, the BluetoothLeBroadcast is null."); mCachedBroadcastCallbackExecutorMap.putIfAbsent(callback, executor); return; } try { mServiceBroadcast.registerCallback(executor, callback); } catch (IllegalArgumentException e) { Log.w(TAG, "registerServiceCallBack failed. " + e.getMessage()); } } /** * Register Broadcast Assistant Callbacks to track it's state and receivers * Register Broadcast Assistant Callbacks to track its state and receivers * * @param executor Executor object for callback * @param callback Callback object to be registered */ public void registerBroadcastAssistantCallback(@NonNull @CallbackExecutor Executor executor, private void registerBroadcastAssistantCallback( @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothLeBroadcastAssistant.Callback callback) { if (mServiceBroadcastAssistant == null) { Log.d(TAG, "The BluetoothLeBroadcastAssisntant is null."); Log.d( TAG, "registerBroadcastAssistantCallback failed, " + "the BluetoothLeBroadcastAssistant is null."); return; } mServiceBroadcastAssistant.registerCallback(executor, callback); } /** * Unregister previously registered Broadcast Callbacks * * @param callback Callback object to be unregistered */ public void unregisterServiceCallBack(@NonNull BluetoothLeBroadcast.Callback callback) { mCachedBroadcastCallbackExecutorMap.remove(callback); if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); Log.d(TAG, "unregisterServiceCallBack failed, the BluetoothLeBroadcast is null."); return; } try { mServiceBroadcast.unregisterCallback(callback); } catch (IllegalArgumentException e) { Log.w(TAG, "unregisterServiceCallBack failed. " + e.getMessage()); } } /** * Unregister previousely registered Broadcast Assistant Callbacks * Unregister previously registered Broadcast Assistant Callbacks * * @param callback Callback object to be unregistered */ public void unregisterBroadcastAssistantCallback( private void unregisterBroadcastAssistantCallback( @NonNull BluetoothLeBroadcastAssistant.Callback callback) { if (mServiceBroadcastAssistant == null) { Log.d(TAG, "The BluetoothLeBroadcastAssisntant is null."); Log.d( TAG, "unregisterBroadcastAssistantCallback, " + "the BluetoothLeBroadcastAssistant is null."); return; } Loading @@ -570,8 +668,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } private void buildContentMetadata(String language, String programInfo) { mBluetoothLeAudioContentMetadata = mBuilder.setLanguage(language).setProgramInfo( programInfo).build(); mBluetoothLeAudioContentMetadata = mBuilder.setLanguage(language).setProgramInfo(programInfo).build(); } public LocalBluetoothLeBroadcastMetadata getLocalBluetoothLeBroadcastMetaData() { Loading Loading @@ -600,9 +698,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return true; } /** * Not supported since LE Audio Broadcasts do not establish a connection. */ /** Not supported since LE Audio Broadcasts do not establish a connection. */ public int getConnectionStatus(BluetoothDevice device) { if (mServiceBroadcast == null) { return BluetoothProfile.STATE_DISCONNECTED; Loading @@ -611,9 +707,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return mServiceBroadcast.getConnectionState(device); } /** * Not supported since LE Audio Broadcasts do not establish a connection. */ /** Not supported since LE Audio Broadcasts do not establish a connection. */ public List<BluetoothDevice> getConnectedDevices() { if (mServiceBroadcast == null) { return new ArrayList<BluetoothDevice>(0); Loading @@ -622,8 +716,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return mServiceBroadcast.getConnectedDevices(); } public @NonNull List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata() { /** Get all broadcast metadata. */ public @NonNull List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata() { if (mServiceBroadcast == null) { Log.d(TAG, "The BluetoothLeBroadcast is null."); return Collections.emptyList(); Loading @@ -640,16 +734,14 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { return !mServiceBroadcast.getAllBroadcastMetadata().isEmpty(); } /** * Service does not provide method to get/set policy. */ /** Service does not provide method to get/set policy. */ public int getConnectionPolicy(BluetoothDevice device) { return CONNECTION_POLICY_FORBIDDEN; } /** * Service does not provide "setEnabled" method. Please use {@link #startBroadcast}, * {@link #stopBroadcast()} or {@link #updateBroadcast(String, String)} * Service does not provide "setEnabled" method. Please use {@link #startBroadcast}, {@link * #stopBroadcast()} or {@link #updateBroadcast(String, String)} */ public boolean setEnabled(BluetoothDevice device, boolean enabled) { return false; Loading Loading @@ -683,9 +775,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } if (mServiceBroadcast != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy( BluetoothProfile.LE_AUDIO_BROADCAST, mServiceBroadcast); BluetoothAdapter.getDefaultAdapter() .closeProfileProxy(BluetoothProfile.LE_AUDIO_BROADCAST, mServiceBroadcast); mServiceBroadcast = null; } catch (Throwable t) { Log.w(TAG, "Error cleaning up LeAudio proxy", t); Loading Loading @@ -752,5 +843,4 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } } } }
packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java +148 −83 File changed.Preview size limit exceeded, changes collapsed. Show changes