Skip to content

Commit

Permalink
Audio deamon: Add support of audio device events
Browse files Browse the repository at this point in the history
Audio daemon will catch the events regarding the audio device changes and
transfer them to audio HAL.

Change-Id: Ida6b26142ece472a6e127904a43890ee44632d75
  • Loading branch information
tfinkel authored and Gerrit - the friendly Code Review server committed Jul 30, 2014
1 parent dddca0f commit f8d52aa
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 3 deletions.
132 changes: 129 additions & 3 deletions audiod/AudioDaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
}
}
13 changes: 13 additions & 0 deletions audiod/AudioDaemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*/
Expand All @@ -64,16 +68,25 @@ 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();
virtual ~AudioDaemon();

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;

};

}

0 comments on commit f8d52aa

Please sign in to comment.