Home | History | Annotate | Download | only in oboeservice
      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