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