Loading audiod/AudioDaemon.cpp +129 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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"); Loading Loading @@ -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; Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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: Loading Loading @@ -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); } } audiod/AudioDaemon.h +13 −0 Original line number Diff line number Diff line Loading @@ -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*/ Loading @@ -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(); Loading @@ -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
audiod/AudioDaemon.cpp +129 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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"); Loading Loading @@ -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; Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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: Loading Loading @@ -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); } }
audiod/AudioDaemon.h +13 −0 Original line number Diff line number Diff line Loading @@ -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*/ Loading @@ -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(); Loading @@ -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; }; }