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 <time.h> 22 //#include <pthread.h> 23 24 #include <aaudio/AAudio.h> 25 #include <mediautils/SchedulingPolicyService.h> 26 #include <utils/String16.h> 27 28 #include "binding/AAudioServiceMessage.h" 29 #include "AAudioService.h" 30 #include "AAudioServiceStreamMMAP.h" 31 #include "AAudioServiceStreamShared.h" 32 #include "AAudioServiceStreamMMAP.h" 33 #include "binding/IAAudioService.h" 34 #include "utility/HandleTracker.h" 35 36 using namespace android; 37 using namespace aaudio; 38 39 typedef enum 40 { 41 AAUDIO_HANDLE_TYPE_STREAM 42 } aaudio_service_handle_type_t; 43 static_assert(AAUDIO_HANDLE_TYPE_STREAM < HANDLE_TRACKER_MAX_TYPES, "Too many handle types."); 44 45 android::AAudioService::AAudioService() 46 : BnAAudioService() { 47 } 48 49 AAudioService::~AAudioService() { 50 } 51 52 aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &request, 53 aaudio::AAudioStreamConfiguration &configurationOutput) { 54 aaudio_result_t result = AAUDIO_OK; 55 AAudioServiceStreamBase *serviceStream = nullptr; 56 const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration(); 57 bool sharingModeMatchRequired = request.isSharingModeMatchRequired(); 58 aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode(); 59 60 if (sharingMode != AAUDIO_SHARING_MODE_EXCLUSIVE && sharingMode != AAUDIO_SHARING_MODE_SHARED) { 61 ALOGE("AAudioService::openStream(): unrecognized sharing mode = %d", sharingMode); 62 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 63 } 64 65 if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) { 66 serviceStream = new AAudioServiceStreamMMAP(); 67 result = serviceStream->open(request, configurationOutput); 68 if (result != AAUDIO_OK) { 69 // fall back to using a shared stream 70 ALOGD("AAudioService::openStream(), EXCLUSIVE mode failed"); 71 delete serviceStream; 72 serviceStream = nullptr; 73 } else { 74 configurationOutput.setSharingMode(AAUDIO_SHARING_MODE_EXCLUSIVE); 75 } 76 } 77 78 // if SHARED requested or if EXCLUSIVE failed 79 if (sharingMode == AAUDIO_SHARING_MODE_SHARED 80 || (serviceStream == nullptr && !sharingModeMatchRequired)) { 81 serviceStream = new AAudioServiceStreamShared(*this); 82 result = serviceStream->open(request, configurationOutput); 83 configurationOutput.setSharingMode(AAUDIO_SHARING_MODE_SHARED); 84 } 85 86 if (result != AAUDIO_OK) { 87 delete serviceStream; 88 ALOGE("AAudioService::openStream(): failed, return %d", result); 89 return result; 90 } else { 91 aaudio_handle_t handle = mHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM, serviceStream); 92 ALOGV("AAudioService::openStream(): handle = 0x%08X", handle); 93 if (handle < 0) { 94 ALOGE("AAudioService::openStream(): handle table full"); 95 delete serviceStream; 96 } 97 return handle; 98 } 99 } 100 101 aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { 102 AAudioServiceStreamBase *serviceStream = (AAudioServiceStreamBase *) 103 mHandleTracker.remove(AAUDIO_HANDLE_TYPE_STREAM, 104 streamHandle); 105 ALOGV("AAudioService.closeStream(0x%08X)", streamHandle); 106 if (serviceStream != nullptr) { 107 serviceStream->close(); 108 delete serviceStream; 109 return AAUDIO_OK; 110 } 111 return AAUDIO_ERROR_INVALID_HANDLE; 112 } 113 114 AAudioServiceStreamBase *AAudioService::convertHandleToServiceStream( 115 aaudio_handle_t streamHandle) const { 116 return (AAudioServiceStreamBase *) mHandleTracker.get(AAUDIO_HANDLE_TYPE_STREAM, 117 (aaudio_handle_t)streamHandle); 118 } 119 120 aaudio_result_t AAudioService::getStreamDescription( 121 aaudio_handle_t streamHandle, 122 aaudio::AudioEndpointParcelable &parcelable) { 123 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 124 if (serviceStream == nullptr) { 125 ALOGE("AAudioService::getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); 126 return AAUDIO_ERROR_INVALID_HANDLE; 127 } 128 aaudio_result_t result = serviceStream->getDescription(parcelable); 129 // parcelable.dump(); 130 return result; 131 } 132 133 aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) { 134 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 135 if (serviceStream == nullptr) { 136 ALOGE("AAudioService::startStream(), illegal stream handle = 0x%0x", streamHandle); 137 return AAUDIO_ERROR_INVALID_HANDLE; 138 } 139 aaudio_result_t result = serviceStream->start(); 140 return result; 141 } 142 143 aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) { 144 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 145 if (serviceStream == nullptr) { 146 ALOGE("AAudioService::pauseStream(), illegal stream handle = 0x%0x", streamHandle); 147 return AAUDIO_ERROR_INVALID_HANDLE; 148 } 149 aaudio_result_t result = serviceStream->pause(); 150 return result; 151 } 152 153 aaudio_result_t AAudioService::stopStream(aaudio_handle_t streamHandle) { 154 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 155 if (serviceStream == nullptr) { 156 ALOGE("AAudioService::pauseStream(), illegal stream handle = 0x%0x", streamHandle); 157 return AAUDIO_ERROR_INVALID_HANDLE; 158 } 159 aaudio_result_t result = serviceStream->stop(); 160 return result; 161 } 162 163 aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) { 164 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 165 if (serviceStream == nullptr) { 166 ALOGE("AAudioService::flushStream(), illegal stream handle = 0x%0x", streamHandle); 167 return AAUDIO_ERROR_INVALID_HANDLE; 168 } 169 return serviceStream->flush(); 170 } 171 172 aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle, 173 pid_t clientProcessId, 174 pid_t clientThreadId, 175 int64_t periodNanoseconds) { 176 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 177 if (serviceStream == nullptr) { 178 ALOGE("AAudioService::registerAudioThread(), illegal stream handle = 0x%0x", streamHandle); 179 return AAUDIO_ERROR_INVALID_HANDLE; 180 } 181 if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { 182 ALOGE("AAudioService::registerAudioThread(), thread already registered"); 183 return AAUDIO_ERROR_INVALID_STATE; 184 } 185 serviceStream->setRegisteredThread(clientThreadId); 186 int err = android::requestPriority(clientProcessId, clientThreadId, 187 DEFAULT_AUDIO_PRIORITY, true /* isForApp */); 188 if (err != 0){ 189 ALOGE("AAudioService::registerAudioThread() failed, errno = %d, priority = %d", 190 errno, DEFAULT_AUDIO_PRIORITY); 191 return AAUDIO_ERROR_INTERNAL; 192 } else { 193 return AAUDIO_OK; 194 } 195 } 196 197 aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle, 198 pid_t clientProcessId, 199 pid_t clientThreadId) { 200 AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle); 201 if (serviceStream == nullptr) { 202 ALOGE("AAudioService::unregisterAudioThread(), illegal stream handle = 0x%0x", 203 streamHandle); 204 return AAUDIO_ERROR_INVALID_HANDLE; 205 } 206 if (serviceStream->getRegisteredThread() != clientThreadId) { 207 ALOGE("AAudioService::unregisterAudioThread(), wrong thread"); 208 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 209 } 210 serviceStream->setRegisteredThread(0); 211 return AAUDIO_OK; 212 } 213