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

Commit aa90de8c authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Automerger Merge Worker
Browse files

Merge "LeAudio: Make device inactive if Media is not available" into main am: ab05db25

parents c84c0291 ab05db25
Loading
Loading
Loading
Loading
+43 −5
Original line number Diff line number Diff line
@@ -186,13 +186,14 @@ public class LeAudioService extends ProfileService {
            mAvailableContexts = 0;
            mInputSelectableConfig = new ArrayList<>();
            mOutputSelectableConfig = new ArrayList<>();
            mInactivatedDueToContextType = false;
        }

        public Boolean mIsConnected;
        public Boolean mIsActive;
        public Boolean mHasFallbackDeviceWhenGettingInactive;
        public Integer mDirection;
        public BluetoothLeAudioCodecStatus mCodecStatus;
        Boolean mIsConnected;
        Boolean mIsActive;
        Boolean mHasFallbackDeviceWhenGettingInactive;
        Integer mDirection;
        BluetoothLeAudioCodecStatus mCodecStatus;
        /* This can be non empty only for the streaming time */
        BluetoothDevice mLostLeadDeviceWhileStreaming;
        BluetoothDevice mCurrentLeadDevice;
@@ -200,6 +201,7 @@ public class LeAudioService extends ProfileService {
        Integer mAvailableContexts;
        List<BluetoothLeAudioCodecConfig> mInputSelectableConfig;
        List<BluetoothLeAudioCodecConfig> mOutputSelectableConfig;
        Boolean mInactivatedDueToContextType;
    }

    private static class LeAudioDeviceDescriptor {
@@ -1522,6 +1524,21 @@ public class LeAudioService extends ProfileService {
        return mActiveAudioOutDevice != null;
    }

    private void clearInactiveDueToContextTypeFlags() {
        synchronized (mGroupLock) {
            for (Map.Entry<Integer, LeAudioGroupDescriptor> groupEntry :
                    mGroupDescriptors.entrySet()) {
                LeAudioGroupDescriptor groupDescriptor = groupEntry.getValue();
                if (groupDescriptor.mInactivatedDueToContextType) {
                    if (DBG) {
                        Log.d(TAG, "clearInactiveDueToContextTypeFlags " + groupEntry.getKey());
                    }
                    groupDescriptor.mInactivatedDueToContextType = false;
                }
            }
        }
    }

    /**
     * Set the active device group.
     *
@@ -1539,6 +1556,7 @@ public class LeAudioService extends ProfileService {
            }

            groupId = descriptor.mGroupId;
            clearInactiveDueToContextTypeFlags();
        }

        int currentlyActiveGroupId = getActiveGroupId();
@@ -1824,6 +1842,13 @@ public class LeAudioService extends ProfileService {
                                                .LE_AUDIO_NONALLOWLIST_GROUP_HEALTH_STATUS_TRENDING_BAD,
                                1);
                break;
            case LeAudioStackEvent.HEALTH_RECOMMENDATION_ACTION_INACTIVATE_GROUP:
                LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId);
                if (groupDescriptor != null && groupDescriptor.mIsActive) {
                    Log.i(TAG, "Group " + groupId + " is inactivated due to blocked media context");
                    groupDescriptor.mInactivatedDueToContextType = true;
                    setActiveGroupWithDevice(null, true);
                }
            default:
                break;
        }
@@ -2238,6 +2263,15 @@ public class LeAudioService extends ProfileService {
                    descriptor.mDirection = direction;
                    descriptor.mAvailableContexts = available_contexts;
                    updateInbandRingtoneForTheGroup(groupId);

                    boolean mediaIsAvailable =
                            ((descriptor.mAvailableContexts & BluetoothLeAudio.CONTEXT_TYPE_MEDIA)
                                    != 0);

                    if (descriptor.mInactivatedDueToContextType && mediaIsAvailable) {
                        Log.i(TAG, " Media context type again available for " + groupId);
                        setActiveGroupWithDevice(getLeadDeviceForTheGroup(groupId), true);
                    }
                } else {
                    Log.e(TAG, "messageFromNative: no descriptors for group: " + groupId);
                }
@@ -4148,6 +4182,10 @@ public class LeAudioService extends ProfileService {
                        + groupDescriptor.mLostLeadDeviceWhileStreaming);
                ProfileService.println(sb, "  mInbandRingtoneEnabled: "
                        + groupDescriptor.mInbandRingtoneEnabled);
                ProfileService.println(
                        sb,
                        "mInactivatedDueToContextType: "
                                + groupDescriptor.mInactivatedDueToContextType);

                for (Map.Entry<BluetoothDevice, LeAudioDeviceDescriptor> deviceEntry
                        : mDeviceDescriptors.entrySet()) {
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ public class LeAudioStackEvent {
    static final int HEALTH_RECOMMENDATION_ACTION_NONE = 0;
    static final int HEALTH_RECOMMENDATION_ACTION_DISABLE = 1;
    static final int HEALTH_RECOMMENDATION_ACTION_CONSIDER_DISABLING = 2;
    static final int HEALTH_RECOMMENDATION_ACTION_INACTIVATE_GROUP = 3;

    static final int GROUP_STATUS_INACTIVE = 0;
    static final int GROUP_STATUS_ACTIVE = 1;
@@ -217,6 +218,8 @@ public class LeAudioStackEvent {
                        return "ACTION_DISABLE";
                    case HEALTH_RECOMMENDATION_ACTION_CONSIDER_DISABLING:
                        return "ACTION_CONSIDER_DISABLING";
                    case HEALTH_RECOMMENDATION_ACTION_INACTIVATE_GROUP:
                        return "ACTION_INACTIVATE_GROUP";
                    default:
                        return "UNKNOWN";
                }
+34 −0
Original line number Diff line number Diff line
@@ -1536,6 +1536,40 @@ public class LeAudioServiceTest {
        assertThat(mService.mLeAudioNativeIsInitialized).isTrue();
    }

    @Test
    public void testMediaContextUnavailableForAWhile() {
        doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class));
        connectTestDevice(mSingleDevice, testGroupId);

        String action = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED;
        Integer contexts = BluetoothLeAudio.CONTEXT_TYPE_MEDIA;
        injectAudioConfChanged(testGroupId, contexts, 1);

        // Set group and device as active.
        injectGroupStatusChange(testGroupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE);

        verify(mAudioManager, times(1))
                .handleBluetoothActiveDeviceChanged(
                        eq(mSingleDevice), any(), any(BluetoothProfileConnectionInfo.class));

        LeAudioStackEvent healthBasedGroupAction =
                new LeAudioStackEvent(
                        LeAudioStackEvent.EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION);
        healthBasedGroupAction.valueInt1 = testGroupId;
        healthBasedGroupAction.valueInt2 =
                LeAudioStackEvent.HEALTH_RECOMMENDATION_ACTION_INACTIVATE_GROUP;
        mService.messageFromNative(healthBasedGroupAction);

        verify(mAudioManager, times(1))
                .handleBluetoothActiveDeviceChanged(
                        eq(null), any(), any(BluetoothProfileConnectionInfo.class));

        injectAudioConfChanged(testGroupId, contexts, 1);
        verify(mAudioManager, times(1))
                .handleBluetoothActiveDeviceChanged(
                        eq(mSingleDevice), any(), any(BluetoothProfileConnectionInfo.class));
    }

    private void sendEventAndVerifyIntentForGroupStatusChanged(int groupId, int groupStatus) {

        onGroupStatusCallbackCalled = false;
+4 −0
Original line number Diff line number Diff line
@@ -3815,6 +3815,10 @@ class LeAudioClientImpl : public LeAudioClient {

    if (!remote_contexts.sink.any() && !remote_contexts.source.any()) {
      LOG_WARN("Requested context type not available on the remote side");
      if (leAudioHealthStatus_) {
        leAudioHealthStatus_->AddStatisticForGroup(
            group, LeAudioHealthGroupStatType::STREAM_CONTEXT_NOT_AVAILABLE);
      }
      return false;
    }

+13 −1
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ class LeAudioHealthStatusImpl : public LeAudioHealthStatus {
        group->stream_signaling_failures_cnt_++;
        group->stream_failures_cnt_++;
        break;
      case LeAudioHealthGroupStatType::STREAM_CONTEXT_NOT_AVAILABLE:
        group->stream_context_not_avail_cnt_++;
        break;
    }

    LeAudioHealthBasedAction action = LeAudioHealthBasedAction::NONE;
@@ -152,12 +155,20 @@ class LeAudioHealthStatusImpl : public LeAudioHealthStatus {
      if ((group->stream_failures_cnt_ >=
           MAX_ALLOWED_FAILURES_IN_A_ROW_WITHOUT_SUCCESS)) {
        action = LeAudioHealthBasedAction::DISABLE;
      } else if (group->stream_context_not_avail_cnt_ >=
                 MAX_ALLOWED_FAILURES_IN_A_ROW_WITHOUT_SUCCESS) {
        action = LeAudioHealthBasedAction::INACTIVATE_GROUP;
        group->stream_context_not_avail_cnt_ = 0;
      }
    } else {
      /* Had some success before */
      if ((100 * group->stream_failures_cnt_ / group->stream_success_cnt_) >=
          THRESHOLD_FOR_DISABLE_CONSIDERATION) {
        action = LeAudioHealthBasedAction::CONSIDER_DISABLING;
      } else if (group->stream_context_not_avail_cnt_ >=
                 MAX_ALLOWED_FAILURES_IN_A_ROW_WITHOUT_SUCCESS) {
        action = LeAudioHealthBasedAction::INACTIVATE_GROUP;
        group->stream_context_not_avail_cnt_ = 0;
      }
    }

@@ -195,7 +206,8 @@ class LeAudioHealthStatusImpl : public LeAudioHealthStatus {
           << ", success: " << group.stream_success_cnt_
           << ", fail total: " << group.stream_failures_cnt_
           << ", fail cis: " << group.stream_cis_failures_cnt_
           << ", fail signaling: " << group.stream_signaling_failures_cnt_;
           << ", fail signaling: " << group.stream_signaling_failures_cnt_
           << ", context not avail: " << group.stream_context_not_avail_cnt_;

    dprintf(fd, "%s", stream.str().c_str());
  }
Loading