xref: /aosp_15_r20/frameworks/av/media/audioserver/main_audioserver.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "audioserver"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <algorithm>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <fcntl.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <sys/prctl.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <sys/wait.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker #include <android/media/audio/common/AudioMMapPolicy.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <android/media/audio/common/AudioMMapPolicyInfo.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <android/media/audio/common/AudioMMapPolicyType.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <android/media/IAudioFlingerService.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
34*ec779b8eSAndroid Build Coastguard Worker #include <hidl/HidlTransportSupport.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/LimitProcessMemory.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker // from include_dirs
39*ec779b8eSAndroid Build Coastguard Worker #include "AudioFlinger.h"
40*ec779b8eSAndroid Build Coastguard Worker #include "AudioPolicyService.h"
41*ec779b8eSAndroid Build Coastguard Worker #include "AAudioService.h"
42*ec779b8eSAndroid Build Coastguard Worker #include "utility/AAudioUtilities.h"
43*ec779b8eSAndroid Build Coastguard Worker #include "MediaLogService.h"
44*ec779b8eSAndroid Build Coastguard Worker 
45*ec779b8eSAndroid Build Coastguard Worker using namespace android;
46*ec779b8eSAndroid Build Coastguard Worker 
47*ec779b8eSAndroid Build Coastguard Worker using android::media::audio::common::AudioMMapPolicy;
48*ec779b8eSAndroid Build Coastguard Worker using android::media::audio::common::AudioMMapPolicyInfo;
49*ec779b8eSAndroid Build Coastguard Worker using android::media::audio::common::AudioMMapPolicyType;
50*ec779b8eSAndroid Build Coastguard Worker 
main(int argc __unused,char ** argv)51*ec779b8eSAndroid Build Coastguard Worker int main(int argc __unused, char **argv)
52*ec779b8eSAndroid Build Coastguard Worker {
53*ec779b8eSAndroid Build Coastguard Worker     ALOGD("%s: starting", __func__);
54*ec779b8eSAndroid Build Coastguard Worker     const auto startTime = std::chrono::steady_clock::now();
55*ec779b8eSAndroid Build Coastguard Worker     // TODO: update with refined parameters
56*ec779b8eSAndroid Build Coastguard Worker     limitProcessMemory(
57*ec779b8eSAndroid Build Coastguard Worker         "audio.maxmem", /* "ro.audio.maxmem", property that defines limit */
58*ec779b8eSAndroid Build Coastguard Worker         (size_t)512 * (1 << 20), /* SIZE_MAX, upper limit in bytes */
59*ec779b8eSAndroid Build Coastguard Worker         20 /* upper limit as percentage of physical RAM */);
60*ec779b8eSAndroid Build Coastguard Worker 
61*ec779b8eSAndroid Build Coastguard Worker     signal(SIGPIPE, SIG_IGN);
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker #if 1
64*ec779b8eSAndroid Build Coastguard Worker     // FIXME See bug 165702394 and bug 168511485
65*ec779b8eSAndroid Build Coastguard Worker     const bool doLog = false;
66*ec779b8eSAndroid Build Coastguard Worker #else
67*ec779b8eSAndroid Build Coastguard Worker     bool doLog = (bool) property_get_bool("ro.test_harness", 0);
68*ec779b8eSAndroid Build Coastguard Worker #endif
69*ec779b8eSAndroid Build Coastguard Worker 
70*ec779b8eSAndroid Build Coastguard Worker     pid_t childPid;
71*ec779b8eSAndroid Build Coastguard Worker     // FIXME The advantage of making the process containing media.log service the parent process of
72*ec779b8eSAndroid Build Coastguard Worker     // the process that contains the other audio services, is that it allows us to collect more
73*ec779b8eSAndroid Build Coastguard Worker     // detailed information such as signal numbers, stop and continue, resource usage, etc.
74*ec779b8eSAndroid Build Coastguard Worker     // But it is also more complex.  Consider replacing this by independent processes, and using
75*ec779b8eSAndroid Build Coastguard Worker     // binder on death notification instead.
76*ec779b8eSAndroid Build Coastguard Worker     if (doLog && (childPid = fork()) != 0) {
77*ec779b8eSAndroid Build Coastguard Worker         // media.log service
78*ec779b8eSAndroid Build Coastguard Worker         //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0);
79*ec779b8eSAndroid Build Coastguard Worker         // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack
80*ec779b8eSAndroid Build Coastguard Worker         strcpy(argv[0], "media.log");
81*ec779b8eSAndroid Build Coastguard Worker         sp<ProcessState> proc(ProcessState::self());
82*ec779b8eSAndroid Build Coastguard Worker         MediaLogService::instantiate();
83*ec779b8eSAndroid Build Coastguard Worker         ProcessState::self()->startThreadPool();
84*ec779b8eSAndroid Build Coastguard Worker         IPCThreadState::self()->joinThreadPool();
85*ec779b8eSAndroid Build Coastguard Worker         for (;;) {
86*ec779b8eSAndroid Build Coastguard Worker             siginfo_t info;
87*ec779b8eSAndroid Build Coastguard Worker             int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info,
88*ec779b8eSAndroid Build Coastguard Worker                                                 WEXITED | WSTOPPED | WCONTINUED));
89*ec779b8eSAndroid Build Coastguard Worker             if (ret < 0) {
90*ec779b8eSAndroid Build Coastguard Worker                 break;
91*ec779b8eSAndroid Build Coastguard Worker             }
92*ec779b8eSAndroid Build Coastguard Worker             char buffer[32];
93*ec779b8eSAndroid Build Coastguard Worker             const char *code;
94*ec779b8eSAndroid Build Coastguard Worker             switch (info.si_code) {
95*ec779b8eSAndroid Build Coastguard Worker             case CLD_EXITED:
96*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_EXITED";
97*ec779b8eSAndroid Build Coastguard Worker                 break;
98*ec779b8eSAndroid Build Coastguard Worker             case CLD_KILLED:
99*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_KILLED";
100*ec779b8eSAndroid Build Coastguard Worker                 break;
101*ec779b8eSAndroid Build Coastguard Worker             case CLD_DUMPED:
102*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_DUMPED";
103*ec779b8eSAndroid Build Coastguard Worker                 break;
104*ec779b8eSAndroid Build Coastguard Worker             case CLD_STOPPED:
105*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_STOPPED";
106*ec779b8eSAndroid Build Coastguard Worker                 break;
107*ec779b8eSAndroid Build Coastguard Worker             case CLD_TRAPPED:
108*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_TRAPPED";
109*ec779b8eSAndroid Build Coastguard Worker                 break;
110*ec779b8eSAndroid Build Coastguard Worker             case CLD_CONTINUED:
111*ec779b8eSAndroid Build Coastguard Worker                 code = "CLD_CONTINUED";
112*ec779b8eSAndroid Build Coastguard Worker                 break;
113*ec779b8eSAndroid Build Coastguard Worker             default:
114*ec779b8eSAndroid Build Coastguard Worker                 snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code);
115*ec779b8eSAndroid Build Coastguard Worker                 code = buffer;
116*ec779b8eSAndroid Build Coastguard Worker                 break;
117*ec779b8eSAndroid Build Coastguard Worker             }
118*ec779b8eSAndroid Build Coastguard Worker             struct rusage usage;
119*ec779b8eSAndroid Build Coastguard Worker             getrusage(RUSAGE_CHILDREN, &usage);
120*ec779b8eSAndroid Build Coastguard Worker             ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds",
121*ec779b8eSAndroid Build Coastguard Worker                     info.si_pid, info.si_status, code,
122*ec779b8eSAndroid Build Coastguard Worker                     usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000,
123*ec779b8eSAndroid Build Coastguard Worker                     usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000);
124*ec779b8eSAndroid Build Coastguard Worker             sp<IServiceManager> sm = defaultServiceManager();
125*ec779b8eSAndroid Build Coastguard Worker             sp<IBinder> binder = sm->getService(String16("media.log"));
126*ec779b8eSAndroid Build Coastguard Worker             if (binder != 0) {
127*ec779b8eSAndroid Build Coastguard Worker                 Vector<String16> args;
128*ec779b8eSAndroid Build Coastguard Worker                 binder->dump(-1, args);
129*ec779b8eSAndroid Build Coastguard Worker             }
130*ec779b8eSAndroid Build Coastguard Worker             switch (info.si_code) {
131*ec779b8eSAndroid Build Coastguard Worker             case CLD_EXITED:
132*ec779b8eSAndroid Build Coastguard Worker             case CLD_KILLED:
133*ec779b8eSAndroid Build Coastguard Worker             case CLD_DUMPED: {
134*ec779b8eSAndroid Build Coastguard Worker                 ALOG(LOG_INFO, "media.log", "exiting");
135*ec779b8eSAndroid Build Coastguard Worker                 _exit(0);
136*ec779b8eSAndroid Build Coastguard Worker                 // not reached
137*ec779b8eSAndroid Build Coastguard Worker                 }
138*ec779b8eSAndroid Build Coastguard Worker             default:
139*ec779b8eSAndroid Build Coastguard Worker                 break;
140*ec779b8eSAndroid Build Coastguard Worker             }
141*ec779b8eSAndroid Build Coastguard Worker         }
142*ec779b8eSAndroid Build Coastguard Worker     } else {
143*ec779b8eSAndroid Build Coastguard Worker         // all other services
144*ec779b8eSAndroid Build Coastguard Worker         if (doLog) {
145*ec779b8eSAndroid Build Coastguard Worker             prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
146*ec779b8eSAndroid Build Coastguard Worker             setpgid(0, 0);                      // but if I die first, don't kill my parent
147*ec779b8eSAndroid Build Coastguard Worker         }
148*ec779b8eSAndroid Build Coastguard Worker         android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
149*ec779b8eSAndroid Build Coastguard Worker 
150*ec779b8eSAndroid Build Coastguard Worker         // Ensure threads for possible callbacks.  Note that get_audio_flinger() does
151*ec779b8eSAndroid Build Coastguard Worker         // this automatically when called from AudioPolicy, but we do this anyways here.
152*ec779b8eSAndroid Build Coastguard Worker         ProcessState::self()->startThreadPool();
153*ec779b8eSAndroid Build Coastguard Worker 
154*ec779b8eSAndroid Build Coastguard Worker         // Instantiating AudioFlinger (making it public, e.g. through ::initialize())
155*ec779b8eSAndroid Build Coastguard Worker         // and then instantiating AudioPolicy (and making it public)
156*ec779b8eSAndroid Build Coastguard Worker         // leads to situations where AudioFlinger is accessed remotely before
157*ec779b8eSAndroid Build Coastguard Worker         // AudioPolicy is initialized.  Not only might this
158*ec779b8eSAndroid Build Coastguard Worker         // cause inaccurate results, but if AudioPolicy has slow audio HAL
159*ec779b8eSAndroid Build Coastguard Worker         // initialization, it can cause a TimeCheck abort to occur on an AudioFlinger
160*ec779b8eSAndroid Build Coastguard Worker         // call which tries to access AudioPolicy.
161*ec779b8eSAndroid Build Coastguard Worker         //
162*ec779b8eSAndroid Build Coastguard Worker         // We create AudioFlinger and AudioPolicy locally then make it public to ServiceManager.
163*ec779b8eSAndroid Build Coastguard Worker         // This requires both AudioFlinger and AudioPolicy to be in-proc.
164*ec779b8eSAndroid Build Coastguard Worker         //
165*ec779b8eSAndroid Build Coastguard Worker         const auto af = sp<AudioFlinger>::make();
166*ec779b8eSAndroid Build Coastguard Worker         const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);
167*ec779b8eSAndroid Build Coastguard Worker         ALOGD("%s: AudioFlinger created", __func__);
168*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(AudioSystem::setLocalAudioFlinger(af) != OK,
169*ec779b8eSAndroid Build Coastguard Worker                 "%s: AudioSystem already has an AudioFlinger instance!", __func__);
170*ec779b8eSAndroid Build Coastguard Worker         const auto aps = sp<AudioPolicyService>::make();
171*ec779b8eSAndroid Build Coastguard Worker         af->initAudioPolicyLocal(aps);
172*ec779b8eSAndroid Build Coastguard Worker         ALOGD("%s: AudioPolicy created", __func__);
173*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(AudioSystem::setLocalAudioPolicyService(aps) != OK,
174*ec779b8eSAndroid Build Coastguard Worker                  "%s: AudioSystem already has an AudioPolicyService instance!", __func__);
175*ec779b8eSAndroid Build Coastguard Worker 
176*ec779b8eSAndroid Build Coastguard Worker         // Start initialization of internally managed audio objects such as Device Effects.
177*ec779b8eSAndroid Build Coastguard Worker         aps->onAudioSystemReady();
178*ec779b8eSAndroid Build Coastguard Worker 
179*ec779b8eSAndroid Build Coastguard Worker         // Add AudioFlinger and AudioPolicy to ServiceManager.
180*ec779b8eSAndroid Build Coastguard Worker         sp<IServiceManager> sm = defaultServiceManager();
181*ec779b8eSAndroid Build Coastguard Worker         sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter,
182*ec779b8eSAndroid Build Coastguard Worker                 false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
183*ec779b8eSAndroid Build Coastguard Worker         sm->addService(String16(AudioPolicyService::getServiceName()), aps,
184*ec779b8eSAndroid Build Coastguard Worker                 false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
185*ec779b8eSAndroid Build Coastguard Worker 
186*ec779b8eSAndroid Build Coastguard Worker         // AAudioService should only be used in OC-MR1 and later.
187*ec779b8eSAndroid Build Coastguard Worker         // And only enable the AAudioService if the system MMAP policy explicitly allows it.
188*ec779b8eSAndroid Build Coastguard Worker         // This prevents a client from misusing AAudioService when it is not supported.
189*ec779b8eSAndroid Build Coastguard Worker         // If we cannot get audio flinger here, there must be some serious problems. In that case,
190*ec779b8eSAndroid Build Coastguard Worker         // attempting to call audio flinger on a null pointer could make the process crash
191*ec779b8eSAndroid Build Coastguard Worker         // and attract attentions.
192*ec779b8eSAndroid Build Coastguard Worker         std::vector<AudioMMapPolicyInfo> policyInfos;
193*ec779b8eSAndroid Build Coastguard Worker         status_t status = AudioSystem::getMmapPolicyInfos(
194*ec779b8eSAndroid Build Coastguard Worker                 AudioMMapPolicyType::DEFAULT, &policyInfos);
195*ec779b8eSAndroid Build Coastguard Worker         // Initialize aaudio service when querying mmap policy succeeds and
196*ec779b8eSAndroid Build Coastguard Worker         // any of the policy supports MMAP.
197*ec779b8eSAndroid Build Coastguard Worker         if (status == NO_ERROR &&
198*ec779b8eSAndroid Build Coastguard Worker             std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) {
199*ec779b8eSAndroid Build Coastguard Worker                     return info.mmapPolicy == AudioMMapPolicy::AUTO ||
200*ec779b8eSAndroid Build Coastguard Worker                            info.mmapPolicy == AudioMMapPolicy::ALWAYS;
201*ec779b8eSAndroid Build Coastguard Worker             })) {
202*ec779b8eSAndroid Build Coastguard Worker             AAudioService::instantiate();
203*ec779b8eSAndroid Build Coastguard Worker         } else {
204*ec779b8eSAndroid Build Coastguard Worker             ALOGD("%s: Do not init aaudio service, status %d, policy info size %zu",
205*ec779b8eSAndroid Build Coastguard Worker                   __func__, status, policyInfos.size());
206*ec779b8eSAndroid Build Coastguard Worker         }
207*ec779b8eSAndroid Build Coastguard Worker         const auto endTime = std::chrono::steady_clock::now();
208*ec779b8eSAndroid Build Coastguard Worker         af->startupFinished();
209*ec779b8eSAndroid Build Coastguard Worker         using FloatMillis = std::chrono::duration<float, std::milli>;
210*ec779b8eSAndroid Build Coastguard Worker         const float timeTaken = std::chrono::duration_cast<FloatMillis>(
211*ec779b8eSAndroid Build Coastguard Worker                 endTime - startTime).count();
212*ec779b8eSAndroid Build Coastguard Worker         ALOGI("%s: initialization done in %.3f ms, joining thread pool", __func__, timeTaken);
213*ec779b8eSAndroid Build Coastguard Worker         IPCThreadState::self()->joinThreadPool();
214*ec779b8eSAndroid Build Coastguard Worker     }
215*ec779b8eSAndroid Build Coastguard Worker }
216