platform_hardware_libhardwa.../include/hardware_legacy/AudioPolicyManagerBase.h
Jean-Michel Trivi 12bd6e4a5c Only duplicate notifications when no media is playing
Map the NOTIFICATION stream type to a new strategy,
 named STRATEGY_NOTIFICATION_RESPECTFUL, which differs
 from STRATEGY_NOTIFICATION in that, when media is
 playing, the notifications will use the same output
 as the MEDIA strategy. This will results in the
 notifications not being duplicated on the speaker
 when a headset is in use for media playback.

Change-Id: I032be0e2d383c69b5b6c912d7174753f5572c4b4
2012-04-02 09:31:09 -07:00

457 lines
23 KiB
C++

/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <sys/types.h>
#include <utils/Timers.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <hardware_legacy/AudioPolicyInterface.h>
namespace android_audio_legacy {
using android::KeyedVector;
using android::DefaultKeyedVector;
using android::SortedVector;
// ----------------------------------------------------------------------------
#define MAX_DEVICE_ADDRESS_LEN 20
// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
#define SONIFICATION_HEADSET_VOLUME_MIN 0.016
// Time in milliseconds during which we consider that music is still active after a music
// track was stopped - see computeVolume()
#define SONIFICATION_HEADSET_MUSIC_DELAY 5000
// Time in milliseconds after media stopped playing during which we consider that the
// sonification should be as unobtrusive as during the time media was playing.
#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
// Time in milliseconds during witch some streams are muted while the audio path
// is switched
#define MUTE_TIME_MS 2000
#define NUM_TEST_OUTPUTS 5
#define NUM_VOL_CURVE_KNEES 2
// ----------------------------------------------------------------------------
// AudioPolicyManagerBase implements audio policy manager behavior common to all platforms.
// Each platform must implement an AudioPolicyManager class derived from AudioPolicyManagerBase
// and override methods for which the platform specific behavior differs from the implementation
// in AudioPolicyManagerBase. Even if no specific behavior is required, the AudioPolicyManager
// class must be implemented as well as the class factory function createAudioPolicyManager()
// and provided in a shared library libaudiopolicy.so.
// ----------------------------------------------------------------------------
// the output_profile_s structure describes the capabilities of an output stream.
// It is currently assumed that all combination of listed parameters are supported.
// It is used by the policy manager to determine if an output is suitable for a given use case,
// open/close it accordingly and connect/disconnect audio tracks to/from it.
typedef struct output_profile_s {
uint32_t* mSamplingRates; // supported sampling rates (terminated by 0)
audio_channel_mask_t* mChannelMasks; // supported channel masks (terminated by 0)
audio_format_t* mFormats; // supported audio formats (terminated by 0)
audio_devices_t mSupportedDevices; // supported devices (devices this output can be
// routed to)
audio_policy_output_flags_t mFlags; // attribute flags (e.g primary output,
// direct output...)
} output_profile_t;
class AudioPolicyManagerBase: public AudioPolicyInterface
#ifdef AUDIO_POLICY_TEST
, public Thread
#endif //AUDIO_POLICY_TEST
{
public:
AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface);
virtual ~AudioPolicyManagerBase();
// AudioPolicyInterface
virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
AudioSystem::device_connection_state state,
const char *device_address);
virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
const char *device_address);
virtual void setPhoneState(int state);
virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
virtual void setSystemProperty(const char* property, const char* value);
virtual status_t initCheck();
virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
uint32_t samplingRate = 0,
uint32_t format = AudioSystem::FORMAT_DEFAULT,
uint32_t channels = 0,
AudioSystem::output_flags flags =
AudioSystem::OUTPUT_FLAG_INDIRECT);
virtual status_t startOutput(audio_io_handle_t output,
AudioSystem::stream_type stream,
int session = 0);
virtual status_t stopOutput(audio_io_handle_t output,
AudioSystem::stream_type stream,
int session = 0);
virtual void releaseOutput(audio_io_handle_t output);
virtual audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
AudioSystem::audio_in_acoustics acoustics);
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input);
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input);
virtual void releaseInput(audio_io_handle_t input);
virtual void initStreamVolume(AudioSystem::stream_type stream,
int indexMin,
int indexMax);
virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream,
int index,
audio_devices_t device);
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream,
int *index,
audio_devices_t device);
// return the strategy corresponding to a given stream type
virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream);
// return the enabled output devices for the given stream type
virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream);
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
virtual status_t registerEffect(effect_descriptor_t *desc,
audio_io_handle_t io,
uint32_t strategy,
int session,
int id);
virtual status_t unregisterEffect(int id);
virtual status_t setEffectEnabled(int id, bool enabled);
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
virtual status_t dump(int fd);
protected:
enum routing_strategy {
STRATEGY_MEDIA,
STRATEGY_PHONE,
STRATEGY_SONIFICATION,
STRATEGY_SONIFICATION_RESPECTFUL,
STRATEGY_DTMF,
STRATEGY_ENFORCED_AUDIBLE,
NUM_STRATEGIES
};
// 4 points to define the volume attenuation curve, each characterized by the volume
// index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
// we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4};
class VolumeCurvePoint
{
public:
int mIndex;
float mDBAttenuation;
};
// device categories used for volume curve management.
enum device_category {
DEVICE_CATEGORY_HEADSET,
DEVICE_CATEGORY_SPEAKER,
DEVICE_CATEGORY_EARPIECE,
DEVICE_CATEGORY_CNT
};
// default volume curve
static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT];
// default volume curve for media strategy
static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
// volume curve for media strategy on speakers
static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
// volume curve for sonification strategy on speakers
static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT];
// default volume curves per strategy and device category. See initializeVolumeCurves()
static const VolumeCurvePoint *sVolumeProfiles[NUM_STRATEGIES][DEVICE_CATEGORY_CNT];
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor
{
public:
AudioOutputDescriptor(const output_profile_t *profile);
status_t dump(int fd);
audio_devices_t device();
void changeRefCount(AudioSystem::stream_type, int delta);
uint32_t refCount();
uint32_t strategyRefCount(routing_strategy strategy);
bool isUsedByStrategy(routing_strategy strategy) { return (strategyRefCount(strategy) != 0);}
bool isDuplicated() { return (mOutput1 != NULL && mOutput2 != NULL); }
audio_devices_t supportedDevices();
audio_io_handle_t mId; // output handle
uint32_t mSamplingRate; //
uint32_t mFormat; //
uint32_t mChannels; // output configuration
uint32_t mLatency; //
AudioSystem::output_flags mFlags; //
audio_devices_t mDevice; // current device this output is routed to
uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using this output
nsecs_t mStopTime[AudioSystem::NUM_STREAM_TYPES];
AudioOutputDescriptor *mOutput1; // used by duplicated outputs: first output
AudioOutputDescriptor *mOutput2; // used by duplicated outputs: second output
float mCurVolume[AudioSystem::NUM_STREAM_TYPES]; // current stream volume
int mMuteCount[AudioSystem::NUM_STREAM_TYPES]; // mute request counter
const output_profile_t *mProfile;
};
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
class AudioInputDescriptor
{
public:
AudioInputDescriptor();
status_t dump(int fd);
uint32_t mSamplingRate; //
uint32_t mFormat; // input configuration
uint32_t mChannels; //
AudioSystem::audio_in_acoustics mAcoustics; //
audio_devices_t mDevice; // current device this input is routed to
uint32_t mRefCount; // number of AudioRecord clients using this output
int mInputSource; // input source selected by application (mediarecorder.h)
};
// stream descriptor used for volume control
class StreamDescriptor
{
public:
StreamDescriptor();
int getVolumeIndex(audio_devices_t device);
void dump(int fd);
int mIndexMin; // min volume index
int mIndexMax; // max volume index
KeyedVector<audio_devices_t, int> mIndexCur; // current volume index per device
bool mCanBeMuted; // true is the stream can be muted
const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT];
};
// stream descriptor used for volume control
class EffectDescriptor
{
public:
status_t dump(int fd);
int mIo; // io the effect is attached to
routing_strategy mStrategy; // routing strategy the effect is associated to
int mSession; // audio session the effect is on
effect_descriptor_t mDesc; // effect descriptor
bool mEnabled; // enabled state: CPU load being used or not
};
void addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc);
// return the strategy corresponding to a given stream type
static routing_strategy getStrategy(AudioSystem::stream_type stream);
// return appropriate device for streams handled by the specified strategy according to current
// phone state, connected devices...
// if fromCache is true, the device is returned from mDeviceForStrategy[], otherwise it is determined
// by current state (device connected, phone state, force use, a2dp output...)
// This allows to:
// 1 speed up process when the state is stable (when starting or stopping an output)
// 2 access to either current device selection (fromCache == true) or
// "future" device selection (fromCache == false) when called from a context
// where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
// before updateDeviceForStrategy() is called.
virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, bool fromCache = true);
// change the route of the specified output
void setOutputDevice(audio_io_handle_t output,
audio_devices_t device,
bool force = false,
int delayMs = 0);
// select input device corresponding to requested audio source
virtual audio_devices_t getDeviceForInputSource(int inputSource);
// return io handle of active input or 0 if no input is active
audio_io_handle_t getActiveInput();
// initialize volume curves for each strategy and device category
void initializeVolumeCurves();
// compute the actual volume for a given stream according to the requested index and a particular
// device
virtual float computeVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device);
// check that volume change is permitted, compute and send new volume to audio hardware
status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
// apply all stream volumes to the specified output and device
void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
// Mute or unmute all streams handled by the specified strategy on the specified output
void setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs = 0);
// Mute or unmute the stream on the specified output
void setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs = 0);
// handle special cases for sonification strategy while in call: mute streams or replace by
// a special tone in the device used for communication
void handleIncallSonification(int stream, bool starting, bool stateChange);
// true is current platform implements a back microphone
virtual bool hasBackMicrophone() const { return false; }
// true if device is in a telephony or VoIP call
virtual bool isInCall();
// true if given state represents a device in a telephony or VoIP call
virtual bool isStateInCall(int state);
// when a device is connected, checks if an open output can be routed
// to this device. If none is open, tries to open one of the available outputs.
// Returns an output suitable to this device or 0.
// when a device is disconnected, checks if an output is not used any more and
// returns its handle if any.
// transfers the audio tracks and effects from one output thread to another accordingly.
audio_io_handle_t checkOutputForDevice(audio_devices_t device,
AudioSystem::device_connection_state state);
// close an output and its companion duplicating output.
void closeOutput(audio_io_handle_t output);
// checks and if necessary changes outputs used for all strategies.
// must be called every time a condition that affects the output choice for a given strategy
// changes: connected device, phone state, force use...
// Must be called before updateDeviceForStrategy()
void checkOutputForStrategy(routing_strategy strategy);
// Same as checkOutputForStrategy() but for a all strategies in order of priority
void checkOutputForAllStrategies();
// manages A2DP output suspend/restore according to phone state and BT SCO usage
void checkA2dpSuspend();
// returns the A2DP output handle if it is open or 0 otherwise
audio_io_handle_t getA2dpOutput();
// selects the most appropriate device on output for current state
// must be called every time a condition that affects the device choice for a given output is
// changed: connected device, phone state, force use, output start, output stop..
// see getDeviceForStrategy() for the use of fromCache parameter
audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache = true);
// updates cache of device used by all strategies (mDeviceForStrategy[])
// must be called every time a condition that affects the device choice for a given strategy is
// changed: connected device, phone state, force use...
// cached values are used by getDeviceForStrategy() if parameter fromCache is true.
// Must be called after checkOutputForAllStrategies()
void updateDeviceForStrategy();
// true if current platform requires a specific output to be opened for this particular
// set of parameters. This function is called by getOutput() and is implemented by platform
// specific audio policy manager.
virtual bool needsDirectOuput(AudioSystem::stream_type stream,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
AudioSystem::output_flags flags,
uint32_t device);
virtual uint32_t getMaxEffectsCpuLoad();
virtual uint32_t getMaxEffectsMemory();
#ifdef AUDIO_POLICY_TEST
virtual bool threadLoop();
void exit();
int testOutputIndex(audio_io_handle_t output);
#endif //AUDIO_POLICY_TEST
status_t setEffectEnabled(EffectDescriptor *pDesc, bool enabled);
// returns the category the device belongs to with regard to volume curve management
static device_category getDeviceCategory(audio_devices_t device);
// extract one device relevant for volume control from multiple device selection
static audio_devices_t getDeviceForVolume(audio_devices_t device);
SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device);
bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
SortedVector<audio_io_handle_t>& outputs2);
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
audio_io_handle_t mPrimaryOutput; // primary output handle
DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs; // list of output descriptors
DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor *> mInputs; // list of input descriptors
audio_devices_t mAvailableOutputDevices; // bit field of all available output devices
uint32_t mAvailableInputDevices; // bit field of all available input devices
int mPhoneState; // current phone state
AudioSystem::forced_config mForceUse[AudioSystem::NUM_FORCE_USE]; // current forced use configuration
StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES]; // stream descriptors for volume control
String8 mA2dpDeviceAddress; // A2DP device MAC address
String8 mScoDeviceAddress; // SCO device MAC address
bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
float mLastVoiceVolume; // last voice volume value sent to audio HAL
// Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
// Maximum memory allocated to audio effects in KB
static const uint32_t MAX_EFFECTS_MEMORY = 512;
uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
uint32_t mTotalEffectsMemory; // current memory used by effects
KeyedVector<int, EffectDescriptor *> mEffects; // list of registered audio effects
bool mA2dpSuspended; // true if A2DP output is suspended
#ifdef AUDIO_POLICY_TEST
Mutex mLock;
Condition mWaitWorkCV;
int mCurOutput;
bool mDirectOutput;
audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
int mTestInput;
uint32_t mTestDevice;
uint32_t mTestSamplingRate;
uint32_t mTestFormat;
uint32_t mTestChannels;
uint32_t mTestLatencyMs;
#endif //AUDIO_POLICY_TEST
private:
static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
int indexInUi);
// updates device caching and output for streams that can influence the
// routing of notifications
void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
};
};