Loading media/audioserver/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ cc_binary { "libaaudioservice", "libaudioflinger", "libaudiopolicyservice", "libmedialogservice", ], shared_libs: [ Loading media/audioserver/main_audioserver.cpp +65 −152 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #include "AudioPolicyService.h" #include "AAudioService.h" #include "utility/AAudioUtilities.h" #include "MediaLogService.h" using namespace android; Loading @@ -48,7 +47,7 @@ using android::media::audio::common::AudioMMapPolicy; using android::media::audio::common::AudioMMapPolicyInfo; using android::media::audio::common::AudioMMapPolicyType; int main(int argc __unused, char **argv) int main(int argc __unused, char **argv __unused) { ALOGD("%s: starting", __func__); const auto startTime = std::chrono::steady_clock::now(); Loading @@ -60,91 +59,6 @@ int main(int argc __unused, char **argv) signal(SIGPIPE, SIG_IGN); #if 1 // FIXME See bug 165702394 and bug 168511485 const bool doLog = false; #else bool doLog = (bool) property_get_bool("ro.test_harness", 0); #endif pid_t childPid; // FIXME The advantage of making the process containing media.log service the parent process of // the process that contains the other audio services, is that it allows us to collect more // detailed information such as signal numbers, stop and continue, resource usage, etc. // But it is also more complex. Consider replacing this by independent processes, and using // binder on death notification instead. if (doLog && (childPid = fork()) != 0) { // media.log service //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0); // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack strcpy(argv[0], "media.log"); sp<ProcessState> proc(ProcessState::self()); MediaLogService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); for (;;) { siginfo_t info; int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED)); if (ret < 0) { break; } char buffer[32]; const char *code; switch (info.si_code) { case CLD_EXITED: code = "CLD_EXITED"; break; case CLD_KILLED: code = "CLD_KILLED"; break; case CLD_DUMPED: code = "CLD_DUMPED"; break; case CLD_STOPPED: code = "CLD_STOPPED"; break; case CLD_TRAPPED: code = "CLD_TRAPPED"; break; case CLD_CONTINUED: code = "CLD_CONTINUED"; break; default: snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code); code = buffer; break; } struct rusage usage; getrusage(RUSAGE_CHILDREN, &usage); ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds", info.si_pid, info.si_status, code, usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000, usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000); sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.log")); if (binder != 0) { Vector<String16> args; binder->dump(-1, args); } switch (info.si_code) { case CLD_EXITED: case CLD_KILLED: case CLD_DUMPED: { ALOG(LOG_INFO, "media.log", "exiting"); _exit(0); // not reached } default: break; } } } else { // all other services if (doLog) { prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also setpgid(0, 0); // but if I die first, don't kill my parent } android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/); // Ensure threads for possible callbacks. Note that get_audio_flinger() does Loading Loading @@ -212,4 +126,3 @@ int main(int argc __unused, char **argv) ALOGI("%s: initialization done in %.3f ms, joining thread pool", __func__, timeTaken); IPCThreadState::self()->joinThreadPool(); } } services/audioflinger/Android.bp +0 −2 Original line number Diff line number Diff line Loading @@ -211,13 +211,11 @@ cc_library { include_dirs: [ "frameworks/av/services/audiopolicy", "frameworks/av/services/medialog", ], static_libs: [ "libaudiospdif", "libcpustats", "libmedialogservice", ], header_libs: [ Loading services/audioflinger/AudioFlinger.cpp +0 −150 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ #include <media/AidlConversion.h> #include <media/AudioParameter.h> #include <media/AudioValidator.h> #include <media/IMediaLogService.h> #include <media/IPermissionProvider.h> #include <media/MediaMetricsItem.h> #include <media/NativePermissionController.h> Loading Loading @@ -113,20 +112,7 @@ constexpr auto kNoEffectsFactory = "Effects Factory is absent\n"sv; static constexpr char kAudioServiceName[] = "audio"; // Keep a strong reference to media.log service around forever. // The service is within our parent process so it can never die in a way that we could observe. // These two variables are const after initialization. static sp<IMediaLogService> sMediaLogService; static pthread_once_t sMediaLogOnce = PTHREAD_ONCE_INIT; static void sMediaLogInit() { auto sMediaLogServiceAsBinder = defaultServiceManager()->getService(String16("media.log")); if (sMediaLogServiceAsBinder != 0) { sMediaLogService = interface_cast<IMediaLogService>(sMediaLogServiceAsBinder); } } static int writeStr(int fd, std::string_view s) { return write(fd, s.data(), s.size()); Loading Loading @@ -332,24 +318,11 @@ AudioFlinger::AudioFlinger() movingBase : 1) * AUDIO_UNIQUE_ID_USE_MAX; } #if 1 // FIXME See bug 165702394 and bug 168511485 const bool doLog = false; #else const bool doLog = property_get_bool("ro.test_harness", false); #endif if (doLog) { mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters", MemoryHeapBase::READ_ONLY); (void) pthread_once(&sMediaLogOnce, sMediaLogInit); } // reset battery stats. // if the audio service has crashed, battery stats could be left // in bad state, reset the state upon service start. BatteryNotifier::getInstance().noteResetAudio(); mMediaLogNotifier->run("MediaLogNotifier"); // Notify that we have started (also called when audioserver service restarts) mediametrics::LogItem(mMetricsId) Loading Loading @@ -521,16 +494,6 @@ AudioFlinger::~AudioFlinger() // no hardwareMutex() needed, as there are no other references to this delete mAudioHwDevs.valueAt(i); } // Tell media.log service about any old writers that still need to be unregistered if (sMediaLogService != 0) { for (size_t count = mUnregisteredWriters.size(); count > 0; count--) { sp<IMemory> iMemory(mUnregisteredWriters.top()->getIMemory()); mUnregisteredWriters.pop(); sMediaLogService->unregisterWriter(iMemory); } } mMediaLogNotifier->requestExit(); mPatchCommandThread->exit(); } Loading Loading @@ -1067,61 +1030,6 @@ sp<Client> AudioFlinger::registerClient(pid_t pid, uid_t uid) return client; } sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name) { // If there is no memory allocated for logs, return a no-op writer that does nothing. // Similarly if we can't contact the media.log service, also return a no-op writer. if (mLogMemoryDealer == 0 || sMediaLogService == 0) { return new NBLog::Writer(); } sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size)); // If allocation fails, consult the vector of previously unregistered writers // and garbage-collect one or more them until an allocation succeeds if (shared == 0) { audio_utils::lock_guard _l(unregisteredWritersMutex()); for (size_t count = mUnregisteredWriters.size(); count > 0; count--) { { // Pick the oldest stale writer to garbage-collect sp<IMemory> iMemory(mUnregisteredWriters[0]->getIMemory()); mUnregisteredWriters.removeAt(0); sMediaLogService->unregisterWriter(iMemory); // Now the media.log remote reference to IMemory is gone. When our last local // reference to IMemory also drops to zero at end of this block, // the IMemory destructor will deallocate the region from mLogMemoryDealer. } // Re-attempt the allocation shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size)); if (shared != 0) { goto success; } } // Even after garbage-collecting all old writers, there is still not enough memory, // so return a no-op writer return new NBLog::Writer(); } success: NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->unsecurePointer(); new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding // explicit destructor not needed since it is POD sMediaLogService->registerWriter(shared, size, name); return new NBLog::Writer(shared, size); } void AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer) { if (writer == 0) { return; } sp<IMemory> iMemory(writer->getIMemory()); if (iMemory == 0) { return; } // Rather than removing the writer immediately, append it to a queue of old writers to // be garbage-collected later. This allows us to continue to view old logs for a while. audio_utils::lock_guard _l(unregisteredWritersMutex()); mUnregisteredWriters.push(writer); } // IAudioFlinger interface status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, Loading Loading @@ -2464,44 +2372,6 @@ void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who __unuse mAudioFlinger->removeNotificationClient(mPid); } // ---------------------------------------------------------------------------- AudioFlinger::MediaLogNotifier::MediaLogNotifier() : mPendingRequests(false) {} void AudioFlinger::MediaLogNotifier::requestMerge() { audio_utils::lock_guard _l(mMutex); mPendingRequests = true; mCondition.notify_one(); } bool AudioFlinger::MediaLogNotifier::threadLoop() { // Should already have been checked, but just in case if (sMediaLogService == 0) { return false; } // Wait until there are pending requests { audio_utils::unique_lock _l(mMutex); mPendingRequests = false; // to ignore past requests while (!mPendingRequests) { mCondition.wait(_l); // TODO may also need an exitPending check } mPendingRequests = false; } // Execute the actual MediaLogService binder call and ignore extra requests for a while sMediaLogService->requestMergeWakeup(); usleep(kPostTriggerSleepPeriod); return true; } void AudioFlinger::requestLogMerge() { mMediaLogNotifier->requestMerge(); } // ---------------------------------------------------------------------------- status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, media::CreateRecordResponse& _output) { Loading Loading @@ -5368,26 +5238,6 @@ status_t AudioFlinger::onTransactWrapper(TransactionCode code, break; } // List of relevant events that trigger log merging. // Log merging should activate during audio activity of any kind. This are considered the // most relevant events. // TODO should select more wisely the items from the list switch (code) { case TransactionCode::CREATE_TRACK: case TransactionCode::CREATE_RECORD: case TransactionCode::SET_MASTER_VOLUME: case TransactionCode::SET_MASTER_MUTE: case TransactionCode::SET_MIC_MUTE: case TransactionCode::SET_PARAMETERS: case TransactionCode::CREATE_EFFECT: case TransactionCode::SYSTEM_READY: { requestLogMerge(); break; } default: break; } const std::string methodName = getIAudioFlingerStatistics().getMethodForCode(code); mediautils::TimeCheck check( std::string("IAudioFlinger::").append(methodName), Loading services/audioflinger/AudioFlinger.h +0 −35 Original line number Diff line number Diff line Loading @@ -396,12 +396,6 @@ private: IAfEffectChain* srcChain = nullptr) final REQUIRES(mutex(), audio_utils::ThreadBase_Mutex); // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge() final; sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final REQUIRES(mutex()); void unregisterWriter(const sp<NBLog::Writer>& writer) final; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, Loading Loading @@ -522,35 +516,6 @@ private: const std::unique_ptr<media::psh_utils::Token> mClientToken; }; // --- MediaLogNotifier --- // Thread in charge of notifying MediaLogService to start merging. // Receives requests from AudioFlinger's binder activity. It is used to reduce the amount of // binder calls to MediaLogService in case of bursts of AudioFlinger binder calls. class MediaLogNotifier : public Thread { public: MediaLogNotifier(); // Requests a MediaLogService notification. It's ignored if there has recently been another void requestMerge(); private: // Every iteration blocks waiting for a request, then interacts with MediaLogService to // start merging. // As every MediaLogService binder call is expensive, once it gets a request it ignores the // following ones for a period of time. virtual bool threadLoop() override; bool mPendingRequests; // Mutex and condition variable around mPendingRequests' value audio_utils::mutex mMutex{audio_utils::MutexOrder::kMediaLogNotifier_Mutex}; audio_utils::condition_variable mCondition; // Duration of the sleep period after a processed request static const int kPostTriggerSleepPeriod = 1000000; }; const sp<MediaLogNotifier> mMediaLogNotifier = sp<MediaLogNotifier>::make(); // Find io handle by session id. // Preference is given to an io handle with a matching effect chain to session id. // If none found, AUDIO_IO_HANDLE_NONE is returned. Loading Loading
media/audioserver/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ cc_binary { "libaaudioservice", "libaudioflinger", "libaudiopolicyservice", "libmedialogservice", ], shared_libs: [ Loading
media/audioserver/main_audioserver.cpp +65 −152 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #include "AudioPolicyService.h" #include "AAudioService.h" #include "utility/AAudioUtilities.h" #include "MediaLogService.h" using namespace android; Loading @@ -48,7 +47,7 @@ using android::media::audio::common::AudioMMapPolicy; using android::media::audio::common::AudioMMapPolicyInfo; using android::media::audio::common::AudioMMapPolicyType; int main(int argc __unused, char **argv) int main(int argc __unused, char **argv __unused) { ALOGD("%s: starting", __func__); const auto startTime = std::chrono::steady_clock::now(); Loading @@ -60,91 +59,6 @@ int main(int argc __unused, char **argv) signal(SIGPIPE, SIG_IGN); #if 1 // FIXME See bug 165702394 and bug 168511485 const bool doLog = false; #else bool doLog = (bool) property_get_bool("ro.test_harness", 0); #endif pid_t childPid; // FIXME The advantage of making the process containing media.log service the parent process of // the process that contains the other audio services, is that it allows us to collect more // detailed information such as signal numbers, stop and continue, resource usage, etc. // But it is also more complex. Consider replacing this by independent processes, and using // binder on death notification instead. if (doLog && (childPid = fork()) != 0) { // media.log service //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0); // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack strcpy(argv[0], "media.log"); sp<ProcessState> proc(ProcessState::self()); MediaLogService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); for (;;) { siginfo_t info; int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED)); if (ret < 0) { break; } char buffer[32]; const char *code; switch (info.si_code) { case CLD_EXITED: code = "CLD_EXITED"; break; case CLD_KILLED: code = "CLD_KILLED"; break; case CLD_DUMPED: code = "CLD_DUMPED"; break; case CLD_STOPPED: code = "CLD_STOPPED"; break; case CLD_TRAPPED: code = "CLD_TRAPPED"; break; case CLD_CONTINUED: code = "CLD_CONTINUED"; break; default: snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code); code = buffer; break; } struct rusage usage; getrusage(RUSAGE_CHILDREN, &usage); ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds", info.si_pid, info.si_status, code, usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000, usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000); sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("media.log")); if (binder != 0) { Vector<String16> args; binder->dump(-1, args); } switch (info.si_code) { case CLD_EXITED: case CLD_KILLED: case CLD_DUMPED: { ALOG(LOG_INFO, "media.log", "exiting"); _exit(0); // not reached } default: break; } } } else { // all other services if (doLog) { prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also setpgid(0, 0); // but if I die first, don't kill my parent } android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/); // Ensure threads for possible callbacks. Note that get_audio_flinger() does Loading Loading @@ -212,4 +126,3 @@ int main(int argc __unused, char **argv) ALOGI("%s: initialization done in %.3f ms, joining thread pool", __func__, timeTaken); IPCThreadState::self()->joinThreadPool(); } }
services/audioflinger/Android.bp +0 −2 Original line number Diff line number Diff line Loading @@ -211,13 +211,11 @@ cc_library { include_dirs: [ "frameworks/av/services/audiopolicy", "frameworks/av/services/medialog", ], static_libs: [ "libaudiospdif", "libcpustats", "libmedialogservice", ], header_libs: [ Loading
services/audioflinger/AudioFlinger.cpp +0 −150 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ #include <media/AidlConversion.h> #include <media/AudioParameter.h> #include <media/AudioValidator.h> #include <media/IMediaLogService.h> #include <media/IPermissionProvider.h> #include <media/MediaMetricsItem.h> #include <media/NativePermissionController.h> Loading Loading @@ -113,20 +112,7 @@ constexpr auto kNoEffectsFactory = "Effects Factory is absent\n"sv; static constexpr char kAudioServiceName[] = "audio"; // Keep a strong reference to media.log service around forever. // The service is within our parent process so it can never die in a way that we could observe. // These two variables are const after initialization. static sp<IMediaLogService> sMediaLogService; static pthread_once_t sMediaLogOnce = PTHREAD_ONCE_INIT; static void sMediaLogInit() { auto sMediaLogServiceAsBinder = defaultServiceManager()->getService(String16("media.log")); if (sMediaLogServiceAsBinder != 0) { sMediaLogService = interface_cast<IMediaLogService>(sMediaLogServiceAsBinder); } } static int writeStr(int fd, std::string_view s) { return write(fd, s.data(), s.size()); Loading Loading @@ -332,24 +318,11 @@ AudioFlinger::AudioFlinger() movingBase : 1) * AUDIO_UNIQUE_ID_USE_MAX; } #if 1 // FIXME See bug 165702394 and bug 168511485 const bool doLog = false; #else const bool doLog = property_get_bool("ro.test_harness", false); #endif if (doLog) { mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters", MemoryHeapBase::READ_ONLY); (void) pthread_once(&sMediaLogOnce, sMediaLogInit); } // reset battery stats. // if the audio service has crashed, battery stats could be left // in bad state, reset the state upon service start. BatteryNotifier::getInstance().noteResetAudio(); mMediaLogNotifier->run("MediaLogNotifier"); // Notify that we have started (also called when audioserver service restarts) mediametrics::LogItem(mMetricsId) Loading Loading @@ -521,16 +494,6 @@ AudioFlinger::~AudioFlinger() // no hardwareMutex() needed, as there are no other references to this delete mAudioHwDevs.valueAt(i); } // Tell media.log service about any old writers that still need to be unregistered if (sMediaLogService != 0) { for (size_t count = mUnregisteredWriters.size(); count > 0; count--) { sp<IMemory> iMemory(mUnregisteredWriters.top()->getIMemory()); mUnregisteredWriters.pop(); sMediaLogService->unregisterWriter(iMemory); } } mMediaLogNotifier->requestExit(); mPatchCommandThread->exit(); } Loading Loading @@ -1067,61 +1030,6 @@ sp<Client> AudioFlinger::registerClient(pid_t pid, uid_t uid) return client; } sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name) { // If there is no memory allocated for logs, return a no-op writer that does nothing. // Similarly if we can't contact the media.log service, also return a no-op writer. if (mLogMemoryDealer == 0 || sMediaLogService == 0) { return new NBLog::Writer(); } sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size)); // If allocation fails, consult the vector of previously unregistered writers // and garbage-collect one or more them until an allocation succeeds if (shared == 0) { audio_utils::lock_guard _l(unregisteredWritersMutex()); for (size_t count = mUnregisteredWriters.size(); count > 0; count--) { { // Pick the oldest stale writer to garbage-collect sp<IMemory> iMemory(mUnregisteredWriters[0]->getIMemory()); mUnregisteredWriters.removeAt(0); sMediaLogService->unregisterWriter(iMemory); // Now the media.log remote reference to IMemory is gone. When our last local // reference to IMemory also drops to zero at end of this block, // the IMemory destructor will deallocate the region from mLogMemoryDealer. } // Re-attempt the allocation shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size)); if (shared != 0) { goto success; } } // Even after garbage-collecting all old writers, there is still not enough memory, // so return a no-op writer return new NBLog::Writer(); } success: NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->unsecurePointer(); new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding // explicit destructor not needed since it is POD sMediaLogService->registerWriter(shared, size, name); return new NBLog::Writer(shared, size); } void AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer) { if (writer == 0) { return; } sp<IMemory> iMemory(writer->getIMemory()); if (iMemory == 0) { return; } // Rather than removing the writer immediately, append it to a queue of old writers to // be garbage-collected later. This allows us to continue to view old logs for a while. audio_utils::lock_guard _l(unregisteredWritersMutex()); mUnregisteredWriters.push(writer); } // IAudioFlinger interface status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, Loading Loading @@ -2464,44 +2372,6 @@ void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who __unuse mAudioFlinger->removeNotificationClient(mPid); } // ---------------------------------------------------------------------------- AudioFlinger::MediaLogNotifier::MediaLogNotifier() : mPendingRequests(false) {} void AudioFlinger::MediaLogNotifier::requestMerge() { audio_utils::lock_guard _l(mMutex); mPendingRequests = true; mCondition.notify_one(); } bool AudioFlinger::MediaLogNotifier::threadLoop() { // Should already have been checked, but just in case if (sMediaLogService == 0) { return false; } // Wait until there are pending requests { audio_utils::unique_lock _l(mMutex); mPendingRequests = false; // to ignore past requests while (!mPendingRequests) { mCondition.wait(_l); // TODO may also need an exitPending check } mPendingRequests = false; } // Execute the actual MediaLogService binder call and ignore extra requests for a while sMediaLogService->requestMergeWakeup(); usleep(kPostTriggerSleepPeriod); return true; } void AudioFlinger::requestLogMerge() { mMediaLogNotifier->requestMerge(); } // ---------------------------------------------------------------------------- status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, media::CreateRecordResponse& _output) { Loading Loading @@ -5368,26 +5238,6 @@ status_t AudioFlinger::onTransactWrapper(TransactionCode code, break; } // List of relevant events that trigger log merging. // Log merging should activate during audio activity of any kind. This are considered the // most relevant events. // TODO should select more wisely the items from the list switch (code) { case TransactionCode::CREATE_TRACK: case TransactionCode::CREATE_RECORD: case TransactionCode::SET_MASTER_VOLUME: case TransactionCode::SET_MASTER_MUTE: case TransactionCode::SET_MIC_MUTE: case TransactionCode::SET_PARAMETERS: case TransactionCode::CREATE_EFFECT: case TransactionCode::SYSTEM_READY: { requestLogMerge(); break; } default: break; } const std::string methodName = getIAudioFlingerStatistics().getMethodForCode(code); mediautils::TimeCheck check( std::string("IAudioFlinger::").append(methodName), Loading
services/audioflinger/AudioFlinger.h +0 −35 Original line number Diff line number Diff line Loading @@ -396,12 +396,6 @@ private: IAfEffectChain* srcChain = nullptr) final REQUIRES(mutex(), audio_utils::ThreadBase_Mutex); // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge() final; sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final REQUIRES(mutex()); void unregisterWriter(const sp<NBLog::Writer>& writer) final; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, Loading Loading @@ -522,35 +516,6 @@ private: const std::unique_ptr<media::psh_utils::Token> mClientToken; }; // --- MediaLogNotifier --- // Thread in charge of notifying MediaLogService to start merging. // Receives requests from AudioFlinger's binder activity. It is used to reduce the amount of // binder calls to MediaLogService in case of bursts of AudioFlinger binder calls. class MediaLogNotifier : public Thread { public: MediaLogNotifier(); // Requests a MediaLogService notification. It's ignored if there has recently been another void requestMerge(); private: // Every iteration blocks waiting for a request, then interacts with MediaLogService to // start merging. // As every MediaLogService binder call is expensive, once it gets a request it ignores the // following ones for a period of time. virtual bool threadLoop() override; bool mPendingRequests; // Mutex and condition variable around mPendingRequests' value audio_utils::mutex mMutex{audio_utils::MutexOrder::kMediaLogNotifier_Mutex}; audio_utils::condition_variable mCondition; // Duration of the sleep period after a processed request static const int kPostTriggerSleepPeriod = 1000000; }; const sp<MediaLogNotifier> mMediaLogNotifier = sp<MediaLogNotifier>::make(); // Find io handle by session id. // Preference is given to an io handle with a matching effect chain to session id. // If none found, AUDIO_IO_HANDLE_NONE is returned. Loading