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 "MediaLogService.h"
     35 #include "MediaPlayerService.h"
     36 #include "AudioPolicyService.h"
     37 
     38 using namespace android;
     39 
     40 int main(int argc, char** argv)
     41 {
     42     signal(SIGPIPE, SIG_IGN);
     43     char value[PROPERTY_VALUE_MAX];
     44     bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
     45     pid_t childPid;
     46     // FIXME The advantage of making the process containing media.log service the parent process of
     47     // the process that contains all the other real services, is that it allows us to collect more
     48     // detailed information such as signal numbers, stop and continue, resource usage, etc.
     49     // But it is also more complex.  Consider replacing this by independent processes, and using
     50     // binder on death notification instead.
     51     if (doLog && (childPid = fork()) != 0) {
     52         // media.log service
     53         //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0);
     54         // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack
     55         strcpy(argv[0], "media.log");
     56         sp<ProcessState> proc(ProcessState::self());
     57         MediaLogService::instantiate();
     58         ProcessState::self()->startThreadPool();
     59         for (;;) {
     60             siginfo_t info;
     61             int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
     62             if (ret == EINTR) {
     63                 continue;
     64             }
     65             if (ret < 0) {
     66                 break;
     67             }
     68             char buffer[32];
     69             const char *code;
     70             switch (info.si_code) {
     71             case CLD_EXITED:
     72                 code = "CLD_EXITED";
     73                 break;
     74             case CLD_KILLED:
     75                 code = "CLD_KILLED";
     76                 break;
     77             case CLD_DUMPED:
     78                 code = "CLD_DUMPED";
     79                 break;
     80             case CLD_STOPPED:
     81                 code = "CLD_STOPPED";
     82                 break;
     83             case CLD_TRAPPED:
     84                 code = "CLD_TRAPPED";
     85                 break;
     86             case CLD_CONTINUED:
     87                 code = "CLD_CONTINUED";
     88                 break;
     89             default:
     90                 snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code);
     91                 code = buffer;
     92                 break;
     93             }
     94             struct rusage usage;
     95             getrusage(RUSAGE_CHILDREN, &usage);
     96             ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds",
     97                     info.si_pid, info.si_status, code,
     98                     usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000,
     99                     usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000);
    100             sp<IServiceManager> sm = defaultServiceManager();
    101             sp<IBinder> binder = sm->getService(String16("media.log"));
    102             if (binder != 0) {
    103                 Vector<String16> args;
    104                 binder->dump(-1, args);
    105             }
    106             switch (info.si_code) {
    107             case CLD_EXITED:
    108             case CLD_KILLED:
    109             case CLD_DUMPED: {
    110                 ALOG(LOG_INFO, "media.log", "exiting");
    111                 _exit(0);
    112                 // not reached
    113                 }
    114             default:
    115                 break;
    116             }
    117         }
    118     } else {
    119         // all other services
    120         if (doLog) {
    121             prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
    122             setpgid(0, 0);                      // but if I die first, don't kill my parent
    123         }
    124         sp<ProcessState> proc(ProcessState::self());
    125         sp<IServiceManager> sm = defaultServiceManager();
    126         ALOGI("ServiceManager: %p", sm.get());
    127         AudioFlinger::instantiate();
    128         MediaPlayerService::instantiate();
    129         CameraService::instantiate();
    130         AudioPolicyService::instantiate();
    131         registerExtensions();
    132         ProcessState::self()->startThreadPool();
    133         IPCThreadState::self()->joinThreadPool();
    134     }
    135 }
    136