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 "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