Loading android/app/Android.bp +30 −1 Original line number Diff line number Diff line Loading @@ -294,15 +294,44 @@ android_app { javacflags: ["-Aroom.schemaLocation=packages/modules/Bluetooth/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas"], lint: { // TODO(b/318814235): Add back ObsoleteSdkInt to this list. error_checks: [ "Autofill", "DefaultLocale", "DuplicateDefinition", // "ExportedContentProvider", // TODO: b/289445022 - enable this check // "ExportedReceiver", // TODO: b/289445022 - enable this check // "ExportedService", // TODO: b/289445022 - enable this check "ExtraText", "ExtraTranslation", "GestureBackNavigation", "GuardedLogInvocation", "HandlerLeak", "InflateParams", // "InvalidPermission", // TODO: b/289445022 - enable this check "LabelFor", "MissingClass", // "MissingVersion", // TODO: b/289445022 - enable this check "MonochromeLauncherIcon", "NewApi", "ObsoleteSdkInt", // "QueryAllPackagesPermission", // TODO: b/289445022 - enable this check "Recycle", "RtlHardcoded", "RtlSymmetry", "ScrollViewSize", "SetTextI18n", "SimpleDateFormat", "StaticFieldLeak", "StringFormatCount", "StringFormatInvalid", "TextFields", "TypographyEllipsis", "UseSparseArrays", "UseValueOf", "VectorPath", "VisibleForTests", "Wakelock", "WakelockTimeout", ], extra_check_modules: ["BluetoothLintChecker"], baseline_filename: "lint-baseline.xml", Loading android/app/lint-baseline.xml +15703 −3286 File changed.File size exceeds preview limit. View original file View changed file android/app/res/values/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ <!-- label for the notification item of sent file --> <string name="notification_sent">Bluetooth share: Sent <xliff:g id="file">%1$s</xliff:g></string> <!-- label for the notification item of sent file -status --> <string name="notification_sent_complete">100% complete</string> <string name="notification_sent_complete">100%% complete</string> <!-- label for the notification item of failed sending file --> <string name="notification_sent_fail">Bluetooth share: File <xliff:g id="file">%1$s</xliff:g> not sent</string> Loading android/app/src/com/android/bluetooth/bass_client/BassClientService.java +105 −106 Original line number Diff line number Diff line Loading @@ -123,8 +123,8 @@ public class BassClientService extends ProfileService { private static final int BROADCAST_STATE_STREAMING = 6; @VisibleForTesting static final int MESSAGE_SYNC_TIMEOUT = 1; @VisibleForTesting static final int MESSAGE_BIG_CHECK_START = 2; @VisibleForTesting static final int MESSAGE_BIG_CHECK_STOP = 3; @VisibleForTesting static final int MESSAGE_BIG_MONITOR_TIMEOUT = 2; @VisibleForTesting static final int MESSAGE_BROADCAST_MONITOR_TIMEOUT = 3; /* 1 minute timeout for primary device reconnection in Private Broadcast case */ private static final int DIALING_OUT_TIMEOUT_MS = 60000; Loading @@ -132,19 +132,14 @@ public class BassClientService extends ProfileService { // 30 secs timeout for keeping PSYNC active when searching is stopped private static final Duration sSyncActiveTimeout = Duration.ofSeconds(30); // 6 seconds to start BIG check. It has to be greater than kPeriodicSyncTimeout private static final Duration sBigCheckStart = Duration.ofSeconds(6); // 30 minutes timeout for monitoring BIG resynchronization private static final Duration sBigMonitorTimeout = Duration.ofMinutes(30); // 2 second for check if BIG exist private static final Duration sBigCheckStop = Duration.ofSeconds(2); // 5 minutes timeout for monitoring BIG resynchronization private static final Duration sBigMonitorTimeout = Duration.ofMinutes(5); // 5 minutes timeout for monitoring broadcaster private static final Duration sBroadcasterMonitorTimeout = Duration.ofMinutes(5); private enum PauseType { HOST_INTENTIONAL, SINK_UNKNOWN, SINK_INTENTIONAL, SINK_UNINTENTIONAL } Loading @@ -171,7 +166,6 @@ public class BassClientService extends ProfileService { private final Map<BluetoothDevice, BluetoothLeBroadcastMetadata> mBroadcastMetadataMap = new ConcurrentHashMap<>(); private final HashSet<BluetoothDevice> mPausedBroadcastSinks = new HashSet<>(); private final HashSet<Integer> mBigInfoReportExistForBroadcast = new HashSet<>(); private final Map<Integer, PauseType> mPausedBroadcastIds = new HashMap<>(); private final Deque<AddSourceData> mPendingAddSources = new ArrayDeque<>(); private final Map<Integer, HashSet<BluetoothDevice>> mLocalBroadcastReceivers = Loading Loading @@ -219,52 +213,35 @@ public class BassClientService extends ProfileService { switch (msg.what) { case MESSAGE_SYNC_TIMEOUT: { if (!leaudioBroadcastResyncHelper()) { clearAllSyncData(); break; } log("MESSAGE_SYNC_TIMEOUT"); int broadcastId = msg.arg1; stopBigMonitoring(broadcastId, false); synchronized (mSearchScanCallbackLock) { // when searching is stopped then clear all sync data if (mSearchScanCallback == null) { clearAllSyncData(); } } break; } case MESSAGE_BIG_CHECK_START: case MESSAGE_BROADCAST_MONITOR_TIMEOUT: { log("MESSAGE_BIG_CHECK_START"); log("MESSAGE_BROADCAST_MONITOR_TIMEOUT"); int broadcastId = msg.arg1; mBigInfoReportExistForBroadcast.remove(broadcastId); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_CHECK_STOP); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigCheckStop.toMillis()); List<Integer> activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); if (activeSyncedSrc.contains( getSyncHandleForBroadcastId(broadcastId))) { break; } case MESSAGE_BIG_CHECK_STOP: log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); // fall through } case MESSAGE_BIG_MONITOR_TIMEOUT: { log("MESSAGE_BIG_CHECK_STOP"); log("MESSAGE_BIG_MONITOR_TIMEOUT"); int broadcastId = msg.arg1; if (mBigInfoReportExistForBroadcast.contains(broadcastId)) { mPausedBroadcastIds.put( broadcastId, PauseType.SINK_INTENTIONAL); logPausedBroadcastsAndSinks(); } else { mPausedBroadcastIds.put( broadcastId, PauseType.SINK_UNINTENTIONAL); cacheSuspendingSources(broadcastId); stopSourceReceivers(broadcastId); synchronized (mSearchScanCallbackLock) { // when searching is stopped then clear all sync data if (mSearchScanCallback == null) { clearAllSyncData(); } } // Timer starts even if pause is SINK_INTENTIONAL to keep sync in // case that buds send SyncInfo Request mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); log("Started timeout for canceling syncs"); Message newMsg = mHandler.obtainMessage(MESSAGE_SYNC_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigMonitorTimeout.toMillis()); break; } default: Loading Loading @@ -1045,28 +1022,35 @@ public class BassClientService extends ProfileService { && !isLocalBroadcast(receiveState) && !isEmptyBluetoothDevice(receiveState.getSourceDevice()) && !isHostPauseType(broadcastId)) { boolean isPlaying = false; boolean isReadyToAutoResync = false; if (receiveState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { isReadyToAutoResync = true; } else { for (int i = 0; i < receiveState.getNumSubgroups(); i++) { Long syncState = receiveState.getBisSyncState().get(i); /* Synced to BIS */ if (syncState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS && syncState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) { isPlaying = true; isReadyToAutoResync = true; break; } } } if (isPlaying) { if (isReadyToAutoResync) { stopBigMonitoring(broadcastId, false); } else if (!mPausedBroadcastIds.containsKey(broadcastId)) { if (mCachedBroadcasts.containsKey(broadcastId)) { addSelectSourceRequest(broadcastId, true); mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNKNOWN); logPausedBroadcastsAndSinks(); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_CHECK_START); mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNINTENTIONAL); cacheSuspendingSources(broadcastId); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigCheckStart.toMillis()); log("Started MESSAGE_BIG_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBigMonitorTimeout.toMillis()); } } } else if (isEmptyBluetoothDevice(receiveState.getSourceDevice())) { Loading @@ -1093,7 +1077,7 @@ public class BassClientService extends ProfileService { /* Assistant become inactive */ if (mIsAssistantActive && mPausedBroadcastSinks.isEmpty() && !isAnySinkPauseType(broadcastId)) { && !isSinkUnintentionalPauseType(broadcastId)) { mIsAssistantActive = false; mUnicastSourceStreamStatus = Optional.empty(); leAudioService.activeBroadcastAssistantNotification(false); Loading Loading @@ -2057,15 +2041,18 @@ public class BassClientService extends ProfileService { null); addActiveSyncedSource(syncHandle); if (!leaudioBroadcastResyncHelper()) { synchronized (mSearchScanCallbackLock) { // when searching is stopped then start timer to stop active sync // when searching is stopped then start timer to stop active syncs if (mSearchScanCallback == null) { mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); log("Started timeout for canceling syncs"); Message newMsg = mHandler.obtainMessage(MESSAGE_SYNC_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sSyncActiveTimeout.toMillis()); log("Started MESSAGE_SYNC_TIMEOUT"); mHandler.sendEmptyMessageDelayed( MESSAGE_SYNC_TIMEOUT, sSyncActiveTimeout.toMillis()); } } } else { mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); } // update valid sync handle in mPeriodicAdvCallbacksMap Loading Loading @@ -2113,17 +2100,26 @@ public class BassClientService extends ProfileService { } } } stopBigMonitoring(broadcastId, false); synchronized (mSourceSyncRequestsQueue) { int failsCounter = mSyncFailureCounter.getOrDefault(broadcastId, 0) + 1; mSyncFailureCounter.put(broadcastId, failsCounter); } synchronized (mSearchScanCallbackLock) { if (isSinkUnintentionalPauseType(broadcastId)) { if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) { Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis()); } addSelectSourceRequest(broadcastId, true); } else { // Clear from cache to make possible sync again (only during active searching) synchronized (mSearchScanCallbackLock) { if (mSearchScanCallback != null) { mCachedBroadcasts.remove(broadcastId); } } } mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); } handleSelectSourceRequest(); Loading Loading @@ -2186,24 +2182,33 @@ public class BassClientService extends ProfileService { public void onSyncLost(int syncHandle) { int broadcastId = getBroadcastIdForSyncHandle(syncHandle); log("OnSyncLost: syncHandle=" + syncHandle + ", broadcastID=" + broadcastId); clearAllDataForSyncHandle(syncHandle); if (broadcastId != BassConstants.INVALID_BROADCAST_ID) { if (leaudioBroadcastMonitorSourceSyncStatus()) { log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); } stopBigMonitoring(broadcastId, false); synchronized (mSourceSyncRequestsQueue) { int failsCounter = mSyncFailureCounter.getOrDefault(broadcastId, 0) + 1; mSyncFailureCounter.put(broadcastId, failsCounter); } if (isSinkUnintentionalPauseType(broadcastId)) { if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) { Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis()); } clearAllDataForSyncHandle(syncHandle); addSelectSourceRequest(broadcastId, true); } else { // Clear from cache to make possible sync again (only during active searching) synchronized (mSearchScanCallbackLock) { if (mSearchScanCallback != null) { mCachedBroadcasts.remove(broadcastId); } } if (leaudioBroadcastMonitorSourceSyncStatus()) { log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); } } } } @Override Loading Loading @@ -2238,13 +2243,10 @@ public class BassClientService extends ProfileService { log("Notify broadcast source found"); mCallbacks.notifySourceFound(metaData); } if (mPausedBroadcastIds.containsKey(broadcastId)) { mBigInfoReportExistForBroadcast.add(broadcastId); if (mPausedBroadcastIds.get(broadcastId).equals(PauseType.SINK_UNINTENTIONAL)) { if (isSinkUnintentionalPauseType(broadcastId)) { resumeReceiversSourceSynchronization(); } } } @Override public void onSyncTransferred(BluetoothDevice device, int status) { Loading Loading @@ -3233,7 +3235,7 @@ public class BassClientService extends ProfileService { } if (!mPausedBroadcastSinks.contains(device) || isAnySinkPauseType(receiveState.getBroadcastId())) { || isSinkUnintentionalPauseType(receiveState.getBroadcastId())) { // Remove device if not paused yet sourcesToRemove.put(device, receiveState.getSourceId()); } Loading Loading @@ -3435,14 +3437,14 @@ public class BassClientService extends ProfileService { + mPausedBroadcastSinks); } private boolean isAnySinkPauseType(int broadcastId) { private boolean isHostPauseType(int broadcastId) { return (mPausedBroadcastIds.containsKey(broadcastId) && !mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); && mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); } private boolean isHostPauseType(int broadcastId) { private boolean isSinkUnintentionalPauseType(int broadcastId) { return (mPausedBroadcastIds.containsKey(broadcastId) && mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); && mPausedBroadcastIds.get(broadcastId).equals(PauseType.SINK_UNINTENTIONAL)); } public void stopBigMonitoring() { Loading @@ -3450,9 +3452,8 @@ public class BassClientService extends ProfileService { return; } log("stopBigMonitoring"); mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); mPausedBroadcastSinks.clear(); Loading @@ -3479,9 +3480,8 @@ public class BassClientService extends ProfileService { while (iterator.hasNext()) { int pausedBroadcastId = iterator.next(); if (!isAnyReceiverSyncedToBroadcast(pausedBroadcastId)) { mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); iterator.remove(); synchronized (mSearchScanCallbackLock) { // when searching is stopped then stop active sync Loading @@ -3499,9 +3499,8 @@ public class BassClientService extends ProfileService { return; } log("stopBigMonitoring broadcastId: " + broadcastId + ", hostInitiated: " + hostInitiated); mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); if (hostInitiated) { mPausedBroadcastIds.put(broadcastId, PauseType.HOST_INTENTIONAL); } else { Loading android/app/src/com/android/bluetooth/hfp/HeadsetService.java +1 −1 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,7 @@ public class HeadsetService extends ProfileService { if (!Objects.equals(mActiveDevice, device)) { Log.w( TAG, "startVoiceRecognition: requested device " "stopVoiceRecognition: requested device " + device + " is not active, use active device " + mActiveDevice Loading Loading
android/app/Android.bp +30 −1 Original line number Diff line number Diff line Loading @@ -294,15 +294,44 @@ android_app { javacflags: ["-Aroom.schemaLocation=packages/modules/Bluetooth/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas"], lint: { // TODO(b/318814235): Add back ObsoleteSdkInt to this list. error_checks: [ "Autofill", "DefaultLocale", "DuplicateDefinition", // "ExportedContentProvider", // TODO: b/289445022 - enable this check // "ExportedReceiver", // TODO: b/289445022 - enable this check // "ExportedService", // TODO: b/289445022 - enable this check "ExtraText", "ExtraTranslation", "GestureBackNavigation", "GuardedLogInvocation", "HandlerLeak", "InflateParams", // "InvalidPermission", // TODO: b/289445022 - enable this check "LabelFor", "MissingClass", // "MissingVersion", // TODO: b/289445022 - enable this check "MonochromeLauncherIcon", "NewApi", "ObsoleteSdkInt", // "QueryAllPackagesPermission", // TODO: b/289445022 - enable this check "Recycle", "RtlHardcoded", "RtlSymmetry", "ScrollViewSize", "SetTextI18n", "SimpleDateFormat", "StaticFieldLeak", "StringFormatCount", "StringFormatInvalid", "TextFields", "TypographyEllipsis", "UseSparseArrays", "UseValueOf", "VectorPath", "VisibleForTests", "Wakelock", "WakelockTimeout", ], extra_check_modules: ["BluetoothLintChecker"], baseline_filename: "lint-baseline.xml", Loading
android/app/lint-baseline.xml +15703 −3286 File changed.File size exceeds preview limit. View original file View changed file
android/app/res/values/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ <!-- label for the notification item of sent file --> <string name="notification_sent">Bluetooth share: Sent <xliff:g id="file">%1$s</xliff:g></string> <!-- label for the notification item of sent file -status --> <string name="notification_sent_complete">100% complete</string> <string name="notification_sent_complete">100%% complete</string> <!-- label for the notification item of failed sending file --> <string name="notification_sent_fail">Bluetooth share: File <xliff:g id="file">%1$s</xliff:g> not sent</string> Loading
android/app/src/com/android/bluetooth/bass_client/BassClientService.java +105 −106 Original line number Diff line number Diff line Loading @@ -123,8 +123,8 @@ public class BassClientService extends ProfileService { private static final int BROADCAST_STATE_STREAMING = 6; @VisibleForTesting static final int MESSAGE_SYNC_TIMEOUT = 1; @VisibleForTesting static final int MESSAGE_BIG_CHECK_START = 2; @VisibleForTesting static final int MESSAGE_BIG_CHECK_STOP = 3; @VisibleForTesting static final int MESSAGE_BIG_MONITOR_TIMEOUT = 2; @VisibleForTesting static final int MESSAGE_BROADCAST_MONITOR_TIMEOUT = 3; /* 1 minute timeout for primary device reconnection in Private Broadcast case */ private static final int DIALING_OUT_TIMEOUT_MS = 60000; Loading @@ -132,19 +132,14 @@ public class BassClientService extends ProfileService { // 30 secs timeout for keeping PSYNC active when searching is stopped private static final Duration sSyncActiveTimeout = Duration.ofSeconds(30); // 6 seconds to start BIG check. It has to be greater than kPeriodicSyncTimeout private static final Duration sBigCheckStart = Duration.ofSeconds(6); // 30 minutes timeout for monitoring BIG resynchronization private static final Duration sBigMonitorTimeout = Duration.ofMinutes(30); // 2 second for check if BIG exist private static final Duration sBigCheckStop = Duration.ofSeconds(2); // 5 minutes timeout for monitoring BIG resynchronization private static final Duration sBigMonitorTimeout = Duration.ofMinutes(5); // 5 minutes timeout for monitoring broadcaster private static final Duration sBroadcasterMonitorTimeout = Duration.ofMinutes(5); private enum PauseType { HOST_INTENTIONAL, SINK_UNKNOWN, SINK_INTENTIONAL, SINK_UNINTENTIONAL } Loading @@ -171,7 +166,6 @@ public class BassClientService extends ProfileService { private final Map<BluetoothDevice, BluetoothLeBroadcastMetadata> mBroadcastMetadataMap = new ConcurrentHashMap<>(); private final HashSet<BluetoothDevice> mPausedBroadcastSinks = new HashSet<>(); private final HashSet<Integer> mBigInfoReportExistForBroadcast = new HashSet<>(); private final Map<Integer, PauseType> mPausedBroadcastIds = new HashMap<>(); private final Deque<AddSourceData> mPendingAddSources = new ArrayDeque<>(); private final Map<Integer, HashSet<BluetoothDevice>> mLocalBroadcastReceivers = Loading Loading @@ -219,52 +213,35 @@ public class BassClientService extends ProfileService { switch (msg.what) { case MESSAGE_SYNC_TIMEOUT: { if (!leaudioBroadcastResyncHelper()) { clearAllSyncData(); break; } log("MESSAGE_SYNC_TIMEOUT"); int broadcastId = msg.arg1; stopBigMonitoring(broadcastId, false); synchronized (mSearchScanCallbackLock) { // when searching is stopped then clear all sync data if (mSearchScanCallback == null) { clearAllSyncData(); } } break; } case MESSAGE_BIG_CHECK_START: case MESSAGE_BROADCAST_MONITOR_TIMEOUT: { log("MESSAGE_BIG_CHECK_START"); log("MESSAGE_BROADCAST_MONITOR_TIMEOUT"); int broadcastId = msg.arg1; mBigInfoReportExistForBroadcast.remove(broadcastId); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_CHECK_STOP); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigCheckStop.toMillis()); List<Integer> activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); if (activeSyncedSrc.contains( getSyncHandleForBroadcastId(broadcastId))) { break; } case MESSAGE_BIG_CHECK_STOP: log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); // fall through } case MESSAGE_BIG_MONITOR_TIMEOUT: { log("MESSAGE_BIG_CHECK_STOP"); log("MESSAGE_BIG_MONITOR_TIMEOUT"); int broadcastId = msg.arg1; if (mBigInfoReportExistForBroadcast.contains(broadcastId)) { mPausedBroadcastIds.put( broadcastId, PauseType.SINK_INTENTIONAL); logPausedBroadcastsAndSinks(); } else { mPausedBroadcastIds.put( broadcastId, PauseType.SINK_UNINTENTIONAL); cacheSuspendingSources(broadcastId); stopSourceReceivers(broadcastId); synchronized (mSearchScanCallbackLock) { // when searching is stopped then clear all sync data if (mSearchScanCallback == null) { clearAllSyncData(); } } // Timer starts even if pause is SINK_INTENTIONAL to keep sync in // case that buds send SyncInfo Request mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); log("Started timeout for canceling syncs"); Message newMsg = mHandler.obtainMessage(MESSAGE_SYNC_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigMonitorTimeout.toMillis()); break; } default: Loading Loading @@ -1045,28 +1022,35 @@ public class BassClientService extends ProfileService { && !isLocalBroadcast(receiveState) && !isEmptyBluetoothDevice(receiveState.getSourceDevice()) && !isHostPauseType(broadcastId)) { boolean isPlaying = false; boolean isReadyToAutoResync = false; if (receiveState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { isReadyToAutoResync = true; } else { for (int i = 0; i < receiveState.getNumSubgroups(); i++) { Long syncState = receiveState.getBisSyncState().get(i); /* Synced to BIS */ if (syncState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS && syncState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) { isPlaying = true; isReadyToAutoResync = true; break; } } } if (isPlaying) { if (isReadyToAutoResync) { stopBigMonitoring(broadcastId, false); } else if (!mPausedBroadcastIds.containsKey(broadcastId)) { if (mCachedBroadcasts.containsKey(broadcastId)) { addSelectSourceRequest(broadcastId, true); mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNKNOWN); logPausedBroadcastsAndSinks(); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_CHECK_START); mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNINTENTIONAL); cacheSuspendingSources(broadcastId); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sBigCheckStart.toMillis()); log("Started MESSAGE_BIG_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBigMonitorTimeout.toMillis()); } } } else if (isEmptyBluetoothDevice(receiveState.getSourceDevice())) { Loading @@ -1093,7 +1077,7 @@ public class BassClientService extends ProfileService { /* Assistant become inactive */ if (mIsAssistantActive && mPausedBroadcastSinks.isEmpty() && !isAnySinkPauseType(broadcastId)) { && !isSinkUnintentionalPauseType(broadcastId)) { mIsAssistantActive = false; mUnicastSourceStreamStatus = Optional.empty(); leAudioService.activeBroadcastAssistantNotification(false); Loading Loading @@ -2057,15 +2041,18 @@ public class BassClientService extends ProfileService { null); addActiveSyncedSource(syncHandle); if (!leaudioBroadcastResyncHelper()) { synchronized (mSearchScanCallbackLock) { // when searching is stopped then start timer to stop active sync // when searching is stopped then start timer to stop active syncs if (mSearchScanCallback == null) { mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); log("Started timeout for canceling syncs"); Message newMsg = mHandler.obtainMessage(MESSAGE_SYNC_TIMEOUT); newMsg.arg1 = broadcastId; mHandler.sendMessageDelayed(newMsg, sSyncActiveTimeout.toMillis()); log("Started MESSAGE_SYNC_TIMEOUT"); mHandler.sendEmptyMessageDelayed( MESSAGE_SYNC_TIMEOUT, sSyncActiveTimeout.toMillis()); } } } else { mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); } // update valid sync handle in mPeriodicAdvCallbacksMap Loading Loading @@ -2113,17 +2100,26 @@ public class BassClientService extends ProfileService { } } } stopBigMonitoring(broadcastId, false); synchronized (mSourceSyncRequestsQueue) { int failsCounter = mSyncFailureCounter.getOrDefault(broadcastId, 0) + 1; mSyncFailureCounter.put(broadcastId, failsCounter); } synchronized (mSearchScanCallbackLock) { if (isSinkUnintentionalPauseType(broadcastId)) { if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) { Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis()); } addSelectSourceRequest(broadcastId, true); } else { // Clear from cache to make possible sync again (only during active searching) synchronized (mSearchScanCallbackLock) { if (mSearchScanCallback != null) { mCachedBroadcasts.remove(broadcastId); } } } mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); } handleSelectSourceRequest(); Loading Loading @@ -2186,24 +2182,33 @@ public class BassClientService extends ProfileService { public void onSyncLost(int syncHandle) { int broadcastId = getBroadcastIdForSyncHandle(syncHandle); log("OnSyncLost: syncHandle=" + syncHandle + ", broadcastID=" + broadcastId); clearAllDataForSyncHandle(syncHandle); if (broadcastId != BassConstants.INVALID_BROADCAST_ID) { if (leaudioBroadcastMonitorSourceSyncStatus()) { log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); } stopBigMonitoring(broadcastId, false); synchronized (mSourceSyncRequestsQueue) { int failsCounter = mSyncFailureCounter.getOrDefault(broadcastId, 0) + 1; mSyncFailureCounter.put(broadcastId, failsCounter); } if (isSinkUnintentionalPauseType(broadcastId)) { if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) { Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT); newMsg.arg1 = broadcastId; log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT"); mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis()); } clearAllDataForSyncHandle(syncHandle); addSelectSourceRequest(broadcastId, true); } else { // Clear from cache to make possible sync again (only during active searching) synchronized (mSearchScanCallbackLock) { if (mSearchScanCallback != null) { mCachedBroadcasts.remove(broadcastId); } } if (leaudioBroadcastMonitorSourceSyncStatus()) { log("Notify broadcast source lost, broadcast id: " + broadcastId); mCallbacks.notifySourceLost(broadcastId); } } } } @Override Loading Loading @@ -2238,13 +2243,10 @@ public class BassClientService extends ProfileService { log("Notify broadcast source found"); mCallbacks.notifySourceFound(metaData); } if (mPausedBroadcastIds.containsKey(broadcastId)) { mBigInfoReportExistForBroadcast.add(broadcastId); if (mPausedBroadcastIds.get(broadcastId).equals(PauseType.SINK_UNINTENTIONAL)) { if (isSinkUnintentionalPauseType(broadcastId)) { resumeReceiversSourceSynchronization(); } } } @Override public void onSyncTransferred(BluetoothDevice device, int status) { Loading Loading @@ -3233,7 +3235,7 @@ public class BassClientService extends ProfileService { } if (!mPausedBroadcastSinks.contains(device) || isAnySinkPauseType(receiveState.getBroadcastId())) { || isSinkUnintentionalPauseType(receiveState.getBroadcastId())) { // Remove device if not paused yet sourcesToRemove.put(device, receiveState.getSourceId()); } Loading Loading @@ -3435,14 +3437,14 @@ public class BassClientService extends ProfileService { + mPausedBroadcastSinks); } private boolean isAnySinkPauseType(int broadcastId) { private boolean isHostPauseType(int broadcastId) { return (mPausedBroadcastIds.containsKey(broadcastId) && !mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); && mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); } private boolean isHostPauseType(int broadcastId) { private boolean isSinkUnintentionalPauseType(int broadcastId) { return (mPausedBroadcastIds.containsKey(broadcastId) && mPausedBroadcastIds.get(broadcastId).equals(PauseType.HOST_INTENTIONAL)); && mPausedBroadcastIds.get(broadcastId).equals(PauseType.SINK_UNINTENTIONAL)); } public void stopBigMonitoring() { Loading @@ -3450,9 +3452,8 @@ public class BassClientService extends ProfileService { return; } log("stopBigMonitoring"); mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); mPausedBroadcastSinks.clear(); Loading @@ -3479,9 +3480,8 @@ public class BassClientService extends ProfileService { while (iterator.hasNext()) { int pausedBroadcastId = iterator.next(); if (!isAnyReceiverSyncedToBroadcast(pausedBroadcastId)) { mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); iterator.remove(); synchronized (mSearchScanCallbackLock) { // when searching is stopped then stop active sync Loading @@ -3499,9 +3499,8 @@ public class BassClientService extends ProfileService { return; } log("stopBigMonitoring broadcastId: " + broadcastId + ", hostInitiated: " + hostInitiated); mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); mHandler.removeMessages(MESSAGE_BIG_CHECK_START); mHandler.removeMessages(MESSAGE_BIG_CHECK_STOP); mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT); mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT); if (hostInitiated) { mPausedBroadcastIds.put(broadcastId, PauseType.HOST_INTENTIONAL); } else { Loading
android/app/src/com/android/bluetooth/hfp/HeadsetService.java +1 −1 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,7 @@ public class HeadsetService extends ProfileService { if (!Objects.equals(mActiveDevice, device)) { Log.w( TAG, "startVoiceRecognition: requested device " "stopVoiceRecognition: requested device " + device + " is not active, use active device " + mActiveDevice Loading