| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/ash/components/audio/audio_device_encoding.h" |
| |
| #include <bitset> |
| |
| #include "base/check.h" |
| #include "chromeos/ash/components/audio/audio_device.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Bit size for a set of audio devices. |
| const size_t kSingleDeviceSetBitSize = 14; |
| |
| // Gets the bit position of all current input/output device set. |
| // Do not change position since it's used for histograms. |
| size_t GetBitPositionFromDeviceType(AudioDeviceType type) { |
| switch (type) { |
| case AudioDeviceType::kInternalMic: |
| case AudioDeviceType::kFrontMic: |
| case AudioDeviceType::kRearMic: |
| case AudioDeviceType::kInternalSpeaker: |
| return 0; |
| case AudioDeviceType::kMic: |
| case AudioDeviceType::kHeadphone: |
| case AudioDeviceType::kLineout: |
| return 2; |
| case AudioDeviceType::kUsb: |
| return 4; |
| case AudioDeviceType::kBluetooth: |
| case AudioDeviceType::kBluetoothNbMic: |
| return 6; |
| case AudioDeviceType::kHdmi: |
| return 8; |
| default: |
| // All other types. |
| return 10; |
| } |
| } |
| |
| // Counts the device to the given val. |
| void CountDevice(std::bitset<kSingleDeviceSetBitSize>& val, |
| const AudioDevice& device) { |
| size_t pos = GetBitPositionFromDeviceType(device.type); |
| // The position for each device type should be an even number. |
| CHECK(pos % 2 == 0); |
| |
| // If current bit is off, turn it on no matter next bit is on or off. |
| if (!val.test(pos)) { |
| val.set(pos, true); |
| } else if (!val.test(pos + 1)) { |
| // If current bit is on and next bit is off, flip both of them. |
| val.flip(pos); |
| val.flip(pos + 1); |
| } |
| } |
| |
| } // namespace |
| |
| uint32_t EncodeAudioDeviceSet(const AudioDeviceList& devices) { |
| std::bitset<kSingleDeviceSetBitSize> number = 0b0; |
| for (const AudioDevice& device : devices) { |
| CountDevice(number, device); |
| } |
| return static_cast<uint32_t>(number.to_ulong()); |
| } |
| |
| uint32_t EncodeBeforeAndAfterAudioDeviceSets( |
| const AudioDeviceList& device_set_before, |
| const AudioDeviceList& device_set_after) { |
| uint32_t number_before = EncodeAudioDeviceSet(device_set_before); |
| uint32_t number_after = EncodeAudioDeviceSet(device_set_after); |
| return (number_before << kSingleDeviceSetBitSize) | number_after; |
| } |
| |
| } // namespace ash |