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

Commit 0be9fe58 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Add media.log service based on NBLog"

parents 1cca13c7 fdf4e4f1
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_IMEDIALOGSERVICE_H
#define ANDROID_IMEDIALOGSERVICE_H

#include <binder/IInterface.h>
#include <binder/IMemory.h>
#include <binder/Parcel.h>

namespace android {

class IMediaLogService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaLogService);

    virtual void    registerWriter(const sp<IMemory>& shared, size_t size, const char *name) = 0;
    virtual void    unregisterWriter(const sp<IMemory>& shared) = 0;

};

class BnMediaLogService: public BnInterface<IMediaLogService>
{
public:
    virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                uint32_t flags = 0);
};

}   // namespace android

#endif  // ANDROID_IMEDIALOGSERVICE_H
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ LOCAL_SRC_FILES:= \
    AudioRecord.cpp \
    AudioSystem.cpp \
    mediaplayer.cpp \
    IMediaLogService.cpp \
    IMediaPlayerService.cpp \
    IMediaPlayerClient.cpp \
    IMediaRecorderClient.cpp \
+94 −0
Original line number Diff line number Diff line
/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#define LOG_TAG "IMediaLogService"
//#define LOG_NDEBUG 0

#include <utils/Log.h>
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
#include <media/IMediaLogService.h>

namespace android {

enum {
    REGISTER_WRITER = IBinder::FIRST_CALL_TRANSACTION,
    UNREGISTER_WRITER,
};

class BpMediaLogService : public BpInterface<IMediaLogService>
{
public:
    BpMediaLogService(const sp<IBinder>& impl)
        : BpInterface<IMediaLogService>(impl)
    {
    }

    virtual void    registerWriter(const sp<IMemory>& shared, size_t size, const char *name) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor());
        data.writeStrongBinder(shared->asBinder());
        data.writeInt32((int32_t) size);
        data.writeCString(name);
        status_t status = remote()->transact(REGISTER_WRITER, data, &reply);
        // FIXME ignores status
    }

    virtual void    unregisterWriter(const sp<IMemory>& shared) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor());
        data.writeStrongBinder(shared->asBinder());
        status_t status = remote()->transact(UNREGISTER_WRITER, data, &reply);
        // FIXME ignores status
    }

};

IMPLEMENT_META_INTERFACE(MediaLogService, "android.media.IMediaLogService");

// ----------------------------------------------------------------------

status_t BnMediaLogService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {

        case REGISTER_WRITER: {
            CHECK_INTERFACE(IMediaLogService, data, reply);
            sp<IMemory> shared = interface_cast<IMemory>(data.readStrongBinder());
            size_t size = (size_t) data.readInt32();
            const char *name = data.readCString();
            registerWriter(shared, size, name);
            return NO_ERROR;
        }

        case UNREGISTER_WRITER: {
            CHECK_INTERFACE(IMediaLogService, data, reply);
            sp<IMemory> shared = interface_cast<IMemory>(data.readStrongBinder());
            unregisterWriter(shared);
            return NO_ERROR;
        }

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

// ----------------------------------------------------------------------------

}; // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -7,12 +7,17 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
	libaudioflinger \
	libcameraservice \
	libmedialogservice \
	libcutils \
	libnbaio \
	libmedia \
	libmediaplayerservice \
	libutils \
	libbinder

LOCAL_C_INCLUDES := \
    frameworks/av/media/libmediaplayerservice \
    frameworks/av/services/medialog \
    frameworks/av/services/audioflinger \
    frameworks/av/services/camera/libcameraservice

+96 −9
Original line number Diff line number Diff line
@@ -18,14 +18,19 @@
#define LOG_TAG "mediaserver"
//#define LOG_NDEBUG 0

#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <utils/Log.h>

// from LOCAL_C_INCLUDES
#include "AudioFlinger.h"
#include "CameraService.h"
#include "MediaLogService.h"
#include "MediaPlayerService.h"
#include "AudioPolicyService.h"

@@ -34,6 +39,87 @@ using namespace android;
int main(int argc, char** argv)
{
    signal(SIGPIPE, SIG_IGN);
    char value[PROPERTY_VALUE_MAX];
    bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
    pid_t childPid;
    // FIXME The advantage of making the process containing media.log service the parent process of
    // the process that contains all the other real 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();
        for (;;) {
            siginfo_t info;
            int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
            if (ret == EINTR) {
                continue;
            }
            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
        }
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
@@ -44,3 +130,4 @@ int main(int argc, char** argv)
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }
}
Loading