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