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