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 <mediautils/ServiceUtilities.h> 28 #include <utils/String16.h> 29 30 #include "binding/AAudioServiceMessage.h" 31 #include "AAudioClientTracker.h" 32 #include "AAudioEndpointManager.h" 33 #include "AAudioService.h" 34 #include "AAudioServiceStreamMMAP.h" 35 #include "AAudioServiceStreamShared.h" 36 #include "binding/IAAudioService.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 // Try SHARED if SHARED requested or if EXCLUSIVE failed. 122 if (sharingMode == AAUDIO_SHARING_MODE_SHARED) { 123 serviceStream = new AAudioServiceStreamShared(*this); 124 result = serviceStream->open(request); 125 } else if (serviceStream.get() == nullptr && !sharingModeMatchRequired) { 126 aaudio::AAudioStreamRequest modifiedRequest = request; 127 // Overwrite the original EXCLUSIVE mode with SHARED. 128 modifiedRequest.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED); 129 serviceStream = new AAudioServiceStreamShared(*this); 130 result = serviceStream->open(modifiedRequest); 131 } 132 133 if (result != AAUDIO_OK) { 134 serviceStream.clear(); 135 return result; 136 } else { 137 aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get()); 138 ALOGV("openStream(): handle = 0x%08X", handle); 139 serviceStream->setHandle(handle); 140 pid_t pid = request.getProcessId(); 141 AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream); 142 configurationOutput.copyFrom(*serviceStream); 143 return handle; 144 } 145 } 146 147 // If a close request is pending then close the stream 148 bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { 149 bool closed = false; 150 // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes 151 // then only one will get the pointer and do the close. 152 sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( 153 serviceStream->getHandle()); 154 if (foundStream.get() != nullptr) { 155 foundStream->close(); 156 pid_t pid = foundStream->getOwnerProcessId(); 157 AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); 158 closed = true; 159 } 160 return closed; 161 } 162 163 aaudio_result_t AAudioService::checkForPendingClose( 164 const sp<AAudioServiceStreamBase> &serviceStream, 165 aaudio_result_t defaultResult) { 166 return releaseStream(serviceStream) ? AAUDIO_ERROR_INVALID_STATE : defaultResult; 167 } 168 169 aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { 170 // Check permission and ownership first. 171 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 172 if (serviceStream.get() == nullptr) { 173 ALOGE("closeStream(0x%0x), illegal stream handle", streamHandle); 174 return AAUDIO_ERROR_INVALID_HANDLE; 175 } 176 177 pid_t pid = serviceStream->getOwnerProcessId(); 178 AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); 179 180 serviceStream->markCloseNeeded(); 181 (void) releaseStream(serviceStream); 182 return AAUDIO_OK; 183 } 184 185 sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( 186 aaudio_handle_t streamHandle) { 187 sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( 188 streamHandle); 189 if (serviceStream.get() != nullptr) { 190 // Only allow owner or the aaudio service to access the stream. 191 const uid_t callingUserId = IPCThreadState::self()->getCallingUid(); 192 const uid_t ownerUserId = serviceStream->getOwnerUserId(); 193 bool callerOwnsIt = callingUserId == ownerUserId; 194 bool serverCalling = callingUserId == mAudioClient.clientUid; 195 bool serverOwnsIt = ownerUserId == mAudioClient.clientUid; 196 bool allowed = callerOwnsIt || serverCalling || serverOwnsIt; 197 if (!allowed) { 198 ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", 199 callingUserId, streamHandle, ownerUserId); 200 // We incremented the reference count so we must check if it needs to be closed. 201 checkForPendingClose(serviceStream, AAUDIO_OK); 202 serviceStream.clear(); 203 } 204 } 205 return serviceStream; 206 } 207 208 aaudio_result_t AAudioService::getStreamDescription( 209 aaudio_handle_t streamHandle, 210 aaudio::AudioEndpointParcelable &parcelable) { 211 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 212 if (serviceStream.get() == nullptr) { 213 ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); 214 return AAUDIO_ERROR_INVALID_HANDLE; 215 } 216 217 aaudio_result_t result = serviceStream->getDescription(parcelable); 218 // parcelable.dump(); 219 return checkForPendingClose(serviceStream, result); 220 } 221 222 aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) { 223 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 224 if (serviceStream.get() == nullptr) { 225 ALOGE("startStream(), illegal stream handle = 0x%0x", streamHandle); 226 return AAUDIO_ERROR_INVALID_HANDLE; 227 } 228 229 aaudio_result_t result = serviceStream->start(); 230 return checkForPendingClose(serviceStream, result); 231 } 232 233 aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) { 234 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 235 if (serviceStream.get() == nullptr) { 236 ALOGE("pauseStream(), illegal stream handle = 0x%0x", streamHandle); 237 return AAUDIO_ERROR_INVALID_HANDLE; 238 } 239 aaudio_result_t result = serviceStream->pause(); 240 return checkForPendingClose(serviceStream, result); 241 } 242 243 aaudio_result_t AAudioService::stopStream(aaudio_handle_t streamHandle) { 244 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 245 if (serviceStream.get() == nullptr) { 246 ALOGE("stopStream(), illegal stream handle = 0x%0x", streamHandle); 247 return AAUDIO_ERROR_INVALID_HANDLE; 248 } 249 aaudio_result_t result = serviceStream->stop(); 250 return checkForPendingClose(serviceStream, result); 251 } 252 253 aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) { 254 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 255 if (serviceStream.get() == nullptr) { 256 ALOGE("flushStream(), illegal stream handle = 0x%0x", streamHandle); 257 return AAUDIO_ERROR_INVALID_HANDLE; 258 } 259 aaudio_result_t result = serviceStream->flush(); 260 return checkForPendingClose(serviceStream, result); 261 } 262 263 aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle, 264 pid_t clientThreadId, 265 int64_t periodNanoseconds) { 266 aaudio_result_t result = AAUDIO_OK; 267 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 268 if (serviceStream.get() == nullptr) { 269 ALOGE("registerAudioThread(), illegal stream handle = 0x%0x", streamHandle); 270 return AAUDIO_ERROR_INVALID_HANDLE; 271 } 272 if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { 273 ALOGE("AAudioService::registerAudioThread(), thread already registered"); 274 result = AAUDIO_ERROR_INVALID_STATE; 275 } else { 276 const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review 277 serviceStream->setRegisteredThread(clientThreadId); 278 int err = android::requestPriority(ownerPid, clientThreadId, 279 DEFAULT_AUDIO_PRIORITY, true /* isForApp */); 280 if (err != 0) { 281 ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", 282 clientThreadId, errno, DEFAULT_AUDIO_PRIORITY); 283 result = AAUDIO_ERROR_INTERNAL; 284 } 285 } 286 return checkForPendingClose(serviceStream, result); 287 } 288 289 aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle, 290 pid_t clientThreadId) { 291 aaudio_result_t result = AAUDIO_OK; 292 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 293 if (serviceStream.get() == nullptr) { 294 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 295 return AAUDIO_ERROR_INVALID_HANDLE; 296 } 297 if (serviceStream->getRegisteredThread() != clientThreadId) { 298 ALOGE("%s(), wrong thread", __func__); 299 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 300 } else { 301 serviceStream->setRegisteredThread(0); 302 } 303 return checkForPendingClose(serviceStream, result); 304 } 305 306 aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, 307 const android::AudioClient& client, 308 audio_port_handle_t *clientHandle) { 309 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 310 if (serviceStream.get() == nullptr) { 311 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 312 return AAUDIO_ERROR_INVALID_HANDLE; 313 } 314 aaudio_result_t result = serviceStream->startClient(client, clientHandle); 315 return checkForPendingClose(serviceStream, result); 316 } 317 318 aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, 319 audio_port_handle_t portHandle) { 320 sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); 321 if (serviceStream.get() == nullptr) { 322 ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); 323 return AAUDIO_ERROR_INVALID_HANDLE; 324 } 325 aaudio_result_t result = serviceStream->stopClient(portHandle); 326 return checkForPendingClose(serviceStream, result); 327 } 328 329 // This is only called internally when AudioFlinger wants to tear down a stream. 330 // So we do not have to check permissions. 331 aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { 332 ALOGD("%s(%d) called", __func__, portHandle); 333 sp<AAudioServiceStreamBase> serviceStream = 334 mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); 335 if (serviceStream.get() == nullptr) { 336 ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); 337 return AAUDIO_ERROR_INVALID_HANDLE; 338 } 339 aaudio_result_t result = serviceStream->stop(); 340 serviceStream->disconnect(); 341 return checkForPendingClose(serviceStream, result); 342 } 343