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

Commit 1775c89c authored by Atneya Nair's avatar Atneya Nair
Browse files

Remove unused medialog service

This service is not actually started/used, so removing it from source,
as it is a maintenance burden/ownerless. Out of process logging has been
superseded by mediametrics.

Bug: 284657986
Bug: 285414783
Flag: EXEMPT cleanup
Test: Compiles
Change-Id: I24dd3ee3e4561c0288250624d8ce90c1f1eeabb2
parent b1d83e83
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