1 /*
2 **
3 ** Copyright 2014, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #ifndef ANDROID_AUDIO_HARDWARE_OUTPUT_H
19 #define ANDROID_AUDIO_HARDWARE_OUTPUT_H
20 
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <hardware/audio.h>
25 #include <utils/String8.h>
26 #include <utils/threads.h>
27 
28 #include "alsa_utils.h"
29 #include "AudioOutput.h"
30 
31 namespace android {
32 
33 class AudioStreamOut;
34 class AudioOutput;
35 
36 class AudioHardwareOutput {
37   public:
38                 AudioHardwareOutput();
39     virtual    ~AudioHardwareOutput();
40     status_t    initCheck();
41     status_t    setMasterVolume(float volume);
42     status_t    getMasterVolume(float* volume);
43     status_t    setMasterMute(bool mute);
44     status_t    getMasterMute(bool* mute);
45     status_t    setParameters(const char* kvpairs);
46     char*       getParameters(const char* keys);
47     status_t    dump(int fd);
48     void        updateRouting(uint32_t devMask);
getMaxDelayCompUsec()49     uint32_t    getMaxDelayCompUsec() const { return mMaxDelayCompUsec; }
getVideoDelayCompUsec()50     uint32_t    getVideoDelayCompUsec() const {
51         return mSettings.videoDelayCompUsec;
52     }
getHDMIAudioCaps()53     HDMIAudioCaps& getHDMIAudioCaps() { return mHDMIAudioCaps; }
54 
55     // Interface to allow streams to obtain and release various physical
56     // outputs.
57     status_t       obtainOutput(const AudioStreamOut& tgtStream,
58                              uint32_t devMask,
59                              sp<AudioOutput>* newOutput);
60     void           releaseOutput(const AudioStreamOut& tgtStream,
61                               const sp<AudioOutput>& releaseMe);
62 
63 
64     // create I/O streams
65     AudioStreamOut* openOutputStream(uint32_t  devices,
66                                      audio_format_t *format,
67                                      uint32_t *channels,
68                                      uint32_t *sampleRate,
69                                      audio_output_flags_t flags,
70                                      status_t *status);
71     void           closeOutputStream(AudioStreamOut* out);
72 
73     void           standbyStatusUpdate(bool isInStandby, bool isMCStream);
74 
75   private:
76     struct OutputSettings {
77         bool        allowed;
78         uint32_t    delayCompUsec;
79         bool        isFixed;
80         float       fixedLvl;
81         void        setDefaults();
82     };
83 
84     struct Settings {
85         OutputSettings hdmi;
86         uint32_t       videoDelayCompUsec;
87         float          masterVolume;
88         bool           masterMute;
89         void           setDefaults();
90     };
91 
92     void     updateTgtDevices_l();
93     bool     applyOutputSettings_l(const OutputSettings& initial,
94                                    const OutputSettings& current,
95                                    OutputSettings& updateMe,
96                                    uint32_t outDevMask);
97 
98     // Notes on locking:
99     // There are 3 locks in the AudioHardware class; mStreamLock, mOutputLock
100     // and mSettingsLock.
101     //
102     // mStreamLock is held when interacting with AudioStreamOuts, in particular
103     // during creation and destruction of streams, and during routing changes
104     // (HDMI connecting and disconnecting) which (potentially) end up effecting
105     // the target device masks of the output streams.
106     //
107     // mOutputLock is held while interacting with AudioOutputs (which represent
108     // the physical outputs of the system).  AudioStreamOuts grab this lock
109     // during calls to (obtain|release)Output which can trigger instantiation
110     // and destruction of AudioOutputs.  During this operation, the
111     // AudioStreamOut instance will be holding its own "routing" lock.  Care
112     // should be taken to never hold the output lock or setting lock while making
113     // a call into an AudioStreamOut which may obtain the routing lock.
114     // Currently, the set of publicly accessible calls in AudioStreamOut which
115     // may obtain the routing lock are...
116     // 1) ~AudioStreamOut (calls releaseAllOutputs)
117     // 2) standby (calls releaseAllOutputs)
118     // 3) pause (calls releaseAllOutputs)
119     // 4) setTgtDevices
120     // 5) getPresentationPosition
121     // 6) write
122     //
123     // mSettingsLock is held while reading settings and while writing/applying
124     // settings to existing outputs.  Lock ordering is important when applying
125     // settings to outputs as the both the output and settings lock need to be
126     // held at the same time.  Whenever settings need to be applied to outputs,
127     // the output lock should always obtained first, followed by the settings
128     // lock.
129 
130     Mutex            mStreamLock;
131     AudioStreamOut  *mMainOutput;
132     AudioStreamOut  *mMCOutput;
133     bool             mHDMIConnected;
134 
135     Mutex            mOutputLock;
136     AudioOutputList  mPhysOutputs;
137 
138     Mutex            mSettingsLock;
139     Settings         mSettings;
140     uint32_t         mMaxDelayCompUsec;
141 
142     HDMIAudioCaps    mHDMIAudioCaps;
143     int              mHDMICardID;
144 
145     static const String8 kHDMIAllowedParamKey;
146     static const String8 kHDMIDelayCompParamKey;
147     static const String8 kFixedHDMIOutputParamKey;
148     static const String8 kFixedHDMIOutputLevelParamKey;
149     static const String8 kVideoDelayCompParamKey;
150     static const float   kDefaultMasterVol;
151 
152 };
153 
154 // ----------------------------------------------------------------------------
155 
156 }; // namespace android
157 
158 #endif  // ANDROID_AUDIO_HARDWARE_OUTPUT_H
159