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