1 /* 2 * Copyright (C) 2016 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 "AAudioService" 18 //#define LOG_NDEBUG 0 19 #include <utils/Log.h> 20 21 #include <iomanip> 22 #include <iostream> 23 #include <sstream> 24 25 #include <aaudio/AAudio.h> 26 #include <mediautils/SchedulingPolicyService.h> 27 #include <utils/String16.h> 28 29 #include "binding/AAudioServiceMessage.h" 30 #include "AAudioClientTracker.h" 31 #include "AAudioEndpointManager.h" 32 #include "AAudioService.h" 33 #include "AAudioServiceStreamMMAP.h" 34 #include "AAudioServiceStreamShared.h" 35 #include "binding/IAAudioService.h" 36 #include "ServiceUtilities.h" 37 38 using namespace android; 39 using namespace aaudio; 40 41 #define MAX_STREAMS_PER_PROCESS 8 42 43 using android::AAudioService; 44 45 android::AAudioService::AAudioService() 46 : BnAAudioService() { 47 mAudioClient.clientUid = getuid(); // TODO consider using geteuid() 48 mAudioClient.clientPid = getpid(); 49 mAudioClient.packageName = String16(""); 50 AAudioClientTracker::getInstance().setAAudioService(this); 51 } 52 53 AAudioService::~AAudioService() { 54 } 55 56 status_t AAudioService::dump(int fd, const Vector<String16>& args) { 57 std::string result; 58 59 if (!dumpAllowed()) { 60 std::stringstream ss; 61 ss << "Permission denial: can't dump AAudioService from pid=" 62 << IPCThreadState::self()->getCallingPid() << ", uid=" 63 << IPCThreadState::self()->getCallingUid() << "\n"; 64 result = ss.str(); 65 ALOGW("%s", result.c_str()); 66 } else { 67 result = "------------ AAudio Service ------------\n" 68 + mStreamTracker.dump() 69 + AAudioClientTracker::getInstance().dump() 70 + AAudioEndpointManager::getInstance().dump(); 71 } 72 (void)write(fd, result.c_str(), result.size()); 73 return NO_ERROR; 74 } 75 76 void AAudioService::registerClient(const sp<IAAudioClient>& client) { 77 pid_t pid = IPCThreadState::self()->getCallingPid(); 78 AAudioClientTracker::getInstance().registerClient(pid, client); 79 } 80 81 aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &request, 82 aaudio::AAudioStreamConfiguration &configurationOutput) { 83 aaudio_result_t result = AAUDIO_OK; 84 sp<AAudioServiceStreamBase> serviceStream; 85 const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration(); 86 bool sharingModeMatchRequired = request.isSharingModeMatchRequired(); 87 aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode(); 88 89 // Enforce limit on client processes. 90 pid_t pid = request.getProcessId(); 91 if (pid != mAudioClient.clientPid) { 92 int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid); 93 if (count >= MAX_STREAMS_PER_PROCESS) { 94 ALOGE("openStream(): exceeded max streams per process %d >= %d", 95 count, MAX_STREAMS_PER_PROCESS); 96 return AAUDIO_ERROR_UNAVAILABLE; 97 } 98 } 99 100 if (sharingMode != AAUDIO_SHARING_MODE_EXCLUSIVE && sharingMode != AAUDIO_SHARING_MODE_SHARED) { 101 ALOGE("openStream(): unrecognized sharing mode = %d", sharingMode); 102 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 103 } 104 105 if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) { 106 // only trust audioserver for in service indication 107 bool inService = false; 108 if (mAudioClient.clientPid == IPCThreadState::self()->getCallingPid() && 109 mAudioClient.clientUid == IPCThreadState::self()->getCallingUid()) { 110 inService = request.isInService(); 111 } 112 serviceStream = new AAudioServiceStreamMMAP(*this, inService); 113 result = serviceStream->open(request); 114 if (result != AAUDIO_OK) { 115 // Clear it so we can possibly fall back to using a shared stream. 116 ALOGW("openStream(), could not open in EXCLUSIVE mode"); 117 serviceStream.clear(); 118 } 119 } 120 121 // if SHARED requested or if EXCLUSIVE failed 122 if (sharingMode == AAUDIO_SHARING_MODE_SHARED 123 || (serviceStream.get() == nullptr && !sharingModeMatchRequired)) { 124 serviceStream = new AAudioServiceStreamShared(*this); 125 result = serviceStream->open(request); 126 } 127 128 if (result != AAUDIO_OK) { 129 serviceStream.clear(); 130 ALOGE("openStream(): failed, return %d = %s", 131 result, AAudio_convertResultToText(result)); 132 return result; 133 } else { 134 aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get()); 135 ALOGD("openStream(): handle = 0x%08X", handle); 136 serviceStream->setHandle(handle); 137 pid_t pid = request.getProcessId(); 138 AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream); 139 configurationOutput.copyFrom(*serviceStream); 140 return handle; 141 } 142 } 143 144 // If a close request is pending then close the stream 145 bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { 146 bool closed = false; 147 // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes 148 // then only one will get the pointer and do the close. 149 sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( 150 serviceStream->getHandle()); 151 if (foundStream.get() != nullptr) { 152 foundStream->close(); 153 pid_t pid = foundStream->getOwnerProcessId(); 154 AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); 155 closed = true; 156 } 157 return closed; 158 } 159 160 aaudio_result_t AAudioService::checkForPendingClose( 161 const sp<AAudioServiceStreamBase> &serviceStream, 162 aaudio_result_t defaultResult) { 163 return releaseStream(serviceStream) ? AAUDIO_ERROR_INVALID_STATE : defaultResult; 164 } 165 166 aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { 167 // Check permission and ownership first. 168 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 169 if (serviceStream.get() == nullptr) { 170 ALOGE("closeStream(0x%0x), illegal stream handle", streamHandle); 171 return AAUDIO_ERROR_INVALID_HANDLE; 172 } 173 174 pid_t pid = serviceStream->getOwnerProcessId(); 175 AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); 176 177 serviceStream->markCloseNeeded(); 178 (void) releaseStream(serviceStream); 179 return AAUDIO_OK; 180 } 181 182 sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( 183 aaudio_handle_t streamHandle) { 184 sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( 185 streamHandle); 186 if (serviceStream.get() != nullptr) { 187 // Only allow owner or the aaudio service to access the stream. 188 const uid_t callingUserId = IPCThreadState::self()->getCallingUid(); 189 const uid_t ownerUserId = serviceStream->getOwnerUserId(); 190 bool callerOwnsIt = callingUserId == ownerUserId; 191 bool serverCalling = callingUserId == mAudioClient.clientUid; 192 bool serverOwnsIt = ownerUserId == mAudioClient.clientUid; 193 bool allowed = callerOwnsIt || serverCalling || serverOwnsIt; 194 if (!allowed) { 195 ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", 196 callingUserId, streamHandle, ownerUserId); 197 // We incremented the reference count so we must check if it needs to be closed. 198 checkForPendingClose(serviceStream, AAUDIO_OK); 199 serviceStream.clear(); 200 } 201 } 202 return serviceStream; 203 } 204 205 aaudio_result_t AAudioService::getStreamDescription( 206 aaudio_handle_t streamHandle, 207 aaudio::AudioEndpointParcelable &parcelable) { 208 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 209 if (serviceStream.get() == nullptr) { 210 ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); 211 return AAUDIO_ERROR_INVALID_HANDLE; 212 } 213 214 aaudio_result_t result = serviceStream->getDescription(parcelable); 215 // parcelable.dump(); 216 return checkForPendingClose(serviceStream, result); 217 } 218 219 aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) { 220 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 221 if (serviceStream.get() == nullptr) { 222 ALOGE("startStream(), illegal stream handle = 0x%0x", streamHandle); 223 return AAUDIO_ERROR_INVALID_HANDLE; 224 } 225 226 aaudio_result_t result = serviceStream->start(); 227 return checkForPendingClose(serviceStream, result); 228 } 229 230 aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) { 231 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 232 if (serviceStream.get() == nullptr) { 233 ALOGE("pauseStream(), illegal stream handle = 0x%0x", streamHandle); 234 return AAUDIO_ERROR_INVALID_HANDLE; 235 } 236 aaudio_result_t result = serviceStream->pause(); 237 return checkForPendingClose(serviceStream, result); 238 } 239 240 aaudio_result_t AAudioService::stopStream(aaudio_handle_t streamHandle) { 241 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 242 if (serviceStream.get() == nullptr) { 243 ALOGE("stopStream(), illegal stream handle = 0x%0x", streamHandle); 244 return AAUDIO_ERROR_INVALID_HANDLE; 245 } 246 aaudio_result_t result = serviceStream->stop(); 247 return checkForPendingClose(serviceStream, result); 248 } 249 250 aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) { 251 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 252 if (serviceStream.get() == nullptr) { 253 ALOGE("flushStream(), illegal stream handle = 0x%0x", streamHandle); 254 return AAUDIO_ERROR_INVALID_HANDLE; 255 } 256 aaudio_result_t result = serviceStream->flush(); 257 return checkForPendingClose(serviceStream, result); 258 } 259 260 aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle, 261 pid_t clientThreadId, 262 int64_t periodNanoseconds) { 263 aaudio_result_t result = AAUDIO_OK; 264 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 265 if (serviceStream.get() == nullptr) { 266 ALOGE("registerAudioThread(), illegal stream handle = 0x%0x", streamHandle); 267 return AAUDIO_ERROR_INVALID_HANDLE; 268 } 269 if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { 270 ALOGE("AAudioService::registerAudioThread(), thread already registered"); 271 result = AAUDIO_ERROR_INVALID_STATE; 272 } else { 273 const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review 274 serviceStream->setRegisteredThread(clientThreadId); 275 int err = android::requestPriority(ownerPid, clientThreadId, 276 DEFAULT_AUDIO_PRIORITY, true /* isForApp */); 277 if (err != 0) { 278 ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", 279 clientThreadId, errno, DEFAULT_AUDIO_PRIORITY); 280 result = AAUDIO_ERROR_INTERNAL; 281 } 282 } 283 return checkForPendingClose(serviceStream, result); 284 } 285 286 aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle, 287 pid_t clientThreadId) { 288 aaudio_result_t result = AAUDIO_OK; 289 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 290 if (serviceStream.get() == nullptr) { 291 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 292 return AAUDIO_ERROR_INVALID_HANDLE; 293 } 294 if (serviceStream->getRegisteredThread() != clientThreadId) { 295 ALOGE("%s(), wrong thread", __func__); 296 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 297 } else { 298 serviceStream->setRegisteredThread(0); 299 } 300 return checkForPendingClose(serviceStream, result); 301 } 302 303 aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, 304 const android::AudioClient& client, 305 audio_port_handle_t *clientHandle) { 306 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 307 if (serviceStream.get() == nullptr) { 308 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 309 return AAUDIO_ERROR_INVALID_HANDLE; 310 } 311 aaudio_result_t result = serviceStream->startClient(client, clientHandle); 312 return checkForPendingClose(serviceStream, result); 313 } 314 315 aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, 316 audio_port_handle_t portHandle) { 317 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 318 if (serviceStream.get() == nullptr) { 319 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 320 return AAUDIO_ERROR_INVALID_HANDLE; 321 } 322 aaudio_result_t result = serviceStream->stopClient(portHandle); 323 return checkForPendingClose(serviceStream, result); 324 } 325 326 // This is only called internally when AudioFlinger wants to tear down a stream. 327 // So we do not have to check permissions. 328 aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { 329 ALOGD("%s(%d) called", __func__, portHandle); 330 sp<AAudioServiceStreamBase> serviceStream = 331 mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); 332 if (serviceStream.get() == nullptr) { 333 ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); 334 return AAUDIO_ERROR_INVALID_HANDLE; 335 } 336 aaudio_result_t result = serviceStream->stop(); 337 serviceStream->disconnect(); 338 return checkForPendingClose(serviceStream, result); 339 } 340