Audio deamon: Add support of audio device events
Audio daemon will catch the events regarding the audio device changes and transfer them to audio HAL. Change-Id: Ida6b26142ece472a6e127904a43890ee44632d75
This commit is contained in:
parent
dddca0f1f8
commit
f8d52aab10
|
@ -30,6 +30,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
|
|||
#define LOG_NDEBUG 0
|
||||
#define LOG_NDDEBUG 0
|
||||
|
||||
#include <dirent.h>
|
||||
#include <media/AudioSystem.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
|
@ -117,6 +118,89 @@ namespace android {
|
|||
sndcardFdPair.clear();
|
||||
}
|
||||
|
||||
bool AudioDaemon::getDeviceEventFDs()
|
||||
{
|
||||
const char* events_dir = "/sys/class/switch/";
|
||||
DIR *dp;
|
||||
struct dirent* in_file;
|
||||
int fd;
|
||||
String8 path;
|
||||
|
||||
if ((dp = opendir(events_dir)) == NULL) {
|
||||
ALOGE("Cannot open switch directory to get list of audio events %s", events_dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
mAudioEvents.clear();
|
||||
mAudioEventsStatus.clear();
|
||||
|
||||
while ((in_file = readdir(dp)) != NULL) {
|
||||
|
||||
if (!strstr(in_file->d_name, "qc_"))
|
||||
continue;
|
||||
ALOGD(" Found event file = %s", in_file->d_name);
|
||||
path = "/sys/class/switch/";
|
||||
path += in_file->d_name;
|
||||
path += "/state";
|
||||
|
||||
ALOGE("Opening audio event state : %s ", path.string());
|
||||
fd = open(path.string(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
ALOGE("Open %s failed : %s", path.string(), strerror(errno));
|
||||
} else {
|
||||
mAudioEvents.push_back(std::make_pair(in_file->d_name, fd));
|
||||
mAudioEventsStatus.push_back(std::make_pair(in_file->d_name, 0));
|
||||
ALOGD("event status mAudioEventsStatus= %s",
|
||||
mAudioEventsStatus[0].first.string());
|
||||
}
|
||||
}
|
||||
|
||||
ALOGV("%s: %d audio device event detected",
|
||||
__func__,
|
||||
mAudioEvents.size());
|
||||
|
||||
closedir(dp);
|
||||
return mAudioEvents.size() > 0 ? true : false;
|
||||
|
||||
}
|
||||
|
||||
void AudioDaemon::putDeviceEventFDs()
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < mAudioEvents.size(); i++) {
|
||||
close(mAudioEvents[i].second);
|
||||
delete(mAudioEvents[i].first);
|
||||
}
|
||||
mAudioEvents.clear();
|
||||
mAudioEventsStatus.clear();
|
||||
}
|
||||
|
||||
void AudioDaemon::checkEventState(int fd, int index)
|
||||
{
|
||||
char state_buf[2];
|
||||
audio_event_status event_cur_state = audio_event_off;
|
||||
|
||||
if (!read(fd, (void *)state_buf, 1)) {
|
||||
ALOGE("Error receiving device state event (%s)", strerror(errno));
|
||||
} else {
|
||||
state_buf[1] = '\0';
|
||||
if (atoi(state_buf) != mAudioEventsStatus[index].second) {
|
||||
ALOGD("notify audio HAL %s",
|
||||
mAudioEvents[index].first.string());
|
||||
mAudioEventsStatus[index].second = atoi(state_buf);
|
||||
|
||||
if (mAudioEventsStatus[index].second == 1)
|
||||
event_cur_state = audio_event_on;
|
||||
else
|
||||
event_cur_state = audio_event_off;
|
||||
notifyAudioSystemEventStatus(
|
||||
mAudioEventsStatus[index].first.string(),
|
||||
event_cur_state);
|
||||
}
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
status_t AudioDaemon::readyToRun() {
|
||||
|
||||
ALOGV("readyToRun: open snd card state node files");
|
||||
|
@ -151,6 +235,10 @@ namespace android {
|
|||
}
|
||||
}
|
||||
|
||||
if (!getDeviceEventFDs()) {
|
||||
ALOGE("No audio device events detected");
|
||||
}
|
||||
|
||||
if (audioInitDone == false) {
|
||||
ALOGE("Sound Card is empty!!!");
|
||||
goto thread_exit;
|
||||
|
@ -177,13 +265,20 @@ namespace android {
|
|||
}
|
||||
ALOGD("number of sndcards %d CPEs %d", i, cpe_cnt - CPE_MAGIC_NUM);
|
||||
|
||||
pfd = new pollfd[mSndCardFd.size()];
|
||||
bzero(pfd, sizeof(*pfd) * mSndCardFd.size());
|
||||
pfd = new pollfd[mSndCardFd.size() + mAudioEvents.size()];
|
||||
bzero(pfd, (sizeof(*pfd) * mSndCardFd.size() +
|
||||
sizeof(*pfd) * mAudioEvents.size()));
|
||||
for (i = 0; i < mSndCardFd.size(); i++) {
|
||||
pfd[i].fd = mSndCardFd[i].second;
|
||||
pfd[i].events = POLLPRI;
|
||||
}
|
||||
|
||||
/*insert all audio events*/
|
||||
for(i = 0; i < mAudioEvents.size(); i++) {
|
||||
pfd[i+mSndCardFd.size()].fd = mAudioEvents[i].second;
|
||||
pfd[i+mSndCardFd.size()].events = POLLPRI;
|
||||
}
|
||||
|
||||
ALOGD("read for sound card state change before while");
|
||||
for (i = 0; i < mSndCardFd.size(); i++) {
|
||||
if (!read(pfd[i].fd, (void *)rd_buf, 8)) {
|
||||
|
@ -233,9 +328,14 @@ namespace android {
|
|||
}
|
||||
}
|
||||
|
||||
ALOGE("read for event state change before while");
|
||||
for (i = 0; i < mAudioEvents.size(); i++){
|
||||
checkEventState(pfd[i+mSndCardFd.size()].fd, i);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ALOGD("poll() for sound card state change ");
|
||||
if (poll(pfd, mSndCardFd.size(), -1) < 0) {
|
||||
if (poll(pfd, (mSndCardFd.size() + mAudioEvents.size()), -1) < 0) {
|
||||
ALOGE("poll() failed (%s)", strerror(errno));
|
||||
ret = false;
|
||||
break;
|
||||
|
@ -290,9 +390,19 @@ namespace android {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < mAudioEvents.size(); i++) {
|
||||
if (pfd[i + mSndCardFd.size()].revents & POLLPRI) {
|
||||
ALOGE("EVENT recieved pfd[i].revents= 0x%x %d",
|
||||
pfd[i + mSndCardFd.size()].revents,
|
||||
mAudioEvents[i].second);
|
||||
|
||||
checkEventState(pfd[i + mSndCardFd.size()].fd, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putStateFDs(mSndCardFd);
|
||||
putDeviceEventFDs();
|
||||
delete [] pfd;
|
||||
|
||||
thread_exit:
|
||||
|
@ -329,4 +439,20 @@ namespace android {
|
|||
ALOGV("%s: notifyAudioSystem : %s", __func__, str.string());
|
||||
AudioSystem::setParameters(0, str);
|
||||
}
|
||||
|
||||
void AudioDaemon::notifyAudioSystemEventStatus(const char* event,
|
||||
audio_event_status status) {
|
||||
|
||||
String8 str;
|
||||
str += AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE;
|
||||
str += "=";
|
||||
str += event;
|
||||
|
||||
if (status == audio_event_on)
|
||||
str += ",ON";
|
||||
else
|
||||
str += ",OFF";
|
||||
ALOGD("%s: notifyAudioSystemEventStatus : %s", __func__, str.string());
|
||||
AudioSystem::setParameters(0, str);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,10 @@ enum notify_status_type {
|
|||
CPE_STATE
|
||||
};
|
||||
|
||||
enum audio_event_status {audio_event_on, audio_event_off};
|
||||
|
||||
#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
|
||||
|
||||
class AudioDaemon:public Thread, public IBinder :: DeathRecipient
|
||||
{
|
||||
/*Overrides*/
|
||||
|
@ -64,9 +68,13 @@ class AudioDaemon:public Thread, public IBinder :: DeathRecipient
|
|||
void notifyAudioSystem(int snd_card,
|
||||
notify_status status,
|
||||
notify_status_type type);
|
||||
void notifyAudioSystemEventStatus(const char* event, audio_event_status status);
|
||||
int mUeventSock;
|
||||
bool getStateFDs(std::vector<std::pair<int,int> > &sndcardFdPair);
|
||||
void putStateFDs(std::vector<std::pair<int,int> > &sndcardFdPair);
|
||||
bool getDeviceEventFDs();
|
||||
void putDeviceEventFDs();
|
||||
void checkEventState(int fd, int index);
|
||||
|
||||
public:
|
||||
AudioDaemon();
|
||||
|
@ -74,6 +82,11 @@ public:
|
|||
|
||||
private:
|
||||
std::vector<std::pair<int,int> > mSndCardFd;
|
||||
|
||||
//file descriptors for audio device events and their statuses
|
||||
std::vector<std::pair<String8, int> > mAudioEvents;
|
||||
std::vector<std::pair<String8, int> > mAudioEventsStatus;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue