From f77dbb4c4a7da5fdbff8fea555dc95f3827befef Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Thu, 21 Jul 2022 18:11:03 +0800 Subject: [LeBroadcast] Fix the NullPointerException for launching dialog Since the BluetoothLeBroadcastMetadata is null, and it causes the NullPointerException. After the system starts broadcast, the framework sends two callbacks, first is onBroadcastStarted, and second one is onBroadcastMetadataChanged. The BluetoothLeBroadcastMetadata object is created before onBroadcastMetadataChanged. Therefore,the app needs to wait the onBroadcastMetadataChanged, and then launchs the broadcast dialog. If the app launchs after the onBroadcastStarted, then the broadcast dialog can't get the null BluetoothLeBroadcastMetadata and it causes UI show the wrong QR code. Bug: 237976782 Test: build pass and manually test Change-Id: I91a28079ae01bbc5cc4c3ce9331741f0b4ee81c0 --- .../bluetooth/LocalBluetoothLeBroadcast.java | 19 ++++++++++++++++++- .../systemui/media/dialog/MediaOutputBaseDialog.java | 10 +++++++++- .../systemui/media/dialog/MediaOutputController.java | 5 ++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java index bf9debf5ccce..3445b7f79808 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java @@ -299,6 +299,18 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } public BluetoothLeBroadcastMetadata getLatestBluetoothLeBroadcastMetadata() { + if (mService == null) { + Log.d(TAG, "The BluetoothLeBroadcast is null"); + return null; + } + if (mBluetoothLeBroadcastMetadata == null) { + final List metadataList = + mService.getAllBroadcastMetadata(); + mBluetoothLeBroadcastMetadata = metadataList.stream() + .filter(i -> i.getBroadcastId() == mBroadcastId) + .findFirst() + .orElse(null); + } return mBluetoothLeBroadcastMetadata; } @@ -368,7 +380,12 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } public LocalBluetoothLeBroadcastMetadata getLocalBluetoothLeBroadcastMetaData() { - return new LocalBluetoothLeBroadcastMetadata(mBluetoothLeBroadcastMetadata); + final BluetoothLeBroadcastMetadata metadata = getLatestBluetoothLeBroadcastMetadata(); + if (metadata == null) { + Log.d(TAG, "The BluetoothLeBroadcastMetadata is null."); + return null; + } + return new LocalBluetoothLeBroadcastMetadata(metadata); } public boolean isProfileReady() { diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index e5913061ef3f..0a6dc622e9b7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -100,6 +100,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements private int mListMaxHeight; private WallpaperColors mWallpaperColors; private Executor mExecutor; + private boolean mShouldLaunchLeBroadcastDialog; MediaOutputBaseAdapter mAdapter; @@ -394,7 +395,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } public void handleLeBroadcastStarted() { - startLeBroadcastDialog(); + // Waiting for the onBroadcastMetadataChanged. The UI launchs the broadcast dialog when + // the metadata is ready. + mShouldLaunchLeBroadcastDialog = true; } public void handleLeBroadcastStartFailed() { @@ -404,10 +407,15 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } public void handleLeBroadcastMetadataChanged() { + if (mShouldLaunchLeBroadcastDialog) { + startLeBroadcastDialog(); + mShouldLaunchLeBroadcastDialog = false; + } refresh(); } public void handleLeBroadcastStopped() { + mShouldLaunchLeBroadcastDialog = false; refresh(); } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 247ffa7c2ef9..078e622af86d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -62,6 +62,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.Utils; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.InfoMediaManager; import com.android.settingslib.media.LocalMediaManager; @@ -847,7 +848,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, Log.d(TAG, "getBroadcastMetadata: LE Audio Broadcast is null"); return ""; } - return broadcast.getLocalBluetoothLeBroadcastMetaData().convertToQrCodeString(); + final LocalBluetoothLeBroadcastMetadata metadata = + broadcast.getLocalBluetoothLeBroadcastMetaData(); + return metadata != null ? metadata.convertToQrCodeString() : ""; } boolean isActiveRemoteDevice(@NonNull MediaDevice device) { -- cgit v1.2.3-59-g8ed1b