• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "AHAL_UsbAlsaMixerControl"
18 #include <android-base/logging.h>
19 
20 #include <android/binder_status.h>
21 
22 #include "UsbAlsaMixerControl.h"
23 
24 namespace aidl::android::hardware::audio::core::usb {
25 
26 // static
getInstance()27 UsbAlsaMixerControl& UsbAlsaMixerControl::getInstance() {
28     static UsbAlsaMixerControl gInstance;
29     return gInstance;
30 }
31 
setDeviceConnectionState(int card,bool masterMuted,float masterVolume,bool connected)32 void UsbAlsaMixerControl::setDeviceConnectionState(int card, bool masterMuted, float masterVolume,
33                                                    bool connected) {
34     LOG(DEBUG) << __func__ << ": card=" << card << ", connected=" << connected;
35     if (connected) {
36         auto alsaMixer = std::make_shared<alsa::Mixer>(card);
37         if (!alsaMixer->isValid()) {
38             return;
39         }
40         alsaMixer->setMasterMute(masterMuted);
41         alsaMixer->setMasterVolume(masterVolume);
42         const std::lock_guard guard(mLock);
43         mMixerControls.emplace(card, alsaMixer);
44     } else {
45         const std::lock_guard guard(mLock);
46         mMixerControls.erase(card);
47     }
48 }
49 
setMasterMute(bool mute)50 ndk::ScopedAStatus UsbAlsaMixerControl::setMasterMute(bool mute) {
51     auto alsaMixers = getAlsaMixers();
52     for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
53         if (auto result = it->second->setMasterMute(mute); !result.isOk()) {
54             // Return illegal state if there are multiple devices connected and one of them fails
55             // to set master mute. Otherwise, return the error from calling `setMasterMute`.
56             LOG(ERROR) << __func__ << ": failed to set master mute for card=" << it->first;
57             return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
58                                          : std::move(result);
59         }
60     }
61     return ndk::ScopedAStatus::ok();
62 }
63 
setMasterVolume(float volume)64 ndk::ScopedAStatus UsbAlsaMixerControl::setMasterVolume(float volume) {
65     auto alsaMixers = getAlsaMixers();
66     for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
67         if (auto result = it->second->setMasterVolume(volume); !result.isOk()) {
68             // Return illegal state if there are multiple devices connected and one of them fails
69             // to set master volume. Otherwise, return the error from calling `setMasterVolume`.
70             LOG(ERROR) << __func__ << ": failed to set master volume for card=" << it->first;
71             return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
72                                          : std::move(result);
73         }
74     }
75     return ndk::ScopedAStatus::ok();
76 }
77 
setVolumes(int card,const std::vector<float> & volumes)78 ndk::ScopedAStatus UsbAlsaMixerControl::setVolumes(int card, const std::vector<float>& volumes) {
79     auto alsaMixer = getAlsaMixer(card);
80     if (alsaMixer == nullptr) {
81         LOG(ERROR) << __func__ << ": no mixer control found for card=" << card;
82         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
83     }
84     return alsaMixer->setVolumes(volumes);
85 }
86 
getAlsaMixer(int card)87 std::shared_ptr<alsa::Mixer> UsbAlsaMixerControl::getAlsaMixer(int card) {
88     const std::lock_guard guard(mLock);
89     const auto it = mMixerControls.find(card);
90     return it == mMixerControls.end() ? nullptr : it->second;
91 }
92 
getAlsaMixers()93 std::map<int, std::shared_ptr<alsa::Mixer>> UsbAlsaMixerControl::getAlsaMixers() {
94     const std::lock_guard guard(mLock);
95     return mMixerControls;
96 }
97 
98 }  // namespace aidl::android::hardware::audio::core::usb
99