Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe1e9c0d authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Remove unused medialog service" into main

parents b9d3ede9 1775c89c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ cc_binary {
        "libaaudioservice",
        "libaudioflinger",
        "libaudiopolicyservice",
        "libmedialogservice",
    ],

    shared_libs: [
+65 −152
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include "AudioPolicyService.h"
#include "AAudioService.h"
#include "utility/AAudioUtilities.h"
#include "MediaLogService.h"

using namespace android;

@@ -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();
@@ -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
@@ -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();
}
}
+0 −2
Original line number Diff line number Diff line
@@ -211,13 +211,11 @@ cc_library {

    include_dirs: [
        "frameworks/av/services/audiopolicy",
        "frameworks/av/services/medialog",
    ],

    static_libs: [
        "libaudiospdif",
        "libcpustats",
        "libmedialogservice",
    ],

    header_libs: [
+0 −150
Original line number Diff line number Diff line
@@ -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>
@@ -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());
@@ -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)
@@ -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();
}

@@ -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,
@@ -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)
{
@@ -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),
+0 −35
Original line number Diff line number Diff line
@@ -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,
@@ -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