Home | History | Annotate | Download | only in mediaserver
      1 /*
      2 **
      3 ** Copyright 2008, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #define LOG_TAG "mediaserver"
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <fcntl.h>
     22 #include <sys/prctl.h>
     23 #include <sys/wait.h>
     24 #include <binder/IPCThreadState.h>
     25 #include <binder/ProcessState.h>
     26 #include <binder/IServiceManager.h>
     27 #include <cutils/properties.h>
     28 #include <utils/Log.h>
     29 #include "RegisterExtensions.h"
     30 
     31 // from LOCAL_C_INCLUDES
     32 #include "AudioFlinger.h"
     33 #include "CameraService.h"
     34 #include "IcuUtils.h"
     35 #include "MediaLogService.h"
     36 #include "MediaPlayerService.h"
     37 #include "ResourceManagerService.h"
     38 #include "service/AudioPolicyService.h"
     39 #include "SoundTriggerHwService.h"
     40 #include "RadioService.h"
     41 
     42 using namespace android;
     43 
     44 int main(int argc __unused, char** argv)
     45 {
     46     signal(SIGPIPE, SIG_IGN);
     47     char value[PROPERTY_VALUE_MAX];
     48     bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
     49     pid_t childPid;
     50     // FIXME The advantage of making the process containing media.log service the parent process of
     51     // the process that contains all the other real services, is that it allows us to collect more
     52     // detailed information such as signal numbers, stop and continue, resource usage, etc.
     53     // But it is also more complex.  Consider replacing this by independent processes, and using
     54     // binder on death notification instead.
     55     if (doLog && (childPid = fork()) != 0) {
     56         // media.log service
     57         //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0);
     58         // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack
     59         strcpy(argv[0], "media.log");
     60         sp<ProcessState> proc(ProcessState::self());
     61         MediaLogService::instantiate();
     62         ProcessState::self()->startThreadPool();
     63         for (;;) {
     64             siginfo_t info;
     65             int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
     66             if (ret == EINTR) {
     67                 continue;
     68             }
     69             if (ret < 0) {
     70                 break;
     71             }
     72             char buffer[32];
     73             const char *code;
     74             switch (info.si_code) {
     75             case CLD_EXITED:
     76                 code = "CLD_EXITED";
     77                 break;
     78             case CLD_KILLED:
     79                 code = "CLD_KILLED";
     80                 break;
     81             case CLD_DUMPED:
     82                 code = "CLD_DUMPED";
     83                 break;
     84             case CLD_STOPPED:
     85                 code = "CLD_STOPPED";
     86                 break;
     87             case CLD_TRAPPED:
     88                 code = "CLD_TRAPPED";
     89                 break;
     90             case CLD_CONTINUED:
     91                 code = "CLD_CONTINUED";
     92                 break;
     93             default:
     94                 snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code);
     95                 code = buffer;
     96                 break;
     97             }
     98             struct rusage usage;
     99             getrusage(RUSAGE_CHILDREN, &usage);
    100             ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds",
    101                     info.si_pid, info.si_status, code,
    102                     usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000,
    103                     usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000);
    104             sp<IServiceManager> sm = defaultServiceManager();
    105             sp<IBinder> binder = sm->getService(String16("media.log"));
    106             if (binder != 0) {
    107                 Vector<String16> args;
    108                 binder->dump(-1, args);
    109             }
    110             switch (info.si_code) {
    111             case CLD_EXITED:
    112             case CLD_KILLED:
    113             case CLD_DUMPED: {
    114                 ALOG(LOG_INFO, "media.log", "exiting");
    115                 _exit(0);
    116                 // not reached
    117                 }
    118             default:
    119                 break;
    120             }
    121         }
    122     } else {
    123         // all other services
    124         if (doLog) {
    125             prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
    126             setpgid(0, 0);                      // but if I die first, don't kill my parent
    127         }
    128         InitializeIcuOrDie();
    129         sp<ProcessState> proc(ProcessState::self());
    130         sp<IServiceManager> sm = defaultServiceManager();
    131         ALOGI("ServiceManager: %p", sm.get());
    132         AudioFlinger::instantiate();
    133         MediaPlayerService::instantiate();
    134         ResourceManagerService::instantiate();
    135         CameraService::instantiate();
    136         AudioPolicyService::instantiate();
    137         SoundTriggerHwService::instantiate();
    138         RadioService::instantiate();
    139         registerExtensions();
    140         ProcessState::self()->startThreadPool();
    141         IPCThreadState::self()->joinThreadPool();
    142     }
    143 }
    144