Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1a4a6c2 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12158986 from 15b566ad to 24Q4-release

Change-Id: I3228d18bf70eaf4aaf626c3db419e7df3335b0ab
parents 28057c5c 15b566ad
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
licorne@google.com
wescande@google.com
wescande@google.com
+0 −1
Original line number Original line Diff line number Diff line
charliebout@google.com
charliebout@google.com
licorne@google.com
+69 −31
Original line number Original line Diff line number Diff line
@@ -92,7 +92,6 @@ import java.util.Deque;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
@@ -148,7 +147,7 @@ public class BassClientService extends ProfileService {
    private final Map<BluetoothDevice, List<Integer>> mActiveSourceMap = new ConcurrentHashMap<>();
    private final Map<BluetoothDevice, List<Integer>> mActiveSourceMap = new ConcurrentHashMap<>();
    private final Map<BluetoothDevice, BluetoothLeBroadcastMetadata> mBroadcastMetadataMap =
    private final Map<BluetoothDevice, BluetoothLeBroadcastMetadata> mBroadcastMetadataMap =
            new ConcurrentHashMap<>();
            new ConcurrentHashMap<>();
    private final LinkedList<BluetoothDevice> mPausedBroadcastSinks = new LinkedList<>();
    private final HashSet<BluetoothDevice> mPausedBroadcastSinks = new HashSet<>();
    private final Deque<AddSourceData> mPendingAddSources = new ArrayDeque<>();
    private final Deque<AddSourceData> mPendingAddSources = new ArrayDeque<>();
    private final Map<Integer, HashSet<BluetoothDevice>> mLocalBroadcastReceivers =
    private final Map<Integer, HashSet<BluetoothDevice>> mLocalBroadcastReceivers =
            new ConcurrentHashMap<>();
            new ConcurrentHashMap<>();
@@ -704,6 +703,7 @@ public class BassClientService extends ProfileService {
            mLocalBroadcastReceivers.clear();
            mLocalBroadcastReceivers.clear();
            mPendingGroupOp.clear();
            mPendingGroupOp.clear();
            mBroadcastMetadataMap.clear();
            mBroadcastMetadataMap.clear();
            mPausedBroadcastSinks.clear();
        }
        }
    }
    }


@@ -1394,6 +1394,7 @@ public class BassClientService extends ProfileService {
        // Check if the device is disconnected - if unbond, remove the state machine
        // Check if the device is disconnected - if unbond, remove the state machine
        if (toState == BluetoothProfile.STATE_DISCONNECTED) {
        if (toState == BluetoothProfile.STATE_DISCONNECTED) {
            mPendingGroupOp.remove(device);
            mPendingGroupOp.remove(device);
            mPausedBroadcastSinks.remove(device);


            int bondState = mAdapterService.getBondState(device);
            int bondState = mAdapterService.getBondState(device);
            if (bondState == BluetoothDevice.BOND_NONE) {
            if (bondState == BluetoothDevice.BOND_NONE) {
@@ -1892,9 +1893,12 @@ public class BassClientService extends ProfileService {
                int skip,
                int skip,
                int timeout,
                int timeout,
                int status) {
                int status) {
            int broadcastId = getBroadcastIdForSyncHandle(BassConstants.INVALID_SYNC_HANDLE);
            log(
            log(
                    "onSyncEstablished syncHandle: "
                    "onSyncEstablished syncHandle: "
                            + syncHandle
                            + syncHandle
                            + ", broadcastId: "
                            + broadcastId
                            + ", device: "
                            + ", device: "
                            + device
                            + device
                            + ", advertisingSid: "
                            + ", advertisingSid: "
@@ -1944,9 +1948,7 @@ public class BassClientService extends ProfileService {
                    Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator();
                    Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator();
                    while (iterator.hasNext()) {
                    while (iterator.hasNext()) {
                        AddSourceData pendingSourcesToAdd = iterator.next();
                        AddSourceData pendingSourcesToAdd = iterator.next();
                        BluetoothDevice sourceDevice =
                        if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() == broadcastId) {
                                pendingSourcesToAdd.mSourceMetadata.getSourceDevice();
                        if (sourceDevice.equals(device)) {
                            addSource(
                            addSource(
                                    pendingSourcesToAdd.mSink,
                                    pendingSourcesToAdd.mSink,
                                    pendingSourcesToAdd.mSourceMetadata,
                                    pendingSourcesToAdd.mSourceMetadata,
@@ -1957,9 +1959,31 @@ public class BassClientService extends ProfileService {
                }
                }
            } else {
            } else {
                // remove failed sync handle
                // remove failed sync handle
                int broadcastId = getBroadcastIdForSyncHandle(BassConstants.INVALID_SYNC_HANDLE);
                log("onSyncEstablished failed for broadcast id: " + broadcastId);
                log("onSyncEstablished failed for broadcast id: " + broadcastId);
                boolean notifiedOfLost = false;
                synchronized (mPendingSourcesToAdd) {
                    Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator();
                    while (iterator.hasNext()) {
                        AddSourceData pendingSourcesToAdd = iterator.next();
                        if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() == broadcastId) {
                            if (!notifiedOfLost) {
                                notifiedOfLost = true;
                                mCallbacks.notifySourceLost(broadcastId);
                            }
                            mCallbacks.notifySourceAddFailed(
                                    pendingSourcesToAdd.mSink,
                                    pendingSourcesToAdd.mSourceMetadata,
                                    BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES);
                            iterator.remove();
                        }
                    }
                }
                synchronized (mSearchScanCallbackLock) {
                    // Clear from cache to make possible sync again (only during active searching)
                    if (mSearchScanCallback != null) {
                        mCachedBroadcasts.remove(broadcastId);
                        mCachedBroadcasts.remove(broadcastId);
                    }
                }
                mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE);
                mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE);
            }
            }
            handleSelectSourceRequest();
            handleSelectSourceRequest();
@@ -2029,9 +2053,13 @@ public class BassClientService extends ProfileService {
                }
                }
            }
            }
            clearAllDataForSyncHandle(syncHandle);
            clearAllDataForSyncHandle(syncHandle);
            // Clear from cache to make possible sync again
            // Clear from cache to make possible sync again (only during active searching)
            synchronized (mSearchScanCallbackLock) {
                if (mSearchScanCallback != null) {
                    mCachedBroadcasts.remove(broadcastId);
                    mCachedBroadcasts.remove(broadcastId);
                }
                }
            }
        }


        @Override
        @Override
        public void onBigInfoAdvertisingReport(int syncHandle, boolean encrypted) {
        public void onBigInfoAdvertisingReport(int syncHandle, boolean encrypted) {
@@ -2533,11 +2561,21 @@ public class BassClientService extends ProfileService {
                if (broadcastId != BassConstants.INVALID_BROADCAST_ID
                if (broadcastId != BassConstants.INVALID_BROADCAST_ID
                        && getCachedBroadcast(broadcastId) != null) {
                        && getCachedBroadcast(broadcastId) != null) {
                    // If the source has been synced before, try to re-sync
                    // If the source has been synced before, try to re-sync
                    // with the source by previously cached scan result
                    // with the source by previously cached scan result.
                    addSelectSourceRequest(getCachedBroadcast(broadcastId), true);
                    // Check if not added already
                    boolean alreadyAdded = false;
                    synchronized (mPendingSourcesToAdd) {
                    synchronized (mPendingSourcesToAdd) {
                        for (AddSourceData pendingSourcesToAdd : mPendingSourcesToAdd) {
                            if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId()
                                    == broadcastId) {
                                alreadyAdded = true;
                            }
                        }
                        mPendingSourcesToAdd.add(
                        mPendingSourcesToAdd.add(
                                new AddSourceData(sink, sourceMetadata, isGroupOp));
                                new AddSourceData(sink, sourceMetadata, isGroupOp));
                        if (!alreadyAdded) {
                            addSelectSourceRequest(getCachedBroadcast(broadcastId), true);
                        }
                    }
                    }
                } else {
                } else {
                    log("AddSource: broadcast not cached or invalid, broadcastId: " + broadcastId);
                    log("AddSource: broadcast not cached or invalid, broadcastId: " + broadcastId);
@@ -2958,15 +2996,14 @@ public class BassClientService extends ProfileService {
    private void stopSourceReceivers(int broadcastId, boolean store) {
    private void stopSourceReceivers(int broadcastId, boolean store) {
        Log.d(TAG, "stopSourceReceivers(), broadcastId: " + broadcastId + ", store: " + store);
        Log.d(TAG, "stopSourceReceivers(), broadcastId: " + broadcastId + ", store: " + store);


        if (store && !mPausedBroadcastSinks.isEmpty()) {
            Log.w(TAG, "stopSourceReceivers(), paused broadcast sinks are replaced");
            sEventLogger.logd(TAG, "Clear broadcast sinks paused cache");
            mPausedBroadcastSinks.clear();
        }

        Map<BluetoothDevice, Integer> sourcesToRemove = new HashMap<>();
        Map<BluetoothDevice, Integer> sourcesToRemove = new HashMap<>();


        for (BluetoothDevice device : getConnectedDevices()) {
        for (BluetoothDevice device : getConnectedDevices()) {
            if (mPausedBroadcastSinks.contains(device)) {
                // Skip this device if it has been paused
                continue;
            }

            for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) {
            for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) {
                /* Check if local/last broadcast is the synced one. Invalid broadcast ID means
                /* Check if local/last broadcast is the synced one. Invalid broadcast ID means
                 * that all receivers should be considered.
                 * that all receivers should be considered.
@@ -2976,7 +3013,7 @@ public class BassClientService extends ProfileService {
                    continue;
                    continue;
                }
                }


                if (store && !mPausedBroadcastSinks.contains(device)) {
                if (store) {
                    sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device);
                    sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device);
                    mPausedBroadcastSinks.add(device);
                    mPausedBroadcastSinks.add(device);
                }
                }
@@ -3130,18 +3167,12 @@ public class BassClientService extends ProfileService {
        }
        }
    }
    }


    /** Cache suspending sources */
    /** Cache suspending sources when broadcast paused */
    public void cacheSuspendingSources(int broadcastId) {
    public void cacheSuspendingSources(int broadcastId) {
        sEventLogger.logd(TAG, "Cache suspending sources: " + broadcastId);
        sEventLogger.logd(TAG, "Cache suspending sources: " + broadcastId);
        List<Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice>> sourcesToCache =
        List<Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice>> sourcesToCache =
                getReceiveStateDevicePairs(broadcastId);
                getReceiveStateDevicePairs(broadcastId);


        if (!mPausedBroadcastSinks.isEmpty()) {
            Log.w(TAG, "cacheSuspendingSources(), paused broadcast sinks are replaced");
            sEventLogger.logd(TAG, "Clear broadcast sinks paused cache");
            mPausedBroadcastSinks.clear();
        }

        for (Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice> pair : sourcesToCache) {
        for (Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice> pair : sourcesToCache) {
            mPausedBroadcastSinks.add(pair.second);
            mPausedBroadcastSinks.add(pair.second);
        }
        }
@@ -3173,8 +3204,9 @@ public class BassClientService extends ProfileService {
    public void resumeReceiversSourceSynchronization() {
    public void resumeReceiversSourceSynchronization() {
        sEventLogger.logd(TAG, "Resume receivers source synchronization");
        sEventLogger.logd(TAG, "Resume receivers source synchronization");


        while (!mPausedBroadcastSinks.isEmpty()) {
        Iterator<BluetoothDevice> iterator = mPausedBroadcastSinks.iterator();
            BluetoothDevice sink = mPausedBroadcastSinks.remove();
        while (iterator.hasNext()) {
            BluetoothDevice sink = iterator.next();
            sEventLogger.logd(TAG, "Remove broadcast sink from paused cache: " + sink);
            sEventLogger.logd(TAG, "Remove broadcast sink from paused cache: " + sink);
            BluetoothLeBroadcastMetadata metadata = mBroadcastMetadataMap.get(sink);
            BluetoothLeBroadcastMetadata metadata = mBroadcastMetadataMap.get(sink);


@@ -3182,9 +3214,11 @@ public class BassClientService extends ProfileService {
                if (metadata == null) {
                if (metadata == null) {
                    Log.w(
                    Log.w(
                            TAG,
                            TAG,
                            "resumeReceiversSourceSynchronization: failed to get metadata to resume"
                            "resumeReceiversSourceSynchronization: failed to get metadata to"
                                    + " sink: "
                                    + " resume sink: "
                                    + sink);
                                    + sink);
                    // remove the device from mPausedBroadcastSinks
                    iterator.remove();
                    continue;
                    continue;
                }
                }


@@ -3207,6 +3241,8 @@ public class BassClientService extends ProfileService {


                    if (statusCode != BluetoothStatusCodes.SUCCESS) {
                    if (statusCode != BluetoothStatusCodes.SUCCESS) {
                        mCallbacks.notifySourceModifyFailed(sink, sourceId, statusCode);
                        mCallbacks.notifySourceModifyFailed(sink, sourceId, statusCode);
                        // remove the device from mPausedBroadcastSinks
                        iterator.remove();
                        continue;
                        continue;
                    }
                    }


@@ -3238,11 +3274,13 @@ public class BassClientService extends ProfileService {
                } else {
                } else {
                    Log.w(
                    Log.w(
                            TAG,
                            TAG,
                            "resumeReceiversSourceSynchronization: failed to get metadata to resume"
                            "resumeReceiversSourceSynchronization: failed to get metadata to"
                                    + " sink: "
                                    + " resume sink: "
                                    + sink);
                                    + sink);
                }
                }
            }
            }
            // remove the device from mPausedBroadcastSinks
            iterator.remove();
        }
        }
    }
    }


+1 −4
Original line number Original line Diff line number Diff line
@@ -78,16 +78,13 @@ import java.util.function.Predicate;
/**
/**
 * A helper class which contains all scan related functions extracted from {@link
 * A helper class which contains all scan related functions extracted from {@link
 * com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan
 * com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan
 * functionality within GattService and provide the same functionality in a new scan dedicated
 * functionality within GattService and provide the same functionality in {@link ScanController}.
 * {@link com.android.bluetooth.btservice.ProfileService} when introduced.
 */
 */
public class TransitionalScanHelper {
public class TransitionalScanHelper {
    private static final String TAG = GattServiceConfig.TAG_PREFIX + "ScanHelper";
    private static final String TAG = GattServiceConfig.TAG_PREFIX + "ScanHelper";


    // Batch scan related constants.
    // Batch scan related constants.
    private static final int TRUNCATED_RESULT_SIZE = 11;
    private static final int TRUNCATED_RESULT_SIZE = 11;
    static final int SCAN_FILTER_ENABLED = 1;
    static final int SCAN_FILTER_MODIFIED = 2;


    /** The default floor value for LE batch scan report delays greater than 0 */
    /** The default floor value for LE batch scan report delays greater than 0 */
    @VisibleForTesting static final long DEFAULT_REPORT_DELAY_FLOOR = 5000;
    @VisibleForTesting static final long DEFAULT_REPORT_DELAY_FLOOR = 5000;
+22 −17
Original line number Original line Diff line number Diff line
@@ -160,16 +160,19 @@ public class NotificationHelperService extends Service {
    }
    }


    private boolean shouldDisplayNotification(String countKey) {
    private boolean shouldDisplayNotification(String countKey) {
        final LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        final String dateKey = countKey + "_date";
        final String dateKey = countKey + "_date";
        final String date = Settings.Secure.getString(getContentResolver(), dateKey);
        final int countShown = Settings.Secure.getInt(getContentResolver(), countKey, 0);
        final int countShown = Settings.Secure.getInt(getContentResolver(), countKey, 0);
        final LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        LocalDateTime savedDate = null;
        if (countShown != 0) {
            // Check the saved date only if there is a count of notification.
            // This will detect manual override of the count setting.
            final String date = Settings.Secure.getString(getContentResolver(), dateKey);


            // The notification is always displayed the first time and if it has been at least…:
            // The notification is always displayed the first time and if it has been at least…:
            //  * … 1 week since the first display (aka recurring only once)
            //  * … 1 week since the first display (aka recurring only once)
            //  * … 6 months since the last display (aka recurring forever)
            //  * … 6 months since the last display (aka recurring forever)


        LocalDateTime savedDate = null;
            if (date != null) {
            if (date != null) {
                savedDate = LocalDateTime.parse(date);
                savedDate = LocalDateTime.parse(date);
                if ((countShown == 1 && now.isBefore(savedDate.plusWeeks(1)))
                if ((countShown == 1 && now.isBefore(savedDate.plusWeeks(1)))
@@ -183,6 +186,8 @@ public class NotificationHelperService extends Service {
                }
                }
            }
            }


        }

        Settings.Secure.putInt(getContentResolver(), countKey, Math.min(3, countShown + 1));
        Settings.Secure.putInt(getContentResolver(), countKey, Math.min(3, countShown + 1));
        Settings.Secure.putString(getContentResolver(), dateKey, now.toString());
        Settings.Secure.putString(getContentResolver(), dateKey, now.toString());
        Log.i(
        Log.i(
Loading