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

Commit 7147c575 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

csip: Allow to lock only connected devices

Before, CSIP required to have all devices connected in the set to
perform lock procedure.
From now on, CSIP will relax and allow to lock only connected devices
as there is no reason for beeing that strict

Bug: 230426955
Test: atest BluetoothInstrumentationTests
Test: atest --host bluetooth_csis_test
Tag: #stability
Change-Id: I88fc3f2a0e7af67cc3ee7e62813ee3ec08434cd9
parent bf99d7bc
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -498,6 +498,9 @@ public class CsipSetCoordinatorService extends ProfileService {
    public @Nullable UUID lockGroup(
            int groupId, @NonNull IBluetoothCsipSetCoordinatorLockCallback callback) {
        if (callback == null) {
            if (DBG) {
                Log.d(TAG, "lockGroup(): " + groupId + ", callback not provided ");
            }
            return null;
        }

@@ -524,12 +527,18 @@ public class CsipSetCoordinatorService extends ProfileService {
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
                if (DBG) {
                    Log.d(TAG, "lockGroup(): " + groupId + ", ERROR_CSIP_GROUP_LOCKED_BY_OTHER ");
                }
                return null;
            }

            mLocks.put(groupId, new Pair<>(uuid, callback));
        }

        if (DBG) {
            Log.d(TAG, "lockGroup(): locking group: " + groupId);
        }
        mCsipSetCoordinatorNativeInterface.groupLockSet(groupId, true);
        return uuid;
    }
@@ -542,6 +551,9 @@ public class CsipSetCoordinatorService extends ProfileService {
     */
    public void unlockGroup(@NonNull UUID lockUuid) {
        if (lockUuid == null) {
            if (DBG) {
                Log.d(TAG, "unlockGroup(): lockUuid is null");
            }
            return;
        }

@@ -550,6 +562,9 @@ public class CsipSetCoordinatorService extends ProfileService {
                    mLocks.entrySet()) {
                Pair<UUID, IBluetoothCsipSetCoordinatorLockCallback> uuidCbPair = entry.getValue();
                if (uuidCbPair.first.equals(lockUuid)) {
                    if (DBG) {
                        Log.d(TAG, "unlockGroup(): unlocking ... " + lockUuid);
                    }
                    mCsipSetCoordinatorNativeInterface.groupLockSet(entry.getKey(), false);
                    return;
                }
+4 −1
Original line number Diff line number Diff line
@@ -1011,7 +1011,10 @@ public class BluetoothProxy {

        Log.d("Lock", "lock: " + lock);
        if (lock) {
            if (mGroupLocks.containsKey(group_id)) return;
            if (mGroupLocks.containsKey(group_id)) {
                Log.e("Lock", "group" + group_id + " is already in locking process or locked: " + lock);
                return;
            }

            UUID uuid = bluetoothCsis.lockGroup(group_id, mExecutor,
                    (int group, int op_status, boolean is_locked) -> {
+12 −1
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ class CsisClientImpl : public CsisClient {
  std::shared_ptr<bluetooth::csis::CsisGroup> AssignCsisGroup(
      const RawAddress& address, int group_id,
      bool create_group_if_non_existing, const bluetooth::Uuid& uuid) {
    LOG_DEBUG("Device: %s, group_id: %d", address.ToString().c_str(), group_id);
    auto csis_group = FindCsisGroup(group_id);
    if (!csis_group) {
      if (create_group_if_non_existing) {
@@ -322,6 +323,10 @@ class CsisClientImpl : public CsisClient {
    }

    CsisLockState target_lock_state = csis_group->GetTargetLockState();

    LOG_DEBUG("Device %s, target lock: %d, status: 0x%02x",
              device->addr.ToString().c_str(), (int)target_lock_state,
              (int)status);
    if (target_lock_state == CsisLockState::CSIS_STATE_UNSET) return;

    if (status != GATT_SUCCESS &&
@@ -490,6 +495,10 @@ class CsisClientImpl : public CsisClient {
       * can revert lock previously locked devices as per specification.
       */
      auto csis_device = csis_group->GetFirstDevice();
      while (!csis_device->IsConnected()) {
        csis_device = csis_group->GetNextDevice(csis_device);
      }

      auto csis_instance = csis_device->GetCsisInstanceByGroupId(group_id);
      LOG_ASSERT(csis_instance) << " csis_instance does not exist!";
      SetLock(csis_device, csis_instance, new_lock_state);
@@ -676,7 +685,9 @@ class CsisClientImpl : public CsisClient {
        if (!instance) {
          stream << "          No csis instance available\n";
        } else {
          stream << "          rank: " << instance->GetRank() << "\n";
          stream << "          service handle: "
                 << loghex(instance->svc_data.start_handle)
                 << "          rank: " << +instance->GetRank() << "\n";
        }

        if (!device->IsConnected()) {
+29 −8
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include "bta_gatt_api.h"
#include "bta_groups.h"
#include "gap_api.h"
#include "gd/common/init_flags.h"
#include "gd/common/strings.h"
#include "stack/crypto_toolbox/crypto_toolbox.h"

namespace bluetooth {
@@ -363,15 +365,34 @@ class CsisGroup {

  bool IsAvailableForCsisLockOperation(void) {
    int id = group_id_;
    auto iter = std::find_if(devices_.begin(), devices_.end(), [id](auto& d) {
      if (!d->IsConnected()) return false;
    int number_of_connected = 0;
    auto iter = std::find_if(
        devices_.begin(), devices_.end(), [id, &number_of_connected](auto& d) {
          if (!d->IsConnected()) {
            LOG_DEBUG("Device %s is not connected in group %d",
                      d->addr.ToString().c_str(), id);
            return false;
          }
          auto inst = d->GetCsisInstanceByGroupId(id);
      LOG_ASSERT(inst);
          if (!inst) {
            LOG_DEBUG("Instance not available for group %d", id);
            return false;
          }
          number_of_connected++;
          LOG_DEBUG("Device %s,  lock state: %d", d->addr.ToString().c_str(),
                    (int)inst->GetLockState());
          return inst->GetLockState() == CsisLockState::CSIS_STATE_LOCKED;
        });

    LOG_DEBUG("Locked set: %d, number of connected %d", iter != devices_.end(),
              number_of_connected);
    /* If there is no locked device, we are good to go */
    return iter == devices_.end();
    if (iter != devices_.end()) {
      LOG_WARN("Device %s is locked ", (*iter)->addr.ToString().c_str());
      return false;
    }

    return (number_of_connected > 0);
  }

  void SortByCsisRank(void) {