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 36using namespace android; 37using namespace aaudio; 38 39typedef enum 40{ 41 AAUDIO_HANDLE_TYPE_STREAM 42} aaudio_service_handle_type_t; 43static_assert(AAUDIO_HANDLE_TYPE_STREAM < HANDLE_TRACKER_MAX_TYPES, "Too many handle types."); 44 45android::AAudioService::AAudioService() 46 : BnAAudioService() { 47} 48 49AAudioService::~AAudioService() { 50} 51 52aaudio_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 101aaudio_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 114AAudioServiceStreamBase *AAudioService::convertHandleToServiceStream( 115 aaudio_handle_t streamHandle) const { 116 return (AAudioServiceStreamBase *) mHandleTracker.get(AAUDIO_HANDLE_TYPE_STREAM, 117 (aaudio_handle_t)streamHandle); 118} 119 120aaudio_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 133aaudio_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 143aaudio_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 153aaudio_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 163aaudio_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 172aaudio_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 197aaudio_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