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